Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/Tree.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/Tree.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/Tree.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/Tree.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,1021 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.jdoql.tree; + +import antlr.collections.AST; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedList; +import java.util.Map; + +import org.apache.jdo.impl.jdoql.jdoqlc.JDOQLTokenTypes; +import org.apache.jdo.jdoql.JDOQueryException; +import org.apache.jdo.jdoql.tree.AndExpression; +import org.apache.jdo.jdoql.tree.CandidateClass; +import org.apache.jdo.jdoql.tree.CastExpression; +import org.apache.jdo.jdoql.tree.ComplementExpression; +import org.apache.jdo.jdoql.tree.ConditionalAndExpression; +import org.apache.jdo.jdoql.tree.ConditionalOrExpression; +import org.apache.jdo.jdoql.tree.ConstantExpression; +import org.apache.jdo.jdoql.tree.Declaration; +import org.apache.jdo.jdoql.tree.DivideExpression; +import org.apache.jdo.jdoql.tree.EqualsExpression; +import org.apache.jdo.jdoql.tree.Expression; +import org.apache.jdo.jdoql.tree.ExpressionFactory; +import org.apache.jdo.jdoql.tree.FieldAccessExpression; +import org.apache.jdo.jdoql.tree.GreaterThanEqualsExpression; +import org.apache.jdo.jdoql.tree.GreaterThanExpression; +import org.apache.jdo.jdoql.tree.IdentifierExpression; +import org.apache.jdo.jdoql.tree.LessThanEqualsExpression; +import org.apache.jdo.jdoql.tree.LessThanExpression; +import org.apache.jdo.jdoql.tree.MethodCallExpression; +import org.apache.jdo.jdoql.tree.MinusExpression; +import org.apache.jdo.jdoql.tree.Node; +import org.apache.jdo.jdoql.tree.NodeVisitor; +import org.apache.jdo.jdoql.tree.NotEqualsExpression; +import org.apache.jdo.jdoql.tree.NotExpression; +import org.apache.jdo.jdoql.tree.OrExpression; +import org.apache.jdo.jdoql.tree.ParameterDeclaration; +import org.apache.jdo.jdoql.tree.PlusExpression; +import org.apache.jdo.jdoql.tree.QueryTree; +import org.apache.jdo.jdoql.tree.StaticFieldAccessExpression; +import org.apache.jdo.jdoql.tree.TimesExpression; +import org.apache.jdo.jdoql.tree.UnaryMinusExpression; +import org.apache.jdo.jdoql.tree.UnaryPlusExpression; +import org.apache.jdo.jdoql.tree.VariableDeclaration; + + +/** + * This node represents the root of a query tree. + * You can use it to factorize this node's children, as there are + * candidate class, declarations, filter expression and + * ordering expressions. + * + * @author Michael Watzek + */ +public final class Tree extends NodeImpl implements QueryTree, ExpressionFactory +{ + static final JavaKeyWords javaKeyWords = new JavaKeyWords(); + + CandidateClass candidateClass; + Map parameterMap; + List parameterList; + Map variableMap; + List orderings; + Expression filter; + + String serializedCandidateClassName; // serialization support + + /** + * The noarg constructor is called by persistence manager internal. + */ + public Tree() + { super( JDOQLTokenTypes.QUERY_TREE, "QueryTree", null ); //NOI18N + init(); + } + + /** + * This constructor is called by semantic analysis only. + * @param candidateClass the candidate class + * @param parameterDeclarations the antlr node containing all + * parameter declaration nodes as siblings + * @param variableDeclarations the antlr node containing all + * variable declaration nodes as siblings + * @param orderingExpressions the antlr node containing all + * ordering nodes as siblings + * @param filter the filter expression + */ + public Tree(CandidateClass candidateClass, + ParameterDecl parameterDeclarations, + VariableDecl variableDeclarations, + OrderingExpr orderingExpressions, + Expr filter) + { this(); + Class clazz = candidateClass.getJavaClass(); + this.clazz = clazz; + this.candidateClass = candidateClass; + for( ParameterDecl current=parameterDeclarations; current!=null; current = (ParameterDecl)current.getNextSibling() ) + { this.parameterMap.put( current.getName(), current ); + this.parameterList.add( current ); + } + for( VariableDecl current=variableDeclarations; current!=null; current = (VariableDecl)current.getNextSibling() ) + this.variableMap.put( current.getName(), current ); + for( OrderingExpr current=orderingExpressions; current!=null; current = (OrderingExpr)current.getNextSibling() ) + this.orderings.add( current ); + this.filter = filter; + initANTLRAST(); + } + + /** + * Creates and returns a copy of this object. + * @return the copy + * @exception CloneNotSupportedException thrown by <code>super.clone()</code> + */ + protected Object clone() throws CloneNotSupportedException + { Tree copy = (Tree) super.clone(); + init(); + return copy; + } + + /** + * Sets the candidate class for this query tree. + * This method throws <code>NullPointerException</code> if the argument + * <code>clazz</code> is <code>null</code>. + * Otherwise this method invalidates this tree: + * Parameters, variables, orderings and the filter are nullified. + * @param clazz the candidate class + * @exception <code>NullPointerException</code> if the argument <code>clazz</code> is null + */ + public void setCandidateClass(Class clazz) + { if( clazz==null ) + throw new NullPointerException(); + if( this.clazz!=null ) + reset(); + this.clazz = clazz; + this.candidateClass = new CandidateClassImpl( new TypeImpl(clazz) ); + } + + /** + * Declares a parameter for this query tree. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>type</code> or <code>parameter</code> are <code>null</code>. + * If a parameter is already declared having the same name + * as the argument <code>parameter</code>, then that declaration is + * replaced by this declaration. + * Once you have declared a parameter, you can access it using method + * <code>newIdentifier</code>. + * Please note: You can not declare a parameter and a variable having the same name. + * @param clazz the instance of a Java class which is the type of the declared parameter + * @param parameter the name of the declared parameter + * @exception NullPointerException if type or parameter are null + * @exception JDOQueryException if a variable has been declared with the same name + */ + public void declareParameter(Class clazz, String parameter) + { if( clazz==null || + parameter==null ) + throw new NullPointerException(); + if( this.variableMap.get(parameter)!=null ) + throw new JDOQueryException( msg.msg("EXC_ParameterVariableCollision", parameter) ); //NOI18N + ParameterDeclaration decl = new ParameterDecl( new TypeImpl(clazz), parameter ); + this.parameterMap.put( parameter, decl ); + this.parameterList.add( decl ); + } + + /** + * Declares a variable for this query tree. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>type</code> or <code>variable</code> are <code>null</code>. + * If a variable is already declared having the same name + * as the argument <code>variable</code>, then that declaration is + * replaced by this declaration. + * Once you have declared a variable, you can access it using method + * <code>newIdentifier</code>. + * Please note: You can not declare a parameter and a variable having the same name. + * @param clazz the instance of a Java class which is the type of the declared variable + * @param variable the name of the declared variable + * @exception NullPointerException if type or variable are null + * @exception JDOQueryException if a parameter has been declared with the same name + */ + public void declareVariable(Class clazz, String variable) + { if( clazz==null || + variable==null ) + throw new NullPointerException(); + if( this.parameterMap.get(variable)!=null ) + throw new JDOQueryException( msg.msg("EXC_VariableParameterCollision", variable) ); //NOI18N + VariableDeclaration decl = new VariableDecl( new TypeImpl(clazz), variable ); + this.variableMap.put( variable, decl ); + } + + /** + * Adds an ascending ordering expression to this query tree. + * This method throws <code>NullPointerException</code> if the argument + * <code>expression</code> is <code>null</code>. + * The order of adding ascending and descending ordering expressions defines + * the order of instances in the result collection of an executed query + * instance corresponding with this query tree. + * @param expression the order expression + * @exception NullPointerException if expression is null + */ + public void addAscendingOrdering(Expression expression) + { if( expression==null ) + throw new NullPointerException(); + this.orderings.add( new AscendingOrderingExpr(expression) ); + } + + /** + * Adds an descending ordering expression to this query tree. + * This method throws <code>NullPointerException</code> if the argument + * <code>expression</code> is <code>null</code>. + * The order of adding ascending and descending ordering expressions defines + * the order of instances in the result collection of an executed query + * instance corresponding with this query tree. + * @param expression the order expression + * @exception NullPointerException if expression is null + */ + public void addDescendingOrdering(Expression expression) + { if( expression==null ) + throw new NullPointerException(); + this.orderings.add( new DescendingOrderingExpr(expression) ); + } + + /** + * Sets the filter expression for this query tree. + * This method throws <code>NullPointerException</code> if the argument + * <code>filter</code> is <code>null</code>. + * @param filter the filter expression + * @exception NullPointerException if filter is null + * @exception JDOQueryException if the result type of filter is a non boolean type + */ + public void setFilter(Expression filter) + { if( filter==null ) + throw new NullPointerException(); + if( filter.getJavaClass()!=Boolean.class && + filter.getJavaClass()!=boolean.class ) + throw new JDOQueryException( msg.msg("EXC_IllegalTypeForFilterExpression", filter) ); //NOI18N + this.filter = filter; + } + + /** + * Returns the candidate class. + * @return the candidate class + */ + public Class getCandidateClass() + { if( this.candidateClass==null ) + throw new JDOQueryException( msg.msg("EXC_MissingCandidateClass") ); //NOI18N + return this.candidateClass.getJavaClass(); + } + + /** + * Returns a map containing all declared variables. + * This map contains variable names as keys and instances of + * <code>VariableDeclaration</code> as values. + * @return the map of declared variables + */ + public Map getDeclaredVariables() + { return this.variableMap; + } + + /** + * Returns a map containing all declared parameters. + * This map contains parameter names as keys and instances of + * <code>ParameterDeclaration</code> as values. + * @return the map of declared parameters + */ + public Map getDeclaredParameters() + { return this.parameterMap; + } + + /** + * Returns a list of all declared parameters. The order of entries is + * defined by the order of calls <code>declareParameter</code>. + * This list contains instances of + * <code>ParametersDeclaration</code> as entries. + * @return the list of declared parameters + */ + public List getDeclaredParametersAsList() + { return this.parameterList; + } + + /** + * Returns the filter expression of this query tree. + * @return the filter or null. + */ + public Expression getFilter() + { return (Expression) this.filter; + } + + /** + * Returns a list of all added ordering expressions. + * The order of entries is defined by the order of calls + * <code>addAscendingOrdering</code> and <code>addDescendingOrdering</code>. + * This list contains instances of + * <code>OrderingExpression</code> as entries. + * @return the list of declared parameters + */ + public List getOrderingExpressions() + { return this.orderings; + } + + /** + * Returns an instance of either <code>ThisExpression</code> or + * <code>VariableAccessExpression</code> or + * <code>ParameterAccessExpression</code> or <code>FieldAccessExpression</code> + * depending on the fact which of the classes the argument + * <code>identifier</code> maps to. + * This method throws <code>NullPointerException</code> if the argument + * <code>identifier</code> is <code>null</code> or the candidate class is not set. + * Note: If you pass <code>"this"</code> as an identifier name, then + * an instance of <code>ThisExpression</code> is returned. If you pass any + * other java key word as an identifier name, then an instance of + * <code>JDOQueryException</code> is thrown. + * @param identifier the name of the identifier access expression + * @return the specialized identifier access expression instance + * @exception NullPointerException if identifier is null + * @exception JDOQueryException if identifier is a java key word. + */ + public IdentifierExpression newIdentifier(String identifier) + { if( identifier==null ) + throw new NullPointerException(); + IdentifierExpression identifierExpr; + if( identifier.equals("this") ) //NOI18N + identifierExpr = new ThisExpr( this.candidateClass==null?null:this.candidateClass.getJavaClass() ); + else + { if( javaKeyWords.isJavaKeyWord(identifier) ) + throw new JDOQueryException( msg.msg("EXC_IllegalIdentifier", identifier) ); //NOI18N + Declaration decl = (Declaration) this.variableMap.get( identifier ); + if( decl==null ) + { decl = (Declaration) this.parameterMap.get( identifier ); + if( decl==null ) + //identifierExpr = new FieldAccessExpr( new ThisExpr(this.candidateClass.getJavaClass()), identifier ); + identifierExpr = new IdentifierExpr( JDOQLTokenTypes.IDENT, identifier, null ); + else + identifierExpr = new ParameterAccessExpr( decl.getJavaClass(), identifier ); + } + else + identifierExpr = new VariableAccessExpr( decl.getJavaClass(), identifier ); + } + return identifierExpr; + } + + /** + * Returns an instance of <code>FieldAccessExpression</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>target</code> or <code>fieldName</code> are <code>null</code>. + * @param target the target expression of the field access expression + * @param fieldName the name of the field to access + * @return the field access expression instance + * @exception NullPointerException if target or fieldName are null + */ + public FieldAccessExpression newFieldAccess(Expression target, String fieldName) + { if( target==null || + fieldName==null ) + throw new NullPointerException(); + return new FieldAccessExpr( target, fieldName ); + } + + /** + * Returns an instance of <code>StaticFieldAccessExpression</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>clazz</code> or <code>fieldName</code> are <code>null</code>. + * @param clazz the class instance defining the field + * @param fieldName the name of the field to access + * @return the static field access expression instance + * @exception NullPointerException if clazz or fieldName are null + */ + public StaticFieldAccessExpression newFieldAccess(Class clazz, String fieldName) + { if( clazz==null || + fieldName==null ) + throw new NullPointerException(); + return new StaticFieldAccessExpr( new TypeImpl(clazz), fieldName ); + } + + /** + * Returns an instance of <code>MethodCallExpression</code>. + * Note: If the method corresponding with methodName does not have any + * arguments, then the argument <code>arguments</code> is ignored. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>target</code> or <code>methodName</code> + * are <code>null</code>. + * @param target the target expression of the method call expression + * @param methodName the name of the method + * @param arguments the array of arguments + * @return the specialized method call expression + * @exception NullPointerException if target or methodName are null + * @exception JDOQueryException if methodName is not one of + * <code>"contains"</code>, <code>"endsWith"</code>, <code>"isEmpty"</code> + * or <code>"startsWith"</code>. + */ + public MethodCallExpression newMethodCall(Expression target, String methodName, Expression[] arguments) + { if( target==null || + methodName==null ) + throw new NullPointerException(); + MethodCallExpression methodCall; + if( methodName.equals("contains") ) //NOI18N + methodCall = new ContainsCallExpr( target, arguments ); + else if( methodName.equals("endsWith") ) //NOI18N + methodCall = new EndsWithCallExpr( target, arguments ); + else if( methodName.equals("isEmpty") ) //NOI18N + methodCall = new IsEmptyCallExpr( target ); + else if( methodName.equals("startsWith") ) //NOI18N + methodCall = new StartsWithCallExpr( target, arguments ); + else + throw new JDOQueryException( msg.msg("EXC_NonSupportedMethodCall", methodName) ); //NOI18N + return methodCall; + } + + /** + * Returns an instance of <code>CastExpression</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>clazz</code> or <code>expression</code> + * are <code>null</code>. + * @param clazz the Java class to cast the argument <code>expression</code> to + * @param expression the expression to cast + * @return the cast expression instance + * @exception NullPointerException if expression is null + */ + public CastExpression newCast(Class clazz, Expression expression) + { if( clazz==null || + expression==null ) + throw new NullPointerException(); + return new CastExpr( new TypeImpl(clazz), expression ); + } + + /** + * Returns an instance of <code>ConstantExpression</code>. + * This method handles <code>null</code> as a constant expression. + * @param value the object wrapped by the constant expression + * @return the constant expression instance + */ + public ConstantExpression newConstant(Object value) + { return ConstantExpr.newConstant( value ); + } + + /** + * Returns an instance of <code>BooleanLiteralExpression</code>. + * @param b the value wrapped by the boolean expression + * @return the boolean expression instance + */ + public ConstantExpression newConstant(boolean b) + { return new BooleanLiteralExpr( b ); + } + + /** + * Returns an instance of <code>ByteLiteralExpression</code>. + * @param b the value wrapped by the byte expression + * @return the byte expression instance + */ + public ConstantExpression newConstant(byte b) + { return new ByteLiteralExpr( b ); + } + + /** + * Returns an instance of <code>CharLiteralExpression</code>. + * @param c the value wrapped by the char expression + * @return the char expression instance + */ + public ConstantExpression newConstant(char c) + { return new CharLiteralExpr( c ); + } + + /** + * Returns an instance of <code>DoubleLiteralExpression</code>. + * @param d the value wrapped by the double expression + * @return the double expression instance + */ + public ConstantExpression newConstant(double d) + { return new DoubleLiteralExpr( d ); + } + + /** + * Returns an instance of <code>FloatLiteralExpression</code>. + * @param f the value wrapped by the float expression + * @return the float expression instance + */ + public ConstantExpression newConstant(float f) + { return new FloatLiteralExpr( f ); + } + + /** + * Returns an instance of <code>IntLiteralExpression</code>. + * @param i the value wrapped by the int expression + * @return the int expression instance + */ + public ConstantExpression newConstant(int i) + { return new IntLiteralExpr( i ); + } + + /** + * Returns an instance of <code>LongLiteralExpression</code>. + * @param l the value wrapped by the long expression + * @return the long expression instance + */ + public ConstantExpression newConstant(long l) + { return new LongLiteralExpr( l ); + } + + /** + * Returns an instance of <code>ShortLiteralExpression</code>. + * @param s the value wrapped by the short expression + * @return the short expression instance + */ + public ConstantExpression newConstant(short s) + { return new ShortLiteralExpr( s ); + } + + /** + * Returns a complement expression for the argument + * <code>expr</code>. + * This method throws <code>NullPointerException</code> if the argument + * <code>expr</code> is <code>null</code>. + * @param expr the expression argument for the operation + * @return the complement expression instance + * @exception NullPointerException if expr is null + */ + public ComplementExpression newComplement(Expression expr) + { if( expr==null ) + throw new NullPointerException(); + return new ComplementExpr( expr ); + } + + /** + * Returns a unary minus expression for the argument + * <code>expr</code>. + * This method throws <code>NullPointerException</code> if the argument + * <code>expr</code> is <code>null</code>. + * @param expr the expression argument for the operation + * @return the unary minus expression instance + * @exception NullPointerException if expr is null + */ + public UnaryMinusExpression newMinus(Expression expr) + { if( expr==null ) + throw new NullPointerException(); + return new UnaryMinusExpr( expr ); + } + + /** + * Returns a not expression for the argument + * <code>expr</code>. + * This method throws <code>NullPointerException</code> if the argument + * <code>expr</code> is <code>null</code>. + * @param expr the expression argument for the operation + * @return the not expression instance + * @exception NullPointerException if expr is null + */ + public NotExpression newNot(Expression expr) + { if( expr==null ) + throw new NullPointerException(); + return new NotExpr( expr ); + } + + /** + * Returns a plus expression for the argument + * <code>expr</code>. + * This method throws <code>NullPointerException</code> if the argument + * <code>expr</code> is <code>null</code>. + * @param expr the expression argument for the operation + * @return the plus expression instance + * @exception NullPointerException if expr is null + */ + public UnaryPlusExpression newPlus(Expression expr) + { if( expr==null ) + throw new NullPointerException(); + return new UnaryPlusExpr( expr ); + } + + /** + * Returns an and expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the and expression instance + * @exception NullPointerException if left or right are null + */ + public AndExpression newAnd(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new AndExpr( left, right ); + } + + /** + * Returns a conditional and expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the conditional and expression instance + * @exception NullPointerException if left or right are null + */ + public ConditionalAndExpression newConditionalAnd(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new ConditionalAndExpr( left, right ); + } + + /** + * Returns a conditional or expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the conditional or expression instance + * @exception NullPointerException if left or right are null + */ + public ConditionalOrExpression newConditionalOr(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new ConditionalOrExpr( left, right ); + } + + /** + * Returns a divide expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the divide expression instance + * @exception NullPointerException if left or right are null + */ + public DivideExpression newDivide(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new DivideExpr( left, right ); + } + + /** + * Returns an equals expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the equals expression instance + * @exception NullPointerException if left or right are null + */ + public EqualsExpression newEquals(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new EqualsExpr( left, right ); + } + + /** + * Returns a greater than expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the greater than expression instance + * @exception NullPointerException if left or right are null + */ + public GreaterThanExpression newGreaterThan(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new GreaterThanExpr( left, right ); + } + + /** + * Returns a greater than equals expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the greater than equals expression instance + * @exception NullPointerException if left or right are null + */ + public GreaterThanEqualsExpression newGreaterThanEquals(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new GreaterThanEqualsExpr( left, right ); + } + + /** + * Returns a less than expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the less than expression instance + * @exception NullPointerException if left or right are null + */ + public LessThanExpression newLessThan(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new LessThanExpr( left, right ); + } + + /** + * Returns a less than equals expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the less than equals expression instance + * @exception NullPointerException if left or right are null + */ + public LessThanEqualsExpression newLessThanEquals(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new LessThanEqualsExpr( left, right ); + } + + /** + * Returns a minus expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the minus expression instance + * @exception NullPointerException if left or right are null + */ + public MinusExpression newMinus(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new MinusExpr( left, right ); + } + + /** + * Returns a not equals expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the not equals expression instance + * @exception NullPointerException if left or right are null + */ + public NotEqualsExpression newNotEquals(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new NotEqualsExpr( left, right ); + } + + /** + * Returns a plus expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the plus expression instance + * @exception NullPointerException if left or right are null + */ + public PlusExpression newPlus(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new PlusExpr( left, right ); + } + + /** + * Returns an or expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the or expression instance + * @exception NullPointerException if left or right are null + */ + public OrExpression newOr(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new OrExpr( left, right ); + } + + /** + * Returns a times expression for the arguments + * <code>left</code> and <code>right</code>. + * This method throws <code>NullPointerException</code> if one of the arguments + * <code>left</code> or <code>right</code> are <code>null</code>. + * @param left the left expression argument for the operation + * @param right the right expression argument for the operation + * @return the times expression instance + * @exception NullPointerException if left or right are null + */ + public TimesExpression newTimes(Expression left, Expression right) + { if( left==null || + right==null ) + throw new NullPointerException(); + return new TimesExpr( left, right ); + } + + /** + * Returns the children of this node. + * This method ensures that the children array corresponds with + * the children nodes of the underlying ANTLR tree structure. + * @return the children + * @exception JDOQueryException if the candidate class is not set + */ + public Node[] getChildren() + { initANTLRAST(); + return super.getChildren(); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + */ + public void arrive(NodeVisitor visitor) + { visitor.arrive( this ); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + * @param results the result array + * @return the object returned by the visitor instance + */ + public Object leave(NodeVisitor visitor, Object[] results) + { return visitor.leave( this, results ); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + * @param resultOfPreviousChild the result computed by leaving the + * previous child node. + * @param indexOfNextChild the index of the next child node + * @return the boolean value returned by the visitor instance + */ + public boolean walkNextChild(NodeVisitor visitor, Object resultOfPreviousChild, int indexOfNextChild) + { return visitor.walkNextChild( this, resultOfPreviousChild, indexOfNextChild ); + } + + /** + * Ensures that this node has a corresponding ANTLR tree structure. + * @exception JDOQueryException if the candidate class is not set + */ + public void initANTLRAST() + { if( getFirstChild()==null ) + { if( this.candidateClass==null ) + throw new JDOQueryException( msg.msg("EXC_MissingCandidateClass") ); //NOI18N + + setFirstChild( (AST) this.candidateClass ); + AST current = (AST) candidateClass; + for( Iterator i=this.parameterList.iterator(); i.hasNext(); ) + { current.setNextSibling( (AST) i.next() ); + current = current.getNextSibling(); + } + for( Iterator i=this.variableMap.values().iterator(); i.hasNext(); ) + { current.setNextSibling( (AST) i.next() ); + current = current.getNextSibling(); + } + for( Iterator i=this.orderings.iterator(); i.hasNext(); ) + { current.setNextSibling( (AST) i.next() ); + current = current.getNextSibling(); + } + current.setNextSibling( (AST) this.filter ); + } + } + + /** + * Nullifies the declared fields in this node as well as the underlying + * ANTLR tree structure. + */ + private void reset() + { this.candidateClass = null; + this.parameterMap.clear(); + this.parameterList.clear(); + this.variableMap.clear(); + this.orderings.clear(); + this.filter = null; + this.children = null; + + this.parent = null; + setFirstChild( null ); + setChildren( null ); + } + + private void init() + { this.candidateClass = null; + this.parameterMap = new HashMap(); + this.parameterList = new LinkedList(); + this.variableMap = new HashMap(); + this.orderings = new LinkedList(); + this.filter = null; + } + + static Class toWrapperClass(Class clazz) + { if( clazz==boolean.class ) + clazz = Boolean.class; + if( clazz==byte.class ) + clazz = Byte.class; + if( clazz==char.class ) + clazz = Character.class; + if( clazz==double.class ) + clazz = Double.class; + if( clazz==float.class ) + clazz = Float.class; + if( clazz==int.class ) + clazz = Integer.class; + if( clazz==long.class ) + clazz = Long.class; + if( clazz==short.class ) + clazz = Short.class; + return clazz; + } + + static class JavaKeyWords + { Collection javaKeyWords = new HashSet(); + JavaKeyWords() + { javaKeyWords.add( "abstract" ); //NOI18N + javaKeyWords.add( "boolean" ); //NOI18N + javaKeyWords.add( "break" ); //NOI18N + javaKeyWords.add( "byte" ); //NOI18N + javaKeyWords.add( "case" ); //NOI18N + javaKeyWords.add( "catch" ); //NOI18N + javaKeyWords.add( "char" ); //NOI18N + javaKeyWords.add( "class" ); //NOI18N + javaKeyWords.add( "const" ); //NOI18N + javaKeyWords.add( "continue" ); //NOI18N + javaKeyWords.add( "default" ); //NOI18N + javaKeyWords.add( "do" ); //NOI18N + javaKeyWords.add( "double" ); //NOI18N + javaKeyWords.add( "else" ); //NOI18N + javaKeyWords.add( "extends" ); //NOI18N + javaKeyWords.add( "final" ); //NOI18N + javaKeyWords.add( "finally" ); //NOI18N + javaKeyWords.add( "float" ); //NOI18N + javaKeyWords.add( "for" ); //NOI18N + javaKeyWords.add( "goto" ); //NOI18N + javaKeyWords.add( "if" ); //NOI18N + javaKeyWords.add( "implements" ); //NOI18N + javaKeyWords.add( "import" ); //NOI18N + javaKeyWords.add( "instanceof" ); //NOI18N + javaKeyWords.add( "int" ); //NOI18N + javaKeyWords.add( "interface" ); //NOI18N + javaKeyWords.add( "long" ); //NOI18N + javaKeyWords.add( "native" ); //NOI18N + javaKeyWords.add( "new" ); //NOI18N + javaKeyWords.add( "package" ); //NOI18N + javaKeyWords.add( "private" ); //NOI18N + javaKeyWords.add( "protected" ); //NOI18N + javaKeyWords.add( "public" ); //NOI18N + javaKeyWords.add( "return" ); //NOI18N + javaKeyWords.add( "short" ); //NOI18N + javaKeyWords.add( "static" ); //NOI18N + javaKeyWords.add( "strictfp" ); //NOI18N + javaKeyWords.add( "super" ); //NOI18N + javaKeyWords.add( "switch" ); //NOI18N + javaKeyWords.add( "synchronized" ); //NOI18N + javaKeyWords.add( "this" ); //NOI18N + javaKeyWords.add( "throw" ); //NOI18N + javaKeyWords.add( "throws" ); //NOI18N + javaKeyWords.add( "transient" ); //NOI18N + javaKeyWords.add( "try" ); //NOI18N + javaKeyWords.add( "void" ); //NOI18N + javaKeyWords.add( "volatile" ); //NOI18N + javaKeyWords.add( "while" ); //NOI18N + } + /** + * Checks if the argument <code>identifier</code> equals a Java key word. + * @param identifier the identifier to check + * @return <code>true</code>, if <code>identifier</code> is a Java key word, + * else <code>false</code> + */ + private boolean isJavaKeyWord(String identifier) + { return javaKeyWords.contains(identifier); + } + } + + // Serialization support + + /** + * Returns the candidate class name calculated during serialization of + * this query tree instance. + * @return serialized candidate class name + */ + public String getSerializedCandidateClassName() + { + return serializedCandidateClassName; + } + + /** Deserialization support. */ + private void writeObject(java.io.ObjectOutputStream out) + throws java.io.IOException + { + if ((candidateClass != null) && (getCandidateClass() != null)) + this.serializedCandidateClassName = getCandidateClass().getName(); + out.defaultWriteObject(); + } +} +
Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/TypeImpl.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/TypeImpl.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/TypeImpl.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/TypeImpl.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,93 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.jdoql.tree; + +import org.apache.jdo.impl.jdoql.jdoqlc.JDOQLTokenTypes; +import org.apache.jdo.jdoql.tree.NodeVisitor; +import org.apache.jdo.jdoql.tree.Type; + + +/** + * This node represents a type instance. A type instance wraps a + * <code>java.lang.Class</code> instance which has been supplied by + * the application. The following nodes have type instances as children: + * <LI><code>CandidateClass</code> + * <LI><code>CastExpr</code> + * <LI><code>Decl</code> + * <LI><code>StaticFieldAccessExpr</code> + * The result type of a type instance is the wrapped <code>java.lang.Class</code> + * instance. Type instances are not visible in query tree factory methods and + * expression factory methods. They are internally created by in implementation + * and are walked by a node visitor. + * + * @author Michael Watzek + */ +public final class TypeImpl extends NodeImpl implements Type +{ + /** + * The noarg constructor is needed for ANTLR support and deserialization. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public TypeImpl() + {} + + /** + * The noarg constructor is needed for ANTLR support. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public TypeImpl(antlr.Token token) + { initialize( token ); + } + + /** + * This constructor is called by the query tree instance. + * It delegates to the super class constructor. + * @param clazz the Java class which is wrapped by this instance + */ + TypeImpl(Class clazz) + { super( JDOQLTokenTypes.TYPE, clazz.getName(), clazz ); + } + + /** + * Returns the string representation of the Java class, + * which is wrapped by this instance. + * @return the Java type name + */ + public String getTypeName() + { return getJavaClass().getName(); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + */ + public void arrive(NodeVisitor visitor) + { visitor.arrive( this ); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + * @param results the result array + * @return the object returned by the visitor instance + */ + public Object leave(NodeVisitor visitor, Object[] results) + { return visitor.leave( this, results ); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryExpr.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryExpr.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryExpr.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryExpr.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,64 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.jdoql.tree; + +import org.apache.jdo.jdoql.tree.Expression; +import org.apache.jdo.jdoql.tree.Node; +import org.apache.jdo.jdoql.tree.UnaryExpression; + +/** + * This node represents a unary operator. All unary operators have exactly + * one children. Examples of binary operators + * are <code>ComplementExpression</code> and <code>NotExpression</code>. + * + * @author Michael Watzek + */ +public abstract class UnaryExpr extends Expr implements UnaryExpression +{ + /** + * The noarg constructor is needed for ANTLR support and deserialization. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public UnaryExpr() + {} + + /** + * This constructor is called by specialized nodes. + * It calls <code>setChildren</code> in order to initialize the node's + * child <code>expr</code>. + * @param tokenType the token tpye + * @param tokenName the name of this node + * @param expr the first child + */ + UnaryExpr(int tokenType, String tokenName, Expression expr) + { super( tokenType, tokenName, expr.getJavaClass() ); + setChildren( new Node[] {expr} ); + } + + /** + * Returns the node's expression. + * @return the node's expression + */ + public Expression getExpression() + { ASTToChildren(); + if( this.children==null || + this.children.length<1 ) + return null; + return (Expression) this.children[0]; + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryMinusExpr.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryMinusExpr.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryMinusExpr.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryMinusExpr.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,77 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.jdoql.tree; + +import org.apache.jdo.impl.jdoql.jdoqlc.JDOQLTokenTypes; +import org.apache.jdo.jdoql.tree.Expression; +import org.apache.jdo.jdoql.tree.NodeVisitor; +import org.apache.jdo.jdoql.tree.UnaryMinusExpression; + + +/** + * This node represents a unary minus operator. + * The string representation of this operator is <code>-</code>. + * + * @author Michael Watzek + */ +public final class UnaryMinusExpr + extends UnaryExpr implements UnaryMinusExpression +{ + /** + * The noarg constructor is needed for ANTLR support and deserialization. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public UnaryMinusExpr() + {} + + /** + * The noarg constructor is needed for ANTLR support. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public UnaryMinusExpr(antlr.Token token) + { initialize( token ); + } + + /** + * This constructor is called by the query tree instance. + * It delegates to the super class constructor. + * @param expr the expression to compute the complement for + */ + UnaryMinusExpr(Expression expr) + { super( JDOQLTokenTypes.UNARY_MINUS, "UnaryMinus", expr ); //NOI18N + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + */ + public void arrive(NodeVisitor visitor) + { visitor.arrive( this ); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + * @param results the result array + * @return the object returned by the visitor instance + */ + public Object leave(NodeVisitor visitor, Object[] results) + { return visitor.leave( this, results ); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryPlusExpr.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryPlusExpr.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryPlusExpr.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/UnaryPlusExpr.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,76 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.jdoql.tree; + +import org.apache.jdo.impl.jdoql.jdoqlc.JDOQLTokenTypes; +import org.apache.jdo.jdoql.tree.Expression; +import org.apache.jdo.jdoql.tree.NodeVisitor; +import org.apache.jdo.jdoql.tree.UnaryPlusExpression; + + +/** + * This node represents a unary plus operator. + * The string representation of this operator is <code>+</code>. + * + * @author Michael Watzek + */ +public final class UnaryPlusExpr extends UnaryExpr implements UnaryPlusExpression +{ + /** + * The noarg constructor is needed for ANTLR support and deserialization. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public UnaryPlusExpr() + {} + + /** + * The noarg constructor is needed for ANTLR support. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public UnaryPlusExpr(antlr.Token token) + { initialize( token ); + } + + /** + * This constructor is called by the query tree instance. + * It delegates to the super class constructor. + * @param expr the expression to compute the complement for + */ + UnaryPlusExpr(Expression expr) + { super( JDOQLTokenTypes.UNARY_PLUS, "UnaryPlus", expr ); //NOI18N + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + */ + public void arrive(NodeVisitor visitor) + { visitor.arrive( this ); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + * @param results the result array + * @return the object returned by the visitor instance + */ + public Object leave(NodeVisitor visitor, Object[] results) + { return visitor.leave( this, results ); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/VariableAccessExpr.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/VariableAccessExpr.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/VariableAccessExpr.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/VariableAccessExpr.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,81 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.jdoql.tree; + +import org.apache.jdo.impl.jdoql.jdoqlc.JDOQLTokenTypes; +import org.apache.jdo.jdoql.tree.Declaration; +import org.apache.jdo.jdoql.tree.Expression; +import org.apache.jdo.jdoql.tree.NodeVisitor; +import org.apache.jdo.jdoql.tree.VariableAccessExpression; + + +/** + * This node represents a variable access expression. + * It does not have any children. + * + * @author Michael Watzek + */ +public final class VariableAccessExpr + extends IdentifierExpr implements VariableAccessExpression +{ + /** + * The noarg constructor is needed for ANTLR support and deserialization. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public VariableAccessExpr() + {} + + /** + * The noarg constructor is needed for ANTLR support. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public VariableAccessExpr(antlr.Token token) + { initialize( token ); + } + + /** + * This constructor is called by the query tree instance. + * It delegates to the super class constructor. + * @param clazz the Java type of this identifier + * @param name the name of this identifier + */ + VariableAccessExpr(Class clazz, String name) + { super( JDOQLTokenTypes.VARIABLE_ACCESS, name, + Tree.toWrapperClass(clazz) ); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + */ + public void arrive(NodeVisitor visitor) + { visitor.arrive( this ); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + * @param results the result array + * @return the object returned by the visitor instance + */ + public Object leave(NodeVisitor visitor, Object[] results) + { return visitor.leave( this, results ); + } +} + Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/VariableDecl.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/VariableDecl.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/VariableDecl.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/jdoql/tree/VariableDecl.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,77 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.jdoql.tree; + +import org.apache.jdo.impl.jdoql.jdoqlc.JDOQLTokenTypes; +import org.apache.jdo.jdoql.tree.NodeVisitor; +import org.apache.jdo.jdoql.tree.Type; +import org.apache.jdo.jdoql.tree.VariableDeclaration; + + +/** + * This node represents a variable declaration. + * It does not have any children. + * + * @author Michael Watzek + */ +public final class VariableDecl extends Decl implements VariableDeclaration +{ + /** + * The noarg constructor is needed for ANTLR support and deserialization. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public VariableDecl() + {} + + /** + * The noarg constructor is needed for ANTLR support. + * The caller must make sure to set the ANTLR tree structure himself + * or, call <code>setChildren</code> optionally. + */ + public VariableDecl(antlr.Token token) + { initialize( token ); + } + + /** + * This constructor delegates to the super class constructor. + * @param type the type instance wrapping the Java class + * @param name the name of the variable + */ + VariableDecl(Type type, String name) + { super( JDOQLTokenTypes.VARIABLE_DECL, "VariableDeclaration", + type, name ); //NOI18N + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + */ + public void arrive(NodeVisitor visitor) + { visitor.arrive( this ); + } + + /** + * Delegates to the argument <code>visitor</code>. + * @param visitor the node visitor + * @param results the result array + * @return the object returned by the visitor instance + */ + public Object leave(NodeVisitor visitor, Object[] results) + { return visitor.leave( this, results ); + } +} Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaField.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaField.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaField.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaField.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,154 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.model.java; + +import org.apache.jdo.model.java.JavaField; +import org.apache.jdo.model.java.JavaType; +import org.apache.jdo.model.jdo.JDOField; + + +/** + * Abstract super class for JavaField implementations. + * It provides getters for the name and declaringClass properties which are + * initialized in the constructor. The implementation of method getJDOField + * always returns <code>null</code>. + * <p> + * A non-abstract subclass must implement methods + * [EMAIL PROTECTED] #getModifiers()} and [EMAIL PROTECTED] #getType()}. Note, this + * implementation of method [EMAIL PROTECTED] #getJDOField()} always returns + * <code>null</code>, so a subclass may want to override this method. + * + * @author Michael Bouschen + * @since JDO 1.0.1 + */ +abstract public class AbstractJavaField + implements JavaField +{ + /** The Field name. */ + private String name; + + /** The declaring class. */ + private JavaType declaringClass; + + /** + * Constructor setting the name and declaringClass property. + * @param name field name + * @param declaringClass the JavaType of the class or interface that + * declares this JavaField. + */ + public AbstractJavaField(String name, JavaType declaringClass) + { + this.name = name; + this.declaringClass = declaringClass; + } + + /** + * Returns the name of the field. + * @return field name + */ + public String getName() + { + return name; + } + + /** + * Returns the Java language modifiers for the field represented by + * this JavaField, as an integer. The java.lang.reflect.Modifier class + * should be used to decode the modifiers. + * @return the Java language modifiers for this JavaField + * @see java.lang.reflect.Modifier + */ + abstract public int getModifiers(); + + /** + * Returns the JavaType representation of the field type. + * @return field type + */ + abstract public JavaType getType(); + + /** + * Returns the JavaType instance representing the class or interface + * that declares the field represented by this JavaField instance. + * @return the JavaType instance of the declaring class. + */ + public JavaType getDeclaringClass() + { + return declaringClass; + } + + /** + * Returns the corresponding JDOField instance, if the JDOModel + * provides any JDO metadata for the field represented by this + * JavaField. If there is no corresponding JDOField representation, the + * method returns <code>null</code>. + * <p> + * This implementation always returns <code>null</code>. + * @return the corresponding JDOField instance (if available); + * <code>null</code> otherwise. + */ + public JDOField getJDOField() + { + return null; + } + + // ===== Methods not defined in JavaField ===== + + /** + * Indicates whether some other object is "equal to" this one. + * @param obj the reference object with which to compare. + * <p> + * This implementation matches the declaring class and the name of the + * specified object to the declaring class and the name of this + * JavaField. + * @return <code>true</code> if this object is the same as the obj + * argument; <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + // return true if obj is this + if (obj == this) return true; + // return false if obj does not have the correct type + if ((obj == null) || !(obj instanceof JavaField)) return false; + + JavaField other = (JavaField)obj; + // compare declaringClass and field names + return (getDeclaringClass() == other.getDeclaringClass()) + && (getName().equals(other.getName())); + } + + /** + * Returns a hash code value for the object. + * <p> + * This is computed as the exclusive-or of the hashcodes for the + * underlying field's declaring class name and its name. + * @return a hash code value for this object. + */ + public int hashCode() + { + return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); + } + + /** + * Returns a string representation of the object. + * @return a string representation of the object. + */ + public String toString() + { + return getDeclaringClass().getName() + "." + getName(); + } +} + Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaModel.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaModel.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaModel.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaModel.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,175 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.model.java; + +import java.util.Map; +import java.util.Set; +import java.util.HashMap; +import java.util.HashSet; +import java.io.InputStream; + +import org.apache.jdo.model.ModelException; +import org.apache.jdo.model.java.JavaModel; +import org.apache.jdo.model.java.JavaType; +import org.apache.jdo.model.jdo.JDOModel; + + +/** + * Abstract super class for JavaModel implementations. + * It implements the jdoModel property and the parent/child relationship + * between javaModels. It also provides a map of types managed by this + * JavaModel (see [EMAIL PROTECTED] #types}). The AbstractJavaModel constructor + * automatically adds all the predefined types to this map. + * <p> + * A non-abstract subclass must implement methods + * [EMAIL PROTECTED] #getJavaType(String name)} and + * [EMAIL PROTECTED] #getInputStreamForResource(String resourceName)}. + * + * @author Michael Bouschen + * @since JDO 1.0.1 + */ +abstract public class AbstractJavaModel + implements JavaModel +{ + /** Map of known JavaTypes. Key is the type name as a string. */ + protected Map types; + + /** The parent JavaModel. */ + protected JavaModel parent; + + /** The child JavaModels. */ + protected Set children = new HashSet(); + + /** The corresponding JDOModel instance. */ + protected JDOModel jdoModel; + + /** + * Constructor. It adds all predefined types to the cache of types + * known by this model instance. + * @see PredefinedType + */ + protected AbstractJavaModel() + { + types = new HashMap(PredefinedType.getPredefinedTypes()); + } + + /** + * The method returns the JavaType instance for the specified type + * name. A type name is unique within one JavaModel instance. The + * method returns <code>null</code> if this model instance does not + * know a type with the specified name. + * @return a JavaType instance for the specified name or + * <code>null</code> if not present in this model instance. + */ + abstract public JavaType getJavaType(String name); + + /** + * The method returns the JavaType instance for the type name of the + * specified class object. This is a convenience method for + * <code>getJavaType(clazz.getName())</code>. The major difference + * between this method and getJavaType taking a type name is that this + * method is supposed to return a non-<code>null<code> value. The + * specified class object describes an existing type. + * @param clazz the Class instance representing the type + * @return a JavaType instance for the name of the specified class + * object. + */ + public JavaType getJavaType(Class clazz) + { + return (clazz == null) ? null : getJavaType(clazz.getName()); + } + + /** + * Finds a resource with a given name. A resource is some data that can + * be accessed by class code in a way that is independent of the + * location of the code. The name of a resource is a "/"-separated path + * name that identifies the resource. The method method opens the + * resource for reading and returns an InputStream. It returns + * <code>null</code> if no resource with this name is found or if the + * caller doesn't have adequate privileges to get the resource. + * @param resourceName the resource name + * @return an input stream for reading the resource, or <code>null</code> + * if the resource could not be found or if the caller doesn't have + * adequate privileges to get the resource. + */ + abstract public InputStream getInputStreamForResource(String resourceName); + + /** + * Returns the parent JavaModel instance of this JavaModel. + * @return the parent JavaModel + */ + public JavaModel getParent() + { + return parent; + } + + /** + * Set the parent JavaModel for this JavaModel. The method + * automatically adds this JavaModel to the collection of children + * of the specified parent JavaModel. + * @param parent the parent JavaModel + * @exception ModelException if impossible + */ + public void setParent(JavaModel parent) + throws ModelException + { + if (this.parent == parent) { + // no changes => return; + return; + } + if (this.parent != null) { + // remove this from the collection of children of the old parent + ((AbstractJavaModel)this.parent).children.remove(this); + // add this to the collection of children of the new parent + ((AbstractJavaModel)parent).children.add(this); + } + this.parent = parent; + } + + /** + * Returns a collection of child JavaModel instances in the form + * of an array. All instances from the returned array have this + * JavaModel instance as parent. + * @return the child JavaModel instances + */ + public JavaModel[] getChildren() + { + return (JavaModel[])children.toArray(new JavaModel[children.size()]); + } + + /** + * Returns the corresponding JDOModel instance. + * @return the corresponding JDOModel. + */ + public JDOModel getJDOModel() + { + return jdoModel; + } + + /** + * Sets the corresponding JDOModel instance. + * @param jdoModel the JDOModel instance + * @exception ModelException if impossible + */ + public void setJDOModel(JDOModel jdoModel) + throws ModelException + { + this.jdoModel = jdoModel; + } + +} + Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaModelFactory.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaModelFactory.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaModelFactory.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaModelFactory.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,161 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.model.java; + +import java.util.Map; +import java.util.HashMap; + +import org.apache.jdo.impl.model.jdo.JDOModelFactoryImplDynamic; +import org.apache.jdo.model.ModelException; +import org.apache.jdo.model.ModelFatalException; +import org.apache.jdo.model.java.JavaModel; +import org.apache.jdo.model.java.JavaModelFactory; +import org.apache.jdo.model.java.JavaType; +import org.apache.jdo.model.jdo.JDOModel; +import org.apache.jdo.model.jdo.JDOModelFactory; +import org.apache.jdo.util.I18NHelper; + +/** + * Abstract super class for JavaModelFactory implementations. It provides a + * JavaModel cache and implements the JavaModel lookup method + * [EMAIL PROTECTED] #getJavaModel(Object key)}. Any JavaModel instance returned by + * this method is automatically connected to its corresponding JDOModel + * instance. + * <p> + * A non-abstract subclass must implement method + * [EMAIL PROTECTED] #createJavaModel(Object key)}. The lookup method calls this + * method if it cannot find a JavaModel instance in the cache. The method + * should also check whether the specified key is of an appropriate type + * for the JavaModelFactory implementation. A subclass should check whether + * it can implement method [EMAIL PROTECTED] #getJavaType(Object typeDesc)}. The + * implementation in AbstractJavaModelFactory always throws a + * ModelFatalException. + * + * @author Michael Bouschen + * @since JDO 1.0.1 + */ +abstract public class AbstractJavaModelFactory + implements JavaModelFactory +{ + /** + * Map of JavaModel instances, key is implementation specific. + * @see #getJavaModel(Object key) + */ + private Map modelCache = new HashMap(); + + /** I18N support */ + private static I18NHelper msg = + I18NHelper.getInstance(AbstractJavaModelFactory.class); + + /** + * Creates a new empty JavaModel instance. A factory implementation may + * use the specified key when caching the new JavaModel instance. + * <p> + * Each JavaModelFactory imposes its own restrictions for the keys to + * cache JavaModel instances. Some implementation will allow only keys + * of a certain type. Some implementations will prohibit + * <code>null</code> keys. Attempting to use an ineligible key will + * result in a [EMAIL PROTECTED] org.apache.jdo.model.ModelException}. This means + * the specified key is of an inappropriate type for this + * JavaModelFactory or if the key is <code>null</code> and this + * JavaModelFactory does not support <code>null</code> keys. + * @param key the key that may be used to cache the returned JavaModel instance. + * @return a new JavaModel instance. + * @exception ModelException if impossible; the key is of an + * inappropriate type or the key is <code>null</code> and this + * JavaModelFactory does not support <code>null</code> keys. + */ + abstract public JavaModel createJavaModel(Object key) + throws ModelException; + + /** + * Returns the JavaModel instance for the specified key. + * <p> + * The method throws a [EMAIL PROTECTED] org.apache.jdo.model.ModelFatalException}, + * if the specified key is of an inappropriate type for this + * JavaModelFactory or if the key is <code>null</code> and this + * JavaModelFactory does not support <code>null</code> keys. + * @param key the key used to cache the returned JavaModel instance. + * @return a JavaModel instance for the specified key. + * @exception ModelFatalException the key is of an inappropriate type + * or the key is <code>null</code> and this JavaModelFactory does not + * support <code>null</code> keys. + */ + public JavaModel getJavaModel(Object key) + { + synchronized (this.modelCache) { + JavaModel javaModel = (JavaModel)modelCache.get(key); + if (javaModel == null) { + // create new model and store it using the specified key + try { + javaModel = createJavaModel(key); + modelCache.put(key, javaModel); + // get the corresponding JDOModel + JDOModel jdoModel = + getJDOModelFactory().getJDOModel(javaModel); + // update the JDOModel property of the JavaModel + javaModel.setJDOModel(jdoModel); + } + catch (ModelException ex) { + throw new ModelFatalException( + "EXC_CannotCreateJavaModel", ex); //NOI18N + } + } + return javaModel; + } + } + + /** + * Returns a JavaType instance for the specified type description + * (optional operation). This method is a convenience method and a + * short cut for <code>getJavaModel(key).getJavaType(typeName)</code>. + * If the factory supports this method, it needs to be able to get the + * key for the JavaModel lookup and the type name for the JavaType + * lookup from the specified typeDesc. An example for such a type + * description is the java.lang.Class instance in the runtime + * environment. + * <p> + * The method throws a [EMAIL PROTECTED] org.apache.jdo.model.ModelFatalException}, + * if this factory does not support this short cut or if it does not + * support the specified type description. + * <p> + * This implementation always throws a ModelFatalException. + * @param typeDesc the type description. + * @return a JavaType instance for the specified type. + * @exception ModelFatalException this factory does not support this + * short cut or does not support the specified type description. + */ + public JavaType getJavaType(Object typeDesc) + { + throw new ModelFatalException(msg.msg( + "EXC_MethodNotSupported", this.getClass().getName(), //NOI18N + "getJavaType")); //NOI18N + } + + //========= Internal helper methods ========== + + /** + * Returns the JDOModelFactory instance used to get/create JDOModel + * instances. + * @return JDOModelFactory instance. + */ + protected JDOModelFactory getJDOModelFactory() + { + return JDOModelFactoryImplDynamic.getInstance(); + } +} + Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaType.java URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaType.java?view=auto&rev=158176 ============================================================================== --- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaType.java (added) +++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/model/java/AbstractJavaType.java Fri Mar 18 17:02:29 2005 @@ -0,0 +1,110 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jdo.impl.model.java; + +import org.apache.jdo.model.java.JavaField; +import org.apache.jdo.model.java.JavaType; +import org.apache.jdo.model.jdo.JDOClass; + + +/** + * Abstract super class for JavaType implementations. It provides a + * default implementation for all methods except getName. The methods return + * the Java default value of the return type. + * <p> + * A non-abstract subclass must implement method [EMAIL PROTECTED] #getName()} and + * needs to override any of the other methods where the default + * implementation is not appropriate. + * <p> + * Note, the class implements methods [EMAIL PROTECTED] #equals(Object obj)}, + * [EMAIL PROTECTED] #hashCode()} and [EMAIL PROTECTED] #toString()}using the name of a JavaType. + * + * @author Michael Bouschen + * @since JDO 1.0.1 + */ +abstract public class AbstractJavaType + implements JavaType +{ + public boolean isPrimitive() { return false; } + public boolean isIntegral() { return false; } + public boolean isFloatingPoint() { return false; } + public boolean isInterface() { return false; } + public boolean isArray() { return false; } + public boolean isWrapperClass() { return false; } + public boolean isJDOSupportedCollection() { return false; } + public boolean isJDOSupportedMap() { return false; } + public boolean isTrackable() { return false; } + public boolean isValue() { return false; } + public boolean isOrderable() { return false; } + public boolean isPersistenceCapable() { return false; } + public boolean isCompatibleWith(JavaType javaType) { return false; } + abstract public String getName(); + public int getModifiers() { return 0; } + public JavaType getSuperclass() { return null; } + public JDOClass getJDOClass() { return null; } + public JavaType getArrayComponentType() { return null; } + public JavaField getJavaField(String name) { return null; } + + // ===== Methods not defined in JavaType ===== + + /** + * Indicates whether some other object is "equal to" this one. + * @param obj the reference object with which to compare. + * <p> + * This implementation compares the name of the specified object to be + * equal to the name of this JavaType. + * this + * @return <code>true</code> if this object is the same as the obj + * argument; <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + // return true if obj is this + if (obj == this) return true; + // return false if obj does not have the correct type + if ((obj == null) || !(obj instanceof JavaType)) return false; + + JavaType other = (JavaType)obj; + // compare names + String name = getName(); + if (name == null) return other.getName() == null; + return name.equals(other.getName()); + } + + /** + * Returns a hash code value for the object. + * <p> + * This implementation returns the hashCode of the name of this + * JavaType. + * @return a hash code value for this object. + */ + public int hashCode() + { + String name = getName(); + return (name == null) ? 0 : name.hashCode(); + } + + /** + * Returns a string representation of the object. + * @return a string representation of the object. + */ + public String toString() + { + return getName(); + } + +}