openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fayw...@apache.org
Subject svn commit: r781621 [2/3] - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/ openjpa-persistence/src/main/java/org/apache/openjpa/persiste...
Date Wed, 03 Jun 2009 23:44:59 GMT
Added: 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=781621&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java (added)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java Wed Jun  3 23:44:58 2009
@@ -0,0 +1,235 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Join;
+import javax.persistence.criteria.Order;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Selection;
+
+import org.apache.openjpa.kernel.exps.ExpressionFactory;
+import org.apache.openjpa.kernel.exps.QueryExpressions;
+import org.apache.openjpa.kernel.exps.Value;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.persistence.meta.MetamodelImpl;
+import org.apache.openjpa.persistence.meta.Types;
+
+/**
+ * Subquery is an expression as its selection item.
+ * 
+ */
+public class CriteriaExpressionBuilder {
+    
+    private int aliasCount = 0;
+    
+    private CriteriaQueryImpl criteriaQuery = null;
+    
+    public CriteriaExpressionBuilder(CriteriaQueryImpl criteriaQuery) {
+        this.criteriaQuery = criteriaQuery;
+    }
+    
+    public QueryExpressions getQueryExpressions(ExpressionFactory factory, 
+        CriteriaQueryImpl q) {
+        QueryExpressions exps = new QueryExpressions();
+
+        evalAccessPaths(exps, factory, q);
+        //exps.alias = null;      // String   
+        exps.ascending = new boolean[]{false};
+        evalDistinct(exps, factory, q);
+        evalFetchJoin(exps, factory, q);
+
+        evalFilter(exps, factory, q);
+
+        evalGrouping(exps, factory, q);
+
+        evalOrdering(exps, factory, q);
+        //exps.operation = QueryOperations.OP_SELECT;
+
+        evalProjections(exps, factory, q);
+
+
+        //exps.range = null; // Value[]
+        //exps.resultClass = null; // Class
+        if (q.getParameterTypes() != null)
+            exps.parameterTypes = q.getParameterTypes();
+        return exps;
+    }
+
+    protected void evalAccessPaths(QueryExpressions exps, 
+        ExpressionFactory factory, CriteriaQueryImpl q) {
+        Set<Root<?>> roots = q.getRoots();
+        if (roots != null) {
+            exps.accessPath = new ClassMetaData[roots.size()];
+            int i = 0;
+            for (Root<?> r : roots)
+                exps.accessPath[i++] = ((Types.Managed<?>)r.getModel()).meta;
+        }
+    }
+
+    protected void evalOrdering(QueryExpressions exps, 
+        ExpressionFactory factory, CriteriaQueryImpl q) {
+        List<Order> orders = q.getOrderList();
+        MetamodelImpl model = q.getMetamodel(); 
+        if (orders == null) 
+            return;
+        int ordercount = orders.size();
+        exps.ordering = new Value[ordercount];
+        exps.orderingClauses = new String[ordercount];
+        exps.orderingAliases = new String[ordercount];
+        exps.ascending = new boolean[ordercount];
+        for (int i = 0; i < ordercount; i++) {
+            OrderImpl order = (OrderImpl)orders.get(i);
+            //Expression<? extends Comparable> expr = order.getExpression();
+            Expression expr = order.getExpression5();
+            exps.ordering[i] = Expressions.toValue(
+                    (ExpressionImpl<?>)expr, factory, model, q);
+
+            //exps.orderingClauses[i] = assemble(firstChild);
+            //exps.orderingAliases[i] = firstChild.text;
+            exps.ascending[i] = order.isAscending();
+        }
+    }
+
+    protected void evalGrouping(QueryExpressions exps, 
+        ExpressionFactory factory, CriteriaQueryImpl q) {
+        //    exps.grouping = null; // Value[]
+        //    exps.groupingClauses = null; // String[]
+        List<Expression<?>> groups = q.getGroupList();
+        MetamodelImpl model = q.getMetamodel();
+        PredicateImpl having = q.getGroupRestriction();
+        if (groups == null) 
+            return;
+        int groupByCount = groups.size();
+        exps.grouping = new Value[groupByCount];
+        for (int i = 0; i < groupByCount; i++) {
+            Expression<?> groupBy = groups.get(i);    
+            exps.grouping[i] = Expressions.toValue(
+                    (ExpressionImpl<?>)groupBy, factory, model, q);;
+        }
+
+        exps.having = having == null ? factory.emptyExpression() 
+                : having.toKernelExpression(factory, model, q);
+    }
+
+    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;
+    }
+
+    protected void evalFilter(QueryExpressions exps, ExpressionFactory factory,
+        CriteriaQueryImpl q) {
+        Set<Root<?>> roots = q.getRoots();
+        MetamodelImpl model = q.getMetamodel();
+        PredicateImpl where = q.getRestriction();
+        q.assertRoot();
+        org.apache.openjpa.kernel.exps.Expression filter = null;
+        for (Root<?> root : roots) {
+            if (root.getJoins() != null) {
+                for (Join<?, ?> join : root.getJoins()) {
+                    filter = and(factory, ((ExpressionImpl<?>)join)
+                        .toKernelExpression(factory, model, q), filter);
+                }
+            }
+            if (((RootImpl<?>)root).getCorrelatedParent() != null) {
+                filter = and(factory, ((RootImpl<?>)root)
+                    .toKernelExpression(factory, model, q), filter);
+            }
+        }
+        if (where != null) {
+            filter = and(factory, where.toKernelExpression
+                    (factory, model, q), filter);
+        }
+        if (filter == null) 
+            filter = factory.emptyExpression();
+        exps.filter = filter;
+    }
+
+    protected void evalProjections(QueryExpressions exps, 
+        ExpressionFactory factory, CriteriaQueryImpl q) {
+        List<Selection<?>> selections = q.getSelectionList();
+        MetamodelImpl model = q.getMetamodel();
+        // TODO: fill in projection clauses
+        //    exps.projectionClauses = null; // String[]
+        if (isDefaultProjection(selections, q)) {
+            exps.projections = new Value[0];
+            return ;
+        }
+        exps.projections = new Value[selections.size()];
+        List<Value> projections = new ArrayList<Value>();
+        List<String> aliases = new ArrayList<String>();
+        getProjections(exps, selections, projections, aliases, factory, q, 
+            model);
+        exps.projections = projections.toArray(new Value[0]);
+        exps.projectionAliases = aliases.toArray(new String[0]);
+    }
+
+    private void getProjections(QueryExpressions exps, 
+        List<Selection<?>> selections, List projections, List aliases, 
+        ExpressionFactory factory, CriteriaQueryImpl q, MetamodelImpl model) {
+        for (Selection<?> s : selections) {
+            List<Selection<?>> sels = ((SelectionImpl)s).getSelections();
+            if (sels == null) {
+                projections.add(((ExpressionImpl<?>)s).
+                    toValue(factory, model, q));
+                aliases.add(nextAlias());
+            } else {
+                // this is for constructor expression in the selection
+                exps.resultClass = s.getJavaType();
+                getProjections(exps, sels, projections, aliases, factory, q, 
+                    model);
+            }            
+        }
+    }
+
+    protected boolean isDefaultProjection(List<Selection<?>> selections, 
+        CriteriaQueryImpl q) {
+        return selections == null 
+        || (selections.size() == 1 && selections.get(0) == q.getRoot());
+    }
+
+    protected void evalFetchJoin(QueryExpressions exps, 
+        ExpressionFactory factory, CriteriaQueryImpl q) {
+        //exps.fetchInnerPaths = null; // String[]
+        //exps.fetchPaths = null;      // String[]
+    }
+
+    protected 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);
+    }
+   
+    protected String nextAlias() {
+        return "jpqlalias" + (++aliasCount);
+    }   
+}

Propchange: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

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=781621&r1=781620&r2=781621&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 Wed Jun  3 23:44:58 2009
@@ -20,7 +20,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -28,7 +27,6 @@
 import javax.persistence.Parameter;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
-import javax.persistence.criteria.Join;
 import javax.persistence.criteria.Order;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
@@ -37,14 +35,8 @@
 import javax.persistence.metamodel.Entity;
 
 import org.apache.commons.collections.map.LinkedMap;
-import org.apache.openjpa.kernel.exps.AbstractExpressionBuilder;
 import org.apache.openjpa.kernel.exps.ExpressionFactory;
-import org.apache.openjpa.kernel.exps.Path;
 import org.apache.openjpa.kernel.exps.QueryExpressions;
-import org.apache.openjpa.kernel.exps.Value;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.persistence.meta.Members;
 import org.apache.openjpa.persistence.meta.MetamodelImpl;
 import org.apache.openjpa.persistence.meta.Types;
 
@@ -69,16 +61,28 @@
     private List<Selection<?>>  _selections;
     private List<Expression<?>> _groups;
     private PredicateImpl       _having;
+    private List<Subquery<?>>   _subqueries;
     private Boolean             _distinct;
     private LinkedMap           _parameterTypes;
-    private Class               _resultClass;
-    private Value[]             _projections;
-    private int                 _aliasCount = 0;
+    private CriteriaExpressionBuilder _exprBuilder;
+    private SubqueryImpl        _context;
     
     public CriteriaQueryImpl(MetamodelImpl model) {
         this._model = model;
     }
-
+    
+    public void setContext(SubqueryImpl context) {
+        _context = context;
+    }
+    
+    public SubqueryImpl getContext() {
+        return _context;
+    }
+    
+    public MetamodelImpl getMetamodel() {
+        return _model;
+    }
+    
     public CriteriaQuery distinct(boolean distinct) {
         _distinct = distinct;
         return this;
@@ -154,7 +158,7 @@
         return _groups;
     }
 
-    public Predicate getGroupRestriction() {
+    public PredicateImpl getGroupRestriction() {
         return _having;
     }
 
@@ -166,6 +170,10 @@
         return _roots;
     }
     
+    public void setRoots (Set<Root<?>> roots) {
+        this._roots = roots;
+    }
+
     public Root<?> getRoot() {
         assertRoot();
         return _roots.iterator().next();
@@ -175,9 +183,16 @@
         return _distinct;
     }
 
+    public Boolean getDistinct() {
+        return _distinct;
+    }
+
     public <U> Subquery<U> subquery(Class<U> type) {
-        // TODO Auto-generated method stub
-        return null;
+        if (_subqueries == null)
+            _subqueries = new ArrayList<Subquery<?>>();
+        Subquery<U> subquery = new SubqueryImpl(type, this);
+        _subqueries.add(subquery);
+        return subquery;
     }
     
     public LinkedMap getParameterTypes() {
@@ -188,12 +203,8 @@
         _parameterTypes = parameterTypes;
     }
     
-    public void setResultClass(Class resultClass) {
-        _resultClass = resultClass;
-    }
-
-    public void setProjections(Value[] projections) {
-        _projections = projections;
+    public CriteriaExpressionBuilder getExprBuilder() {
+        return _exprBuilder;
     }
 
     /**
@@ -201,242 +212,12 @@
      * receiver with the help of the given {@link ExpressionFactory}.
      */
     QueryExpressions getQueryExpressions(ExpressionFactory factory) {
-	    QueryExpressions exps = new QueryExpressions();
-	    
-	    evalAccessPaths(exps, factory);
-//    exps.alias = null;      // String   
-	    exps.ascending = new boolean[]{false};
-	    evalDistinct(exps, factory);
-	    evalFetchJoin(exps, factory);
-	    
-	    evalFilter(exps, factory);
-	    
-	    evalGrouping(exps, factory);
-	    exps.having = _having == null ? factory.emptyExpression() 
-	    		: _having.toKernelExpression(factory, _model, this);
-	    
-	    evalOrdering(exps, factory);
-	//    exps.operation = QueryOperations.OP_SELECT;
-	    
-
-	//    exps.parameterTypes = null; // LinkedMap<>
-	      evalProjections(exps, factory);
-
-	    evalProjection(exps, factory);
-	    
-
-	//    exps.range = null; // Value[]
-	//    exps.resultClass = null; // Class
-	    if (_parameterTypes != null)
-	        exps.parameterTypes = _parameterTypes;
-	    exps.resultClass = _resultClass;
-	    return exps;
-    }
-
-    void evalAccessPaths(QueryExpressions exps, ExpressionFactory factory) {
-        if (_roots != null) {
-            exps.accessPath = new ClassMetaData[_roots.size()];
-            int i = 0;
-            for (Root<?> r : _roots)
-               exps.accessPath[i++] = ((Types.Managed<?>)r.getModel()).meta;
-        }
-    }
-    
-    void evalOrdering(QueryExpressions exps, ExpressionFactory factory) {
-        if (_orders == null) 
-            return;
-        int ordercount = _orders.size();
-        exps.ordering = new Value[ordercount];
-        exps.orderingClauses = new String[ordercount];
-        exps.orderingAliases = new String[ordercount];
-        exps.ascending = new boolean[ordercount];
-        for (int i = 0; i < ordercount; i++) {
-            OrderImpl order = (OrderImpl)_orders.get(i);
-            //Expression<? extends Comparable> expr = order.getExpression();
-            Expression expr = order.getExpression5();
-            exps.ordering[i] = Expressions.toValue(
-                (ExpressionImpl<?>)expr, factory, _model, this);
-            
-            //exps.orderingClauses[i] = assemble(firstChild);
-            //exps.orderingAliases[i] = firstChild.text;
-            exps.ascending[i] = order.isAscending();
-        }
-    }
-    
-    void evalGrouping(QueryExpressions exps, ExpressionFactory factory) {
-        //    exps.grouping = null; // Value[]
-        //    exps.groupingClauses = null; // String[]
-        if (_groups == null) 
-            return;
-        int groupByCount = _groups.size();
-        exps.grouping = new Value[groupByCount];
-        for (int i = 0; i < groupByCount; i++) {
-             Expression<?> groupBy = _groups.get(i);    
-             exps.grouping[i] = Expressions.toValue(
-                 (ExpressionImpl<?>)groupBy, factory, _model, this);;
-        }
-    }
-    
-    void evalProjections(QueryExpressions exps, ExpressionFactory factory) {
-        // TODO: fill in projection aliases and clauses
-        //    exps.projectionAliases = null; // String[]
-        //    exps.projectionClauses = null; // String[]
-    	if (isDefaultProjection()) {
-    	    exps.projections = new Value[0];
-    	    return ;
-    	}
-    	exps.projections = new Value[_selections.size()];
-    	int i = 0;
-    	for (Selection<?> s : _selections) {
-    	    exps.projections[i++] = ((ExpressionImpl<?>)s)
-    	       .toValue(factory, _model, this);
-    	}
-    	return;
-    }
-    
-    boolean isDefaultProjection() {
-        return _selections == null 
-           || (_selections.size() == 1 && _selections.get(0) == getRoot());
-    }
-    
-    void evalDistinct(QueryExpressions exps, ExpressionFactory factory) {
-        if (_distinct == null) {
-            exps.distinct = QueryExpressions.DISTINCT_FALSE;
-        } else if (_distinct) {
-            exps.distinct = QueryExpressions.DISTINCT_TRUE 
-                          | QueryExpressions.DISTINCT_AUTO;
-        }
-        exps.distinct &= ~QueryExpressions.DISTINCT_AUTO;
-    }
-
-    void evalFilter(QueryExpressions exps, ExpressionFactory factory) {
-        assertRoot();
-        org.apache.openjpa.kernel.exps.Expression filter = null;
-        for (Root<?> root : _roots) {
-            if (root.getJoins() != null) {
-                for (Join<?, ?> join : root.getJoins()) {
-                    filter = and(factory, ((ExpressionImpl<?>)join)
-                        .toKernelExpression(factory, _model, this), filter);
-                }
-            }
-        }
-        if (_where != null) {
-            filter = and(factory, _where.toKernelExpression
-                         (factory, _model, this), filter);
-        }
-        if (filter == null) 
-            filter = factory.emptyExpression();
-        exps.filter = filter;
-    }
-    
-    void evalProjection(QueryExpressions exps, ExpressionFactory factory) {
-        Value [] projs = toValues(exps, factory, getSelectionList());
-        if (projs.length == 1 && projs[0] == null)
-            exps.projections = _projections;
-        else 
-            exps.projections = projs;
-        //exps.projectionClauses = String[];
+        _exprBuilder = new CriteriaExpressionBuilder(this);
+        return _exprBuilder.getQueryExpressions(factory, this);
     }    
-
-    Value[] toValues(QueryExpressions exps, ExpressionFactory factory, 
-        List<Selection<?>> sels) {
-    	if (sels == null || (sels.size() == 1 && sels.get(0) == getRoot()))
-    			return new Value[0];
-    	Value[] result = new Value[sels.size()];
-    	String[] aliases = new String[sels.size()];
-    	int i = 0;
-    	for (Selection<?> s : sels) {
-            result[i] = ((SelectionImpl<?>)s).toValue(factory, _model, 
-    		    this);
-            aliases[i] = nextAlias();
-            i++;
-        }
-        exps.projectionAliases = aliases;
-    	
-    	return result;
-    }
     
-    void evalFetchJoin(QueryExpressions exps, ExpressionFactory factory) {
-    //    exps.fetchInnerPaths = null; // String[]
-    //    exps.fetchPaths = null;      // String[]
-    }
-
-
-    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);
-    }
-    
-    void assertRoot() {
+    public void assertRoot() {
         if (_roots == null || _roots.isEmpty())
             throw new IllegalStateException("no root is set");
     }
-
-    void setImplicitTypes(Value val1, Value val2, Class<?> expected) {
-        Class<?> c1 = (val1 == null ? null : val1.getType());
-        Class<?> c2 = (val2 == null ? null : val2.getType());
-        
-        boolean o1 = c1 == AbstractExpressionBuilder.TYPE_OBJECT;
-        boolean o2 = c2 == AbstractExpressionBuilder.TYPE_OBJECT;
-
-        if (o1 && !o2) {
-            val1.setImplicitType(c2);
-            if (val1.getMetaData() == null && !val1.isXPath())
-                val1.setMetaData(val2.getMetaData());
-        } else if (!o1 && o2) {
-            val2.setImplicitType(c1);
-            if (val2.getMetaData() == null && !val1.isXPath())
-                val2.setMetaData(val1.getMetaData());
-        } else if (o1 && o2 && expected != null) {
-            // we never expect a pc type, so don't bother with metadata
-            val1.setImplicitType(expected);
-            val2.setImplicitType(expected);
-        } else if (c1 != null && c2 != null && 
-            AbstractExpressionBuilder.isNumeric(c1) 
-            != AbstractExpressionBuilder.isNumeric(c2)) {
-            AbstractExpressionBuilder.convertTypes(val1, val2);
-        }
-
-        // as well as setting the types for conversions, we also need to
-        // ensure that any parameters are declared with the correct type,
-        // since the JPA spec expects that these will be validated
-        org.apache.openjpa.kernel.exps.Parameter param =
-            val1 instanceof org.apache.openjpa.kernel.exps.Parameter ? 
-            (org.apache.openjpa.kernel.exps.Parameter) val1
-            : val2 instanceof org.apache.openjpa.kernel.exps.Parameter ? 
-            (org.apache.openjpa.kernel.exps.Parameter) val2 : null;
-        Path path = val1 instanceof Path ? (Path) val1
-            : val2 instanceof Path ? (Path) val2 : null;
-
-        // we only check for parameter-to-path comparisons
-        if (param == null || path == null || _parameterTypes == null)
-            return;
-
-        FieldMetaData fmd = path.last();
-        if (fmd == null)
-            return;
-
-        //TODO:
-        //if (expected == null)
-        //    checkEmbeddable(path);
-
-        Class<?> type = path.getType();
-        if (type == null)
-            return;
-
-        Object paramKey = param.getParameterKey();
-        if (paramKey == null)
-            return;
-
-        // make sure we have already declared the parameter
-        if (_parameterTypes.containsKey(paramKey))
-            _parameterTypes.put(paramKey, type);
-    }
-    
-    private String nextAlias() {
-        return "jpqlalias" + (++_aliasCount);
-    }
-    
-
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java?rev=781621&r1=781620&r2=781621&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java Wed Jun  3 23:44:58 2009
@@ -21,7 +21,6 @@
 
 import java.util.Collection;
 
-import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.QueryBuilder.In;
@@ -41,13 +40,13 @@
     implements Expression<X> {
 
     Value toValue(ExpressionFactory factory, MetamodelImpl model,
-        CriteriaQuery q) {
+        CriteriaQueryImpl q) {
         throw new AbstractMethodError(this.getClass().getName());
     }
     
     org.apache.openjpa.kernel.exps.Expression toKernelExpression(
         ExpressionFactory factory, MetamodelImpl model,
-        CriteriaQuery q) {
+        CriteriaQueryImpl q) {
         throw new AbstractMethodError(this.getClass().getName());
     }
     

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=781621&r1=781620&r2=781621&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 Wed Jun  3 23:44:58 2009
@@ -23,22 +23,21 @@
 import java.util.Collection;
 import java.util.List;
 
-import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
-import javax.persistence.criteria.ListJoin;
-import javax.persistence.criteria.Path;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.QueryBuilder;
+import javax.persistence.criteria.Subquery;
 import javax.persistence.criteria.QueryBuilder.Trimspec;
 
-import org.apache.openjpa.persistence.meta.Types;
 import org.apache.openjpa.kernel.exps.ExpressionFactory;
 import org.apache.openjpa.kernel.exps.Literal;
 import org.apache.openjpa.kernel.exps.Value;
 import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.persistence.meta.MetamodelImpl;
+import org.apache.openjpa.persistence.meta.Types;
 
+import serp.util.Numbers;
 public class Expressions {
 	
     /**
@@ -46,21 +45,21 @@
      * using the given ExpressionFactory.
      * Also sets the alias of the resulting value.
      */
-	static Value toValue(ExpressionImpl<?> e, ExpressionFactory factory, 
-		MetamodelImpl model, CriteriaQuery q) {
+     static Value toValue(ExpressionImpl<?> e, ExpressionFactory factory, 
+        MetamodelImpl model, CriteriaQueryImpl q) {
         Value v = e == null ? factory.getNull() : e.toValue(factory, model, q);
-	    v.setImplicitType(e.getJavaType());
-	    v.setAlias(e.getAlias());
+        //v.setImplicitType(e.getJavaType());
+        //v.setAlias(e.getAlias());
 
-		return v;
-	}
-	
-	/**
-	 * Unary Functional Expression applies a unary function on a input
-	 * Expression.
-	 *
-	 * @param <X> the type of the resultant expression
-	 */
+        return v;
+    }
+    
+    /**
+     * Unary Functional Expression applies a unary function on a input
+     * Expression.
+     *
+     * @param <X> the type of the resultant expression
+     */
     public static class UnaryFunctionalExpression<X> 
         extends ExpressionImpl<X> {
         protected ExpressionImpl<?> e;
@@ -80,7 +79,7 @@
      * input Expression.
      * 
      *
-	 * @param <X> the type of the resultant expression
+     * @param <X> the type of the resultant expression
      */
     public static class BinarayFunctionalExpression<X> 
         extends ExpressionImpl<X>{
@@ -88,7 +87,7 @@
         protected ExpressionImpl<?> e2;
         
         public BinarayFunctionalExpression(Class<X> t, Expression<?> x, 
-        		Expression<?> y) {
+                Expression<?> y) {
             super(t);
             e1 = (ExpressionImpl<?>)x;
             e2 = (ExpressionImpl<?>)y;
@@ -110,101 +109,106 @@
             e1 = (ExpressionImpl<?>)x;
             e2 = (ExpressionImpl<?>)y;
         }
+        
+        @Override
+        public PredicateImpl clone() {
+            return new BinaryLogicalExpression(e1, e2);
+        }
     }
     
     
     public static class Abs<X> extends UnaryFunctionalExpression<X> {
-    	public  Abs(Expression<X> x) {
-    		super(x);
-    	}
+        public  Abs(Expression<X> x) {
+            super(x);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.abs(Expressions.toValue(e, factory, model, q));
         }
     }
     
     public static class Count extends UnaryFunctionalExpression<Long> {
-    	private boolean _distinct; 
-    	public  Count(Expression<?> x) {
-    		this(x, false);
-    	}
-    	
-    	public  Count(Expression<?> x, boolean distinct) {
-    		super(Long.class, x);
-    		_distinct = distinct;
-    		
-    	}
+        private boolean _distinct; 
+        public  Count(Expression<?> x) {
+            this(x, false);
+        }
+        
+        public  Count(Expression<?> x, boolean distinct) {
+            super(Long.class, x);
+            _distinct = distinct;
+            
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             Value v = factory.count(Expressions.toValue(e, factory, model, q));
             return _distinct ? factory.distinct(v) : v;
         }
     }
 
     public static class Avg extends UnaryFunctionalExpression<Double> {
-    	public  Avg(Expression<?> x) {
-    		super(Double.class, x);
-    	}
+        public  Avg(Expression<?> x) {
+            super(Double.class, x);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.avg(Expressions.toValue(e, factory, model, q));
         }
     }
     
     public static class Sqrt extends UnaryFunctionalExpression<Double> {
-    	public  Sqrt(Expression<? extends Number> x) {
-    		super(Double.class, x);
-    	}
+        public  Sqrt(Expression<? extends Number> x) {
+            super(Double.class, x);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.sqrt(Expressions.toValue(e, factory, model, q));
         }
     }
     
     public static class Max<X> extends UnaryFunctionalExpression<X> {
-    	public  Max(Expression<X> x) {
-    		super(x);
-    	}
+        public  Max(Expression<X> x) {
+            super(x);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.max(Expressions.toValue(e, factory, model, q));
         }
     }
 
     public static class Min<X> extends UnaryFunctionalExpression<X> {
-    	public  Min(Expression<X> x) {
-    		super(x);
-    	}
+        public  Min(Expression<X> x) {
+            super(x);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.min(Expressions.toValue(e, factory, model, q));
         }
     }
     
     public static class Size extends UnaryFunctionalExpression<Integer> {
-    	public  Size(Expression<? extends Collection<?>> x) {
-    		super(Integer.class, x);
-    	}
-    	
-    	public  Size(Collection<?> x) {
-    		this(new Constant<Collection<?>>(x));
-    	}
+        public  Size(Expression<? extends Collection<?>> x) {
+            super(Integer.class, x);
+        }
+        
+        public  Size(Collection<?> x) {
+            this(new Constant<Collection<?>>(x));
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.size(Expressions.toValue(e, factory, model, q));
         }
     }
@@ -218,293 +222,340 @@
         
         @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.type(Expressions.toValue(e, factory, model, q));
         }
     }
 
     public static class Cast<B> extends UnaryFunctionalExpression<B> {
-    	Class<B> b;
-    	public Cast(Expression<?> x, Class<B> b) {
-    		super(b, x);
-    	}
+        Class<B> b;
+        public Cast(Expression<?> x, Class<B> b) {
+            super(b, x);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.cast(Expressions.toValue(e, factory, model, q), b);
         }
     }
     public static class Concat extends BinarayFunctionalExpression<String> {
-    	public Concat(Expression<String> x, Expression<String> y) {
-    		super(String.class, x, y);
-    	}
-    	
-    	public Concat(Expression<String> x, String y) {
-    		this(x, new Constant<String>(y));
-    	}
-    	
-    	public Concat(String x, Expression<String> y) {
-    		this(new Constant<String>(x), y);
-    	}
-    	
-    	@Override
+        public Concat(Expression<String> x, Expression<String> y) {
+            super(String.class, x, y);
+        }
+        
+        public Concat(Expression<String> x, String y) {
+            this(x, new Constant<String>(y));
+        }
+        
+        public Concat(String x, Expression<String> y) {
+            this(new Constant<String>(x), y);
+        }
+        
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.concat(
-            	Expressions.toValue(e1, factory, model, q), 
-            	Expressions.toValue(e2, factory, model, q));
+                Expressions.toValue(e1, factory, model, q), 
+                Expressions.toValue(e2, factory, model, q));
         }
     }
     
     public static class Substring extends UnaryFunctionalExpression<String> {
-    	private ExpressionImpl<Integer> from;
-    	private ExpressionImpl<Integer> len;
-    	
-    	public Substring(Expression<String> s, Expression<Integer> from, 
-    			Expression<Integer> len) {
-    		super(s);
-    		this.from = (ExpressionImpl<Integer>)from;
-    		this.len  = (ExpressionImpl<Integer>)len;
-    	}
-    	
-    	public Substring(Expression<String> s) {
-    		this(s, (Expression<Integer>)null, (Expression<Integer>)null);
-    	}
-    	
-    	public Substring(Expression<String> s, Integer from) {
-    		this(s, new Constant<Integer>(from), null);
-    	}
-    	
-    	public Substring(Expression<String> s, Integer from, Integer len) {
+        private ExpressionImpl<Integer> from;
+        private ExpressionImpl<Integer> len;
+        
+        public Substring(Expression<String> s, Expression<Integer> from, 
+                Expression<Integer> len) {
+            super(s);
+            this.from = (ExpressionImpl<Integer>)from;
+            this.len  = (ExpressionImpl<Integer>)len;
+        }
+        
+        public Substring(Expression<String> s, Expression<Integer> from) {
+            this(s, (ExpressionImpl<Integer>)from, null);
+        }
+
+        public Substring(Expression<String> s) {
+            this(s, (Expression<Integer>)null, (Expression<Integer>)null);
+        }
+        
+        public Substring(Expression<String> s, Integer from) {
+            this(s, new Constant<Integer>(from), null);
+        }
+        
+        public Substring(Expression<String> s, Integer from, Integer len) {
             this(s, new Constant<Integer>(from), new Constant<Integer>(len));
-    	}
-    	
-    	@Override
+        }
+        
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return JPQLExpressionBuilder.convertSubstringArguments(factory, 
-            	Expressions.toValue(e, factory, model, q), 
-            	from == null ? null : from.toValue(factory, model, q), 
-            	len == null ? null : len.toValue(factory, model, q));
+                Expressions.toValue(e, factory, model, q), 
+                from == null ? null : from.toValue(factory, model, q), 
+                len == null ? null : len.toValue(factory, model, q));
+        }
+    }
+
+    public static class Locate extends ExpressionImpl<Integer> {
+        private ExpressionImpl<String> pattern;
+        private ExpressionImpl<Integer> from;
+        private ExpressionImpl<String> path;
+        
+        public Locate(Expression<String> x, Expression<String> y,
+            Expression<Integer> from) {
+            super(Integer.class);
+            path = (ExpressionImpl<String>)x;
+            pattern = (ExpressionImpl<String>)y;
+            this.from = (ExpressionImpl<Integer>)from;
+        }
+
+        public Locate(Expression<String> x, Expression<String> y) {
+            this(x, y, null);
+         }
+        
+        public Locate(Expression<String> x, String y) {
+            this(x, new Constant<String>(y), null);
+        }
+        
+        public Locate(String x, Expression<String> y) {
+            this(new Constant<String>(x), y, null);
+        }
+        
+        public Locate(Expression<String> x, String y,
+            int from) {
+            this(x, new Constant<String>(y), new Constant<Integer>(from));
+        }
+
+        @Override
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQueryImpl q) {
+            Value locateSearch = path.toValue(factory, model, q);
+            Value locateFromIndex = (from == null ? 
+                null : Expressions.toValue(from, factory, model, q));
+            Value locatePath = Expressions.toValue(pattern, factory, model, q);
+            
+            return factory.add(factory.indexOf(locateSearch,
+                    locateFromIndex == null ? locatePath
+                        : factory.newArgumentList(locatePath,
+                        factory.subtract(locateFromIndex,
+                            factory.newLiteral(Numbers.valueOf(1),
+                                Literal.TYPE_NUMBER)))),
+                    factory.newLiteral(Numbers.valueOf(1),
+                        Literal.TYPE_NUMBER));
         }
     }
     
     public static class Trim extends BinarayFunctionalExpression<String> {
-    	static Expression<Character> defaultTrim = new Constant<Character>
-    	   (Character.class, new Character(' '));
-    	static Trimspec defaultSpec = Trimspec.BOTH;
-    	Trimspec ts;
-    	public Trim(Expression<String> x, Expression<Character> y, 
-    		Trimspec ts) {
-    		super(String.class, x, y);
-    		this.ts = ts;
-    	}
-    	
-    	public Trim(Expression<String> x, Expression<Character> y) {
-    		this(x, y, defaultSpec);
-    	}
-    	
-    	public Trim(Expression<String> x) {
-    		this(x, defaultTrim, defaultSpec);
-    	}
-    	
-    	public Trim(Expression<String> x, Character t) {
+        static Expression<Character> defaultTrim = new Constant<Character>
+           (Character.class, new Character(' '));
+        static Trimspec defaultSpec = Trimspec.BOTH;
+        Trimspec ts;
+        public Trim(Expression<String> x, Expression<Character> y, 
+            Trimspec ts) {
+            super(String.class, x, y);
+            this.ts = ts;
+        }
+        
+        public Trim(Expression<String> x, Expression<Character> y) {
+            this(x, y, defaultSpec);
+        }
+        
+        public Trim(Expression<String> x) {
+            this(x, defaultTrim, defaultSpec);
+        }
+        
+        public Trim(Expression<String> x, Character t) {
             this(x, new Constant<Character>(Character.class, t), defaultSpec);
-    	}
-    	
-    	public Trim(Expression<String> x, Character t, Trimspec ts) {
-    		this(x, new Constant<Character>(Character.class, t), ts);
-    	}
-    	
-    	public Trim(Expression<String> x, Trimspec ts) {
-    		this(x, defaultTrim, ts);
-    	}
-
-    	@Override
-        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
-    		Boolean spec = null;
-    		if (ts != null) {
-    			switch (ts) {
-    			case LEADING : spec = true; break;
-    			case TRAILING : spec = false; break;
-    			case BOTH : spec = null; break;
-    			}
-    		}
+        }
+        
+        public Trim(Expression<String> x, Character t, Trimspec ts) {
+            this(x, new Constant<Character>(Character.class, t), ts);
+        }
+        
+        public Trim(Expression<String> x, Trimspec ts) {
+            this(x, defaultTrim, ts);
+        }
+
+        @Override
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQueryImpl q) {
+            Boolean spec = null;
+            if (ts != null) {
+                switch (ts) {
+                case LEADING : spec = true; break;
+                case TRAILING : spec = false; break;
+                case BOTH : spec = null; break;
+                }
+            }
             return factory.trim(
-            	Expressions.toValue(e1, factory, model, q), 
-            	Expressions.toValue(e2, factory, model, q), spec);
+                Expressions.toValue(e1, factory, model, q), 
+                Expressions.toValue(e2, factory, model, q), spec);
         }
     }
-
-
     
     public static class Sum<N extends Number> 
         extends BinarayFunctionalExpression<N> {
-    	public Sum(Expression<? extends Number> x, 
-    		Expression<? extends Number> y) {
-    		super((Class<N>)x.getJavaType(), x, y);
-    	}
-    	
-    	public Sum(Expression<? extends Number> x) {
-    		this(x, (Expression<? extends Number>)null);
-    	}
-    	
-
-    	public Sum(Expression<? extends Number> x, Number y) {
-    		this(x, new Constant<Number>(Number.class, y));
-    	}
-
-    	public Sum(Number x, Expression<? extends Number> y) {
-    		this(new Constant<Number>(Number.class, x), y);
-    	}
-    	
-    	@Override
+        public Sum(Expression<? extends Number> x, 
+            Expression<? extends Number> y) {
+            super((Class<N>)x.getJavaType(), x, y);
+        }
+        
+        public Sum(Expression<? extends Number> x) {
+            this(x, (Expression<? extends Number>)null);
+        }
+
+        public Sum(Expression<? extends Number> x, Number y) {
+            this(x, new Constant<Number>(Number.class, y));
+        }
+
+        public Sum(Number x, Expression<? extends Number> y) {
+            this(new Constant<Number>(Number.class, x), y);
+        }
+        
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
-    		return (e2 == null) 
+            CriteriaQueryImpl q) {
+            return (e2 == null) 
             ?   factory.sum(Expressions.toValue(e1, factory, model, q))
-    		:   factory.add(
-    			   Expressions.toValue(e1, factory, model, q), 
-    			   Expressions.toValue(e2, factory, model, q));
+            :   factory.add(
+                   Expressions.toValue(e1, factory, model, q), 
+                   Expressions.toValue(e2, factory, model, q));
         }
     }
     
     public static class Product<N extends Number> 
         extends BinarayFunctionalExpression<N> {
-    	public Product(Expression<? extends Number> x, 
-    		Expression<? extends Number> y) {
-    		super((Class<N>)x.getJavaType(), x, y);
-    	}
-
-    	public Product(Expression<? extends Number> x, Number y) {
-    		this(x, new Constant<Number>(Number.class, y));
-    	}
-
-    	public Product(Number x, Expression<? extends Number> y) {
-    		this(new Constant<Number>(Number.class, x), y);
-    	}
-    	
-    	@Override
+        public Product(Expression<? extends Number> x, 
+            Expression<? extends Number> y) {
+            super((Class<N>)x.getJavaType(), x, y);
+        }
+
+        public Product(Expression<? extends Number> x, Number y) {
+            this(x, new Constant<Number>(Number.class, y));
+        }
+
+        public Product(Number x, Expression<? extends Number> y) {
+            this(new Constant<Number>(Number.class, x), y);
+        }
+        
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.multiply(
-            	Expressions.toValue(e1, factory, model, q), 
-            	Expressions.toValue(e2, factory, model, q));
+                Expressions.toValue(e1, factory, model, q), 
+                Expressions.toValue(e2, factory, model, q));
         }
     }
     
     public static class Diff<N extends Number> 
         extends BinarayFunctionalExpression<N> {
-    	public Diff(Expression<? extends Number> x, 
-    		Expression<? extends Number> y) {
-    		super((Class<N>)x.getJavaType(), x, y);
-    	}
-
-    	public Diff(Expression<? extends Number> x, Number y) {
-    		this(x, new Constant<Number>(Number.class, y));
-    	}
-
-    	public Diff(Number x, Expression<? extends Number> y) {
-    		this(new Constant<Number>(Number.class, x), y);
-    	}
-    	
-    	@Override
+        public Diff(Expression<? extends Number> x, 
+            Expression<? extends Number> y) {
+            super((Class<N>)x.getJavaType(), x, y);
+        }
+
+        public Diff(Expression<? extends Number> x, Number y) {
+            this(x, new Constant<Number>(Number.class, y));
+        }
+
+        public Diff(Number x, Expression<? extends Number> y) {
+            this(new Constant<Number>(Number.class, x), y);
+        }
+        
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.subtract(
-            	Expressions.toValue(e1, factory, model, q), 
-            	Expressions.toValue(e2, factory, model, q));
+                Expressions.toValue(e1, factory, model, q), 
+                Expressions.toValue(e2, factory, model, q));
         }
     }
 
     
     public static class Quotient<N extends Number> 
         extends BinarayFunctionalExpression<N> {
-    	public Quotient(Expression<? extends Number> x, 
-    		Expression<? extends Number> y) {
-    		super((Class<N>)x.getJavaType(), x, y);
-    	}
-
-    	public Quotient(Expression<? extends Number> x, Number y) {
-    		this(x, new Constant<Number>(y));
-    	}
-
-    	public Quotient(Number x, Expression<? extends Number> y) {
-    		this(new Constant<Number>(x), y);
-    	}
-    	
-    	@Override
+        public Quotient(Expression<? extends Number> x, 
+            Expression<? extends Number> y) {
+            super((Class<N>)x.getJavaType(), x, y);
+        }
+
+        public Quotient(Expression<? extends Number> x, Number y) {
+            this(x, new Constant<Number>(y));
+        }
+
+        public Quotient(Number x, Expression<? extends Number> y) {
+            this(new Constant<Number>(x), y);
+        }
+        
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.divide(
-            	Expressions.toValue(e1, factory, model, q), 
-            	Expressions.toValue(e2, factory, model, q));
+                Expressions.toValue(e1, factory, model, q), 
+                Expressions.toValue(e2, factory, model, q));
         }
     }
 
-
-
     public static class Mod extends BinarayFunctionalExpression<Integer> {
-    	public  Mod(Expression<Integer> x, Expression<Integer> y) {
-    		super(Integer.class, x,y);
-    	}
-    	public  Mod(Expression<Integer> x, Integer y) {
-    		this(x,new Constant<Integer>(Integer.class, y));
-    	}
-    	public  Mod(Integer x, Expression<Integer> y) {
-    		this(new Constant<Integer>(Integer.class, x),y);
-    	}
+        public  Mod(Expression<Integer> x, Expression<Integer> y) {
+            super(Integer.class, x,y);
+        }
+        public  Mod(Expression<Integer> x, Integer y) {
+            this(x,new Constant<Integer>(Integer.class, y));
+        }
+        public  Mod(Integer x, Expression<Integer> y) {
+            this(new Constant<Integer>(Integer.class, x),y);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.mod(
-            	Expressions.toValue(e1, factory, model, q), 
-            	Expressions.toValue(e2, factory, model, q));
+                Expressions.toValue(e1, factory, model, q), 
+                Expressions.toValue(e2, factory, model, q));
         }
     }
 
     public static class CurrentDate extends ExpressionImpl<java.sql.Date> {
-    	public  CurrentDate() {
-    		super(java.sql.Date.class);
-    	}
+        public  CurrentDate() {
+            super(java.sql.Date.class);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.getCurrentDate();
         }
     }
     
     public static class CurrentTime extends ExpressionImpl<java.sql.Time> {
-    	public  CurrentTime() {
-    		super(java.sql.Time.class);
-    	}
+        public  CurrentTime() {
+            super(java.sql.Time.class);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.getCurrentTime();
         }
     }
     
     public static class CurrentTimestamp 
         extends ExpressionImpl<java.sql.Timestamp> {
-    	public  CurrentTimestamp() {
-    		super(java.sql.Timestamp.class);
-    	}
+        public  CurrentTimestamp() {
+            super(java.sql.Timestamp.class);
+        }
 
-    	@Override
+        @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.getCurrentTimestamp();
         }
     }
 
     public static class Equal extends BinaryLogicalExpression {
-        boolean negate;
         public <X,Y> Equal(Expression<X> x, Expression<Y> y) {
             super(x,y);
         }
@@ -514,22 +565,19 @@
         }
         
         @Override
+        public PredicateImpl clone() {
+            return new Equal(e1, e2);
+        }
+        
+        @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
             boolean isTypeExpr = false;
             Value val1 = Expressions.toValue(e1, factory, model, q);
             Value val2 = Expressions.toValue(e2, factory, model, q);
-//            if (e1 instanceof TypePathImpl) {
-//                PathImpl path = (PathImpl)e1;
-//                isTypeExpr = path.isTypeExpr();
-//                if (isTypeExpr) {
-//                    ((Constant)e2).setTypeLit(isTypeExpr);
-//                    val2 = Expressions.toValue(e2, factory, model, q);
-//                    Class clzz = (Class)((Literal)val2).getValue();
-//                    val2.setMetaData(((Types.Managed)model.type(clzz)).meta);
-//                }
-//            }
-            ((CriteriaQueryImpl)q).setImplicitTypes(val1, val2, null);
+            JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null, 
+                ((CriteriaQueryImpl)q).getParameterTypes(), null);
             return isNegated() ? factory.notEqual(val1, val2) 
                     : factory.equal(val1, val2);
         }
@@ -546,10 +594,13 @@
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
-                return factory.greaterThan(
-                	Expressions.toValue(e1, factory, model, q), 
-                	Expressions.toValue(e2, factory, model, q));
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            Value val1 = Expressions.toValue(e1, factory, model, q);
+            Value val2 = Expressions.toValue(e2, factory, model, q); 
+            JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null, 
+                ((CriteriaQueryImpl)q).getParameterTypes(), null);
+            return factory.greaterThan(val1, val2);
         }
     }
     
@@ -564,13 +615,15 @@
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
-                return factory.greaterThanEqual(
-                    Expressions.toValue(e1, factory, model, q), 
-                    Expressions.toValue(e2, factory, model, q));
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            Value val1 = Expressions.toValue(e1, factory, model, q);
+            Value val2 = Expressions.toValue(e2, factory, model, q); 
+            JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null, 
+                ((CriteriaQueryImpl)q).getParameterTypes(), null);
+            return factory.greaterThanEqual(val1, val2);
         }
     }
-
    
     public static class LessThan extends BinaryLogicalExpression {
         public <X,Y> LessThan(Expression<X> x, Expression<Y> y) {
@@ -583,10 +636,13 @@
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
-                return factory.lessThan(
-                    Expressions.toValue(e1, factory, model, q), 
-                    Expressions.toValue(e2, factory, model, q));
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            Value val1 = Expressions.toValue(e1, factory, model, q);
+            Value val2 = Expressions.toValue(e2, factory, model, q); 
+            JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null, 
+                ((CriteriaQueryImpl)q).getParameterTypes(), null);
+            return factory.lessThan(val1, val2);
         }
     }
     
@@ -601,11 +657,13 @@
         
         @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
-                return factory.lessThanEqual(
-                	Expressions.toValue(e1, factory, model, q), 
-                    Expressions.toValue(e2, factory, model, q));
-
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            Value val1 = Expressions.toValue(e1, factory, model, q);
+            Value val2 = Expressions.toValue(e2, factory, model, q); 
+            JPQLExpressionBuilder.setImplicitTypes(val1, val2, null, null, 
+                ((CriteriaQueryImpl)q).getParameterTypes(), null);
+            return factory.lessThanEqual(val1, val2);
         }
     }
 
@@ -629,12 +687,12 @@
         }
         
         public Constant(X x) {
-        	this((Class<X>)x.getClass(),x);
+            this((Class<X>)x.getClass(),x);
         }
         
         @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             int literalType = Literal.TYPE_UNKNOWN;
             if (arg != null) {
                 Class<?> literalClass = arg.getClass();
@@ -649,12 +707,17 @@
                 else if (Class.class.isAssignableFrom(literalClass)) {
                     literalType = Literal.TYPE_CLASS;
                     Literal lit = factory.newTypeLiteral(arg, 
-                            Literal.TYPE_CLASS);
-                    lit.setMetaData(model.repos.getMetaData((Class<?>)arg, 
+                        Literal.TYPE_CLASS);
+                    ClassMetaData can = 
+                        ((Types.Entity<X>)q.getRoot().getModel()).meta;
+                    Class<?> candidate = can.getDescribedType();
+                    if (candidate.isAssignableFrom((Class)arg))
+                        lit.setMetaData(model.repos.getMetaData((Class<?>)arg, 
                             null, true));
+                    else
+                        lit.setMetaData(can);
                     return lit;
                 }
-                
             }
             return factory.newLiteral(arg, literalType);
         }
@@ -667,21 +730,27 @@
         
         @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery q) {
+            CriteriaQueryImpl q) {
             return factory.newTypeLiteral(arg, Literal.TYPE_CLASS);
         }
     }
     
     public static class IsEmpty extends PredicateImpl {
-    	ExpressionImpl<?> collection;
-    	public IsEmpty(Expression<?> collection) {
-    		super();
-    		this.collection = (ExpressionImpl<?>)collection;
-    	}
-    	
+        ExpressionImpl<?> collection;
+        public IsEmpty(Expression<?> collection) {
+            super();
+            this.collection = (ExpressionImpl<?>)collection;
+        }
+        
+        @Override
+        public PredicateImpl clone() {
+            return new IsEmpty(collection);
+        }
+        
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
             Value val = Expressions.toValue(collection, factory, model, q);
             return (isNegated()) 
                 ? factory.isNotEmpty(val) : factory.isEmpty(val);
@@ -695,7 +764,8 @@
         
         @Override
         public org.apache.openjpa.kernel.exps.Value toValue(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
             Value v = Expressions.toValue(e, factory, model, q);
             ClassMetaData meta = ((PathImpl)e)._member.fmd.getElement()
                .getTypeMetaData();
@@ -705,33 +775,32 @@
     }
     
     public static class IsMember<E> extends PredicateImpl {
-    	ExpressionImpl<E> element;
-    	ExpressionImpl<?> collection;
-    	boolean negate;
-    	
-    	public IsMember(Class<E> t, Expression<E> element, 
-    		Expression<?> collection) {
-    		this.element = (ExpressionImpl<E>)element;
-    		this.collection = (ExpressionImpl<?>)collection;
-    	}
-    	
-    	public IsMember(Class<E> t, E element, Expression<?> collection) {
-    		this(t, new Constant<E>(element), collection);
-    	}
-    	
-    	public IsMember(E element, Expression<?> collection) {
-    		this((Class<E>)element.getClass(), element, collection);
-    	}
-    	
-    	public IsMember<E> negate() {
-    	    negate = true;
-    	    return this;
-    	}
-    	
+        ExpressionImpl<E> element;
+        ExpressionImpl<?> collection;
+        
+        public IsMember(Class<E> t, Expression<E> element, 
+            Expression<?> collection) {
+            this.element = (ExpressionImpl<E>)element;
+            this.collection = (ExpressionImpl<?>)collection;
+        }
+        
+        public IsMember(Class<E> t, E element, Expression<?> collection) {
+            this(t, new Constant<E>(element), collection);
+        }
+        
+        public IsMember(E element, Expression<?> collection) {
+            this((Class<E>)element.getClass(), element, collection);
+        }
+        
+        @Override
+        public PredicateImpl clone() {
+            return new IsMember(element, collection);
+        }
+        
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-        	ExpressionFactory factory, MetamodelImpl model, 
-        	CriteriaQuery q) {
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
             return factory.contains(
                 Expressions.toValue(collection, factory, model, q), 
                 Expressions.toValue(element, factory, model, q));
@@ -739,162 +808,210 @@
     }
     
     public static class Like extends PredicateImpl {
-    	ExpressionImpl<String> str;
-    	ExpressionImpl<String> pattern;
-    	ExpressionImpl<Character> escapeChar;
-    	
-    	public Like(Expression<String> x, Expression<String> pattern,
-    	        Expression<Character> escapeChar) {
-    		super();
-    		this.str = (ExpressionImpl<String>)x;
-    		this.pattern = (ExpressionImpl<String>)pattern;
-    		this.escapeChar = (ExpressionImpl<Character>)escapeChar;
-    	}
-    	
-    	public Like(Expression<String> x, Expression<String> pat, char esc) {
-    		this(x, pat, new Constant<Character>(Character.class, esc));
-    	}
-    	
-    	public Like(Expression<String> x, Expression<String> pattern) {
-    		this(x, pattern, null);
-    	}
-    	
-    	public Like(Expression<String> x, String pattern) {
-    		this(x, new Constant<String>(pattern), null);
-    	}
-    	public Like(Expression<String> x, String pat,  
-    		Expression<Character> esc) {
-    		this(x, new Constant<String>(pat), esc);
-    	}
-    	public Like(Expression<String> x, String pat,  Character esc) {
+        ExpressionImpl<String> str;
+        ExpressionImpl<String> pattern;
+        ExpressionImpl<Character> escapeChar;
+        
+        public Like(Expression<String> x, Expression<String> pattern,
+                Expression<Character> escapeChar) {
+            super();
+            this.str = (ExpressionImpl<String>)x;
+            this.pattern = (ExpressionImpl<String>)pattern;
+            this.escapeChar = (ExpressionImpl<Character>)escapeChar;
+        }
+        
+        public Like(Expression<String> x, Expression<String> pat, char esc) {
+            this(x, pat, new Constant<Character>(Character.class, esc));
+        }
+        
+        public Like(Expression<String> x, Expression<String> pattern) {
+            this(x, pattern, null);
+        }
+        
+        public Like(Expression<String> x, String pattern) {
+            this(x, new Constant<String>(pattern), null);
+        }
+        
+        public Like(Expression<String> x, String pat,  
+            Expression<Character> esc) {
+            this(x, new Constant<String>(pat), esc);
+        }
+        
+        public Like(Expression<String> x, String pat,  Character esc) {
             this(x, new Constant<String>(pat), new Constant<Character>(esc));
-    	}
+        }
 
-    	@Override
+        @Override
+        public PredicateImpl clone() {
+            return new Like(str, pattern, escapeChar);
+        }
+        
+        @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-        	ExpressionFactory factory, MetamodelImpl model, 
-        	CriteriaQuery q) {
-    	    String escapeStr = escapeChar == null ? null :
-    	        ((Character)((Literal)Expressions.toValue(
-    	            escapeChar, factory, model, q)).getValue()).toString();
-    	    
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            String escapeStr = escapeChar == null ? null :
+                ((Character)((Literal)Expressions.toValue(
+                    escapeChar, factory, model, q)).getValue()).toString();
+            
             return factory.matches(
-            	Expressions.toValue(str, factory, model, q), 
-            	Expressions.toValue(pattern, factory, model, q), "_", "%", 
-            	escapeStr);
+                Expressions.toValue(str, factory, model, q), 
+                Expressions.toValue(pattern, factory, model, q), "_", "%", 
+                escapeStr);
         }
     }
     
     public static class Coalesce<T> extends ExpressionImpl<T> 
-    	implements QueryBuilder.Coalesce<T> {
-    	private List<Expression<? extends T>> values = 
-    		new ArrayList<Expression<? extends T>>();
-    	
-    	public Coalesce() {
-    		super(null);
-    	}
-    	
-    	public Coalesce(Class<T> cls) {
-    		super(cls);
-    	}
-    	
+        implements QueryBuilder.Coalesce<T> {
+        private List<Expression<? extends T>> values = 
+            new ArrayList<Expression<? extends T>>();
+        
+        public Coalesce() {
+            super(null);
+        }
+        
+        public Coalesce(Class<T> cls) {
+            super(cls);
+        }
+        
         public Coalesce<T> value(T value) {
-        	return value(new Constant<T>(value));
+            values.add(new Constant<T>(value));
+            return this;
         }
         
         public Coalesce<T> value(Expression<? extends T> value) {
-        	values.add(value); 
-        	return this;
+            values.add(value); 
+            return this;
         }
-
-    	
-    	@Override
+        
+        @Override
         public org.apache.openjpa.kernel.exps.Value toValue(
-        	ExpressionFactory factory, MetamodelImpl model, 
-        	CriteriaQuery q) {
-    		Value[] vs = new Value[values.size()];
-    		int i = 0;
-    		for (Expression<?> e : values)
-    	        vs[i++] = Expressions.toValue((ExpressionImpl<?>)e, 
-    	           factory, model, q);
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            Value[] vs = new Value[values.size()];
+            int i = 0;
+            for (Expression<?> e : values)
+                vs[i++] = Expressions.toValue((ExpressionImpl<?>)e, 
+                   factory, model, q);
             return factory.coalesceExpression(vs);
         }
     }
     
+    public static class Nullif<T> extends ExpressionImpl<T> {
+        private Expression<T> val1;
+        private Expression<?> val2;
+
+        public Nullif(Expression<T> x, Expression<?> y) {
+            super(x.getJavaType());
+            val1 = x;
+            val2 = y;
+        }
+
+        public Nullif(Expression<T> x, T y) {
+            super(x.getJavaType());
+            val1 = x;
+            val2 = new Constant<T>(y);
+        }
+
+        @Override
+        public org.apache.openjpa.kernel.exps.Value toValue(
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            Value value1 = Expressions.toValue((ExpressionImpl<?>)val1, 
+                factory, model, q); 
+            Value value2 = Expressions.toValue((ExpressionImpl<?>)val2, 
+                factory, model, q); 
+            return factory.nullIfExpression(value1, value2);
+        }
+    }
+
     public static class IsNull extends PredicateImpl {
-    	ExpressionImpl<?> e;
-    	public IsNull(ExpressionImpl<?> e) {
-    		super();
-    		this.e = e;
-    	}
-    	
-    	@Override
+        ExpressionImpl<?> e;
+        public IsNull(ExpressionImpl<?> e) {
+            super();
+            this.e = e;
+        }
+        
+        @Override
+        public PredicateImpl negate() {
+            return new Expressions.IsNotNull(e);
+        }        
+        
+        @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
-    		return factory.equal(
-    			Expressions.toValue(e, factory, model, q), 
-    			factory.getNull());
-    	}
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            return factory.equal(
+                Expressions.toValue(e, factory, model, q), 
+                factory.getNull());
+        }
     }
     
     public static class IsNotNull extends PredicateImpl {
-    	ExpressionImpl<?> e;
-    	public IsNotNull(ExpressionImpl<?> e) {
-    		super();
-    		this.e = e;
-    	}
-    	
-    	@Override
+        ExpressionImpl<?> e;
+        public IsNotNull(ExpressionImpl<?> e) {
+            super();
+            this.e = e;
+        }
+        
+        @Override
+        public PredicateImpl negate() {
+            return new Expressions.IsNull(e);
+        }       
+
+        @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
-    		return factory.notEqual(
-    			Expressions.toValue(e, factory, model, q), 
-    			factory.getNull());
-    	}
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            return factory.notEqual(
+                Expressions.toValue(e, factory, model, q), 
+                factory.getNull());
+        }
     }
     
     
     public static class In<T> extends PredicateImpl.Or 
-    	implements QueryBuilder.In<T> {
-    	ExpressionImpl<?> e;
-    	boolean negate;
-    	public In(Expression<?> e) {
-    		super((Predicate[])null);
-    		this.e = (ExpressionImpl<?>)e;
-    	}
-    	
-    	public Expression<T> getExpression() {
-    		return null;
-    	}
-
-    	public In<T> value(T value) {
-    		add(new Expressions.Equal(e,value));
-        	return this;
-    	}
-
-    	public In<T> value(Expression<? extends T> value) {
-    		add(new Expressions.Equal(e,value));
-        	return this;
-    	}
-    	
-    	public In<T> negate() {
-    	    this.negate = true;
-    	    return this;
-    	}
+        implements QueryBuilder.In<T> {
+        ExpressionImpl<?> e;
+        boolean negate;
+        public In(Expression<?> e) {
+            super((Predicate[])null);
+            this.e = (ExpressionImpl<?>)e;
+        }
+        
+        public Expression<T> getExpression() {
+            return null;
+        }
+
+        public In<T> value(T value) {
+            add(new Expressions.Equal(e,value));
+            return this;
+        }
+
+        public In<T> value(Expression<? extends T> value) {
+            add(new Expressions.Equal(e,value));
+            return this;
+        }
+        
+        public In<T> negate() {
+            this.negate = true;
+            return this;
+        }
     
-    	@Override
+        @Override
         org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery q) {
-    	    org.apache.openjpa.kernel.exps.Expression 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));
-    	}
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            org.apache.openjpa.kernel.exps.Expression 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));
+        }
     }
     
     public static class Case<T> extends ExpressionImpl<T> 
@@ -943,7 +1060,7 @@
         @Override
         public org.apache.openjpa.kernel.exps.Value toValue(
                 ExpressionFactory factory, MetamodelImpl model, 
-                CriteriaQuery q) {
+                CriteriaQueryImpl q) {
             int size = whens.size();
             org.apache.openjpa.kernel.exps.Expression[] exps = 
                 new org.apache.openjpa.kernel.exps.Expression[size];
@@ -967,7 +1084,7 @@
         private List<Expression<? extends R>> thens = 
             new ArrayList<Expression<? extends R>>();
 
-        private List<C> whens = new ArrayList<C>();
+        private List<Expression<C>> whens = new ArrayList<Expression<C>>();
 
         private Expression<? extends R> otherwise;
 
@@ -991,13 +1108,13 @@
         }
 
         public SimpleCase<C,R> when(C when, Expression<? extends R> then) {
-            whens.add(when);
+            whens.add(new Constant<C>(when));
             thens.add(then);
             return this;
         }
 
         public SimpleCase<C,R> when(C when, R then) {
-            whens.add(when);
+            whens.add(new Constant<C>(when));
             Expression<? extends R> thenExpr = 
                 new Expressions.Constant<R>(then);
             thens.add(thenExpr);
@@ -1017,19 +1134,18 @@
         @Override
         public org.apache.openjpa.kernel.exps.Value toValue(
                 ExpressionFactory factory, MetamodelImpl model, 
-                CriteriaQuery q) {
+                CriteriaQueryImpl q) {
             Value caseOperandExpr = Expressions.toValue(
                 (ExpressionImpl<?>)caseOperand, factory, model, q);
             int size = whens.size();
             org.apache.openjpa.kernel.exps.Expression[] exps = 
                 new org.apache.openjpa.kernel.exps.Expression[size];
             for (int i = 0; i < size; i++) {
-                org.apache.openjpa.kernel.exps.Literal val = null;
-                //TODO: Boolean literal, String literal    
-                val = factory.newLiteral(whens.get(i), Literal.TYPE_NUMBER);
+                Value when = Expressions.toValue(
+                    (ExpressionImpl<C>)whens.get(i), factory, model, q);
                 Value action = Expressions.toValue(
-                        (ExpressionImpl<?>)thens.get(i), factory, model, q);
-                exps[i] = factory.whenScalar(val, action);
+                    (ExpressionImpl<?>)thens.get(i), factory, model, q);
+                exps[i] = factory.whenScalar(when, action);
             }
 
             Value other = Expressions.toValue(
@@ -1037,4 +1153,113 @@
             return factory.simpleCaseExpression(caseOperandExpr, exps, other);
         }
     }
+
+    public static class Lower extends UnaryFunctionalExpression<String> {
+        public Lower(Expression<String> x) {
+            super(String.class, x);
+        }
+        
+        @Override
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQueryImpl q) {
+            return factory.toLowerCase(
+                Expressions.toValue(e, factory, model, q));
+        }
+    }
+
+    public static class Upper extends UnaryFunctionalExpression<String> {
+        public Upper(Expression<String> x) {
+            super(String.class, x);
+        }
+        
+        @Override
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQueryImpl q) {
+            return factory.toUpperCase(
+                Expressions.toValue(e, factory, model, q));
+        }
+    }
+
+    public static class Length extends UnaryFunctionalExpression<Integer> {
+        public Length(Expression<String> x) {
+            super(Integer.class, x);
+        }
+        
+        @Override
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQueryImpl q) {
+            return factory.stringLength(
+                Expressions.toValue(e, factory, model, q));
+        }
+    }
+    
+    public static class Exists extends PredicateImpl {
+        SubqueryImpl<?> e;
+        public Exists(Subquery<?> x) {
+            super();
+            e = (SubqueryImpl<?>)x;
+        }
+
+        @Override
+        public PredicateImpl clone() {
+            return new Exists(e);
+        }
+        
+        @Override
+        org.apache.openjpa.kernel.exps.Expression toKernelExpression(
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl q) {
+            org.apache.openjpa.kernel.exps.Expression notEmpty = 
+                factory.isNotEmpty(Expressions.toValue(e, factory, model, q));
+            if (isNegated())
+                return factory.not(notEmpty);
+            else
+                return notEmpty;
+                
+        }        
+    }
+    
+    public static class All<X> extends ExpressionImpl<X> {
+        SubqueryImpl<X> e;
+        public All(Subquery<X> x) {
+            super(x.getJavaType());
+            e = (SubqueryImpl<X>)x;
+        }
+        
+        @Override
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQueryImpl q) {
+            return factory.all(Expressions.toValue(e, factory, model, q));
+        }        
+    }
+
+    public static class Any<X> extends ExpressionImpl<X> {
+        SubqueryImpl<X> e;
+        public Any(Subquery<X> x) {
+            super(x.getJavaType());
+            e = (SubqueryImpl<X>)x;
+        }
+        
+        @Override
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQueryImpl q) {
+            return factory.any(Expressions.toValue(e, factory, model, q));
+        }        
+    }
+
+    public static class Some<X> extends ExpressionImpl<X> {
+        SubqueryImpl<X> e;
+        public Some(Subquery<X> x) {
+            super(x.getJavaType());
+            e = (SubqueryImpl<X>)x;
+        }
+        
+        @Override
+        public Value toValue(ExpressionFactory factory, MetamodelImpl model,
+            CriteriaQueryImpl q) {
+            //return factory.some(Expressions.toValue(e, factory, model, q));
+            return null;
+        }        
+    }
+
 }

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=781621&r1=781620&r2=781621&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 Wed Jun  3 23:44:58 2009
@@ -20,7 +20,6 @@
 
 import javax.persistence.criteria.AbstractCollectionJoin;
 import javax.persistence.criteria.CollectionJoin;
-import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Join;
 import javax.persistence.criteria.JoinType;
@@ -74,7 +73,7 @@
         
         @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model, 
-            CriteriaQuery c) {
+            CriteriaQueryImpl c) {
             boolean allowNull = joinType != JoinType.INNER;
             org.apache.openjpa.kernel.exps.Path path = 
                 (org.apache.openjpa.kernel.exps.Path)
@@ -88,7 +87,8 @@
         
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery c) {
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl c) {
             org.apache.openjpa.kernel.exps.Value path = this.toValue
                 (factory, model, c);
             ClassMetaData meta = _member.fmd.getDeclaredTypeMetaData();
@@ -150,7 +150,7 @@
          */
         @Override
         public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-            CriteriaQuery c) {
+            CriteriaQueryImpl c) {
             boolean allowNull = joinType != JoinType.INNER;
             org.apache.openjpa.kernel.exps.Path path = 
                 (org.apache.openjpa.kernel.exps.Path)
@@ -169,7 +169,8 @@
          */
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-            ExpressionFactory factory, MetamodelImpl model, CriteriaQuery c) {
+            ExpressionFactory factory, MetamodelImpl model, 
+            CriteriaQueryImpl c) {
             org.apache.openjpa.kernel.exps.Value path = toValue
                (factory, model, c);
             

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterImpl.java?rev=781621&r1=781620&r2=781621&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterImpl.java Wed Jun  3 23:44:58 2009
@@ -19,8 +19,9 @@
 package org.apache.openjpa.persistence.criteria;
 
 import java.util.Collection;
+
 import javax.persistence.Parameter;
-import javax.persistence.criteria.CriteriaQuery;
+
 import org.apache.commons.collections.map.LinkedMap;
 import org.apache.openjpa.kernel.exps.ExpressionFactory;
 import org.apache.openjpa.kernel.exps.Value;
@@ -57,7 +58,7 @@
 
     @Override
     public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-        CriteriaQuery q) {
+        CriteriaQueryImpl q) {
         boolean positional = false;
         LinkedMap parameterTypes = ((CriteriaQueryImpl)q).getParameterTypes();
         if (parameterTypes == null) {

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=781621&r1=781620&r2=781621&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 Wed Jun  3 23:44:58 2009
@@ -19,15 +19,16 @@
 
 package org.apache.openjpa.persistence.criteria;
 
-import javax.persistence.criteria.CriteriaQuery;
+import java.util.Set;
+
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Root;
 import javax.persistence.metamodel.AbstractCollection;
 import javax.persistence.metamodel.Attribute;
 import javax.persistence.metamodel.Bindable;
 import javax.persistence.metamodel.ManagedType;
 import javax.persistence.metamodel.Map;
-import javax.persistence.metamodel.Member;
 import javax.persistence.metamodel.Type;
 
 import org.apache.openjpa.kernel.exps.ExpressionFactory;
@@ -78,14 +79,34 @@
         return _parent;
     }
     
+    public PathImpl getInnermostParentPath() {
+        if (_parent == null)
+            return this;
+        PathImpl _p = _parent.getInnermostParentPath(); 
+        if (_p == null)
+            return _parent;
+        else
+            return _p.getInnermostParentPath();
+    }
+
     /**
      * Convert this path to a kernel path value.
      */
     @Override
     public Value toValue(ExpressionFactory factory, MetamodelImpl model,
-        CriteriaQuery q) {
+        CriteriaQueryImpl q) {
         Value var = null;
-        if (_parent != null) { 
+        SubqueryImpl subquery = q.getContext();
+        PathImpl parent = getInnermostParentPath();
+        if (subquery != null && inSubquery(parent, subquery)) {
+            org.apache.openjpa.kernel.exps.Subquery subQ = 
+                subquery.getSubQ();
+            org.apache.openjpa.kernel.exps.Path path = factory.newPath(subQ);
+            path.setMetaData(subQ.getMetaData());
+            boolean allowNull = false;
+            path.get(_member.fmd, allowNull);
+            var = path;
+        } else if (_parent != null) { 
             org.apache.openjpa.kernel.exps.Path path = 
                 (org.apache.openjpa.kernel.exps.Path)
                 _parent.toValue(factory, model, q);
@@ -104,6 +125,16 @@
         var.setAlias(getAlias());
         return var;
     }
+    
+    public static boolean inSubquery(PathImpl parent, SubqueryImpl subquery) {
+        Set<Root<?>> roots = subquery.getRoots();
+        for (Root<?> r : roots) {
+            if (parent == r) 
+                return true;
+        }
+        return false;
+    }
+    
 
     public <Y> Path<Y> get(Attribute<? super X, Y> attr) {
         return new PathImpl<X,Y>(this, (Members.Attribute<? super X, Y>)attr, 



Mime
View raw message