openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ppod...@apache.org
Subject svn commit: r1466339 [3/3] - in /openjpa/sandboxes/21: ./ openjpa-all/ openjpa-examples/ openjpa-examples/image-gallery/ openjpa-examples/openbooks/ openjpa-examples/simple/ openjpa-integration/ openjpa-integration/daytrader/ openjpa-integration/exampl...
Date Wed, 10 Apr 2013 06:09:59 GMT
Added: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/GenericCriteriaImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/GenericCriteriaImpl.java?rev=1466339&view=auto
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/GenericCriteriaImpl.java (added)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/GenericCriteriaImpl.java Wed Apr 10 06:09:57 2013
@@ -0,0 +1,917 @@
+/*
+ * 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.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+import javax.persistence.criteria.AbstractQuery;
+import javax.persistence.criteria.CommonAbstractCriteria;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Fetch;
+import javax.persistence.criteria.From;
+import javax.persistence.criteria.Join;
+import javax.persistence.criteria.Order;
+import javax.persistence.criteria.ParameterExpression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Selection;
+import javax.persistence.criteria.Subquery;
+import javax.persistence.metamodel.EntityType;
+
+import org.apache.openjpa.kernel.QueryOperations;
+import org.apache.openjpa.kernel.StoreQuery;
+import org.apache.openjpa.kernel.exps.Context;
+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.lib.util.Localizer;
+import org.apache.openjpa.lib.util.OrderedMap;
+import org.apache.openjpa.persistence.meta.MetamodelImpl;
+import org.apache.openjpa.persistence.meta.Types;
+
+/**
+ * Generic implementation of Criteria Query.
+ * <br>
+ * Collects clauses of criteria query (e.g. select projections, from/join, 
+ * where conditions, order by etc).
+ * <br>
+ * Translates these clauses to a similar form of Expression tree
+ * that can be interpreted and executed against a data store by OpenJPA kernel.
+ * <br>
+ * This class also provides the management of aliases for query variables.
+ *  
+ * This implementation is factored from {@link CriteriaQueryImpl} in version
+ * later than 2.3.0 to accommodate the delete and update criteria in one single
+ * place. The {@link CriteriaQueryImpl} extends this class to lower the 
+ * regression risk.
+ *   
+ * @author Pinaki Poddar
+ *
+ * @since 3.0
+ */
+class GenericCriteriaImpl<T> implements OpenJPACriteriaQuery<T>, AliasContext {
+    private static final Localizer _loc = Localizer.forPackage(GenericCriteriaImpl.class);
+    
+    private final MetamodelImpl  _model;
+    private Set<Root<?>>        _roots;
+    private PredicateImpl       _where;
+    private List<Order>         _orders;
+    private OrderedMap<Object, Class<?>> _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 final SubqueryImpl<?> _delegatorSubquery;
+    private final Class<T>      _resultClass;
+    private boolean             _compiled;
+    private final int           _operation;
+    private CommonAbstractCriteria _owner;
+    
+    // AliasContext
+    private int aliasCount = 0;
+    private static String ALIAS_BASE = "autoAlias";
+    
+    private Map<Selection<?>,Value> _variables = new HashMap<Selection<?>, Value>();
+    private Map<Selection<?>,Value> _values    = new HashMap<Selection<?>, Value>();
+    private Map<Selection<?>,String> _aliases  = null;
+    private Map<Selection<?>,Value> _rootVariables = new HashMap<Selection<?>, Value>();
+    
+    // SubqueryContext
+    private Stack<Context> _contexts = null;
+    
+    /**
+     * Supply a model, the class of result to produce.
+     * @param model the meta model of the persistence types
+     * @param delegator
+     */
+    GenericCriteriaImpl(MetamodelImpl model, SubqueryImpl<T> delegator) {
+    	this(model, delegator, QueryOperations.OP_SELECT);
+    }
+    
+    /**
+     * Supply a model, the class of result to produce and the {@link QueryOperations query operation}.
+     * @param model the meta model of the persistence types
+     * @param resultClass the class of result for the select queries, the target type for
+     * delete/update query.
+     *  
+     * @param op indicates the type of query e.g. {@code SELECT}, {@code UPDATE} or {@code DELETE}
+     */
+    public GenericCriteriaImpl(MetamodelImpl model, Class<T> resultClass, int op) {
+        _model       = model;
+        _resultClass = resultClass;
+        _operation   = op;
+        _delegatorSubquery = null;
+        _aliases           = new HashMap<Selection<?>, String>(); 
+    }
+    
+    
+    /**
+     * Used by a subquery to delegate to this receiver.
+     * 
+     * @param model the metamodel defines the scope of all persistent entity references.
+     * @param delegator the subquery which will delegate to this receiver.
+     */
+    GenericCriteriaImpl(MetamodelImpl model, SubqueryImpl<T> delegator, int op) {
+        _model        = model;
+        _resultClass  = delegator.getJavaType();
+        _operation    = op;
+        _delegatorSubquery = delegator;
+        _aliases           = getAliases();
+    }
+    
+    CommonAbstractCriteria getOwner() {
+    	return _owner;
+    }
+    void setOwner(CommonAbstractCriteria owner) {
+    	_owner = owner;
+    }
+    /**
+     * Gets the ordinal value of the query operation performed by this receiver.
+     * 
+     * @return one of the integers defined in {@link QueryOperations}.
+     */
+    public final int getOperation() {
+    	return _operation;
+    }
+    
+    /**
+     * Gets the metamodel which defines the scope of all persistent entity references.
+     */
+    public MetamodelImpl getMetamodel() {
+        return _model;
+    }
+    
+    /**
+     * Gets the stack of contexts used by this query.
+     */
+    Stack<Context> getContexts() {
+        return _contexts;
+    }
+    
+    //-------------------------------------------------------------------------------
+    //  Projection expressions
+    //-------------------------------------------------------------------------------
+
+    /**
+     * Return the selection of the query
+     * @return the item to be returned in the query result
+     */
+    public Selection<T> getSelection() {
+        return (Selection<T>)_selection;
+    }
+    
+    /**
+     * Gets the selection items of the query as a list
+     * @return the selection items of the query as a list
+     */
+    public List<Selection<?>> getSelectionList() {
+        return Expressions.returnCopy(_selections);
+    }
+
+    /**
+     * Affirms if selection of this query is distinct.
+     */
+    public boolean isDistinct() {
+        return _distinct;
+    }
+    
+    /**
+     * Sets whether this query as distinct.
+     */
+    public CriteriaQuery<T> distinct(boolean distinct) {
+        _distinct = distinct;
+        return this;
+    }
+    /**
+     * Specify the item that is to be returned in the query result.
+     * Replaces the previously specified selection(s), if any.
+     * @param selection  selection specifying the item that
+     *        is to be returned in the query result
+     * @return the modified query
+     */
+    public CriteriaQuery<T> select(Selection<? extends T> selection) {
+        _selection = selection;
+        _selections = new ArrayList<Selection<?>>();
+        _selections.add(selection);
+        return this;
+    }
+
+    /**
+     * Specify the items that are to be returned in the query result.
+     * Replaces the previously specified selection(s), if any.
+     *
+     * The type of the result of the query execution depends on
+     * the specification of the criteria query object as well as the
+     * arguments to the multiselect method as follows:
+     *
+     * If the type of the criteria query is CriteriaQuery<Tuple>,
+     * a Tuple object corresponding to the arguments of the 
+     * multiselect method will be instantiated and returned for 
+     * each row that results from the query execution.
+     *
+     * If the type of the criteria query is CriteriaQuery<X> for
+     * some user-defined class X, then the arguments to the 
+     * multiselect method will be passed to the X constructor and 
+     * an instance of type X will be returned for each row.  
+     * The IllegalStateException will be thrown if a constructor 
+     * for the given argument types does not exist.
+     *
+     * If the type of the criteria query is CriteriaQuery<X[]> for
+     * some class X, an instance of type X[] will be returned for 
+     * each row.  The elements of the array will correspond to the 
+     * arguments of the multiselect method.    The 
+     * IllegalStateException will be thrown if the arguments to the 
+     * multiselect method are not of type X.
+     *
+     * If the type of the criteria query is CriteriaQuery<Object>,
+     * and only a single argument is passed to the multiselect 
+     * method, an instance of type Object will be returned for 
+     * each row.
+     *
+     * If the type of the criteria query is CriteriaQuery<Object>,
+     * and more than one argument is passed to the multiselect 
+     * method, an instance of type Object[] will be instantiated 
+     * and returned for each row.  The elements of the array will
+     * correspond to the arguments to the multiselect method.
+     *
+     * @param selections  expressions specifying the items that
+     *        are returned in the query result
+     * @return the modified query
+     */
+    public CriteriaQuery<T> multiselect(Selection<?>... selections) {
+        _selections = Arrays.asList(selections); // do not telescope
+        _selection  = new CompoundSelections.MultiSelection(_resultClass, selections);
+        return this;
+    }
+
+    public Class<T> getResultType() {
+        return _resultClass;
+    }
+
+    public CriteriaQuery<T> multiselect(List<Selection<?>> list) {
+        return multiselect(list.toArray(new Selection<?>[list.size()]));
+    }
+    
+    boolean isMultiselect() {
+        return _selection instanceof CompoundSelections.MultiSelection;
+    }
+    
+    /**
+     * Affirms if this receiver can select something by default if nothing
+     * has been selected explicitly by the user.
+     * @return
+     */
+    protected boolean isDefaultProjection() {
+        if (_selections == null) {
+            return getRoots().size() == 1 
+               && (getRoot().getModel().getJavaType() == _resultClass ||
+                   _resultClass == Object.class);
+        } 
+        if (_selections.size() != 1) {
+            return false;
+        }
+        Selection<?> sel = _selections.get(0);
+        if (!getRoots().isEmpty() && sel == getRoot()) {
+            return true;
+        }
+        if ((sel instanceof From<?,?>) && ((From<?,?>)sel).isCorrelated()) {
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * Asserts at least one element has been selected or a default selection
+     * is possible.
+     */
+    public void assertSelection() {
+        if (_selection == null && !isDefaultProjection())
+            throw new IllegalStateException(_loc.get("select-undefined").getMessage());
+    }
+    
+    //-------------------------------------------------------------------------------
+    //  FROM clause expressions
+    //-------------------------------------------------------------------------------
+    public Set<Root<?>> getRoots() {
+        return Expressions.returnCopy(_roots);
+    }
+
+    /**
+     * Gets the first root instance.
+     */
+    public Root<?> getRoot() {
+        assertRoot();
+        return _roots.iterator().next();
+    }
+    
+    /**
+     * Asserts at least one root has been set on this receiver.
+     */
+    void assertRoot() {
+        if (_roots == null || _roots.isEmpty())
+            throw new IllegalStateException(_loc.get("root-undefined").getMessage());
+    }
+    
+    /**
+     * Gets the first root
+     * @param mustExist if true at least one root must exist.
+     * @return
+     */
+    Root<?> getRoot(boolean mustExist) {
+        if (mustExist) {
+            return getRoot();
+        }
+        return _roots == null || _roots.isEmpty() ? null : _roots.iterator().next();
+    }
+    
+    /**
+     * Adds a root corresponding to the given entity type.
+     */
+    public <X> RootImpl<X> from(EntityType<X> entity) {
+        RootImpl<X> root = new RootImpl<X>((Types.Entity<X>)entity);
+        addRoot(root);
+        return root;
+    }
+
+    /**
+     * Adds a root corresponding to the given entity type.
+     */
+    public <X> RootImpl<X> from(Class<X> cls) {
+        EntityType<X> entity = _model.entity(cls);
+        if (entity == null)
+            throw new IllegalArgumentException(_loc.get("root-non-entity", cls).getMessage());
+        return from(entity);
+    }
+    
+    /**
+     * Adds a root to this receiver.
+     * @param root
+     */
+    void addRoot(RootImpl<?> root) {
+        if (_roots == null) {
+            _roots = new LinkedHashSet<Root<?>>();
+        }
+        if (_operation != QueryOperations.OP_SELECT && !_roots.isEmpty()) {
+        	throw new IllegalArgumentException(getOperationAsString() + " can not have more than one root");
+        }
+        _roots.add(root);
+    }
+    
+    //-------------------------------------------------------------------------------
+    //  Predicate (WHERE clause) expressions
+    //-------------------------------------------------------------------------------
+    public PredicateImpl getRestriction() {
+        return _where;
+    }
+
+    public CriteriaQuery<T> where(Expression<Boolean> restriction) {
+        invalidateCompilation();
+        if (restriction == null) {
+            _where = null;
+            return this;
+        }
+        _where = (PredicateImpl)restriction;
+        return this;
+    }
+
+    public CriteriaQuery<T> where(Predicate... restrictions) {
+        invalidateCompilation();
+        if (restrictions == null) {
+            _where = null;
+            return this;
+        }
+        _where = new PredicateImpl.And(restrictions);
+        return this;
+    }
+
+
+    //-------------------------------------------------------------------------------
+    //  GROUP BY, HAVING and OREDER BY expressions
+    //-------------------------------------------------------------------------------
+
+    public List<Expression<?>> getGroupList() {
+        return Expressions.returnCopy(_groups);
+    }
+
+    public PredicateImpl getGroupRestriction() {
+        return _having;
+    }
+    
+    /**
+     * Gets the list of ordering elements.
+     * 
+     * @return Empty list if there is no ordering elements.
+     * The returned list if mutable but mutation has no impact on this query.
+     */
+    public List<Order> getOrderList() {
+        return Expressions.returnCopy(_orders);
+    }
+        
+    public CriteriaQuery<T> groupBy(Expression<?>... grouping) {
+    	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) {
+        if (grouping == null) {
+            _groups = null;
+            return this;
+        }
+        _groups = new ArrayList<Expression<?>>();
+        for (Expression<?> e : grouping)
+            _groups.add(e);
+        return this;
+    }
+
+
+    public CriteriaQuery<T> having(Expression<Boolean> restriction) {
+        _having = (PredicateImpl)restriction;
+        return this;
+    }
+
+    public CriteriaQuery<T> having(Predicate... restrictions) {
+        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) {
+        if (orders == null) {
+            _orders = null;
+            return this;
+        }
+        _orders = new ArrayList<Order>();
+        for (Order o : orders) {
+            _orders.add(o);
+        }
+        return this;
+    }
+    
+    public CriteriaQuery<T> orderBy(List<Order> orders) {
+        if (orders == null) {
+            _orders = null;
+            return this;
+        }
+        _orders = new ArrayList<Order>();
+        for (Order o : orders) {
+            _orders.add(o);
+        }
+        return this;
+    }
+    
+
+    //-------------------------------------------------------------------------------
+    //  Bind Parameter handling
+    //-------------------------------------------------------------------------------
+    /**
+     * Registers the given parameter.
+     */
+    /**
+     * Return map where key is the parameter expression itself and value is the expected type.
+     * Empty map if no parameter has been declared. 
+     */
+    public OrderedMap<Object, Class<?>> getParameterTypes() {
+        collectParameters(new CriteriaExpressionVisitor.ParameterVisitor(this));
+        return _params == null ? StoreQuery.EMPTY_ORDERED_PARAMS : _params;
+    }
+    
+    final void registerParameter(ParameterExpressionImpl<?> p) {
+        if (_params == null)
+            _params = new OrderedMap/*<ParameterExpression<?>, Class<?>*/();
+        if (!_params.containsKey(p)) {
+            p.setIndex(_params.size());
+            _params.put(p, p.getJavaType());
+        }
+    }
+    
+    /**
+     * Gets the bound parameters as expressions.
+     * @return empty set if no parameter has been bound.
+     */
+    public final Set<ParameterExpression<?>> getParameters() {
+        collectParameters(new CriteriaExpressionVisitor.ParameterVisitor(this));
+        return _params == null ? Collections.EMPTY_SET : _params.keySet();
+    }
+    
+    /**
+     * Traverse the expression tree to collect all parameter node. 
+     * @param visitor
+     */
+    void collectParameters(CriteriaExpressionVisitor visitor) {
+        if (_compiled)
+            return;
+        if (_where != null) {
+            _where.acceptVisit(visitor);
+        }
+        if (_having != null) {
+            _having.acceptVisit(visitor);
+        }
+        
+        if (_subqueries != null) {
+            for (Subquery<?> subq : _subqueries) {
+                ((SubqueryImpl<?>)subq).getDelegate().collectParameters(visitor);
+            }
+        }
+    }
+
+    //-------------------------------------------------------------------------------
+    //  Subquery
+    //  A query can have zero of more subqueries.
+    //  Also a subquery can use this receiver as a captive.
+    //-------------------------------------------------------------------------------
+    /**
+     * Affirms if this receiver is a captive i.e. working on behalf
+     * of a subquery.
+     */
+    boolean isCaptive() {
+    	return _delegatorSubquery != null;
+    }
+    
+    /**
+     * Gets the subquery, if any, which is delegating to this receiver.
+     */
+    SubqueryImpl<?> getDelegator() {
+        return _delegatorSubquery;
+    }
+    
+    /**
+     * Gets the parent of the subquery S1, if any, which is delegating to
+     * this receiver. If the parent of the subquery itself is another
+     * subquery S2, then gets the captive of S2.
+     * <br><b>Implementation note</b>: Call only when this receiver is captive
+     * @return
+     */
+    private GenericCriteriaImpl<?> getDelegatorParent() {
+    	if (!isCaptive())
+    		throw new IllegalStateException(this + " is not a captive quuery");
+        AbstractQuery<?> parent = _delegatorSubquery.getParent();
+        if (parent instanceof GenericCriteriaImpl) 
+            return ((GenericCriteriaImpl<?>)parent);
+        // parent is a SubqueryImpl    
+        return ((SubqueryImpl<?>)parent).getDelegate();
+    }
+    
+    
+    /**
+     * Create a subquery as a part of this receiver.
+     */
+    public <U> Subquery<U> subquery(Class<U> type) {
+        if (_subqueries == null)
+            _subqueries = new ArrayList<Subquery<?>>();
+        Subquery<U> subquery = new SubqueryImpl<U>(type, this);
+        _subqueries.add(subquery);
+        return subquery;
+    }
+    
+    /**
+     * Gets either this query itself if this is not a captive query for
+     * a subquery. Otherwise gets the parent query of the delegating
+     * subquery.
+     */
+    GenericCriteriaImpl<?> getAncestor() {
+        if (_delegatorSubquery == null)
+            return this;
+        AbstractQuery<?> parent = _delegatorSubquery.getParent();
+        if (parent instanceof GenericCriteriaImpl) 
+            return (GenericCriteriaImpl<?>)parent;
+        // parent is a SubqueryImpl    
+        return ((SubqueryImpl<?>)parent).getDelegate().getAncestor();
+    }
+    
+    //-------------------------------------------------------------------------------
+    // Bridge pattern for kernel query
+    //-------------------------------------------------------------------------------
+    /**
+     * Populate a kernel expression tree by translating the components of this
+     * receiver with the help of the given {@link ExpressionFactory}.
+     */
+    QueryExpressions getQueryExpressions(ExpressionFactory factory) {
+        _contexts = new Stack<Context>();
+        Context context = new Context(null, null, null);
+        _contexts.push(context);
+        return new CriteriaExpressionBuilder().getQueryExpressions(factory, this);
+    }    
+    
+    //-------------------------------------------------------------------------------
+    // AliasContext management
+    //-------------------------------------------------------------------------------
+    
+    /**
+     * Gets the current context.
+     */
+    Context ctx() {
+        return _contexts == null || _contexts.isEmpty() ? null :  _contexts.peek();
+    }
+    
+    /**
+     * Sets the context used by this receiver.
+     * @param contexts
+     */
+    void setContexts(Stack<Context> contexts) {
+        _contexts = contexts;
+    }
+    
+    
+    /**
+     * Gets the aliases defined for this receiver. If this receiver is captive,
+     * then the aliases defined by the ancestor.
+     * @return
+     */
+    public Map<Selection<?>,String> getAliases() {
+        GenericCriteriaImpl<?> c = getAncestor();
+        if (c._aliases == null)
+            c._aliases = new HashMap<Selection<?>, String>();
+        return c._aliases;
+    }
+    
+    
+    /**
+     * Gets the alias of the given node. Creates an automatic alias, if necessary.
+     */
+    public String getAlias(Selection<?> selection) {
+        String alias = selection.getAlias();
+        if (alias != null) {
+            _aliases.put(selection, alias);
+            return alias;
+        }
+        alias = ALIAS_BASE + (++aliasCount);
+        while (_aliases.containsValue(alias))
+            alias = ALIAS_BASE + (++aliasCount);
+        ((SelectionImpl<?>)selection).setAutoAlias(alias);
+        _aliases.put(selection, alias);
+        return _aliases.get(selection);
+    }
+    
+    /**
+     * Register the given variable of given path value against the given node.
+     * If the given node has no alias then an alias is set to the given node.
+     * If the variable or the path has non-null alias, then that alias must
+     * be equal to the alias of the given node. Otherwise, the node alias is set
+     * on the variable and path.  
+     */
+    public void registerVariable(Selection<?> node, Value var, Value path) {
+        if (isRegistered(node)) {
+            return;
+            //throw new RuntimeException(node + " is already bound");
+        }
+        if (!var.isVariable())
+            throw new RuntimeException(var.getClass() + " is not a variable");
+        if (var.getPath() != path)
+            throw new RuntimeException(var + " does not match given " + path + 
+            		" Variable path is " + var.getPath());
+        String alias = getAlias(node);
+        
+        if (!alias.equals(var.getAlias())) {
+            if (var.getAlias() == null)
+                var.setAlias(alias);
+            else
+                throw new RuntimeException("Variable alias " + var.getAlias() + 
+                " does not match expected selection alias " + alias);
+        }
+        if (!alias.equals(path.getAlias())) {
+            if (path.getAlias() == null) 
+                path.setAlias(alias);
+            else
+                throw new RuntimeException("Path alias " + path.getAlias() + 
+                " does not match expected selection alias " + alias);
+        }
+        _variables.put(node, var);
+        _values.put(node, path);
+        _aliases.put(node, alias);
+        // add to context
+        ctx().addSchema(alias, var.getMetaData());
+        ctx().addVariable(alias, var);
+    }
+    
+    /**
+     * Affirms if the given term is a registered variable in this
+     * receiver. If this receiver is captive (i.e working on behalf
+     * of a subquery), then 
+     */
+    public boolean isRegistered(Selection<?> selection) {
+        if (_variables.containsKey(selection))
+            return true;
+        SubqueryImpl<?> delegator = getDelegator();
+        return (delegator == null) ? false : getDelegatorParent().isRegistered(selection);
+    }
+
+    public Value getRegisteredVariable(Selection<?> selection) {
+        Value var = _variables.get(selection);
+        if (var != null)
+            return var;
+        SubqueryImpl<?> delegator = getDelegator();
+        return (delegator == null) ? null : getDelegatorParent().getRegisteredVariable(selection);
+    }
+
+    public Value getRegisteredValue(Selection<?> selection) {
+        Value val = _values.get(selection);
+        if (val != null)
+            return val;
+        SubqueryImpl<?> delegator = getDelegator();
+        return (delegator == null) ? null : getDelegatorParent().getRegisteredValue(selection);
+    }
+
+    /**
+     * Registers a variable for the given root expression.
+     * A root expression is registered only for cross join.  
+     * @param root
+     * @param var
+     */
+    void registerRoot(Root<?> root, Value var) {
+        if (var == null || !var.isVariable())
+            throw new IllegalArgumentException("Attempt to register non-variable " + var);
+        _rootVariables.put(root, var);
+        String alias = var.getName();
+        ctx().addSchema(alias, var.getMetaData());
+        ctx().addVariable(alias, var);
+    }
+    
+    /**
+     * Gets the registered variable for the given root. 
+     */
+    public Value getRegisteredRootVariable(Root<?> root) {
+        Value var = _rootVariables.get(root);
+        if (var != null)
+            return var;
+        SubqueryImpl<?> delegator = getDelegator();
+        return (delegator == null) ? null : getDelegatorParent().getRegisteredRootVariable(root);
+    }
+    
+    void invalidateCompilation() {
+        _compiled = false;
+        _params   = null;
+    }
+    
+    /**
+     * Compiles to verify that at least one root is defined, a selection term is present
+     * and, most importantly, collects all the parameters so that they can be bound to
+     * the executable query. 
+     */
+    public OpenJPACriteriaQuery<T> compile() {
+        if (_compiled)
+            return this;
+        assertRoot();
+        assertSelection();
+        collectParameters(new CriteriaExpressionVisitor.ParameterVisitor(this));
+        _compiled = true;
+        return this;
+    }
+    
+    // ------------------------------------------------------------------------
+    //  Rendering the expression tree as a string
+    // ------------------------------------------------------------------------
+    /**
+     * Returns a JPQL-like string, if this receiver is populated. Otherwise 
+     * returns <code>Object.toString()</code>.
+     */
+    public String toString() {
+        try {
+            return toCQL();
+        } catch (Throwable t) {
+            return super.toString();
+        }
+    }
+    
+    /**
+     * Gets the string representation of the query.
+     */
+    public String toCQL() {
+        StringBuilder buffer = new StringBuilder();
+        render(buffer, _roots, null);
+        return buffer.toString().trim();
+    }
+    
+    void render(StringBuilder buffer, Set<Root<?>> roots, List<Join<?,?>> correlatedJoins) {
+        buffer.append(getOperationAsString()).append(" ");
+        if (isDistinct()) buffer.append(" DISTINCT ");
+        buffer.append(_selection != null ? ((CriteriaExpression)_selection).asProjection(this) : 
+        	getOperation() == QueryOperations.OP_SELECT ? "*" : "");
+        if (getOperation() != QueryOperations.OP_UPDATE) {
+        	buffer.append(" FROM ");
+        } 
+        renderRoots(buffer, roots);
+        if (getOperation() == QueryOperations.OP_UPDATE) {
+        	renderMap(buffer, " SET ", ((CriteriaUpdateImpl)getOwner()).getUpdates());
+        }
+        renderJoins(buffer, correlatedJoins);
+        if (_where != null) {
+            buffer.append(" WHERE ").append(_where.asValue(this));
+        }
+        renderList(buffer, " ORDER BY ", getOrderList());
+        renderList(buffer, " GROUP BY ", getGroupList());
+        if (_having != null) {
+            buffer.append(" HAVING ");
+            buffer.append(_having.asValue(this));
+        }
+    }
+    
+    private void renderList(StringBuilder buffer, String clause, Collection<?> coll) {
+    	if (coll == null || coll.isEmpty())
+    		return;
+    	
+    	buffer.append(clause);
+    	for (Iterator<?> i = coll.iterator(); i.hasNext(); ) {
+    		buffer.append(((CriteriaExpression)i.next()).asValue(this));
+    		if (i.hasNext()) buffer.append(", ");
+    	}
+    }
+    
+    private void renderMap(StringBuilder buffer, String clause, Map<?,?> map) {
+    	if (map == null || map.isEmpty())
+    		return;
+    	
+    	buffer.append(clause);
+    	for (Iterator<?> i = map.keySet().iterator(); i.hasNext(); ) {
+    		CriteriaExpression key = (CriteriaExpression)i.next();
+    		CriteriaExpression value = (CriteriaExpression)map.get(key);
+    		buffer.append(key.asValue(this)).append("=").append(value.asValue(this));
+    		if (i.hasNext()) buffer.append(", ");
+    	}
+    }
+
+    
+    private void renderJoins(StringBuilder buffer, Collection<Join<?,?>> joins) {
+        if (joins == null) return;
+        for (Join j : joins) {
+            buffer.append(((CriteriaExpression)j).asVariable(this)).append(" ");
+            renderJoins(buffer, j.getJoins());
+            renderFetches(buffer, j.getFetches());
+        }
+    }
+    
+    private void renderRoots(StringBuilder buffer, Collection<Root<?>> roots) {
+        if (roots == null) return;
+        int i = 0;
+        for (Root r : roots) {
+            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(" ");
+        }
+    }
+    
+    String getOperationAsString() {
+    	switch (getOperation()) {
+    	case QueryOperations.OP_DELETE: return "DELETE";
+    	case QueryOperations.OP_UPDATE: return "UPDATE";
+    	default: return "SELECT";
+    	}
+    }
+    
+    /**
+     * Compares equal if the other object has the same stringified form.
+     * This equality is important for cacheing the query that uses
+     * the string as the identifier of the query.
+     */
+    public boolean equals(Object other) {
+        if (toString().equals(other.toString()))
+            return true;
+        return false;
+    }
+}

Propchange: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/GenericCriteriaImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java Wed Apr 10 06:09:57 2013
@@ -30,6 +30,7 @@ import javax.persistence.criteria.ListJo
 import javax.persistence.criteria.MapJoin;
 import javax.persistence.criteria.Path;
 import javax.persistence.criteria.PluralJoin;
+import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.SetJoin;
 import javax.persistence.metamodel.Attribute;
 import javax.persistence.metamodel.CollectionAttribute;
@@ -149,7 +150,7 @@ abstract class Joins {
         }
         
         @Override
-        public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> c) {
+        public Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> c) {
             ClassMetaData meta = _member.fmd.getDeclaredTypeMetaData();
             org.apache.openjpa.kernel.exps.Path path = null;
             SubqueryImpl<?> subquery = c.getDelegator();
@@ -174,7 +175,7 @@ abstract class Joins {
         
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, 
-            CriteriaQueryImpl<?> c) {
+            GenericCriteriaImpl<?> c) {
             ClassMetaData meta = _member.fmd.getDeclaredTypeMetaData();
             org.apache.openjpa.kernel.exps.Path path = null;
             SubqueryImpl<?> subquery = c.getDelegator();
@@ -303,6 +304,24 @@ abstract class Joins {
         public StringBuilder asVariable(AliasContext q) {
             return new StringBuilder(" " + joinType + " JOIN ").append(super.asVariable(q));
         }
+
+		@Override
+		public Join<Z, X> on(Expression<Boolean> restriction) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public Join<Z, X> on(Predicate... restrictions) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public Predicate getOn() {
+			// TODO JPA 2.1 Method
+			return null;
+		}
     }
     
     /**
@@ -353,7 +372,7 @@ abstract class Joins {
          * Convert this path to a kernel path (value).
          */
         @Override
-        public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> c) {
+        public Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> c) {
             org.apache.openjpa.kernel.exps.Path path = null;
             SubqueryImpl<?> subquery = c.getDelegator();
             PathImpl<?,?> parent = getInnermostParentPath();
@@ -379,7 +398,7 @@ abstract class Joins {
          */
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, 
-            CriteriaQueryImpl<?> c) {
+            GenericCriteriaImpl<?> c) {
             ClassMetaData meta = getMemberClassMetaData(); 
             org.apache.openjpa.kernel.exps.Path path = null;
             SubqueryImpl<?> subquery = c.getDelegator();
@@ -499,6 +518,25 @@ abstract class Joins {
         public CollectionAttribute<? super Z, E> getModel() {
             return (CollectionAttribute<? super Z, E>)_member;
         }
+
+		@Override
+		public Predicate getOn() {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public CollectionJoin<Z, E> on(Expression<Boolean> restriction) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public CollectionJoin<Z, E> on(Predicate... restrictions) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
     }
     
     /**
@@ -516,6 +554,24 @@ abstract class Joins {
         public SetAttribute<? super Z, E> getModel() {
             return (SetAttribute<? super Z, E>)_member;
         }
+
+		@Override
+		public Predicate getOn() {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public SetJoin<Z, E> on(Expression<Boolean> restriction) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public SetJoin<Z, E> on(Predicate... restrictions) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
     }
     
     /**
@@ -539,6 +595,24 @@ abstract class Joins {
         public Expression<Integer> index() {
             return new Expressions.Index(this);
         }
+
+		@Override
+		public Predicate getOn() {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public ListJoin<Z, E> on(Expression<Boolean> restriction) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public ListJoin<Z, E> on(Predicate... restrictions) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
     }
     
     /**
@@ -592,11 +666,29 @@ abstract class Joins {
                 
         @Override
         public org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, 
-            CriteriaQueryImpl<?> c) {
+            GenericCriteriaImpl<?> c) {
             return (_keyJoin == null) 
                 ? super.toKernelExpression(factory, c)
                 : _keyJoin.toKernelExpression(factory, c);
         }
+
+		@Override
+		public Predicate getOn() {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public MapJoin<Z, K, V> on(Expression<Boolean> restriction) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
+
+		@Override
+		public MapJoin<Z, K, V> on(Predicate... restrictions) {
+			// TODO JPA 2.1 Method
+			return null;
+		}
     }
     
        
@@ -620,7 +712,7 @@ abstract class Joins {
         * 
         */
        @Override
-       public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> c) {
+       public Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> c) {
            Value val = c.getRegisteredVariable(map);
            org.apache.openjpa.kernel.exps.Path path = factory.newPath(val);
            return factory.getKey(path);
@@ -648,7 +740,7 @@ abstract class Joins {
         * 
         */
        @Override
-       public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> c) {
+       public Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> c) {
            Value val = c.getRegisteredVariable(map);
            org.apache.openjpa.kernel.exps.Path path = factory.newPath(val);
            org.apache.openjpa.kernel.exps.Path var = factory.newPath(val);
@@ -679,7 +771,7 @@ abstract class Joins {
     }
     
     @Override
-    public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> c) {
+    public Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> c) {
         return factory.getKey(getParent().toValue(factory, c));
     }
    }

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OpenJPACriteriaQuery.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OpenJPACriteriaQuery.java?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OpenJPACriteriaQuery.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OpenJPACriteriaQuery.java Wed Apr 10 06:09:57 2013
@@ -19,7 +19,6 @@
 package org.apache.openjpa.persistence.criteria;
 
 import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.metamodel.Metamodel;
 
 /**
  * OpenJPA-specific extension to JPA 2.0 Criteria Query API.

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java Wed Apr 10 06:09:57 2013
@@ -86,7 +86,7 @@ class ParameterExpressionImpl<T> extends
     }
     
     @Override
-    public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> q) {
+    public Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> q) {
         Class<?> clzz = getJavaType();
         Object paramKey = _name == null ? _index : _name;
         boolean isCollectionValued  = Collection.class.isAssignableFrom(clzz);

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java Wed Apr 10 06:09:57 2013
@@ -157,7 +157,7 @@ class PathImpl<Z,X> extends ExpressionIm
      * Convert this path to a kernel path.
      */
     @Override
-    public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> q) {
+    public Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> q) {
         if (q.isRegistered(this))
             return q.getRegisteredValue(this);
         org.apache.openjpa.kernel.exps.Path path = null;
@@ -319,4 +319,15 @@ class PathImpl<Z,X> extends ExpressionIm
         Value var = q.getRegisteredVariable(this);
         return asValue(q).append(" ").append(var == null ? "?" : var.getName());
     }
+    
+    public <D extends X> PathImpl<Z,D> downcast(Class<D> down) {
+    	return new Treated<Z,D>(this, down);
+    }
+    
+    class Treated<O,T> extends PathImpl<O,T> {
+
+		protected Treated(PathImpl<O,? super T> original, Class<T> cls) {
+			super(cls);
+		}
+    }
 }

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java Wed Apr 10 06:09:57 2013
@@ -146,7 +146,7 @@ abstract class PredicateImpl extends Exp
     }
     
     @Override
-    org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> q) {
+    org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> q) {
         if (_exps.isEmpty()) {
             return factory.newLiteral(_op == BooleanOperator.AND, Literal.TYPE_BOOLEAN);
         }
@@ -154,7 +154,7 @@ abstract class PredicateImpl extends Exp
     }
     
     @Override
-    org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, CriteriaQueryImpl<?> q) {
+    org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, GenericCriteriaImpl<?> q) {
         if (_exps.isEmpty()) {
             Predicate nil = _op == BooleanOperator.AND ? TRUE() : FALSE();
             return ((PredicateImpl)nil).toKernelExpression(factory, q);

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java Wed Apr 10 06:09:57 2013
@@ -30,6 +30,7 @@ import org.apache.openjpa.kernel.exps.Su
 import org.apache.openjpa.kernel.exps.Value;
 import org.apache.openjpa.persistence.meta.MetamodelImpl;
 import org.apache.openjpa.persistence.meta.Types;
+import org.apache.openjpa.persistence.meta.Types.Entity;
 
 /**
  * A root path without a parent.
@@ -53,7 +54,7 @@ class RootImpl<X> extends FromImpl<X,X> 
         return _entity;
     }
 
-    public void addToContext(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
+    public void addToContext(ExpressionFactory factory, MetamodelImpl model, GenericCriteriaImpl<?> q) {
         String alias = q.getAlias(this);
         Value var = factory.newBoundVariable(alias, AbstractExpressionBuilder.TYPE_OBJECT);
         var.setMetaData(_entity.meta);
@@ -68,7 +69,7 @@ class RootImpl<X> extends FromImpl<X,X> 
      * Convert this path to a kernel path value.
      */
     @Override
-    public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> c) {
+    public Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> c) {
         SubqueryImpl<?> subquery = c.getDelegator();
         Path var = null;
         Value val = null;
@@ -94,7 +95,7 @@ class RootImpl<X> extends FromImpl<X,X> 
      */
     @Override
     public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
-        ExpressionFactory factory, CriteriaQueryImpl<?> c) {
+        ExpressionFactory factory, GenericCriteriaImpl<?> c) {
         Value path = toValue(factory, c);
         Value var = factory.newBoundVariable(c.getAlias(this), 
              _entity.meta.getDescribedType());
@@ -116,5 +117,17 @@ class RootImpl<X> extends FromImpl<X,X> 
     public StringBuilder asVariable(AliasContext q) {
         return new StringBuilder(_entity.getName()).append(" ").append(asValue(q));
     }
+    
+    public <Y extends X> RootImpl<Y> downcastRoot(Class<Y> type) {
+    	return new Treated<Y>(this, ((Types.Entity<X>)getType()).model.entity(type));
+    }
+    
+    public class Treated<Y> extends RootImpl<Y> {
+
+		public Treated(RootImpl<X> original, Entity<Y> type) {
+			super(type);
+		}
+    	
+    }
 
 }

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java Wed Apr 10 06:09:57 2013
@@ -27,6 +27,7 @@ import java.util.concurrent.CopyOnWriteA
 
 import javax.persistence.criteria.AbstractQuery;
 import javax.persistence.criteria.CollectionJoin;
+import javax.persistence.criteria.CommonAbstractCriteria;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Join;
 import javax.persistence.criteria.JoinType;
@@ -65,7 +66,7 @@ import org.apache.openjpa.persistence.me
  * @since 2.0.0
  */
 class SubqueryImpl<T> extends ExpressionImpl<T> implements Subquery<T> {
-    private final AbstractQuery<?> _parent;
+    private final CommonAbstractCriteria _parent;
     private final CriteriaQueryImpl<T> _delegate;
     private final MetamodelImpl  _model;
     private org.apache.openjpa.kernel.exps.Subquery _subq;
@@ -77,7 +78,7 @@ class SubqueryImpl<T> extends Expression
      * @param cls the result type of this subquery
      * @param parent the non-null parent query which itself can be a subquery.
      */
-    SubqueryImpl(Class<T> cls, AbstractQuery<?> parent) {
+    SubqueryImpl(Class<T> cls, CommonAbstractCriteria parent) {
         super(cls);
         _parent = parent;
         if (parent instanceof CriteriaQueryImpl) {
@@ -94,8 +95,14 @@ class SubqueryImpl<T> extends Expression
      * Gets the parent query of this subquery.
      * Can be a query or another subquery.
      */
+    @Override
     public AbstractQuery<?> getParent() {
-        return _parent;
+    	if (_parent instanceof AbstractQuery)
+    		return (AbstractQuery<?>)_parent;
+    	else if (_parent instanceof Subquery && getInnermostParent() instanceof AbstractQuery) 
+    		return (AbstractQuery<?>)_parent;
+    	else 
+    		throw new IllegalStateException(this + " is not a subquery for a select operation");
     }
     
     /**
@@ -279,7 +286,7 @@ class SubqueryImpl<T> extends Expression
      * Convert this path to a kernel path value.
      */
     @Override
-    public Value toValue(ExpressionFactory factory, CriteriaQueryImpl<?> q) {
+    public Value toValue(ExpressionFactory factory, GenericCriteriaImpl<?> q) {
         final boolean subclasses = true;
         CriteriaExpressionBuilder exprBuilder = new CriteriaExpressionBuilder();
         String alias = q.getAlias(this);
@@ -368,4 +375,10 @@ class SubqueryImpl<T> extends Expression
     public StringBuilder asVariable(AliasContext q) {
         return asValue(q);
     }
+
+	@Override
+	public CommonAbstractCriteria getContainingQuery() {
+		// TODO JPA 2.1 Method
+		return _parent;
+	}
 }

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/MetamodelImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/MetamodelImpl.java?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/MetamodelImpl.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/meta/MetamodelImpl.java Wed Apr 10 06:09:57 2013
@@ -112,8 +112,8 @@ public class MetamodelImpl implements Me
      *  @return the metamodel embeddable type
      *  @throws IllegalArgumentException if not an embeddable class
      */
-    public <X> EmbeddableType<X> embeddable(Class<X> clazz) {
-        return (EmbeddableType<X>)find(clazz, _embeddables, EMBEDDABLE);
+    public <X> Types.Embeddable<X> embeddable(Class<X> clazz) {
+        return (Types.Embeddable<X>)find(clazz, _embeddables, EMBEDDABLE);
     }
 
     /**
@@ -122,8 +122,8 @@ public class MetamodelImpl implements Me
      *  @return the metamodel entity type
      *  @throws IllegalArgumentException if not an entity
      */
-    public <X> EntityType<X> entity(Class<X> clazz) {
-        return (EntityType<X>) find(clazz, _entities, ENTITY);
+    public <X> Types.Entity<X> entity(Class<X> clazz) {
+        return (Types.Entity<X>) find(clazz, _entities, ENTITY);
     }
 
     /**

Modified: openjpa/sandboxes/21/openjpa-project/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-project/pom.xml?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-project/pom.xml (original)
+++ openjpa/sandboxes/21/openjpa-project/pom.xml Wed Apr 10 06:09:57 2013
@@ -39,7 +39,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>2.3.0-SNAPSHOT</version>
+        <version>3.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.openjpa</groupId>

Modified: openjpa/sandboxes/21/openjpa-slice/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-slice/pom.xml?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-slice/pom.xml (original)
+++ openjpa/sandboxes/21/openjpa-slice/pom.xml Wed Apr 10 06:09:57 2013
@@ -27,7 +27,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>2.3.0-SNAPSHOT</version>
+        <version>3.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.openjpa</groupId>

Modified: openjpa/sandboxes/21/openjpa-tools/openjpa-fetch-statistics-was/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-tools/openjpa-fetch-statistics-was/pom.xml?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-tools/openjpa-fetch-statistics-was/pom.xml (original)
+++ openjpa/sandboxes/21/openjpa-tools/openjpa-fetch-statistics-was/pom.xml Wed Apr 10 06:09:57 2013
@@ -18,7 +18,7 @@
 	<parent>
 		<groupId>org.apache.openjpa</groupId>
 		<artifactId>openjpa-tools</artifactId>
-		<version>2.3.0-SNAPSHOT</version>
+		<version>3.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>openjpa-fetch-statistics-was</artifactId>

Modified: openjpa/sandboxes/21/openjpa-tools/openjpa-fetch-statistics/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-tools/openjpa-fetch-statistics/pom.xml?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-tools/openjpa-fetch-statistics/pom.xml (original)
+++ openjpa/sandboxes/21/openjpa-tools/openjpa-fetch-statistics/pom.xml Wed Apr 10 06:09:57 2013
@@ -18,7 +18,7 @@
 	<parent>
 		<groupId>org.apache.openjpa</groupId>
 		<artifactId>openjpa-tools</artifactId>
-		<version>2.3.0-SNAPSHOT</version>
+		<version>3.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>openjpa-fetch-statistics</artifactId>

Modified: openjpa/sandboxes/21/openjpa-tools/openjpa-maven-plugin/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-tools/openjpa-maven-plugin/pom.xml?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-tools/openjpa-maven-plugin/pom.xml (original)
+++ openjpa/sandboxes/21/openjpa-tools/openjpa-maven-plugin/pom.xml Wed Apr 10 06:09:57 2013
@@ -27,7 +27,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-tools</artifactId>
-        <version>2.3.0-SNAPSHOT</version>
+        <version>3.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

Modified: openjpa/sandboxes/21/openjpa-tools/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-tools/pom.xml?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-tools/pom.xml (original)
+++ openjpa/sandboxes/21/openjpa-tools/pom.xml Wed Apr 10 06:09:57 2013
@@ -27,7 +27,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>2.3.0-SNAPSHOT</version>
+        <version>3.0-SNAPSHOT</version>
 <!--        <relativePath>../pom.xml</relativePath>-->
     </parent>
 

Modified: openjpa/sandboxes/21/openjpa-xmlstore/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-xmlstore/pom.xml?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-xmlstore/pom.xml (original)
+++ openjpa/sandboxes/21/openjpa-xmlstore/pom.xml Wed Apr 10 06:09:57 2013
@@ -27,7 +27,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>2.3.0-SNAPSHOT</version>
+        <version>3.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.apache.openjpa</groupId>

Modified: openjpa/sandboxes/21/openjpa/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa/pom.xml?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa/pom.xml (original)
+++ openjpa/sandboxes/21/openjpa/pom.xml Wed Apr 10 06:09:57 2013
@@ -28,7 +28,7 @@
     <parent>
         <groupId>org.apache.openjpa</groupId>
         <artifactId>openjpa-parent</artifactId>
-        <version>2.3.0-SNAPSHOT</version>
+        <version>3.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>openjpa</artifactId>

Modified: openjpa/sandboxes/21/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/pom.xml?rev=1466339&r1=1466338&r2=1466339&view=diff
==============================================================================
--- openjpa/sandboxes/21/pom.xml (original)
+++ openjpa/sandboxes/21/pom.xml Wed Apr 10 06:09:57 2013
@@ -34,13 +34,13 @@
     <artifactId>openjpa-parent</artifactId>
     <packaging>pom</packaging>
     <name>OpenJPA Parent POM</name>
-    <description>Apache OpenJPA implementation of JSR-317 JPA 2.0</description>
+    <description>Apache OpenJPA implementation of JSR-317 JPA 2.1</description>
 
     <!--
         Changing this version needs to also be done in all children poms
         See: http://jira.codehaus.org/browse/MNG-624
     -->
-    <version>2.3.0-SNAPSHOT</version>
+    <version>3.0-SNAPSHOT</version>
 
     <properties>
         <openjpa.version>${project.version}</openjpa.version>
@@ -155,6 +155,7 @@
         <module>openjpa-jdbc</module>
         <module>openjpa-persistence</module>
         <module>openjpa-persistence-jdbc</module>
+        <!--  
         <module>openjpa-persistence-locking</module>
         <module>openjpa-xmlstore</module>
         <module>openjpa-slice</module>
@@ -165,6 +166,7 @@
         <module>openjpa-integration</module>
         <module>openjpa-all</module>
         <module>openjpa-tools</module>
+        -->
     </modules>
 
     <profiles>
@@ -485,7 +487,7 @@
             <dependency>
                 <groupId>org.apache.geronimo.specs</groupId>
                 <artifactId>geronimo-jpa_2.0_spec</artifactId>
-                <version>1.1</version>
+                <version>2.1</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.geronimo.specs</groupId>



Mime
View raw message