Fix for bug 454937
- DBWS DDLParser: type parsing fails if a member function/procedure is encountered
- DDLParser.jjt : add MEMBER and STATIC keywords, make parseType()/columnDeclarations(), aware that a member function/procedure may be found, added memberFunctionOrProcedureDeclaration() to skip member functions/procedures, added memberFunctionOrProcedure() token handler, line ending/tab fixes
- TypeDDLTestSuite.java : add testTypeWithMemberFunctions() and testTypeWithMemberFunctionsAndConstructors() (dependency on previous fix to DDLParser) to test member functions and procedures, static/non-static.
- Testing: 100%
Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
diff --git a/oracleddlparser/src/main/jjtree/org/eclipse/persistence/tools/oracleddl/parser/DDLParser.jjt b/oracleddlparser/src/main/jjtree/org/eclipse/persistence/tools/oracleddl/parser/DDLParser.jjt
index 417b93c..c529099 100644
--- a/oracleddlparser/src/main/jjtree/org/eclipse/persistence/tools/oracleddl/parser/DDLParser.jjt
+++ b/oracleddlparser/src/main/jjtree/org/eclipse/persistence/tools/oracleddl/parser/DDLParser.jjt
@@ -253,6 +253,7 @@
| <R_IS: "IS">
| <R_LIKE: "LIKE">
| <R_LOCK: "LOCK">
+ | <R_MEMBER: "MEMBER">
| <R_MINUS: "MINUS">
| <R_MODE: "MODE">
| <R_NOCOMPRESS: "NOCOMPRESS">
@@ -275,6 +276,7 @@
| <R_SIZE: "SIZE">
| <R_SQL: "SQL">
| <R_START: "START">
+ | <R_STATIC: "STATIC">
| <R_SUBTYPE: "SUBTYPE">
| <R_TABAUTH: "TABAUTH">
| <R_TABLE: "TABLE">
@@ -665,7 +667,7 @@
if (schema != null) {
((ObjectType)databaseType).setSchema(schema);
}
- } columnDeclarations(databaseType) constructorDeclaration() <O_CLOSEPAREN>
+ } columnDeclarations(databaseType) constructorDeclaration() memberFunctionOrProcedureDeclaration() <O_CLOSEPAREN>
| <K_VARRAY> <O_OPENPAREN> vsize=<S_NUMBER> <O_CLOSEPAREN> <R_OF>
{
databaseType = new VArrayType(typeName);
@@ -699,7 +701,7 @@
void columnDeclarations(CompositeDatabaseType enclosingType):
{}
{
- (LOOKAHEAD(2) constructor() | columnDeclaration(enclosingType) | constraintDeclaration(enclosingType) )
+ (LOOKAHEAD(2) constructor() | columnDeclaration(enclosingType) | constraintDeclaration(enclosingType) | memberFunctionOrProcedure() )
[ <O_COMMA> columnDeclarations(enclosingType) ]
}
@@ -1641,6 +1643,15 @@
argument(procedureType) ( <O_COMMA> argument(procedureType) )*
}
+// Member Function/Procedure Specification - ignore both
+void memberFunctionOrProcedureDeclaration() :
+{}
+{
+ [ <R_STATIC> ] [ <R_MEMBER> ]
+ [ ( <R_PROCEDURE> skipToClosingParen() <O_CLOSEPAREN> | <R_FUNCTION> skipToReturn() datatype() ) ]
+ [ <O_COMMA> memberFunctionOrProcedureDeclaration() ]
+}
+
// Function Specification
void functionSpec(PLSQLPackageType packageType) :
{String functionName= null;
@@ -1920,4 +1931,13 @@
token = t;
}
+}
+
+void memberFunctionOrProcedure():
+{ Token t = token;
+}
+{
+ [ <R_STATIC> ] <R_MEMBER> ( <R_FUNCTION> | <R_PROCEDURE> ) {
+ token = t;
+ }
}
\ No newline at end of file
diff --git a/oracleddlparser/src/test/java/org/eclipse/persistence/tools/oracleddl/test/ddlparser/TypeDDLTestSuite.java b/oracleddlparser/src/test/java/org/eclipse/persistence/tools/oracleddl/test/ddlparser/TypeDDLTestSuite.java
index 2095fcc..97c6212 100644
--- a/oracleddlparser/src/test/java/org/eclipse/persistence/tools/oracleddl/test/ddlparser/TypeDDLTestSuite.java
+++ b/oracleddlparser/src/test/java/org/eclipse/persistence/tools/oracleddl/test/ddlparser/TypeDDLTestSuite.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 Oracle. All rights reserved.
+ * Copyright (c) 2011-2014 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
@@ -25,6 +25,7 @@
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
//DDL imports
@@ -287,5 +288,90 @@
assertTrue("type with multiple constructors did not parse:\n" + message, worked);
assertEquals("incorrect type name " + TYPE_NAME, TYPE_NAME, typeWithMultipleConstructors.getTypeName());
}
+
+ static final String MEMBER_FUNCTION_TYPE_NAME = "MEMBER_FUNCTION_TYPE";
+ static final String CREATE_MEMBER_FUNCTION_TYPE = CREATE_TYPE_PREFIX + MEMBER_FUNCTION_TYPE_NAME + " AS OBJECT(" +
+ "\n status1 varchar2(5)," +
+ "\n status2 varchar2(5)," +
+ "\n status3 varchar2(5)," +
+ "\n member function my_function1 return varchar2," +
+ "\n member function my_function2 return varchar2," +
+ "\n static member function my_function3 return varchar2," +
+ "\n member function my_function4 return varchar2," +
+ "\n static member function my_function5 return varchar2," +
+ "\n MEMBER PROCEDURE display1 (SELF IN OUT NOCOPY solid_typ)," +
+ "\n MEMBER PROCEDURE display2 (SELF IN OUT NOCOPY solid_typ)," +
+ "\n static MEMBER PROCEDURE display3 (SELF IN OUT NOCOPY solid_typ)," +
+ "\n static MEMBER PROCEDURE display4 (SELF IN OUT NOCOPY solid_typ)," +
+ "\n member function my_function6 return varchar2," +
+ "\n static member function my_function7 return varchar2" +
+ "\n)";
+
+ @Test
+ public void testTypeWithMemberFunctions() {
+ parser.ReInit(new StringReader(CREATE_MEMBER_FUNCTION_TYPE));
+ boolean worked = true;
+ String message = "";
+ ObjectType typeWithMemberFunctions = null;
+ try {
+ typeWithMemberFunctions = (ObjectType)parser.parseType();
+ } catch (ParseException pe) {
+ pe.printStackTrace();
+ message = pe.getMessage();
+ worked = false;
+ }
+ assertTrue("Parse error:\n" + message, worked);
+ assertNotNull("Type should not be null", typeWithMemberFunctions);
+ assertEquals("Incorrect type name: " + MEMBER_FUNCTION_TYPE_NAME, MEMBER_FUNCTION_TYPE_NAME, typeWithMemberFunctions.getTypeName());
+ assertEquals("Type should have three fields", 3, typeWithMemberFunctions.getFields().size());
+ }
+
+ static final String MEMBER_FUNCTION_CONS_TYPE_NAME = "MEMBER_FUNCTION_CONS_TYPE";
+ static final String CREATE_MEMBER_FUNCTION_CONS_TYPE =
+ "CREATE OR REPLACE TYPE " + MEMBER_FUNCTION_CONS_TYPE_NAME + " AS OBJECT(" +
+ "\n status1 varchar2(5)," +
+ "\n status2 varchar2(5)," +
+ "\n status3 varchar2(5)," +
+ "\n constructor function my_type (" +
+ "\n i_status in varchar2," +
+ "\n i_comments in varchar2 := null" +
+ "\n ) return self as result," +
+ "\n constructor function my_type (" +
+ "\n i_status in boolean," +
+ "\n i_orauser in varchar2," +
+ "\n i_comments in varchar2" +
+ "\n ) return self as result," +
+ "\n member function my_function1 return varchar2," +
+ "\n member function my_function2 return varchar2," +
+ "\n static member function my_function3 return varchar2," +
+ "\n member function my_function4 return varchar2," +
+ "\n static member function my_function5 return varchar2," +
+ "\n MEMBER PROCEDURE display1 (SELF IN OUT NOCOPY solid_typ)," +
+ "\n MEMBER PROCEDURE display2 (SELF IN OUT NOCOPY solid_typ)," +
+ "\n static MEMBER PROCEDURE display3 (SELF IN OUT NOCOPY solid_typ)," +
+ "\n static MEMBER PROCEDURE display4 (SELF IN OUT NOCOPY solid_typ)," +
+ "\n member function my_function6 return varchar2," +
+ "\n static member function my_function7 return varchar2" +
+ "\n)";
+
+ @Test
+ public void testTypeWithMemberFunctionsAndConstructors() {
+ parser.ReInit(new StringReader(CREATE_MEMBER_FUNCTION_CONS_TYPE));
+ boolean worked = true;
+ String message = "";
+ ObjectType typeWithMemberFunctions = null;
+ try {
+ typeWithMemberFunctions = (ObjectType)parser.parseType();
+ } catch (ParseException pe) {
+ pe.printStackTrace();
+ message = pe.getMessage();
+ worked = false;
+ }
+ assertTrue("Parse error:\n" + message, worked);
+ assertNotNull("Type should not be null", typeWithMemberFunctions);
+ assertEquals("incorrect type name: " + MEMBER_FUNCTION_CONS_TYPE_NAME, MEMBER_FUNCTION_CONS_TYPE_NAME,
+ typeWithMemberFunctions.getTypeName());
+ assertEquals("Type should have three fields", 3, typeWithMemberFunctions.getFields().size());
+ }
}
\ No newline at end of file