You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2006/08/12 03:17:49 UTC

svn commit: r430936 [4/5] - in /db/ojb/trunk/proposals/jdo: ./ java/ java/org/ java/org/apache/ java/org/apache/ojb/ java/org/apache/ojb/jdo/ java/org/apache/ojb/jdo/jdoql/ java/org/apache/ojb/jdo/spi/ test/ test/org/ test/org/apache/ test/org/apache/o...

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/LocalVariable.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/LocalVariable.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/LocalVariable.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/LocalVariable.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,115 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * Encapsulates a variable local to the JDOQL query. This can be either a
+ * variable or a parameter. Variables must be at some point bound to values
+ * either directly by the user of the query (if a parameter) or during
+ * evaluation of the query.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class LocalVariable extends QueryTreeNode
+{
+    /** The name of the variable */
+    private String  _name;
+    /** The type of the variable */
+    private Type    _type;
+    /** Whether this variable is already bound to a value */
+    private boolean _isBound = false;
+    /** The value of the variable */
+    private Object  _value;
+
+    /**
+     * Creates a new variable object.
+     * 
+     * @param type The type of the variable
+     * @param name The name of the variable
+     */
+    public LocalVariable(Type type, String name)
+    {
+        _type = type;
+        _name = name;
+    }
+    
+    /**
+     * Returns the type of the variable.
+     *  
+     * @return The type
+     */
+    public Type getType()
+    {
+        return _type;
+    }
+
+    /**
+     * Returns the value of this variable
+     * 
+     * @return The value
+     */
+    public Object getValue()
+    {
+        return _value;
+    }
+
+    /**
+     * Sets the value of the variable.
+     * 
+     * @param value The value
+     */
+    public void setValue(Object value)
+    {
+        _value   = value;
+        _isBound = true;
+    }
+
+    /**
+     * Returns whether this variable is bound to a value.
+     *  
+     * @return <code>true</code> if the variable has a value
+     */
+    public boolean isBound()
+    {
+        return _isBound;
+    }
+
+    /**
+     * Returns the name of the variable.
+     * 
+     * @return The name
+     */
+    public String getName()
+    {
+        return _name;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return _type.toString() + " " + _name;
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/LocalVariableAccess.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/LocalVariableAccess.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/LocalVariableAccess.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/LocalVariableAccess.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,74 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * A local variable access expression. Note that this expression type can only be
+ * present in a query tree after resolving it.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class LocalVariableAccess extends NameExpression
+{
+    /** The accessed variable */
+    private LocalVariable _variable;
+
+    /**
+     * Creates a new variable access object.
+     * 
+     * @param name The variable's name
+     */
+    public LocalVariableAccess(String name)
+    {
+        super(null, name);
+    }
+
+    /**
+     * Returns the accessed variable.
+     * 
+     * @return The variable
+     */
+    public LocalVariable getAccessedVariable()
+    {
+        return _variable;
+    }
+    
+    /**
+     * Sets the accessed variable.
+     * 
+     * @param variable The variable
+     */
+    public void setAccessedVariable(LocalVariable variable)
+    {
+        _variable = variable;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Expression#getType()
+     */
+    public Class getType()
+    {
+        return _variable.getType().getType();
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/MethodInvocation.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/MethodInvocation.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/MethodInvocation.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/MethodInvocation.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,180 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+import java.util.*;
+
+/**
+ * A method invocation expression. Because invocation of methods on persistent
+ * classes is not supported, we can simply resolve the invocation to a reflection
+ * method object.
+ * 
+ * TODO: What is the best way to handle these (esp. Collection.contains which
+ *       does not behave like the Java method) ?
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class MethodInvocation extends PostfixExpression
+{
+    /** The method name */
+    private String     _name;
+    /** The arguments (expressions) */
+    private List       _args;
+    /** The return type of the method */
+    private Class      _returnType;
+
+    /**
+     * Creates a new method invocation object.
+     * 
+     * @param base       The base expression (can be <code>null</code>)
+     * @param methodName The name of the method
+     * @param args       The arguments
+     */
+    public MethodInvocation(Expression base, String methodName, List args)
+    {
+        super(base);
+        _name = methodName;
+        _args = args;
+        for (Iterator it = args.iterator(); it.hasNext();)
+        {
+            ((Expression)it.next()).setParent(this);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.PostfixExpression#hasBaseExpression()
+     */
+    public boolean hasBaseExpression()
+    {
+        return _base != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.PostfixExpression#getBaseExpression()
+     */
+    public Expression getBaseExpression()
+    {
+        return _base;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.PostfixExpression#setBaseExpression(org.apache.ojb.jdo.jdoql.Expression)
+     */
+    public void setBaseExpression(Expression base)
+    {
+        _base = base;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Expression#replaceChild(org.apache.ojb.jdo.jdoql.Expression, org.apache.ojb.jdo.jdoql.Expression)
+     */
+    public void replaceChild(Expression oldChild, Expression newChild)
+    {
+        if (oldChild == _base)
+        {
+            _base.setParent(null);
+            _base = newChild;
+            _base.setParent(this);
+        }
+        else
+        {
+            Expression expr;
+
+            for (int idx = 0; idx < _args.size(); idx++)
+            {
+                expr = (Expression)_args.get(idx);
+                if (expr == oldChild)
+                {
+                    expr.setParent(null);
+                    newChild.setParent(this);
+                    _args.set(idx, newChild);
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the name of the accessed method.
+     * 
+     * @return The method's name
+     */
+    public String getName()
+    {
+        return _name;
+    }
+
+    /**
+     * Returns the arguments of the invocation.
+     * 
+     * @return The arguments (list of expressions) 
+     */
+    public List getArguments()
+    {
+        return _args;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        StringBuffer result = new StringBuffer();
+
+        if (_base != null)
+        {
+            result.append(_base.toString());
+            result.append(".");
+        }
+        result.append(_name);
+        result.append("(");
+        for (Iterator it = _args.iterator(); it.hasNext();)
+        {
+            result.append(it.next().toString());
+            if (it.hasNext())
+            {
+                result.append(", ");
+            }
+        }
+        result.append(")");
+        return result.toString();
+    }
+
+    /**
+     * Sets the return type of the method.
+     * 
+     * @param type The return type
+     */
+    public void setType(Class type)
+    {
+        _returnType = type;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Expression#getType()
+     */
+    public Class getType()
+    {
+        return _returnType;
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/NameExpression.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/NameExpression.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/NameExpression.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/NameExpression.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,83 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * A name expression which can mean an access to a variable/field or to a type.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class NameExpression extends PostfixExpression
+{
+    /** The name */
+    private String _name;
+
+    /**
+     * Creates a new name expression object.
+     * 
+     * @param base The base expression (can be <code>null</code>)
+     * @param name The name
+     */
+    public NameExpression(Expression base, String name)
+    {
+        super(base);
+        _name = name;
+    }
+
+    /**
+     * Returns the name.
+     * 
+     * @return The name
+     */
+    public String getName()
+    {
+        return _name;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        StringBuffer result = new StringBuffer();
+
+        if (_base != null)
+        {
+            result.append(_base.toString());
+            result.append(".");
+        }
+        result.append(_name);
+        return result.toString();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Expression#getType()
+     */
+    public Class getType()
+    {
+        // No need to return something because this expression is replaced
+        // in the resolving stage
+        return null;
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/NullLiteral.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/NullLiteral.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/NullLiteral.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/NullLiteral.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,70 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * The 'null' literal.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class NullLiteral extends Expression
+{
+    /** The type of this null literal */
+    private Class _type = Object.class;
+
+    /**
+     * Creates a new null literal object. 
+     */
+    public NullLiteral()
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "null";
+    }
+
+    /**
+     * Sets the type of this null literal. The type depends on the context
+     * of the literal, e.g. in a binary expression where the other side
+     * is of type string, this literal would also have type string.
+     * 
+     * @param type The type
+     */
+    public void setType(Class type)
+    {
+        _type = type;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Expression#getType()
+     */
+    public Class getType()
+    {
+        return _type;
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Ordering.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Ordering.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Ordering.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Ordering.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,77 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * Encapsulates an ordering.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class Ordering extends QueryTreeNode
+{
+    /** The ordering expression */
+    private Expression _expr;
+    /** Whether this is an ascending ordering specification */
+    private boolean    _isAscending = true;
+
+    /**
+     * Creates a new ordering object.
+     * 
+     * @param expr        The ordering expression
+     * @param isAscending Whether this is an ascending ordering specification
+     */
+    public Ordering(Expression expr, boolean isAscending)
+    {
+        _expr        = expr;
+        _isAscending = isAscending;
+    }
+    
+    /**
+     * Returns the ordering expression.
+     *  
+     * @return The expression
+     */
+    public Expression getExpression()
+    {
+        return _expr;
+    }
+
+    /**
+     * Returns whether this ordering is ascending or descending.
+     *  
+     * @return <code>true</code> if the ordering is ascending
+     */
+    public boolean isAscending()
+    {
+        return _isAscending;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return _expr.toString() + " " + (_isAscending ? "ascending" : "descending");
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/PostfixExpression.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/PostfixExpression.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/PostfixExpression.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/PostfixExpression.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,85 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * Specifies an expression that can follow another expression (e.g. in a.b the
+ * field access to b follows the field access to a).
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public abstract class PostfixExpression extends Expression
+{
+    /** The base expression (can be <code>null</code>) */
+    protected Expression _base;
+
+    /**
+     * Creates a new postfix expression. This constructor is intended to be called
+     * from subclass' constructors.
+     * 
+     * @param base The base expression (can be <code>null</code>)
+     */
+    public PostfixExpression(Expression base)
+    {
+        _base = base;
+    }
+    
+    /**
+     * Determines whether this postfix expression has a base expression.
+     * 
+     * @return <code>true</code> if it has a base expression
+     */
+    public boolean hasBaseExpression()
+    {
+        return _base != null;
+    }
+
+    /**
+     * Returns the base expression.
+     * 
+     * @return The base expression (can be <code>null</code>)
+     */
+    public Expression getBaseExpression()
+    {
+        return _base;
+    }
+
+    /**
+     * Sets the base expression.
+     * 
+     * @param base The base expression (can be <code>null</code>)
+     */
+    public void setBaseExpression(Expression base)
+    {
+        if (_base != null)
+        {
+            _base.setParent(null);
+        }
+        _base = base;
+        if (_base != null)
+        {
+            _base.setParent(this);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Expression#replaceChild(org.apache.ojb.jdo.jdoql.Expression, org.apache.ojb.jdo.jdoql.Expression)
+     */
+    public void replaceChild(Expression oldChild, Expression newChild)
+    {
+        setBaseExpression(newChild);
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryParsingHelper.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryParsingHelper.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryParsingHelper.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryParsingHelper.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,228 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+import java.io.StringReader;
+import java.util.*;
+
+import javax.jdo.JDOUserException;
+
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+
+/**
+ * Helper class for building the actual query structure from a JDOQL query definition.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class QueryParsingHelper
+{
+    /**
+     * Parses the given parameter declaration string.
+     *
+     * @return The parameters indexed by their names
+     */
+    public Map parseParameters(String declaration) throws JDOUserException
+    {
+        JDOQLLexer      lexer      = new JDOQLLexer(new StringReader(declaration));
+        JDOQLParser     parser     = new JDOQLParser(lexer);
+        JDOQLTreeParser treeParser = new JDOQLTreeParser();
+        
+        parser.setASTNodeClass(ASTWithPositionInfo.class.getName());
+        try
+        {
+            parser.declareParameters();
+            return treeParser.declareParameters(parser.getAST());
+        }
+        catch (RecognitionException ex)
+        {
+            throw new JDOUserException("Error in parameter declaration at line "+ex.getLine()+", column "+ex.getColumn());
+        }
+        catch (TokenStreamException ex)
+        {
+            throw new JDOUserException("Could not parse the parameter declaration");
+        }
+    }
+
+    /**
+     * Parses the given declaration string.
+     *
+     * @return The variables indexed by their names
+     */
+    public Map parseVariables(String declaration) throws JDOUserException
+    {
+        JDOQLLexer      lexer      = new JDOQLLexer(new StringReader(declaration));
+        JDOQLParser     parser     = new JDOQLParser(lexer);
+        JDOQLTreeParser treeParser = new JDOQLTreeParser();
+        
+        parser.setASTNodeClass(ASTWithPositionInfo.class.getName());
+        try
+        {
+            parser.declareVariables();
+            return treeParser.declareVariables(parser.getAST());
+        }
+        catch (RecognitionException ex)
+        {
+            throw new JDOUserException("Error in variable declaration at line "+ex.getLine()+", column "+ex.getColumn());
+        }
+        catch (TokenStreamException ex)
+        {
+            throw new JDOUserException("Could not parse the variable declaration");
+        }
+    }
+
+    /**
+     * Parses the given imports declaration string.
+     *
+     * @return The imports list
+     */
+    public List parseImports(String declaration) throws JDOUserException
+    {
+        JDOQLLexer      lexer      = new JDOQLLexer(new StringReader(declaration));
+        JDOQLParser     parser     = new JDOQLParser(lexer);
+        JDOQLTreeParser treeParser = new JDOQLTreeParser();
+
+        parser.setASTNodeClass(ASTWithPositionInfo.class.getName());
+        try
+        {
+            parser.declareImports();
+            return treeParser.declareImports(parser.getAST());
+        }
+        catch (RecognitionException ex)
+        {
+            throw new JDOUserException("Error in import specification at line "+ex.getLine()+", column "+ex.getColumn());
+        }
+        catch (TokenStreamException ex)
+        {
+            throw new JDOUserException("Could not parse the import specification");
+        }
+    }
+
+    /**
+     * Parses the given orderings declaration string.
+     *
+     * @return The orderings list
+     */
+    public List parseOrderings(String declaration) throws JDOUserException
+    {
+        JDOQLLexer      lexer      = new JDOQLLexer(new StringReader(declaration));
+        JDOQLParser     parser     = new JDOQLParser(lexer);
+        JDOQLTreeParser treeParser = new JDOQLTreeParser();
+        
+        parser.setASTNodeClass(ASTWithPositionInfo.class.getName());
+        try
+        {
+            parser.setOrdering();
+            return treeParser.setOrdering(parser.getAST());
+        }
+        catch (RecognitionException ex)
+        {
+            throw new JDOUserException("Error in ordering specification at line "+ex.getLine()+", column "+ex.getColumn());
+        }
+        catch (TokenStreamException ex)
+        {
+            throw new JDOUserException("Could not parse the ordering specification");
+        }
+    }
+
+    /**
+     * Parses the given filter expression string.
+     *
+     * @return The filter expression
+     */
+    public Expression parseFilter(String expression) throws JDOUserException
+    {
+        JDOQLLexer      lexer      = new JDOQLLexer(new StringReader(expression));
+        JDOQLParser     parser     = new JDOQLParser(lexer);
+        JDOQLTreeParser treeParser = new JDOQLTreeParser();
+        
+        parser.setASTNodeClass(ASTWithPositionInfo.class.getName());
+        try
+        {
+            parser.expression();
+            return treeParser.expression(parser.getAST());
+        }
+        catch (RecognitionException ex)
+        {
+            throw new JDOUserException("Error in filter expression at line "+ex.getLine()+", column "+ex.getColumn());
+        }
+        catch (TokenStreamException ex)
+        {
+            throw new JDOUserException("Could not parse the filter expression");
+        }
+    }
+
+    public static void main(String[] args) throws JDOUserException
+    {
+        if (args.length < 2)
+        {
+            System.out.println("Usage:\n\njava "+QueryParsingHelper.class.getName()+" [type] [text]\n");
+            System.out.println("where type specifies what kind of text to parse");
+            System.out.println("(imports, parameters, variables, orderings, filter)");
+            System.out.println("and text gives the actual text to parse");
+            return;
+        }
+
+        QueryParsingHelper helper = new QueryParsingHelper();
+        
+        if ("imports".equals(args[0]))
+        {
+            List imports = helper.parseImports(args[1]);
+
+            for (int idx = 0; idx < imports.size(); idx++)
+            {
+                System.out.println("("+idx+"): "+imports.get(idx).toString());
+            }
+        }
+        else if ("parameters".equals(args[0]))
+        {
+            Map params = helper.parseParameters(args[1]);
+
+            for (Iterator it = params.values().iterator(); it.hasNext();)
+            {
+                System.out.println(it.toString());
+            }
+        }
+        else if ("variables".equals(args[0]))
+        {
+            Map vars = helper.parseVariables(args[1]);
+
+            for (Iterator it = vars.values().iterator(); it.hasNext();)
+            {
+                System.out.println(it.toString());
+            }
+        }
+        else if ("orderings".equals(args[0]))
+        {
+            List orderings = helper.parseOrderings(args[1]);
+
+            for (int idx = 0; idx < orderings.size(); idx++)
+            {
+                System.out.println("("+idx+"): "+orderings.get(idx).toString());
+            }
+        }
+        else if ("filter".equals(args[0]))
+        {
+            Expression filterExpr = helper.parseFilter(args[1]);
+
+            System.out.println(filterExpr.toString());
+        }
+        else
+        {
+            System.out.println("Unknown kind of text; allowed are: imports, parameters, variables, orderings, filter");
+        }
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryTreeNode.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryTreeNode.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryTreeNode.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryTreeNode.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,61 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * Base class for nodes of the query trees.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public abstract class QueryTreeNode implements Acceptor
+{
+    /** The line where the source of this node started. */
+    private int _line   = 0;
+    /** The column where the source of this node started. */
+    private int _column = 0;
+
+    /**
+     * Sets the position of this node in the source.
+     * 
+     * @param line   The line
+     * @param column The column
+     */
+    public void setPosition(int line, int column)
+    {
+        _line   = line;
+        _column = column;
+    }
+    
+    /**
+     * Returns the column where the source of this node started.
+     * 
+     * @return The column
+     */
+    public int getColumn()
+    {
+        return _column;
+    }
+
+    /**
+     * Returns the line where the source of this node started.
+     * 
+     * @return The line
+     */
+    public int getLine()
+    {
+        return _line;
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryTreeResolver.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryTreeResolver.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryTreeResolver.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/QueryTreeResolver.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,730 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.jdo.JDOUserException;
+
+import org.apache.ojb.broker.metadata.*;
+import org.apache.ojb.broker.util.ClassHelper;
+import org.apache.ojb.jdo.QueryImpl;
+
+/**
+ * Resolves and checks the query trees. This involves the following things:<br/>
+ * <ul>
+ * <li>Replace {@link NameExpression NameExpression} with {@link LocalVariableAccess VariableAccess},
+ *     {@link FieldAccess FieldAccess}, or {@link TypeAccess TypeAccess}</li>
+ * <li>Resolve types referenced by {@link Type Type} and {@link TypeAccess TypeAccess}</li>
+ * <li>Resolve features/variables referenced by {@link LocalVariableAccess VariableAccess},
+ *     {@link FieldAccess FieldAccess}, and {@link MethodInvocation MethodInvocation}</li>
+ * <li>Check that expression types are valid, e.g. that the types of the two sides of a binary
+ *     expression are compatible to each other and that this binary operator can be applied
+ *     to them</li>
+ * <li>Check that the accessed methods are allowed to be accessed as per JDO spec (or
+ *     extensions allowed by OJB)</li>
+ * <li>Check that for each accessed variable there is a variable or parameter defined</li>
+ * <li>Check that each accessed field is persistent</li>
+ * </ul> 
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class QueryTreeResolver extends VisitorBase
+{
+    // TODO: Integrate position info into the exceptions
+
+    /** Defines the ordering of primitive types */
+    private static HashMap _primitiveTypes = new HashMap();
+
+    static
+    {
+        _primitiveTypes.put(byte.class,       new Integer(0));
+        _primitiveTypes.put(char.class,       new Integer(1));
+        _primitiveTypes.put(short.class,      new Integer(2));
+        _primitiveTypes.put(int.class,        new Integer(3));
+        _primitiveTypes.put(long.class,       new Integer(4));
+        _primitiveTypes.put(BigInteger.class, new Integer(5));
+        _primitiveTypes.put(float.class,      new Integer(6));
+        _primitiveTypes.put(double.class,     new Integer(7));
+        _primitiveTypes.put(BigDecimal.class, new Integer(8));
+    }
+    
+    /** The currently resolved query */ 
+    private QueryImpl _query;
+
+    /**
+     * Resolves and checks the given query. Results from a previous resolving are
+     * overwritten.
+     *  
+     * @param query The query
+     * @exception JDOUserException If the query is invalid
+     */
+    public void resolveAndCheck(QueryImpl query) throws JDOUserException
+    {
+        _query = query;
+        try
+        {
+            checkImports(query.getImports());
+            visit(query.getVariables());
+            visit(query.getParameters());
+            if (query.getFilterExpression() != null)
+            {
+                query.getFilterExpression().accept(this);
+            }
+            visit(query.getOrderings());
+        }
+        finally
+        {
+            _query = null;
+        }
+    }
+
+    /**
+     * Checks the imports. We're a bit more foregiving as the JDO Spec because
+     * we don't demand that all imported types/packages exists as long as they
+     * are not used.
+     * 
+     * @param imports The imports to check
+     * @throws JDOUserException If two direct imports imports types with the same
+     *                          short name
+     */
+    private void checkImports(Collection imports) throws JDOUserException
+    {
+        // It is an error if two direct imports import classes with the same short name
+        HashMap directlyImportedClasses = new HashMap();
+        Import  importDecl;
+        String  shortName;
+
+        for (Iterator it = imports.iterator(); it.hasNext();)
+        {
+            importDecl = (Import)it.next();
+            if (!importDecl.isOnDemand())
+            {
+                shortName = importDecl.getSpec().substring(importDecl.getSpec().lastIndexOf('.'));
+                if (directlyImportedClasses.containsKey(shortName))
+                {
+                    throw new JDOUserException("Multiple direct imports of classes with the same unqualified name "+shortName);
+                }
+                else
+                {
+                    directlyImportedClasses.put(shortName, null);
+                }
+            }
+        }
+    }
+    
+    /**
+     * Visits all elements of the given map.
+     * 
+     * @param objects The objects
+     * @exception JDOUserException If one of the elements is invalid
+     */
+    private void visit(Map objects) throws JDOUserException
+    {
+        if (objects != null)
+        {
+            for (Iterator it = objects.values().iterator(); it.hasNext();)
+            {
+                ((Acceptor)it.next()).accept(this);
+            }
+        }
+    }
+    
+    /**
+     * Visits all elements of the given collection.
+     * 
+     * @param objects The objects
+     * @exception JDOUserException If one of the elements is invalid
+     */
+    private void visit(Collection objects) throws JDOUserException
+    {
+        if (objects != null)
+        {
+            for (Iterator it = objects.iterator(); it.hasNext();)
+            {
+                ((Acceptor)it.next()).accept(this);
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.BinaryExpression)
+     */
+    public void visit(BinaryExpression binExpr) throws JDOUserException
+    {
+        super.visit(binExpr);
+
+        // for the types of the left and right expressions one of the following must hold:
+        // * the operator is '+' and both are String
+        // * the operator is arithmethic and both are numeric (Character, Long or Double)
+        // * the operator is bitwise and both are Character or Long
+        // * the operator is logic and both are Boolean
+        // * the operator is comparative and the both are String, or both are Date, or both are Numeric
+        Class   leftType   = binExpr.getLeftSide().getType();
+        Class   rightType  = binExpr.getRightSide().getType();
+        boolean typeWasSet = false;
+
+        switch (binExpr.getOperator())
+        {
+            case BinaryExpression.OPERATOR_MULTIPLY :
+            case BinaryExpression.OPERATOR_DIVIDE :
+            case BinaryExpression.OPERATOR_PLUS :
+            case BinaryExpression.OPERATOR_MINUS :
+                if (binExpr.getOperator() == BinaryExpression.OPERATOR_PLUS)
+                {
+                    if ((leftType == String.class) && (rightType == String.class))
+                    {
+                        binExpr.setType(String.class);
+                        typeWasSet = true;
+                        break;
+                    }
+                }
+                if (isNumeric(leftType) && isNumeric(rightType))
+                {
+                    binExpr.setType(getBroaderType(leftType, rightType));
+                    typeWasSet = true;
+                }
+                break;
+            case BinaryExpression.OPERATOR_BITWISE_AND :
+            case BinaryExpression.OPERATOR_BITWISE_XOR :
+            case BinaryExpression.OPERATOR_BITWISE_OR :
+                if (isInteger(leftType) && isInteger(rightType))
+                {
+                    binExpr.setType(getBroaderType(leftType, rightType));
+                    typeWasSet = true;
+                }
+                else if ((leftType == boolean.class) && (rightType == boolean.class))
+                {
+                    binExpr.setType(boolean.class);
+                    typeWasSet = true;
+                }
+                break;
+            case BinaryExpression.OPERATOR_LOWER :
+            case BinaryExpression.OPERATOR_GREATER :
+            case BinaryExpression.OPERATOR_LOWER_OR_EQUAL :
+            case BinaryExpression.OPERATOR_GREATER_OR_EQUAL :
+                if (isNumeric(leftType) && isNumeric(rightType))
+                {
+                    binExpr.setType(boolean.class);
+                    typeWasSet = true;
+                }
+                else if ((leftType == String.class) && (rightType == String.class))
+                {
+                    binExpr.setType(boolean.class);
+                    typeWasSet = true;
+                }
+                else if ((leftType == Date.class) && (rightType == Date.class))
+                {
+                    binExpr.setType(boolean.class);
+                    typeWasSet = true;
+                }
+                break;
+            case BinaryExpression.OPERATOR_EQUAL :
+            case BinaryExpression.OPERATOR_NOT_EQUAL :
+                if (isNumeric(leftType) && isNumeric(rightType))
+                {
+                    binExpr.setType(boolean.class);
+                    typeWasSet = true;
+                }
+                else if ((leftType == boolean.class) && (rightType == boolean.class))
+                {
+                    binExpr.setType(boolean.class);
+                    typeWasSet = true;
+                }
+                else if (!leftType.isPrimitive() && !rightType.isPrimitive())
+                {
+                    binExpr.setType(boolean.class);
+                    typeWasSet = true;
+                }
+                break;
+            case BinaryExpression.OPERATOR_AND :
+            case BinaryExpression.OPERATOR_OR :
+                if ((leftType == boolean.class) && (rightType == boolean.class))
+                {
+                    binExpr.setType(boolean.class);
+                    typeWasSet = true;
+                }
+                break;
+        }
+        if (!typeWasSet)
+        {
+            throw new JDOUserException("Binary expression cannot be applied to expressions of types "+leftType.getName()+" and "+rightType.getName());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.MethodInvocation)
+     */
+    public void visit(MethodInvocation methodInvoc) throws JDOUserException
+    {
+        super.visit(methodInvoc);
+
+        Class  type = methodInvoc.getBaseExpression().getType();
+        String name = methodInvoc.getName();
+
+        if (Collection.class.isAssignableFrom(type))
+        {
+            if ("contains".equals(name))
+            {
+                if (methodInvoc.getArguments().size() != 1)
+                {
+                    throw new JDOUserException("Illegal number of arguments to method Collection.contains");
+                }
+            }
+            else if ("isEmpty".equals(name))
+            {
+                if (!methodInvoc.getArguments().isEmpty())
+                {
+                    throw new JDOUserException("Illegal number of arguments to method Collection.isEmpty");
+                }
+            }
+            else
+            {
+                throw new JDOUserException("Only methods 'contains' and 'isEmpty' are allowed to be called at collection objects");
+            }
+            methodInvoc.setType(boolean.class);
+        }
+        else if (type == String.class)
+        {
+            if (!"startsWith".equals(name) && !"endsWith".equals(name))
+            {
+                throw new JDOUserException("Only methods 'contains' and 'isEmpty' are allowed to be called at collection objects");
+            }
+            if (methodInvoc.getArguments().size() != 1)
+            {
+                throw new JDOUserException("Illegal number of arguments to method String."+name);
+            }
+            if (((Expression)methodInvoc.getArguments().get(0)).getType() != String.class)
+            {
+                throw new JDOUserException("Illegal argument to method Collection."+name);
+            }
+            methodInvoc.setType(boolean.class);
+        }
+        else
+        {
+            throw new JDOUserException("Invocation of method "+methodInvoc.getName()+" at type "+type.getName()+" is not allowed");
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.NameExpression)
+     */
+    public void visit(NameExpression nameExpr) throws JDOUserException
+    {
+        super.visit(nameExpr);
+
+        Expression newExpr  = null;
+        Class      baseType = null;
+
+        // we search in this order (which corresponds to Java's name resolution order):
+        //   * variables (only if without base expression)
+        //   * parameters (only if without base expression)
+        //   * fields/references/collections (at searched type if without base expression)
+        // types are currently not searched for as they are not allowed to appear directly
+        // except in casts
+        if (!nameExpr.hasBaseExpression())
+        {
+            // no base expressiom
+            LocalVariable var = _query.getVariable(nameExpr.getName());
+
+            if (var == null)
+            {
+                var = _query.getParameter(nameExpr.getName());
+            }
+            if (var != null)
+            {
+                LocalVariableAccess varAccess = new LocalVariableAccess(nameExpr.getName());
+
+                varAccess.setAccessedVariable(var);
+                newExpr = varAccess;
+            }
+            else
+            {
+                // neither a variable nor parameter, so we must search in the class
+                // whose objects the query searches for
+                baseType = _query.getSearchedClass();
+            }
+        }
+        else
+        {
+            // we have a base expression which means that we follow a reference
+            baseType = nameExpr.getBaseExpression().getType();
+        }
+        if (newExpr == null)
+        {
+            // so we determine the persistent type of the base expression
+            ClassDescriptor classDesc = findClassDescriptorFor(baseType);
+            
+            if (classDesc == null)
+            {
+                throw new JDOUserException("Access to type "+baseType.getName()+" is not allowed because the type is not persistent");
+            }
+
+            FieldAccess fieldAccess = new FieldAccess(nameExpr.getBaseExpression(), nameExpr.getName());
+            
+            // it may be either a field, reference or collection descriptor -
+            // this depends on whether the name expression is a base expression
+            // to another name expression (not a method invocation or other expression)
+            ObjectReferenceDescriptor refDesc = classDesc.getObjectReferenceDescriptorByName(nameExpr.getName());
+            
+            if (refDesc != null)
+            {
+                fieldAccess.setFieldDescriptor(refDesc);
+            }
+            else if (nameExpr.hasParent() && (nameExpr.getParent() instanceof NameExpression))
+            {
+                // if we are the base expression of another name expression, then it must be a reference
+                throw new JDOUserException("Cannot find reference "+nameExpr.getName()+" in type "+baseType.getName()+" because it is not defined, not persistent or not a reference");
+            }
+            else
+            {
+                // it can be a field or collection
+                CollectionDescriptor collDesc = classDesc.getCollectionDescriptorByName(nameExpr.getName());
+                if (collDesc != null)
+                {
+                    fieldAccess.setFieldDescriptor(collDesc);
+                }
+                else
+                {
+                    FieldDescriptor fieldDesc = classDesc.getFieldDescriptorByName(nameExpr.getName());
+    
+                    if (fieldDesc == null)
+                    {
+                        throw new JDOUserException("Cannot find feature "+nameExpr.getName()+" in type "+baseType.getName()+" because it is not defined or not persistent");
+                    }
+                    fieldAccess.setFieldDescriptor(fieldDesc);
+                }
+            }
+            newExpr = fieldAccess;
+        }
+
+        if (nameExpr.hasParent())
+        {
+            nameExpr.getParent().replaceChild(nameExpr, newExpr);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.NullLiteral)
+     */
+    public void visit(NullLiteral nullLit)
+    {
+        Expression parent = nullLit.getParent();
+
+        if (parent == null)
+        {
+            return;
+        }
+
+        // the only interesting case is if the parent is a binary expression (e.g.
+        // a '==' expression) in which case the null literal shall have the same
+        // type as the other operand
+        if (parent instanceof BinaryExpression)
+        {
+            Class type = null;
+
+            if (((BinaryExpression)parent).getLeftSide() == nullLit)
+            {
+                type = ((BinaryExpression)parent).getRightSide().getType();
+            }
+            else
+            {
+                type = ((BinaryExpression)parent).getLeftSide().getType();
+            }
+            if (type.isPrimitive())
+            {
+                throw new JDOUserException("Illegal binary expression with a 'null' and a primitive operand");
+            }
+            nullLit.setType(type);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.ThisExpression)
+     */
+    public void visit(ThisExpression thisExpr)
+    {
+        super.visit(thisExpr);
+        thisExpr.setType(_query.getSearchedClass());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.Type)
+     */
+    public void visit(Type type) throws JDOUserException
+    {
+        ClassLoader loader = ClassHelper.getClassLoader();
+        Class       result = null;
+        String      name   = type.getName();
+        int         pos    = name.indexOf('.');
+
+        if (pos >= 0)
+        {
+            // its either a qualified name or refers to an inner class
+            // we ignore inner classes here as they are handled by the import
+            // resolution below
+            // [tomdz] we might have to resolve inner/nested classes manually
+            //         if the query should be executed in the scope of the
+            //         searched class (which makes private/protected/friendly
+            //         inner/nested classes visible)
+            //         for now we assume that this is not the case
+            try
+            {
+                result = Class.forName(name, true, loader);
+            }
+            catch (ClassNotFoundException ex)
+            {
+                // ignored
+            }
+        }
+        if (result == null)
+        {
+            result = resolveUnqualifiedClassName(loader, name);
+        }
+        if (result == null)
+        {
+            throw new JDOUserException("No such class "+name);
+        }
+        else
+        {
+            type.setType(result);
+        }
+    }
+
+    /**
+     * Resolves the given unqualified class name against the imports of the query.
+     * 
+     * @param loader          The class loader to use
+     * @param unqualifiedName The unqualified class name
+     * @return The class if it has been found
+     * @exception JDOUserException If a direct import declaration is invalid
+     */
+    private Class resolveUnqualifiedClassName(ClassLoader loader, String unqualifiedName) throws JDOUserException
+    {
+        // A direct import has precedence over on-demand imports of packages that contain
+        // a class of the same short name (JLS 7.5.1)
+        // If multiple on-demand imports import packages that have a class with a given
+        // short name, then the last such import defines the class to be used
+        Import importDecl;
+        Class  result = null;
+        int    pos;
+
+        // we first try to resolve it against java.lang
+        try
+        {
+            result = Class.forName("java.lang." + unqualifiedName, true, loader);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            // ignored
+        }
+        for (Iterator it = _query.getImports().iterator(); it.hasNext();)
+        {
+            importDecl = (Import)it.next();
+            if (importDecl.isOnDemand())
+            {
+                try
+                {
+                    result = Class.forName(importDecl.getSpec() + "." + unqualifiedName, true, loader);
+                }
+                catch (ClassNotFoundException ex)
+                {
+                    // ignored
+                }
+            }
+            else
+            {
+                pos = importDecl.getSpec().lastIndexOf('.');
+                if (unqualifiedName.equals(importDecl.getSpec().substring(pos + 1)))
+                {
+                    try
+                    {
+                        // there can only be one direct import of a class with this
+                        // unqualified name (imports have already been checked), and
+                        // no on-demand import can shadow it, so we can simply return it
+                        return Class.forName(importDecl.getSpec() + "." + unqualifiedName, true, loader);
+                    }
+                    catch (ClassNotFoundException ex)
+                    {
+                        // we have a direct import for the class but the import is invalid
+                        throw new JDOUserException("The import "+importDecl.getSpec()+" is invalid");
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.UnaryExpression)
+     */
+    public void visit(UnaryExpression unaryExpr) throws JDOUserException
+    {
+        super.visit(unaryExpr);
+
+        // one of the following must hold:
+        // * the operator is arithmetic and the inner type is numeric
+        // * the operator is bitwise and the inner type is Character or Long
+        // * the operator is logic and the inner type is Boolean
+        // * it is a cast and the cast type is assignment compatible to the inner type
+        Class   innerType  = unaryExpr.getInnerExpression().getType();
+        boolean typeWasSet = false;
+
+        switch (unaryExpr.getOperator())
+        {
+            case UnaryExpression.OPERATOR_PLUS :
+            case UnaryExpression.OPERATOR_MINUS :
+                if (isNumeric(innerType))
+                {
+                    unaryExpr.setType(innerType);
+                    typeWasSet = true;
+                }
+                break;
+            case UnaryExpression.OPERATOR_BITWISE_COMPLEMENT :
+                if (isInteger(innerType))
+                {
+                    unaryExpr.setType(innerType);
+                    typeWasSet = true;
+                }
+                break;
+            case UnaryExpression.OPERATOR_NOT :
+                if (innerType == boolean.class)
+                {
+                    unaryExpr.setType(innerType);
+                    typeWasSet = true;
+                }
+                break;
+            case UnaryExpression.OPERATOR_CAST :
+                Class castType = unaryExpr.getCastType().getType();
+
+                if (isNumeric(castType) && isNumeric(innerType))
+                {
+                    unaryExpr.setType(castType);
+                    typeWasSet = true;
+                }
+                else
+                {
+                    // check for narrowing or widening reference conversion
+                    if (castType.isAssignableFrom(innerType) || innerType.isAssignableFrom(castType))
+                    {
+                        unaryExpr.setType(castType);
+                        typeWasSet = true;
+                    }
+                }
+                break;
+
+        }
+        if (!typeWasSet)
+        {
+            if (unaryExpr.getOperator() == UnaryExpression.OPERATOR_CAST)
+            {
+                throw new JDOUserException("Invalid cast expression because inner expression of type "+innerType.getName()+" cannot be cast to "+unaryExpr.getCastType().getName());
+            }
+            else
+            {
+                throw new JDOUserException("Invalid unary expression");
+            }
+        }
+    }
+
+    // Helper methods
+
+    /**
+     * Retrieves OJB's class descriptor for the given type.
+     * 
+     * @param The type to lookup
+     * @return The class descriptor or <code>null</code> if the class is not persistent
+     */
+    private ClassDescriptor findClassDescriptorFor(Class type)
+    {
+        return MetadataManager.getInstance().getRepository().getDescriptorFor(type);
+    }
+
+    /**
+     * Determines whether the given class denotes an integer primitive type.
+     * 
+     * @param type The type
+     * @return <code>true</code> if the type is an integer type
+     */
+    private static boolean isInteger(Class type)
+    {
+        if (type.isPrimitive())
+        {
+            return (type != boolean.class) && (type != float.class) && (type != double.class);
+        }
+        else
+        {
+            return type == BigInteger.class;
+        }
+    }
+
+    /**
+     * Determines whether the given class denotes a floating point primitive type.
+     * 
+     * @param type The type
+     * @return <code>true</code> if the type is a floating point type
+     */
+    private static boolean isFloatingPoint(Class type)
+    {
+        if (type.isPrimitive())
+        {
+            return (type == float.class) || (type == double.class);
+        }
+        else
+        {
+            return type == BigDecimal.class;
+        }
+    }
+
+    /**
+     * Determines whether the given class denotes a numeric primitive type.
+     * 
+     * @param type The type
+     * @return <code>true</code> if the type is a numeric type
+     */
+    private static boolean isNumeric(Class type)
+    {
+        if (type.isPrimitive())
+        {
+            return type != boolean.class;
+        }
+        else
+        {
+            return (type == BigDecimal.class) || (type == BigInteger.class);
+        }
+    }
+
+    /**
+     * Determines the broader of the two given numeric types.
+     * 
+     * @param typeA The first type
+     * @param typeB The seconf type
+     * @return The broader of the two types
+     */
+    private static Class getBroaderType(Class typeA, Class typeB)
+    {
+        Integer numA = (Integer)_primitiveTypes.get(typeA);
+        Integer numB = (Integer)_primitiveTypes.get(typeB);
+
+        return numA.intValue() < numB.intValue() ? typeB : typeA;
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/ThisExpression.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/ThisExpression.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/ThisExpression.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/ThisExpression.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,68 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * The 'this' expression.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class ThisExpression extends Expression
+{
+    /** The resolved type (which is the type search type of the query) */
+    private Class _type;
+
+    /**
+     * Creates a new this expression object. 
+     */
+    public ThisExpression()
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return "this";
+    }
+
+    /**
+     * Sets the type of this expression.
+     * 
+     * @param type The type
+     */
+    public void setType(Class type)
+    {
+        _type = type;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Expression#getType()
+     */
+    public Class getType()
+    {
+        return _type;
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Type.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Type.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Type.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Type.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,113 @@
+package org.apache.ojb.jdo.jdoql;
+
+import org.apache.ojb.broker.util.ClassHelper;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * Encapsulates a type, either primitive or reference.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class Type extends QueryTreeNode
+{
+    /** The (possibly unqualified) name of the type */
+    private String  _name;
+    /** The type resolved using the imports of the query */
+    private Class   _type;
+
+    /**
+     * Creates a new type object.
+     * 
+     * @param typeName    The (possibly unqualified) name of the variable
+     * @param isPrimitive Whether the type is a primitive type
+     */
+    public Type(String typeName, boolean isPrimitive)
+    {
+        _name = typeName;
+        if (isPrimitive)
+        {
+            resolvePrimitiveType();
+        }
+    }
+
+    /**
+     * Resolves the primitive type of this variable by determining the corresponding
+     * <code>java.lang</code> type.
+     */
+    private void resolvePrimitiveType()
+    {
+        final ClassLoader loader = ClassHelper.getClassLoader();
+        try
+        {
+            _type = Class.forName(_name, true, loader);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            // won't happen because the parser is restricted to valid type names
+        }
+    }
+    
+    /**
+     * Returns the actual class object of the type if already resolved.
+     *  
+     * @return The type or <code>null</code> if not yet resolved
+     */
+    public Class getType()
+    {
+        return _type;
+    }
+
+    /**
+     * Sets the resolved type.
+     * 
+     * @param type The type's class object
+     */
+    public void setType(Class type)
+    {
+        _type = type;
+        if (_type != null)
+        {
+            _name = type.getName();
+        }
+    }
+
+    /**
+     * Returns the variable type's name.
+     * 
+     * @return The type name
+     */
+    public String getName()
+    {
+        return _name;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        return _type == null ? _name : _type.getName();
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/TypeAccess.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/TypeAccess.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/TypeAccess.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/TypeAccess.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,44 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * A type access expression. Note that this expression type can only be
+ * present in a query tree after resolving it.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class TypeAccess extends NameExpression
+{
+    /**
+     * Creates a new type access object.
+     * 
+     * @param base The base expression (can be <code>null</code>)
+     * @param name The type's name
+     */
+    public TypeAccess(Expression base, String name)
+    {
+        super(base, name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/UnaryExpression.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/UnaryExpression.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/UnaryExpression.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/UnaryExpression.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,164 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * A unary expression (arithmetic, logical, or a cast).
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class UnaryExpression extends Expression
+{
+    public static final int OPERATOR_MINUS              = 0;
+    public static final int OPERATOR_PLUS               = 1;
+    public static final int OPERATOR_BITWISE_COMPLEMENT = 2;
+    public static final int OPERATOR_NOT                = 3;
+    public static final int OPERATOR_CAST               = 4;
+
+    /** The unary operator (one of the above constants) */
+    private int        _operator;
+    /** The inner expression */
+    private Expression _inner;
+    /** The type that the inner expression is cast to */
+    private Type       _castType;
+    /** The type of this expression */
+    private Class  _type;
+
+    /**
+     * Creates a new unary expression object.
+     * 
+     * @param operator The unary operator
+     * @param inner    The inner expression
+     */
+    public UnaryExpression(int operator, Expression inner)
+    {
+        _operator = operator;
+        _inner    = inner;
+    }
+
+    /**
+     * Creates a new cast expression object.
+     * 
+     * @param castType The cast-to type
+     * @param inner    The inner expression
+     */
+    public UnaryExpression(Type castType, Expression inner)
+    {
+        _operator = OPERATOR_CAST;
+        _castType = castType;
+        _inner    = inner;
+    }
+
+    /**
+     * Returns the operator.
+     * 
+     * @return The operator
+     */
+    public int getOperator()
+    {
+        return _operator;
+    }
+
+    /**
+     * Returns the inner expression.
+     * 
+     * @return The inner expression 
+     */
+    public Expression getInnerExpression()
+    {
+        return _inner;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Expression#replaceChild(org.apache.ojb.jdo.jdoql.Expression, org.apache.ojb.jdo.jdoql.Expression)
+     */
+    public void replaceChild(Expression oldChild, Expression newChild)
+    {
+        _inner.setParent(null);
+        _inner = newChild;
+        _inner.setParent(this);
+    }
+
+    /**
+     * Returns the target type of this cast expression.
+     * 
+     * @return The type name of the cast type, or <code>null</code> if this is no
+     *         cast expression
+     */
+    public Type getCastType()
+    {
+        return _castType;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Acceptor#accept(org.apache.ojb.jdo.jdoql.Visitor)
+     */
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString()
+    {
+        StringBuffer result = new StringBuffer();
+
+        result.append("(");
+        switch (_operator)
+        {
+            case OPERATOR_PLUS :
+                result.append("+");
+                break;
+            case OPERATOR_MINUS :
+                result.append("-");
+                break;
+            case OPERATOR_BITWISE_COMPLEMENT :
+                result.append("~");
+                break;
+            case OPERATOR_NOT :
+                result.append("!");
+                break;
+            case OPERATOR_CAST :
+                result.append("(");
+                result.append(_castType.toString());
+                result.append(")");
+                break;
+        }
+        result.append(_inner.toString());
+        result.append(")");
+        return result.toString();
+    }
+
+    /**
+     * Sets the type of this unary expression.
+     * 
+     * @param type The type
+     */
+    public void setType(Class type)
+    {
+        _type = type;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Expression#getType()
+     */
+    public Class getType()
+    {
+        return _type;
+    }
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Visitor.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Visitor.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Visitor.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/Visitor.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,152 @@
+package org.apache.ojb.jdo.jdoql;
+
+import java.util.List;
+
+/* Copyright 2003-2004 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.
+ */
+
+/**
+ * Denotes types that visit the jdoql expression trees.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public interface Visitor
+{
+    /**
+     * Processes the variable declarations.
+     * 
+     * @param variables The variables
+     */
+    public void visitVariables(List variables);
+
+    /**
+     * Processes the parameter declarations.
+     * 
+     * @param params The parameters
+     */
+    public void visitParameters(List params);
+
+    /**
+     * Processes the orderings.
+     * 
+     * @param orderings The orderings
+     */
+    public void visitOrderings(List orderings);
+
+    /**
+     * Processes the filter expression.
+     * 
+     * @param filterExpr The filter expression
+     */
+    public void visitFilter(Expression filterExpr);
+
+    /**
+     * Processes the given binary expression.
+     * 
+     * @param binExpr The binary expression to process
+     */
+    void visit(BinaryExpression binExpr);
+
+    /**
+     * Processes the given field access expression.
+     * 
+     * @param fieldAccess The field access to process
+     */
+    void visit(FieldAccess fieldAccess);
+
+    /**
+     * Processes the given import specification.
+     * 
+     * @param nullLit The import specification to process
+     */
+    void visit(Import importSpec);
+
+    /**
+     * Processes the given literal.
+     * 
+     * @param literal The literal to process
+     */
+    void visit(Literal literal);
+
+    /**
+     * Processes the given local variable declaration.
+     * 
+     * @param localVar The local variable declaration to process
+     */
+    void visit(LocalVariable localVar);
+
+    /**
+     * Processes the given local variable access expression.
+     * 
+     * @param localVarAccess The local variable access expression to process
+     */
+    void visit(LocalVariableAccess localVarAccess);
+
+    /**
+     * Processes the given method invocation expression.
+     * 
+     * @param methodInvoc The method invocation expression to process
+     */
+    void visit(MethodInvocation methodInvoc);
+
+    /**
+     * Processes the given name expression.
+     * 
+     * @param varAccess The name expression to process
+     */
+    void visit(NameExpression nameExpr);
+
+    /**
+     * Processes the given <code>null</code> literal.
+     * 
+     * @param nullLit The <code>null</code> literal to process
+     */
+    void visit(NullLiteral nullLit);
+
+    /**
+     * Processes the given ordering.
+     * 
+     * @param ordering The ordering to process
+     */
+    void visit(Ordering ordering);
+
+    /**
+     * Processes the given <code>this</code> expression.
+     * 
+     * @param thisExpr The <code>this</code> expression to process
+     */
+    void visit(ThisExpression thisExpr);
+    
+    /**
+     * Processes the given type.
+     * 
+     * @param type The type to process
+     */
+    void visit(Type type);
+
+    /**
+     * Processes the given type access expression.
+     * 
+     * @param type The type access expression to process
+     */
+    void visit(TypeAccess typeAccess);
+
+    /**
+     * Processes the given unary expression.
+     * 
+     * @param unaryExpr The unary expression to process
+     */
+    void visit(UnaryExpression unaryExpr);
+}

Added: db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/VisitorBase.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/VisitorBase.java?rev=430936&view=auto
==============================================================================
--- db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/VisitorBase.java (added)
+++ db/ojb/trunk/proposals/jdo/java/org/apache/ojb/jdo/jdoql/VisitorBase.java Fri Aug 11 18:17:46 2006
@@ -0,0 +1,196 @@
+package org.apache.ojb.jdo.jdoql;
+
+/* Copyright 2003-2004 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.
+ */
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Convenience base class for visitors that provides basic traversal capabilities.
+ * 
+ * @author <a href="mailto:tomdz@apache.org">Thomas Dudziak</a>
+ */
+public class VisitorBase implements Visitor
+{
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visitFilter(org.apache.ojb.jdo.jdoql.Expression)
+     */
+    public void visitFilter(Expression filterExpr)
+    {
+        filterExpr.accept(this);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visitOrderings(java.util.List)
+     */
+    public void visitOrderings(List orderings)
+    {
+        for (Iterator it = orderings.iterator(); it.hasNext();)
+        {
+            ((Acceptor)it.next()).accept(this);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visitParameters(java.util.List)
+     */
+    public void visitParameters(List params)
+    {
+        for (Iterator it = params.iterator(); it.hasNext();)
+        {
+            ((Acceptor)it.next()).accept(this);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visitVariables(java.util.List)
+     */
+    public void visitVariables(List variables)
+    {
+        for (Iterator it = variables.iterator(); it.hasNext();)
+        {
+            ((Acceptor)it.next()).accept(this);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.BinaryExpression)
+     */
+    public void visit(BinaryExpression binExpr)
+    {
+        binExpr.getLeftSide().accept(this);
+        binExpr.getRightSide().accept(this);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.FieldAccess)
+     */
+    public void visit(FieldAccess fieldAccess)
+    {
+        if (fieldAccess.hasBaseExpression())
+        {
+            fieldAccess.getBaseExpression().accept(this);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.Import)
+     */
+    public void visit(Import importSpec)
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.Literal)
+     */
+    public void visit(Literal literal)
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.LocalVariable)
+     */
+    public void visit(LocalVariable localVar)
+    {
+        localVar.getType().accept(this);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.LocalVariableAccess)
+     */
+    public void visit(LocalVariableAccess localVarAccess)
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.MethodInvocation)
+     */
+    public void visit(MethodInvocation methodInvoc)
+    {
+        if (methodInvoc.hasBaseExpression())
+        {
+            methodInvoc.getBaseExpression().accept(this);
+        }
+        for (Iterator it = methodInvoc.getArguments().iterator(); it.hasNext();)
+        {
+            ((Acceptor)it.next()).accept(this);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.NullLiteral)
+     */
+    public void visit(NullLiteral nullLit)
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.Ordering)
+     */
+    public void visit(Ordering ordering)
+    {
+        ordering.getExpression().accept(this);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.ThisExpression)
+     */
+    public void visit(ThisExpression thisExpr)
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.Type)
+     */
+    public void visit(Type type)
+    {
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.TypeAccess)
+     */
+    public void visit(TypeAccess typeAccess)
+    {
+        if (typeAccess.hasBaseExpression())
+        {
+            typeAccess.getBaseExpression().accept(this);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.UnaryExpression)
+     */
+    public void visit(UnaryExpression unaryExpr)
+    {
+        if (unaryExpr.getOperator() == UnaryExpression.OPERATOR_CAST)
+        {
+            unaryExpr.getCastType().accept(this);
+        }
+        unaryExpr.getInnerExpression().accept(this);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.ojb.jdo.jdoql.Visitor#visit(org.apache.ojb.jdo.jdoql.NameExpression)
+     */
+    public void visit(NameExpression nameExpr)
+    {
+        if (nameExpr.hasBaseExpression())
+        {
+            nameExpr.getBaseExpression().accept(this);
+        }
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org