You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/09/03 10:52:18 UTC

svn commit: r810825 - in /openjpa/trunk: openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/ openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/

Author: ppoddar
Date: Thu Sep  3 08:52:17 2009
New Revision: 810825

URL: http://svn.apache.org/viewvc?rev=810825&view=rev
Log:
OPENJPA-1278,OPENJPA-1276,OPENJPA-1013:   
  Modify negation of predicate logic
  Promote interfaces from internal implementaion argument to  public interfaces
 Add Fetch Join and logical precedence order to CQL generation

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java   (with props)
Modified:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/   (props changed)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCQL.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEmbeddableCriteria.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/AliasContext.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpression.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FetchPathImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OrderImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Thu Sep  3 08:52:17 2009
@@ -4,3 +4,4 @@
 *.log
 maven-eclipse.xml
 *.class
+TestCJQL.java

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCQL.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCQL.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCQL.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCQL.java Thu Sep  3 08:52:17 2009
@@ -63,5 +63,23 @@
         jpql = "SELECT p FROM Person p WHERE (p.name = 'A' OR (p.name = 'B' AND (p.name = 'C' OR p.name = 'D')))";
         assertEquivalence(q, jpql);
         assertEquals(jpql, q.toCQL());
+        
+        // NOT (a OR b) 
+        q.where(cb.or(a, b).negate());
+        jpql = "SELECT p FROM Person p WHERE NOT (p.name = 'A' OR p.name = 'B')";
+        assertEquivalence(q, jpql);
+        assertEquals(jpql, q.toCQL());
+        
+        // NOT a 
+        q.where(cb.and(a).negate());
+        jpql = "SELECT p FROM Person p WHERE NOT p.name = 'A'";
+        assertEquivalence(q, jpql);
+        assertEquals(jpql, q.toCQL());
+
+        // NOT a OR NOT b
+        q.where(cb.or(cb.not(a), cb.not(b)));
+        jpql = "SELECT p FROM Person p WHERE (p.name <> 'A' OR p.name <> 'B')";
+        assertEquivalence(q, jpql);
+        assertEquals(jpql, q.toCQL());
     }
 }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEmbeddableCriteria.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEmbeddableCriteria.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEmbeddableCriteria.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEmbeddableCriteria.java Thu Sep  3 08:52:17 2009
@@ -1477,7 +1477,6 @@
         assertEquivalence(q, jpql);
     }
 
-    @AllowFailure(message="JPQL parse exception")
     public void testEmbeddableQuery111() {
         String jpql = "select i from Item1 i where :image = any(select KEY(e) from i.images e) order by i";
         CriteriaQuery<Item1> q = cb.createQuery(Item1.class);

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java?rev=810825&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java Thu Sep  3 08:52:17 2009
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.openjpa.persistence.criteria;
+
+import javax.persistence.criteria.JoinType;
+import javax.persistence.criteria.Root;
+
+public class TestFetchJoin extends CriteriaTest {
+    public void testFetchJoin() {
+        String jpql = "SELECT e FROM Employee e INNER JOIN FETCH e.department";
+        OpenJPACriteriaQuery<Employee> q = cb.createQuery(Employee.class);
+        Root<Employee> e = q.from(Employee.class);
+        q.select(e);
+        e.fetch(Employee_.department);
+        
+        assertEquivalence(q, jpql);
+        assertEquals(jpql, q.toCQL());
+    }
+    
+    public void testLeftFetchJoin() {
+        String jpql = "SELECT e FROM Employee e LEFT JOIN FETCH e.department";
+        OpenJPACriteriaQuery<Employee> q = cb.createQuery(Employee.class);
+        Root<Employee> e = q.from(Employee.class);
+        q.select(e);
+        e.fetch(Employee_.department, JoinType.LEFT);
+        
+        assertEquivalence(q, jpql);
+        assertEquals(jpql, q.toCQL());
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestFetchJoin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java Thu Sep  3 08:52:17 2009
@@ -112,13 +112,13 @@
 
     public void testLike1() {
         String jpql = "SELECT o.computerName FROM CompUser o "
-                 + "WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC')";
+                 + "WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC','Laptop')";
 
         CriteriaQuery<String> cq = cb.createQuery(String.class);
         Root<CompUser> o = cq.from(CompUser.class);
         cq.where(cb.and(
                     cb.like(o.get(CompUser_.name),"Sha%"), 
-                    cb.in(o.get(CompUser_.computerName)).value("PC").negate()
+                    cb.in(o.get(CompUser_.computerName)).value("PC").value("Laptop").negate()
                 ));
         
         cq.select(o.get(CompUser_.computerName));
@@ -128,13 +128,13 @@
     
     public void testLike2() {
         String jpql = "SELECT o.computerName FROM CompUser o "
-            + "WHERE o.name LIKE 'Sha%o_' AND o.computerName NOT IN ('UNIX')";
+            + "WHERE o.name LIKE 'Sha%o_' AND o.computerName NOT IN ('UNIX','DOS')";
 
         CriteriaQuery<String> cq = cb.createQuery(String.class);
         Root<CompUser> o = cq.from(CompUser.class);
         cq.where(cb.and(
                     cb.like(o.get(CompUser_.name),"Sha%o_"), 
-                    cb.in(o.get(CompUser_.computerName)).value("UNIX").negate()
+                    cb.in(o.get(CompUser_.computerName)).value("UNIX").value("DOS").negate()
                 ));
         cq.select(o.get(CompUser_.computerName));
         

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java Thu Sep  3 08:52:17 2009
@@ -1019,7 +1019,7 @@
     public void testKeys7() {
         String sql = "SELECT t0.name, t2.id, t2.label FROM CR_ITEM t0 "
             + "INNER JOIN CR_ITEM_photos t1 ON t0.id = t1.ITEM_ID "
-            + "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id";
+            + "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id WHERE (NOT (1 <> 1))";
 
         CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
         Root<Item> item = q.from(Item.class);
@@ -1178,7 +1178,7 @@
     public void testValues7() {
         String sql = "SELECT t0.name, t2.id, t2.label FROM CR_ITEM t0 "
             + "INNER JOIN CR_ITEM_photos t1 ON t0.id = t1.ITEM_ID "
-            + "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id";
+            + "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id WHERE (NOT (1 <> 1))";
 
         CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
         Root<Item> item = q.from(Item.class);

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/AliasContext.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/AliasContext.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/AliasContext.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/AliasContext.java Thu Sep  3 08:52:17 2009
@@ -18,6 +18,7 @@
  */
 package org.apache.openjpa.persistence.criteria;
 
+import javax.persistence.criteria.Root;
 import javax.persistence.criteria.Selection;
 
 import org.apache.openjpa.kernel.exps.Value;
@@ -59,6 +60,12 @@
     Value getRegisteredVariable(Selection<?> node);
     
     /**
+     * Gets the registered root variable for the given node. 
+     * Return null if the node is not registered.     
+     */
+    Value getRegisteredRootVariable(Root<?> node);
+    
+    /**
      * Gets the registered path value for the given node. 
      * Return null if the node is not registered.     
      */

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java Thu Sep  3 08:52:17 2009
@@ -97,7 +97,7 @@
         abstract FillStrategy<X> getFillStrategy();
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             StringBuilder buffer = new StringBuilder();
             for (int i = 0; i < _args.size(); i++) {
                 buffer.append((((CriteriaExpression)_args.get(i)).asValue(q)));
@@ -158,7 +158,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return new StringBuilder("NEW ").append(getJavaType().getName()).append("(")
                .append(super.asValue(q)).append(")");
         }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java Thu Sep  3 08:52:17 2009
@@ -392,6 +392,10 @@
     }
 
     public <T> Expression<T> literal(T value) {
+        if (Boolean.TRUE.equals(value))
+            return (Expression<T>)PredicateImpl.TRUE;
+        if (Boolean.FALSE.equals(value))
+            return (Expression<T>)PredicateImpl.FALSE;
         return new Expressions.Constant<T>(value);
     }
 
@@ -452,15 +456,15 @@
     }
 
     public Predicate not(Expression<Boolean> restriction) {
-        return new Expressions.Not(restriction);
+        return ((Predicate)restriction).negate();
     }
 
     public Predicate notEqual(Expression<?> x, Expression<?> y) {
-        return equal(x, y).negate();
+        return new Expressions.NotEqual(x, y);
     }
 
     public Predicate notEqual(Expression<?> x, Object y) {
-        return equal(x, y).negate();
+        return new Expressions.NotEqual(x, y);
     }
 
     public Predicate notLike(Expression<String> x, Expression<String> pattern) {
@@ -679,7 +683,7 @@
     }
 
     public Predicate isNotNull(Expression<?> x) {
-        return new Expressions.IsNull((ExpressionImpl<?> )x).negate();
+        return new Expressions.IsNotNull((ExpressionImpl<?> )x);
     }
 
     public Predicate isNull(Expression<?> x) {

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpression.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpression.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpression.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpression.java Thu Sep  3 08:52:17 2009
@@ -36,10 +36,10 @@
     /**
      * Get a string representation of this node as a value in the context of the given query.
      */
-    StringBuilder asValue(CriteriaQueryImpl<?> q);
+    StringBuilder asValue(AliasContext q);
     
     /**
      * Get a string representation of this node as a variable in the context of the given query.
      */
-    StringBuilder asVariable(CriteriaQueryImpl<?> q);
+    StringBuilder asVariable(AliasContext q);
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java Thu Sep  3 08:52:17 2009
@@ -89,28 +89,21 @@
 
     protected void evalAccessPaths(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
         Set<ClassMetaData> metas = new HashSet<ClassMetaData>();
-        Set<Root<?>> roots = q.getRoots();
-        if (roots != null) {
-            MetamodelImpl metamodel = q.getMetamodel();    
-            for (Root<?> root : roots) {
-                metas.add(((AbstractManagedType<?>)root.getModel()).meta);
-                if (root.getJoins() != null) {
-                    for (Join<?,?> join : root.getJoins()) {
-                        Class<?> cls = join.getAttribute().getJavaType();
-                        if (join.getAttribute().isAssociation()) {
-                            ClassMetaData meta = metamodel.repos.getMetaData(cls, null, true);
-                            PersistenceType type = MetamodelImpl.getPersistenceType(meta);
-                            if (type == PersistenceType.ENTITY || type == PersistenceType.EMBEDDABLE) 
-                                metas.add(meta);
-                        }
-                    }
-                    if (root.getFetches() != null) {
-                        for (Fetch<?,?> fetch : root.getFetches()) {
-                            metas.add(metamodel.repos.getMetaData(fetch.getAttribute().getJavaType(), null, false));
-                        }
-                    }
+        MetamodelImpl metamodel = q.getMetamodel();    
+        for (Root<?> root : q.getRoots()) {
+            metas.add(((AbstractManagedType<?>)root.getModel()).meta);
+            for (Join<?,?> join : root.getJoins()) {
+                Class<?> cls = join.getAttribute().getJavaType();
+                if (join.getAttribute().isAssociation()) {
+                    ClassMetaData meta = metamodel.repos.getMetaData(cls, null, true);
+                    PersistenceType type = MetamodelImpl.getPersistenceType(meta);
+                    if (type == PersistenceType.ENTITY || type == PersistenceType.EMBEDDABLE) 
+                        metas.add(meta);
                 }
             }
+            for (Fetch<?,?> fetch : root.getFetches()) {
+                metas.add(metamodel.repos.getCachedMetaData(fetch.getAttribute().getJavaType()));
+            }
         }
         exps.accessPath = metas.toArray(new ClassMetaData[metas.size()]);
     }
@@ -178,15 +171,9 @@
     }
 
     protected void evalDistinct(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
-        Boolean distinct = q.getDistinct();
-        if (distinct == null) {
-            exps.distinct = QueryExpressions.DISTINCT_FALSE;
-        } else if (distinct) {
-            exps.distinct = QueryExpressions.DISTINCT_TRUE 
-            | QueryExpressions.DISTINCT_AUTO;
-        }
-        //exps.distinct &= ~QueryExpressions.DISTINCT_AUTO;
-    }
+        exps.distinct = q.isDistinct() ? QueryExpressions.DISTINCT_TRUE | QueryExpressions.DISTINCT_AUTO
+                : QueryExpressions.DISTINCT_FALSE;
+     }
 
     protected void evalCrossJoinRoots(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
         Set<Root<?>> roots = q.getRoots();
@@ -197,10 +184,11 @@
                 for (Root<?> root : roots) {
                     String alias = q.getAlias(root);
                     Value var = factory.newBoundVariable(alias, AbstractExpressionBuilder.TYPE_OBJECT);
-                    var.setMetaData(((Types.Entity)root.getModel()).meta);
+                    var.setMetaData(((AbstractManagedType<?>)root.getModel()).meta);
                     q.registerRoot(root, var);
                 }
-            }         }
+            }         
+        }
     }
     
     protected void evalFilter(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
@@ -212,25 +200,23 @@
         if (subQuery == null || subQuery.getCorrelatedJoins() == null) {
             q.assertRoot();
             for (Root<?> root : roots) {
-                if (root.getJoins() != null) {
-                    for (Join<?, ?> join : root.getJoins()) {
-                        filter = and(factory, ((ExpressionImpl<?>)join).toKernelExpression(factory, model, q), filter);
-                    }
+                for (Join<?, ?> join : root.getJoins()) {
+                    filter = Expressions.and(factory, 
+                            ((ExpressionImpl<?>)join).toKernelExpression(factory, model, q), filter);
                 }
                 ((RootImpl<?>)root).addToContext(factory, model, q);
             }
         }
         if (subQuery != null) {
             List<Join<?,?>> corrJoins = subQuery.getCorrelatedJoins();
-            if (corrJoins != null) {
-                for (int i = 0; i < corrJoins.size(); i++) 
-                    filter = and(factory, ((ExpressionImpl<?>)corrJoins.get(i)).toKernelExpression(factory, model, q),  
-                            filter);
+            for (int i = 0; corrJoins != null && i < corrJoins.size(); i++) {
+                filter = Expressions.and(factory, ((ExpressionImpl<?>)corrJoins.get(i))
+                        .toKernelExpression(factory, model, q), filter);
             }
         }
         
         if (where != null) {
-            filter = and(factory, where.toKernelExpression(factory, model, q), filter);
+            filter = Expressions.and(factory, where.toKernelExpression(factory, model, q), filter);
         }
         if (filter == null) {
             filter = factory.emptyExpression();
@@ -296,51 +282,31 @@
             }         
         }
     }
-    
-
-//    protected boolean isDefaultProjection(List<Selection<?>> selections, CriteriaQueryImpl<?> q) {
-//        if (selections == null)
-//            return true;
-//        if (selections.size() != 1)
-//            return false;
-//        Selection<?> sel = selections.get(0);
-//        if (q.getRoots() != null && sel == q.getRoot())
-//            return true;
-//        if ((sel instanceof PathImpl<?,?>) && ((PathImpl<?,?>)sel)._correlatedPath != null)
-//            return true;
-//        return false;
-//    }
 
     protected void evalFetchJoin(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
         List<String> iPaths = new ArrayList<String>();
         List<String> oPaths = new ArrayList<String>();
         Set<Root<?>> roots = q.getRoots();
-        if (roots == null)
-            return;
         for (Root root : roots) {
             Set<Fetch> fetches = root.getFetches();
             if (fetches == null)
                 continue;
             for (Fetch<?,?> fetch : fetches) {
-                String fPath = ((Members.Member<?, ?>)fetch.getAttribute())
-                   .fmd.getFullName(false);
+                String fPath = ((Members.Member<?, ?>)fetch.getAttribute()).fmd.getFullName(false);
                 oPaths.add(fPath);
                 if (fetch.getJoinType() == JoinType.INNER) {
                    iPaths.add(fPath);
                 } 
             }
         }
-        if (!iPaths.isEmpty())
+        if (!iPaths.isEmpty()) {
             exps.fetchInnerPaths = iPaths.toArray(new String[iPaths.size()]);
-        if (!oPaths.isEmpty())
+        }
+        if (!oPaths.isEmpty()) {
             exps.fetchPaths = oPaths.toArray(new String[oPaths.size()]);
+        }
     }
 
-    protected static org.apache.openjpa.kernel.exps.Expression and (ExpressionFactory factory,
-        org.apache.openjpa.kernel.exps.Expression e1, org.apache.openjpa.kernel.exps.Expression e2) {
-        return e1 == null ? e2 : e2 == null ? e1 : factory.and(e1, e2);
-    }
-    
     // ===================================================================================
     // Result Shape processing
     // ===================================================================================
@@ -358,7 +324,7 @@
         if (type == null)
             type = Object.class;
         if (s.isCompoundSelection()) {
-            CompoundSelection<?> cs = (CompoundSelection)s;
+            CompoundSelection<?> cs = (CompoundSelection<?>)s;
             result = new ResultShape(s.getJavaType(), CompoundSelections.getFillStrategy(cs));
             List<Selection<?>> terms = cs.getCompoundSelectionItems();
             for (Selection<?> term : terms) {
@@ -414,6 +380,4 @@
     
         return result;
    }
-
-    
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java Thu Sep  3 08:52:17 2009
@@ -28,11 +28,11 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.Stack;
-import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.persistence.criteria.AbstractQuery;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Fetch;
 import javax.persistence.criteria.Join;
 import javax.persistence.criteria.Order;
 import javax.persistence.criteria.ParameterExpression;
@@ -72,13 +72,13 @@
     private Set<Root<?>>        _roots;
     private PredicateImpl       _where;
     private List<Order>         _orders;
-    private LinkedMap/*<ParameterExpression<?>, Class<?>>*/ _params;
-    private Selection<? extends T>        _selection;
+    private LinkedMap           _params; /*<ParameterExpression<?>, Class<?>>*/ 
+    private Selection<? extends T> _selection;
     private List<Selection<?>>  _selections;
     private List<Expression<?>> _groups;
     private PredicateImpl       _having;
     private List<Subquery<?>>   _subqueries;
-    private Boolean             _distinct;
+    private boolean             _distinct;
     private final SubqueryImpl<?> _delegator;
     private final Class<T>      _resultClass;
     private boolean             _compiled;
@@ -236,18 +236,22 @@
     }
 
     public CriteriaQuery<T> groupBy(Expression<?>... grouping) {
-    	_groups = new ArrayList<Expression<?>>();
-    	if (grouping == null)
+    	if (grouping == null) {
+    	    _groups = null;
     	    return this;
+    	}
+        _groups = new ArrayList<Expression<?>>();
     	for (Expression<?> e : grouping)
     		_groups.add(e);
         return this;
     }
     
     public CriteriaQuery<T> groupBy(List<Expression<?>> grouping) {
-        _groups = new ArrayList<Expression<?>>();
-        if (grouping == null)
+        if (grouping == null) {
+            _groups = null;
             return this;
+        }
+        _groups = new ArrayList<Expression<?>>();
         for (Expression<?> e : grouping)
             _groups.add(e);
         return this;
@@ -255,21 +259,27 @@
 
 
     public CriteriaQuery<T> having(Expression<Boolean> restriction) {
-        _having = new PredicateImpl().add(restriction);
+        _having = (PredicateImpl)restriction;
         return this;
     }
 
     public CriteriaQuery<T> having(Predicate... restrictions) {
-        _having = new PredicateImpl();
+        if (restrictions == null) {
+            _having = null;
+            return this;
+        }
+        _having = new PredicateImpl.And();
         for (Predicate p : restrictions)
         	_having.add(p);
         return this;
     }
 
     public CriteriaQuery<T> orderBy(Order... orders) {
-        _orders = new ArrayList<Order>();
-        if (orders == null)
+        if (orders == null) {
+            _orders = null;
             return this;
+        }
+        _orders = new ArrayList<Order>();
         for (Order o : orders) {
             _orders.add(o);
         }
@@ -277,9 +287,11 @@
     }
     
     public CriteriaQuery<T> orderBy(List<Order> orders) {
-        _orders = new ArrayList<Order>();
-        if (orders == null)
+        if (orders == null) {
+            _orders = null;
             return this;
+        }
+        _orders = new ArrayList<Order>();
         for (Order o : orders) {
             _orders.add(o);
         }
@@ -306,7 +318,7 @@
             _where = null;
             return this;
         }
-        _where = new PredicateImpl().add(restriction);
+        _where = (PredicateImpl)restriction;
         return this;
     }
 
@@ -316,9 +328,7 @@
             _where = null;
             return this;
         }
-        _where = new PredicateImpl();
-        for (Predicate p : restrictions)
-        	_where.add(p);
+        _where = new PredicateImpl.And(restrictions);
         return this;
     }
 
@@ -371,11 +381,10 @@
         _roots.add(root);
     }
     
+    /**
+     * Affirms if selection of this query is distinct.
+     */
     public boolean isDistinct() {
-        return _distinct == null ? false : _distinct.booleanValue();
-    }
-
-    Boolean getDistinct() {
         return _distinct;
     }
 
@@ -553,11 +562,8 @@
     
     /**
      * Gets the registered variable for the given root. 
-     * 
-     * @param root
-     * @return
      */
-    Value getRegisteredRootVariable(Root<?> root) {
+    public Value getRegisteredRootVariable(Root<?> root) {
         Value var = _rootVariables.get(root);
         if (var != null)
             return var;
@@ -640,7 +646,7 @@
     public String toCQL() {
         StringBuilder buffer = new StringBuilder();
         render(buffer, _roots, null);
-        return buffer.toString();
+        return buffer.toString().trim();
     }
     
     void render(StringBuilder buffer, Set<Root<?>> roots, List<Join<?,?>> correlatedJoins) {
@@ -655,11 +661,20 @@
         }
         if (_orders != null) {
             buffer.append(" ORDER BY ");
-            List<Order> orderBys = getOrderList();
-            for (int i = 0; i < orderBys.size(); i++) {
-                buffer.append(((CriteriaExpression)orderBys.get(i)).asValue(this));
+            for (Order orderBy : getOrderList()) {
+                buffer.append(((CriteriaExpression)orderBy).asValue(this));
+            }
+        }
+        if (_groups != null) {
+            buffer.append(" GROUP BY ");
+            for (Expression<?> groupBy : getGroupList()) {
+                buffer.append(((CriteriaExpression)groupBy).asValue(this));
             }
         }
+        if (_having != null) {
+            buffer.append(" HAVING ");
+            buffer.append(_having.asValue(this));
+        }
     }
     
     private void renderJoins(StringBuilder buffer, Collection<Join<?,?>> joins) {
@@ -667,6 +682,7 @@
         for (Join j : joins) {
             buffer.append(((ExpressionImpl<?>)j).asVariable(this)).append(" ");
             renderJoins(buffer, j.getJoins());
+            renderFetches(buffer, j.getFetches());
         }
     }
     
@@ -677,6 +693,13 @@
             buffer.append(((ExpressionImpl<?>)r).asVariable(this));
             if (++i != roots.size()) buffer.append(", ");
             renderJoins(buffer, r.getJoins());
+            renderFetches(buffer, r.getFetches());
+        }
+    }
+    private void renderFetches(StringBuilder buffer, Set<Fetch> fetches) {
+        if (fetches == null) return;
+        for (Fetch j : fetches) {
+            buffer.append(((ExpressionImpl<?>)j).asValue(this)).append(" ");
         }
     }
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java Thu Sep  3 08:52:17 2009
@@ -124,7 +124,7 @@
      /**
       * Renders the given expressions as a list of values separated by the given connector.
       */
-     static StringBuilder asValue(CriteriaQueryImpl<?> q, Expression<?>[] exps, String connector) {
+     static StringBuilder asValue(AliasContext q, Expression<?>[] exps, String connector) {
          StringBuilder buffer = new StringBuilder();
          if (exps == null) return buffer;
          for (int i = 0; i < exps.length; i++) {
@@ -139,7 +139,7 @@
      /**
       * Renders the given arguments as a list of values separated by the given connector.
       */
-     static StringBuilder asValue(CriteriaQueryImpl<?> q, Object...params) {
+     static StringBuilder asValue(AliasContext q, Object...params) {
          StringBuilder buffer = new StringBuilder();
          if (params == null) return buffer;
          for (int i = 0; i < params.length; i++) {
@@ -175,6 +175,11 @@
          return set == null ? new HashSet<X>() : new CopyOnWriteArraySet<X>(set);
      }
      
+     static org.apache.openjpa.kernel.exps.Expression and(ExpressionFactory factory,
+             org.apache.openjpa.kernel.exps.Expression e1, org.apache.openjpa.kernel.exps.Expression e2) {
+             return e1 == null ? e2 : e2 == null ? e1 : factory.and(e1, e2);
+     }
+         
 
 
      /**
@@ -254,7 +259,7 @@
      * i.e. an expression whose resultant type is Boolean.
      *
      */
-   public static class BinaryLogicalExpression extends PredicateImpl {
+   public static abstract class BinaryLogicalExpression extends PredicateImpl {
         protected final ExpressionImpl<?> e1;
         protected final ExpressionImpl<?> e2;
         
@@ -264,10 +269,10 @@
             e2 = (ExpressionImpl<?>)y;
         }
         
-        @Override
-        public PredicateImpl clone() {
-            return new BinaryLogicalExpression(e1, e2);
-        }
+//        @Override
+//        public PredicateImpl clone() {
+//            return new BinaryLogicalExpression(e1, e2);
+//        }
         
         public void acceptVisit(CriteriaExpressionVisitor visitor) {
             Expressions.acceptVisit(visitor, this, e1, e2);
@@ -285,7 +290,7 @@
             return factory.abs(Expressions.toValue(e, factory, model, q));
         }
         
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "ABS", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -309,7 +314,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "COUNT", OPEN_BRACE, _distinct ? "DISTINCT"+OPEN_BRACE : "", 
                 e, _distinct ? CLOSE_BRACE : "", CLOSE_BRACE);
         }
@@ -326,7 +331,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "AVG", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -341,7 +346,7 @@
             return factory.sqrt(Expressions.toValue(e, factory, model, q));
         }
         
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "SQRT", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -356,7 +361,7 @@
             return factory.max(Expressions.toValue(e, factory, model, q));
         }
         
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "MAX", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -371,7 +376,7 @@
             return factory.min(Expressions.toValue(e, factory, model, q));
         }
         
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "MIN", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -395,7 +400,7 @@
             return factory.size(val);
         }
         
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "SIZE", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -416,7 +421,7 @@
                 new Expressions.ListArgument(resultType, args).toValue(factory, model, q));
         }
         
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, functionName, OPEN_BRACE, Expressions.asValue(q, args, COMMA), CLOSE_BRACE);
         }
     }
@@ -433,7 +438,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "TYPE", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -449,7 +454,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, OPEN_BRACE, getJavaType().getSimpleName(), CLOSE_BRACE, e);
         }
     }
@@ -475,7 +480,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "CONCAT", OPEN_BRACE, e1, COMMA, e2, CLOSE_BRACE);
         }
     }
@@ -520,7 +525,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "SUBSTRING", OPEN_BRACE, e, COMMA, from, COMMA, len, CLOSE_BRACE);
         }
     }
@@ -572,7 +577,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "LOCATE", OPEN_BRACE, pattern, COMMA, path, CLOSE_BRACE);
         }
     }
@@ -623,7 +628,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "TRIM", OPEN_BRACE, e1, COMMA, e2, CLOSE_BRACE);
         }        
     }
@@ -655,7 +660,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return e2 == null 
                ? Expressions.asValue(q, "SUM", OPEN_BRACE, e1, CLOSE_BRACE)
                : Expressions.asValue(q, e1, " + ", e2);
@@ -683,7 +688,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e1, " * " ,e2);
         }        
     }
@@ -709,7 +714,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e1, " - " ,e2);
         }        
     }
@@ -736,7 +741,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e1, "%" ,e2);
         }        
     }
@@ -760,7 +765,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "MOD", OPEN_BRACE, e1, COMMA, e2, CLOSE_BRACE);
         }        
     }
@@ -776,7 +781,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return new StringBuilder("CURRENT_DATE");
         }
     }
@@ -792,7 +797,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return new StringBuilder("CURRENT_TIME");
         }
     }
@@ -808,7 +813,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return new StringBuilder("CURRENT_TIMESTAMP");
         }
     }
@@ -821,10 +826,10 @@
         public <X> Equal(Expression<X> x, Object y) {
             this(x, new Constant(y));
         }
-        
+
         @Override
-        public PredicateImpl clone() {
-            return new Equal(e1, e2);
+        public PredicateImpl negate() {
+            return new NotEqual(e1, e2).markNegated();
         }
         
         @Override
@@ -833,15 +838,44 @@
             Value val1 = Expressions.toValue(e1, factory, model, q);
             Value val2 = Expressions.toValue(e2, factory, model, q);
             Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q);
-            return isNegated() ? factory.notEqual(val1, val2) : factory.equal(val1, val2);
+            return factory.equal(val1, val2);
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e1, " = ", e2);
         }        
     }
     
+    public static class NotEqual extends BinaryLogicalExpression {
+        public <X,Y> NotEqual(Expression<X> x, Expression<Y> y) {
+            super(x,y);
+        }
+        
+        public <X> NotEqual(Expression<X> x, Object y) {
+            this(x, new Constant(y));
+        }
+        
+        @Override
+        public PredicateImpl negate() {
+            return new Equal(e1, e2).markNegated();
+        }
+        
+        @Override
+        org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl<?> q) {
+            Value val1 = Expressions.toValue(e1, factory, model, q);
+            Value val2 = Expressions.toValue(e2, factory, model, q);
+            Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q);
+            return factory.notEqual(val1, val2);
+        }
+        
+        @Override
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, e1, " <> ", e2);
+        }        
+    }
+    
     public static class GreaterThan extends BinaryLogicalExpression {
         public <X,Y> GreaterThan(Expression<X> x, Expression<Y> y) {
             super(x,y);
@@ -852,6 +886,11 @@
         }
         
         @Override
+        public PredicateImpl negate() {
+            return new LessThanEqual(e1, e2).markNegated();
+        }
+        
+        @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, 
             CriteriaQueryImpl<?> q) {
             Value val1 = Expressions.toValue(e1, factory, model, q);
@@ -861,7 +900,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e1, " > ", e2);
         }        
     }
@@ -876,6 +915,11 @@
         }
         
         @Override
+        public PredicateImpl negate() {
+            return new LessThan(e1, e2).markNegated();
+        }
+        
+        @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, 
             CriteriaQueryImpl<?> q) {
             Value val1 = Expressions.toValue(e1, factory, model, q);
@@ -885,7 +929,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e1, " >= ", e2);
         }        
     }
@@ -900,6 +944,11 @@
         }
         
         @Override
+        public PredicateImpl negate() {
+            return new GreaterThanEqual(e1, e2).markNegated();
+        }
+        
+        @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, 
             CriteriaQueryImpl<?> q) {
             Value val1 = Expressions.toValue(e1, factory, model, q);
@@ -909,7 +958,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e1, " < ", e2);
         }        
     }
@@ -924,6 +973,11 @@
         }
         
         @Override
+        public PredicateImpl negate() {
+            return new GreaterThan(e1, e2).markNegated();
+        }
+        
+        @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, 
             CriteriaQueryImpl<?> q) {
             Value val1 = Expressions.toValue(e1, factory, model, q);
@@ -934,7 +988,7 @@
         
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e1, " <= ", e2);
         }        
     }
@@ -956,7 +1010,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e, " BETWEEN ", v1, " AND ", v2);
         }
     }
@@ -1009,7 +1063,7 @@
             Expressions.acceptVisit(visitor, this, arg instanceof Expression ? ((Expression)arg) : null);
         }
         
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             if (arg == null)
                 return new StringBuilder("NULL");
             Class<?> literalClass = getJavaType();
@@ -1040,15 +1094,20 @@
         }
         
         @Override
-        public PredicateImpl clone() {
-            return new IsEmpty(collection);
+        public PredicateImpl negate() {
+            return new IsNotEmpty(collection).markNegated();
+        }
+        
+        @Override
+        Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
+            return Expressions.toValue(collection, factory, model, q);
         }
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, 
             CriteriaQueryImpl<?> q) {
             Value val = Expressions.toValue(collection, factory, model, q);
-            return (isNegated()) ? factory.not(factory.isEmpty(val)) : factory.isEmpty(val);
+            return factory.isEmpty(val);
         }
         
         public void acceptVisit(CriteriaExpressionVisitor visitor) {
@@ -1057,7 +1116,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, collection, " IS EMPTY");
         }
     }
@@ -1070,15 +1129,21 @@
         }
         
         @Override
-        public PredicateImpl clone() {
-            return new IsNotEmpty(collection);
+        public PredicateImpl negate() {
+            return new IsEmpty(collection).markNegated();
+        }
+        
+        @Override
+        Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
+            return Expressions.toValue(collection, factory, model, q);
         }
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, 
             CriteriaQueryImpl<?> q) {
             Value val = Expressions.toValue(collection, factory, model, q);
-            return (isNegated()) ? factory.isEmpty(val) : factory.isNotEmpty(val);
+            // factory.isNotEmpty() not used to match JPQL
+            return factory.not(factory.isEmpty(val));
         }
         
         public void acceptVisit(CriteriaExpressionVisitor visitor) {
@@ -1087,7 +1152,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, collection, " IS NOT EMPTY");
         }
     }
@@ -1108,7 +1173,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "INDEX", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -1132,17 +1197,12 @@
         }
         
         @Override
-        public PredicateImpl clone() {
-            return new IsMember<E>(element.getJavaType(), element, collection);
-        }
-        
-        @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
             ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
             org.apache.openjpa.kernel.exps.Expression contains = factory.contains(
                 Expressions.toValue(collection, factory, model, q), 
                 Expressions.toValue(element, factory, model, q));
-            return isNegated() ? factory.not(contains) : contains;
+            return contains;
         }
         
         public void acceptVisit(CriteriaExpressionVisitor visitor) {
@@ -1151,8 +1211,8 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
-            return Expressions.asValue(q, element, isNegated() ? "NOT " : "", "MEMBER OF ", collection);
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, element, "MEMBER OF ", collection);
         }
     }
     
@@ -1193,11 +1253,6 @@
         }
 
         @Override
-        public PredicateImpl clone() {
-            return new Like(str, pattern, escapeChar);
-        }
-        
-        @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
             ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
             String escapeStr = escapeChar == null ? null :
@@ -1215,7 +1270,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, str, " LIKE ", pattern);
         }        
     }
@@ -1252,7 +1307,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "COALESCE", OPEN_BRACE, Expressions.asValue(q, values == null 
                     ? null : values.toArray(new Expression<?>[values.size()]), COMMA), CLOSE_BRACE);
         }        
@@ -1285,7 +1340,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "NULLIF", OPEN_BRACE, val1, COMMA, val2, CLOSE_BRACE);
         }        
     }
@@ -1299,8 +1354,8 @@
         
         @Override
         public PredicateImpl negate() {
-            return new Expressions.IsNotNull(e);
-        }        
+            return new IsNotNull(e).markNegated();
+        }
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
@@ -1316,7 +1371,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e, " IS NULL");
         }
     }
@@ -1330,9 +1385,9 @@
         
         @Override
         public PredicateImpl negate() {
-            return new Expressions.IsNull(e);
-        }       
-
+            return new IsNull(e).markNegated();
+        }
+        
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
             ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
@@ -1347,7 +1402,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, e, " IS NOT NULL");
         }
     }
@@ -1355,7 +1410,6 @@
     
     public static class In<T> extends PredicateImpl.Or implements QueryBuilder.In<T> {
         final ExpressionImpl<T> e;
-        private boolean negate;
         public In(Expression<?> e) {
             super();
             this.e = (ExpressionImpl<T>)e;
@@ -1375,11 +1429,16 @@
             return this;
         }
         
-        public In<T> negate() {
-            this.negate = !negate;
-            return this;
+        @Override
+        public PredicateImpl negate() {
+            In<T> notIn = new In<T>(e);
+            notIn.markNegated();
+            for (Predicate e : _exps) {
+                notIn.add(e);
+            }
+            return notIn;
         }
-    
+        
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
             ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
@@ -1390,23 +1449,20 @@
                 ExpressionImpl<?> e1 = e.e1;
                 Value val2 = Expressions.toValue(e2, factory, model, q);
                 if (!(val2 instanceof Literal)) {
-                     Value val1 = Expressions.toValue(e1, factory, model, q);
+                    Value val1 = Expressions.toValue(e1, factory, model, q);
                     Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q);
                     inExpr = factory.contains(val2, val1);
-                    return negate ? factory.not(inExpr) : inExpr;
+                    return isNegated() ? factory.not(inExpr) : inExpr;
                 } else if (((Literal)val2).getParseType() == Literal.TYPE_COLLECTION) {
-                    List<Expression<Boolean>> exps = new ArrayList<Expression<Boolean>>();
                     Collection coll = (Collection)((Literal)val2).getValue();
+                    _exps.clear();
                     for (Object v : coll) {
-                        exps.add(new Expressions.Equal(e1,v));
+                        add(new Expressions.Equal(e1,v));
                     }
-                    _exps = exps;
                 }
             } 
             inExpr = super.toKernelExpression(factory, model, q); 
             IsNotNull notNull = new Expressions.IsNotNull(e);
-            if (negate) 
-                inExpr = factory.not(inExpr);
             
             return factory.and(inExpr, notNull.toKernelExpression(factory, model, q));
         }
@@ -1417,8 +1473,8 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
-            StringBuilder buffer = Expressions.asValue(q, e, negate ? " NOT IN " : " IN ", OPEN_BRACE);
+        public StringBuilder asValue(AliasContext q) {
+            StringBuilder buffer = Expressions.asValue(q, e, " IN ", OPEN_BRACE);
             for (int i = 0; i < _exps.size(); i++) {
                 buffer.append(((Equal)_exps.get(i)).e2.asValue(q)).append(i+1 == _exps.size() ? CLOSE_BRACE : COMMA);
             }
@@ -1481,7 +1537,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             StringBuilder buffer = new StringBuilder("CASE ");
             int size = whens.size();
             for (int i = 0; i < size; i++) {
@@ -1558,7 +1614,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             StringBuilder buffer = new StringBuilder("CASE ");
             int size = whens.size();
             for (int i = 0; i < size; i++) {
@@ -1580,7 +1636,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "LOWER", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -1596,7 +1652,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "UPPER", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -1612,7 +1668,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "LENGTH", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -1649,21 +1705,16 @@
         }
 
         @Override
-        public PredicateImpl clone() {
-            return new Exists<X>(e);
-        }
-        
-        @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
             ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
             org.apache.openjpa.kernel.exps.Expression exists = 
                 factory.isNotEmpty(Expressions.toValue(e, factory, model, q));
-            return isNegated() ? factory.not(exists) : exists;
+            return exists;
         }        
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
-            return Expressions.asValue(q, isNegated() ? "NOT" : "", " EXISTS", OPEN_BRACE, e, CLOSE_BRACE);
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, " EXISTS", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
     
@@ -1679,7 +1730,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "ALL", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
@@ -1695,12 +1746,12 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return Expressions.asValue(q, "ANY", OPEN_BRACE, e, CLOSE_BRACE);
         }
     }
 
-    public static class Not<X> extends PredicateImpl {
+    public static class Not extends PredicateImpl {
         protected final ExpressionImpl<Boolean> e;
         public Not(Expression<Boolean> ne) {
             super();
@@ -1708,14 +1759,9 @@
         }
         
         @Override
-        public PredicateImpl clone() {
-            return new Not<X>(e);
-        }
-        
-        @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
           ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
-            return factory.not(super.toKernelExpression(factory, model, q));
+            return factory.not(e.toKernelExpression(factory, model, q));
         }        
         
         public void acceptVisit(CriteriaExpressionVisitor visitor) {
@@ -1723,8 +1769,8 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
-            return Expressions.asValue(q, "NOT", OPEN_BRACE, e, CLOSE_BRACE);
+        public StringBuilder asValue(AliasContext q) {
+            return Expressions.asValue(q, "NOT ", e);
         }
     }
     
@@ -1748,7 +1794,7 @@
         }
         
         @Override
-        public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+        public StringBuilder asValue(AliasContext q) {
             return actual.asValue(q);
         }
     }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FetchPathImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FetchPathImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FetchPathImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FetchPathImpl.java Thu Sep  3 08:52:17 2009
@@ -110,4 +110,7 @@
         return fetch;
     }
 
+    public StringBuilder asValue(AliasContext q) {
+        return super.asValue(q).insert(0, " " + joinType + " JOIN FETCH ");
+    }
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java Thu Sep  3 08:52:17 2009
@@ -148,8 +148,7 @@
      *  Join to the given List-valued attribute using the given join type.
      */
     public <Y> ListJoin<X,Y> join(ListAttribute<? super X, Y> list, JoinType jt) {
-        ListJoin<X, Y> join = new Joins.List<X, Y>(this, 
-                (Members.ListAttributeImpl<? super X, Y>)list, jt);
+        ListJoin<X, Y> join = new Joins.List<X, Y>(this, (Members.ListAttributeImpl<? super X, Y>)list, jt);
         addJoin(join);    
         return join;
     }
@@ -283,6 +282,6 @@
     
     public void acceptVisit(CriteriaExpressionVisitor visitor) {
         Expressions.acceptVisit(visitor, this, 
-                _joins == null ? null : _joins.toArray(new ExpressionImpl<?>[_joins.size()]));
+            _joins == null ? null : _joins.toArray(new ExpressionImpl<?>[_joins.size()]));
     }
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java Thu Sep  3 08:52:17 2009
@@ -175,11 +175,11 @@
             }
             if (getJoins() != null) {
                 for (Join<?, ?> join1 : getJoins()) {
-                    filter = CriteriaExpressionBuilder.and(factory, 
-                                 ((FromImpl<?,?>)join1).toKernelExpression(factory, model, c), filter);
+                    filter = Expressions.and(factory, 
+                             ((FromImpl<?,?>)join1).toKernelExpression(factory, model, c), filter);
                 }
             }
-            org.apache.openjpa.kernel.exps.Expression expr = CriteriaExpressionBuilder.and(factory, join, filter);
+            org.apache.openjpa.kernel.exps.Expression expr = Expressions.and(factory, join, filter);
             
             if (correlatedParentPath == null) {
                 return expr;
@@ -199,7 +199,7 @@
                 path.setMetaData(meta);
                 //filter = bindVariableForKeyPath(path, alias, filter);
                 filter = factory.equal(parentPath, path);
-                return CriteriaExpressionBuilder.and(factory, expr, filter);
+                return Expressions.and(factory, expr, filter);
             }
         }
         
@@ -249,7 +249,7 @@
         }
         
         @Override
-        public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
+        public StringBuilder asVariable(AliasContext q) {
             String varName = "?";
             Value var = q.getRegisteredVariable(this);
             if (var == null) {
@@ -257,8 +257,7 @@
             } else {
                 varName = var.getName();
             }
-            return new StringBuilder(joinType.toString()).append(" JOIN ")
-                .append(super.asVariable(q)).append(" " + varName);
+            return new StringBuilder(" " + joinType + " JOIN ").append(super.asVariable(q)).append(" " + varName);
         }
     }
     
@@ -386,11 +385,11 @@
             }
             if (getJoins() != null) {
                 for (Join<?, ?> join1 : getJoins()) {
-                    filter = CriteriaExpressionBuilder.and(factory, 
+                    filter = Expressions.and(factory, 
                         ((FromImpl<?,?>)join1).toKernelExpression(factory, model, c), filter);
                 }
             }
-            org.apache.openjpa.kernel.exps.Expression expr = CriteriaExpressionBuilder.and(factory, join, filter);
+            org.apache.openjpa.kernel.exps.Expression expr = Expressions.and(factory, join, filter);
             if (correlatedParentPath == null) {
                 return expr;
             } else {
@@ -417,11 +416,11 @@
                     c.registerVariable(this, var, parentPath);
                 
                 if (_member.fmd.isElementCollection()) {
-                    filter = CriteriaExpressionBuilder.and(factory, join, filter);
+                    filter = Expressions.and(factory, join, filter);
                 } else { 
                     filter = factory.equal(parentPath, path);
                 }
-                return CriteriaExpressionBuilder.and(factory, expr, filter);
+                return Expressions.and(factory, expr, filter);
             }
         }
         
@@ -580,7 +579,7 @@
        }
        
        @Override
-       public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+       public StringBuilder asValue(AliasContext q) {
            StringBuilder buffer = new StringBuilder("KEY(");
            Value var = q.getRegisteredVariable(map);
            buffer.append(var != null ? var.getName() : map.asValue(q)).append(")");
@@ -609,7 +608,7 @@
        }
        
        @Override
-       public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+       public StringBuilder asValue(AliasContext q) {
            StringBuilder buffer = new StringBuilder("ENTRY(");
            Value var = q.getRegisteredVariable(map);
            buffer.append(var != null ? var.getName() : map.asValue(q)).append(")");

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OrderImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OrderImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OrderImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OrderImpl.java Thu Sep  3 08:52:17 2009
@@ -60,11 +60,11 @@
         }
     }
     
-    public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+    public StringBuilder asValue(AliasContext q) {
         return e.asValue(q).append(_ascending ? "" : " DESC");
     }
     
-    public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
+    public StringBuilder asVariable(AliasContext q) {
         throw new IllegalStateException(this + " can not be rendered as variable");
     }
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java Thu Sep  3 08:52:17 2009
@@ -98,7 +98,7 @@
     }   
     
     @Override
-    public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+    public StringBuilder asValue(AliasContext q) {
         return Expressions.asValue(q, ":", _name == null ? "param" : _name);
     }
     

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java Thu Sep  3 08:52:17 2009
@@ -279,7 +279,7 @@
         return new Expressions.Type<Class<? extends X>>(this);
     }
     
-    public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+    public StringBuilder asValue(AliasContext q) {
         StringBuilder buffer = new StringBuilder();
         if (_parent != null) {
             Value var = q.getRegisteredVariable(_parent);
@@ -291,7 +291,7 @@
         return buffer;
     }
     
-    public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
+    public StringBuilder asVariable(AliasContext q) {
         Value var = q.getRegisteredVariable(this);
         return asValue(q).append(" ").append(var == null ? "?" : var.getName());
     }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java Thu Sep  3 08:52:17 2009
@@ -19,7 +19,6 @@
 package org.apache.openjpa.persistence.criteria;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
@@ -29,24 +28,37 @@
 import org.apache.openjpa.kernel.exps.ExpressionFactory;
 import org.apache.openjpa.persistence.meta.MetamodelImpl;
 
-public class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate {
+/**
+ * Predicate is a expression that evaluates to true or false.
+ * All boolean expressions are implemented as Predicate.
+ * A predicate can have zero or more predicate arguments.
+ * Default predicate operator is AND (conjunction).
+ * Two constant predicates are Predicate.TRUE and Predicate.FALSE.
+ * AND predicate with no argument evaluates to TRUE.
+ * OR predicate with no argument evaluates to FALSE.
+ * Negation of a Predicate creates a new Predicate.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public abstract class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate {
     private static final ExpressionImpl<Integer> ONE  = new Expressions.Constant<Integer>(1);
-    public static final ExpressionImpl<Boolean> TRUE  = new Expressions.Equal(ONE,ONE);
-    public static final ExpressionImpl<Boolean> FALSE = new Expressions.Equal(ONE,ONE).negate();
+    public static final Predicate TRUE  = new Expressions.Equal(ONE,ONE);
+    public static final Predicate FALSE = new Expressions.NotEqual(ONE,ONE);
     
-    List<Expression<Boolean>> _exps;
+    protected final List<Predicate> _exps = new ArrayList<Predicate>();
     protected final BooleanOperator _op;
-    private boolean _negated = false;
+    protected boolean _negated = false;
 
     /**
-     * A predicate with empty name and AND operator.
+     * A predicate no arguments representing AND operator.
      */
     protected PredicateImpl() {
         this(BooleanOperator.AND);
     }
     
     /**
-     * A predicate with given name and given operator.
+     * A predicate representing given operator.
      */
     protected PredicateImpl(BooleanOperator op) {
         super(Boolean.class);
@@ -54,13 +66,13 @@
     }
 
     /**
-     * A predicate with given name, given operator with given arguments.
+     * A predicate of given operator with given arguments.
      */
     protected PredicateImpl(BooleanOperator op, Predicate...restrictions) {
         this(op);
         if (restrictions != null) {
             for (Predicate p : restrictions)
-                add((PredicateImpl)p);
+                add(p);
         }
     }
 
@@ -68,14 +80,16 @@
      * Adds the given predicate expression.
      */
     public PredicateImpl add(Expression<Boolean> s) {
-        if (_exps == null)
-            _exps = new ArrayList<Expression<Boolean>>();
-        _exps.add(s);
+        _exps.add((Predicate)s); // all boolean expressions are Predicate
         return this;
     }
 
     public List<Expression<Boolean>> getExpressions() {
-        return Expressions.returnCopy(_exps);
+        List<Expression<Boolean>> result = new CopyOnWriteArrayList<Expression<Boolean>>();
+        if (_exps.isEmpty())
+            return result;
+        result.addAll(_exps);
+        return result;
     }
 
     public final BooleanOperator getOperator() {
@@ -86,38 +100,38 @@
         return _negated;
     }
 
+    /**
+     * Default negation creates a Not expression with this receiver as delegate.
+     * Derived predicates can return the inverse expression such as NotEqual
+     * for Equal or LessThan for GreaterThanEqual etc.
+     */
     public PredicateImpl negate() {
-        PredicateImpl not = clone();
-        not._negated = true;
-        return not;
+        return new Expressions.Not(this).markNegated();
     }
-
-    public PredicateImpl clone() {
-        PredicateImpl clone = new PredicateImpl(_op);
-        if (_exps != null)
-            clone._exps = new ArrayList<Expression<Boolean>>(this._exps);
-        return clone;
+    
+    protected PredicateImpl markNegated() {
+        _negated = true;
+        return this;
     }
     
     @Override
-    org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, MetamodelImpl model, 
+    org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, MetamodelImpl model,
         CriteriaQueryImpl<?> q) {
-        throw new AbstractMethodError();
+        throw new AbstractMethodError(this.getClass().getName());
     }
     
     @Override
     org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model, 
         CriteriaQueryImpl<?> q) {
-        if (_exps == null || _exps.isEmpty()) {
-            ExpressionImpl<Boolean> nil = _op == BooleanOperator.AND ? TRUE : FALSE;
-            return nil.toKernelExpression(factory, model, q);
+        if (_exps.isEmpty()) {
+            Predicate nil = _op == BooleanOperator.AND ? TRUE : FALSE;
+            return ((PredicateImpl)nil).toKernelExpression(factory, model, q);
         }
         if (_exps.size() == 1) {
-            ExpressionImpl<Boolean> e0 = (ExpressionImpl<Boolean>)_exps.get(0);
-            if (e0 instanceof Expressions.Constant && e0.getJavaType() == Boolean.class) {
-                e0 = Boolean.TRUE.equals(((Expressions.Constant<Boolean>)e0).arg) ? TRUE : FALSE;
-            }
-            return e0.toKernelExpression(factory, model, q);
+            Predicate e0 = _exps.get(0);
+            if (isNegated())
+                e0 = e0.negate();
+            return ((PredicateImpl)e0).toKernelExpression(factory, model, q);
         }
         
         ExpressionImpl<?> e1 = (ExpressionImpl<?>)_exps.get(0);
@@ -128,27 +142,30 @@
             ? factory.and(ke1,ke2) : factory.or(ke1, ke2);
 
         for (int i = 2; i < _exps.size(); i++) {
-            ExpressionImpl<?> e = (ExpressionImpl<?>)_exps.get(i);
+            PredicateImpl p = (PredicateImpl)_exps.get(i);
             result = _op == BooleanOperator.AND 
-            ? factory.and(result, e.toKernelExpression(factory, model, q))
-            : factory.or(result, e.toKernelExpression(factory,model,q));
+              ? factory.and(result, p.toKernelExpression(factory, model, q))
+              : factory.or(result, p.toKernelExpression(factory,model,q));
         }
         return _negated ? factory.not(result) : result;
     }
 
     public void acceptVisit(CriteriaExpressionVisitor visitor) {
-        Expressions.acceptVisit(visitor, this, _exps == null ? null : _exps.toArray(new Expression<?>[_exps.size()]));
+        Expressions.acceptVisit(visitor, this, _exps.toArray(new Expression<?>[_exps.size()]));
     }
     
-    public StringBuilder asValue(CriteriaQueryImpl<?> q) {
-        boolean braces = _exps != null && _exps.size() > 1;
-        StringBuilder buffer =  Expressions.asValue(q, _exps == null ? null : 
-            _exps.toArray(new Expression<?>[_exps.size()]), " " +_op + " ");
+    public StringBuilder asValue(AliasContext q) {
+        boolean braces = _exps.size() > 1;
+        StringBuilder buffer =  Expressions.asValue(q, _exps.toArray(new Expression<?>[_exps.size()]), " " +_op + " ");
         if (braces) buffer.insert(0, "(").append(")");
+        if (isNegated()) buffer.insert(0, "NOT ");
         return buffer;
     }
 
-    
+    /**
+     * Concrete AND predicate.
+     *
+     */
     public static class And extends PredicateImpl {
         public And(Expression<Boolean> x, Expression<Boolean> y) {
             super(BooleanOperator.AND);
@@ -160,6 +177,10 @@
         }
     }
 
+    /**
+     * Concrete OR predicate.
+     *
+     */
     public static class Or extends PredicateImpl {
         public Or(Expression<Boolean> x, Expression<Boolean> y) {
             super(BooleanOperator.OR);

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java Thu Sep  3 08:52:17 2009
@@ -99,7 +99,7 @@
         return factory.bindVariable(var, path);
     }
     
-    public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+    public StringBuilder asValue(AliasContext q) {
         Value v = q.getRegisteredRootVariable(this);
         if (v != null)
             return new StringBuilder(v.getAlias());
@@ -111,7 +111,7 @@
         return new StringBuilder().append(Character.toLowerCase(_entity.getName().charAt(0)));
     }
     
-    public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
+    public StringBuilder asVariable(AliasContext q) {
         return new StringBuilder(_entity.getName()).append(" ").append(asValue(q));
     }
 

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java Thu Sep  3 08:52:17 2009
@@ -52,11 +52,11 @@
         return false;
     }
     
-    public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+    public StringBuilder asValue(AliasContext q) {
         throw new IllegalStateException(this.getClass().getSimpleName() + " can not be rendered as value");
     }
     
-    public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
+    public StringBuilder asVariable(AliasContext q) {
         throw new IllegalStateException(this.getClass().getSimpleName() + " can not be rendered as variable");
     }
     

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java?rev=810825&r1=810824&r2=810825&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java Thu Sep  3 08:52:17 2009
@@ -379,13 +379,13 @@
         return getJavaType();
     }
     
-    public StringBuilder asValue(CriteriaQueryImpl<?> q) {
+    public StringBuilder asValue(AliasContext q) {
         StringBuilder buffer = new StringBuilder();
         _delegate.render(buffer, _delegate.getRoots(), _corrJoins);
         return buffer;
     }
     
-    public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
+    public StringBuilder asVariable(AliasContext q) {
         return asValue(q);
     }
 }