/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* JDOQLCodeGeneration.g
*
* Created on Decemember 10, 2001
*/
{
}
/**
* This class defines the semantic analysis of the EJBQL compiler.
* Input of this pass is the AST as produced by the parser,
* that consists of EJBQLAST nodes.
* The result is a typed EJBQLAST tree.
*
* @author Michael Bouschen
* @author Shing Wai Chan
*/
class JDOQLCodeGeneration extends TreeParser;
{
importVocab = EJBQL;
defaultErrorHandler = false;
}
{
/** Type helper. */
protected TypeSupport typeSupport;
/** Parameter helper. */
protected ParameterSupport paramSupport;
/** I18N support. */
protected final static ResourceBundle msgs =
/** The identification variable used for the candidate class. */
private String candidateClassIdentificationVar;
/** The name of the candidate class. */
private String candidateClassName;
/** The parameter declarations. */
private StringBuffer parameterDecls;
/** The variable declarations. */
private StringBuffer variableDecls;
/** The filter expression. */
private StringBuffer filter;
/** The ordering expression. */
private StringBuffer ordering;
/** The result expression. */
private StringBuffer result;
/** The result type. */
private String resultType;
/** Flag indicating whether the result element is a pc class. */
private boolean isPCResult;
/**
* Flag indicating whether the result element is associated to an
* aggregate function.
*/
private boolean isAggregate = false;
/** Counter for variables defined during codegen. */
private int tmpVarCount = 0;
/**
* Counter indicating how many parenthesis need to be closed
* at the end of the filter expr.
*/
private int parenCount = 0;
/** Flag indicates whether the select clause has DISTINCT. */
private boolean isDistinct = false;
/**
*
*/
{
this.typeSupport = typeSupport;
this.paramSupport = paramSupport;
}
/** */
}
/** */
public void reportError(String s) {
"ERR_JDOQLCodeGenerationError") + s); //NOI18N
}
/**
* Returns the result of an EJBQL compile process.
* A JDOQLElements instances represents all the necessary information to
* create a JDOQL query instance that corresponds to the EJBQL query.
* @return JDOQLElements instance representing the JDOQL query.
*/
public JDOQLElements getJDOQLElements()
{
}
//========= Internal helper methods ==========
/**
* Extracts the name of the candidate class of the JDOQL query from the
* select- and from-clause of the EJBQL query.
*/
throws RecognitionException
{
}
/**
* Calculates the parameter declarations of the JDOQL query from the
* signature of the EJB finsder or selector method.
*/
private void initParameterDeclarations()
{
parameterDecls = new StringBuffer();
// This parameter corresponds to an EJB but the ejbName
// cannot be determined from query.
// Since different EJBs may have the same interfaces,
// the explicit pcClassName cannot be determined.
pcClassName = "java.lang.Object";
} else {
}
}
}
/**
* EJBQL string literals escape a single quote using two single quotes.
* In JDOQL string literals single quotes need not to be escaped =>
* replace '' by '.
*/
{
// first replace '' by '
// Add a hack for a backslash at the end of the literal
// Note, we might need to escape backslashes in the entire string
// literal, if the character following the backslash is an "escaped"
// char such as \n, \n, etc. Needs some further investigation.
}
return ret;
}
/** */
throws RecognitionException
{
// iterate all identification var declarations
// domain of the current variable declaration
// identification variable node
// found the declaration node of the variable we are looking for
// the domain is a abstract schema type => found the var decl
return varNode;
else
// domain is a collectionMemberDecl => use its var decl
return getIdentificationVarDecl(from,
}
}
return null;
}
/**
* Returns the name of a new variable of the JDOQL query.
*/
private String getTmpVarName()
{
// TBD: The name must not conflict with a defined identification variable
int no = tmpVarCount++;
}
/**
* Returns the typeInfo of the element type of a collection valued CMR field.
*/
{
}
}
// rules
: #( q:QUERY
{
variableDecls = new StringBuffer();
filter = new StringBuffer();
ordering = new StringBuffer();
result = new StringBuffer();
}
)
;
| i:IDENTIFICATION_VAR { var = i; }
;
// ----------------------------------
// rules: from clause
// ----------------------------------
: #( FROM ( identificationVarDecl )+ )
;
;
: #( IN
{
// Please note, the FROM clause is processed prior to the
// WHERE clause, so a filter of length == 0 means we are
// processing the first IN clause of the FROM clause.
// We need to add an & operator and an open parenthesis for
// all IN clauses but the first one. The parenthesis ensure
// the resulting filter is portable, meaning the contains
// clause must be the left expression of an AND-expression
// where the variable is used in the right expression.
parenCount++;
}
}
{
// generate varibale declaration
v.getTypeInfo()));
// now generate the contains clause
}
)
;
: #( RANGE
)
{
// Do not generate variable decl for identification variable
// that represents the candidate class
v.getTypeInfo()));
}
}
;
// ----------------------------------
// rules: select clause
// ----------------------------------
{
resultType = isPCResult ?
}
;
: // the code generation of this distinct is postponed until projection
// checking as there is no need to generate distinct outside
// aggregate functions
DISTINCT { isDistinct = true; }
| // empty rule
;
| // empty rule
;
: #( AVG
{
isAggregate = true;
}
)
| #( MAX
{
isAggregate = true;
}
)
| #( MIN
{
isAggregate = true;
}
)
| #( SUM
{
isAggregate = true;
}
)
| #( COUNT
{
isAggregate = true;
}
)
| {
if (isDistinct) {
}
}
| {
if (isDistinct) {
}
}
;
// ----------------------------------
// rules: where clause
// ----------------------------------
: #( WHERE
{
// filter.length() > 0 means there are one or more contains
// clauses generated from parsing the from clause =>
// enclose the where clause expression into parenthesis.
parenCount++;
}
}
{
while (parenCount > 0) {
parenCount--;
}
}
)
;
// ----------------------------------
// rules: orderby clause
// ----------------------------------
: #( ORDER
(
{
}
}
(
|
)
)+
)
|
;
// ----------------------------------
// rules: expression
// ----------------------------------
| betweenExpr[buf]
;
)
)
;
)
)
)
)
)
)
;
)
)
)
)
;
: #( UNARY_PLUS
)
)
)
;
{
}
: #( BETWEEN
{
}
{
}
)
| #( NOT_BETWEEN
{
}
{
}
)
;
: #( LIKE
)
)
;
| // empty rule
;
: s:STRING_LITERAL
{
}
;
{
}
: #( IN
{
}
(
{
// create a new StringBuffer for the new elementExpr
elementExpr = new StringBuffer();
}
{
}
)*
{
}
)
| #( NOT_IN
{
}
(
{
// create a new StringBuffer for the new elementExpr
elementExpr = new StringBuffer();
}
{
}
)*
{
}
)
;
: #( NULL
)
| #( NOT_NULL
)
;
: #( EMPTY
)
)
;
{
}
: #( MEMBER
{
// Use the element type as variable type. The value might be
// cannot uniquely map to a PC class during deployment.
// generate varibale declaration
}
)
| #( NOT_MEMBER
{
// Use the element type as variable type. The value might be
// cannot uniquely map to a PC class during deployment.
// generate varibale declaration
}
)
;
;
)
;
: // EJBQL: SUBSTRING(string, start, length) ->
// JDOQL: string.substring(start-1, start+length-1)
#( SUBSTRING
start:.
length:.
)
{
// Optimization: start and length are constant values =>
// calulate beginIndex and endIndex of the JDOQL substring
// call at compile time.
}
else {
}
}
;
: #( LENGTH
)
;
{
}
: // EJBQL: LOCATE(pattern, string) ->
// JDOQL: (string.indexOf(pattern) + 1)
// EJBQL: LOCATE(pattern, string, start) ->
// JDOQL: (string.indexOf(pattern, start - 1) + 1)
)
;
: start:.
{
// Optimization: start is a constant value =>
// calulate startIndex of JDOQL indexOf call at compile time.
}
else {
}
}
| // empty rule
;
: #( ABS
)
;
: #( SQRT
)
;
: #( MOD
)
;
;
: TRUE
| FALSE
| stringLiteral[buf]
| i:INT_LITERAL
{
}
| l:LONG_LITERAL
{
}
| f:FLOAT_LITERAL
{
}
| d:DOUBLE_LITERAL
{
}
;
: s:STRING_LITERAL
{
}
;
: #( CMP_FIELD_ACCESS
)
)
)
{
}
{
}
| i:IDENT
{
}
;
;
{
}
;