Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.kernel;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.datacache.DataCache;
import org.apache.openjpa.kernel.exps.AbstractExpressionVisitor;
import org.apache.openjpa.kernel.exps.AggregateListener;
import org.apache.openjpa.kernel.exps.Constant;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.ExpressionParser;
import org.apache.openjpa.kernel.exps.FilterListener;
import org.apache.openjpa.kernel.exps.InMemoryExpressionFactory;
import org.apache.openjpa.kernel.exps.Path;
import org.apache.openjpa.kernel.exps.QueryExpressions;
import org.apache.openjpa.kernel.exps.Resolver;
import org.apache.openjpa.kernel.exps.StringContains;
import org.apache.openjpa.kernel.exps.Subquery;
import org.apache.openjpa.kernel.exps.Val;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.kernel.exps.WildcardMatch;
import org.apache.openjpa.lib.rop.ListResultObjectProvider;
import org.apache.openjpa.lib.rop.RangeResultObjectProvider;
import org.apache.openjpa.lib.rop.ResultObjectProvider;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.OrderedMap;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.UnsupportedException;
import org.apache.openjpa.util.UserException;
/**
* Implementation of an expression-based query, which can handle
* String-based query expressions such as JPQL and JDOQL.
* This implementation is suitable for in-memory operation.
* Override the following methods to also support datastore operation:
*
*
Override {@link #supportsDataStoreExecution} to return
* true.
*
Override {@link #executeQuery}, {@link #executeDelete}, and
* {@link #executeUpdate} to execute the query against the data store.
* Keep in mind that the parameters passed to this method might be in use
* by several threads in different query instances. Thus components like
* the expression factory must either be thread safe, or this method must
* synchronize on them.
*
Override {@link #getDataStoreActions} to return a representation of
* the actions that will be taken on the data store. For use in visual
* tools.
*
Override {@link #getExpressionFactory} to return a factory for creating
* expressions in the datastore's language. The factory must be cachable.
*
*
* @author Abe White
*/
public class ExpressionStoreQuery
extends AbstractStoreQuery {
private static final long serialVersionUID = 1L;
private static final Localizer _loc = Localizer.forPackage
(ExpressionStoreQuery.class);
// maintain support for a couple of deprecated extensions
private static final FilterListener[] _listeners = new FilterListener[]{
new StringContains(), new WildcardMatch(),
};
protected final ExpressionParser _parser;
protected transient Object _parsed;
/**
* Construct a query with a parser for the language.
*/
public ExpressionStoreQuery(ExpressionParser parser) {
_parser = parser;
}
/**
* Resolver used in parsing.
*/
public Resolver getResolver() {
return new Resolver() {
@Override
public Class classForName(String name, String[] imports) {
return ctx.classForName(name, imports);
}
@Override
public FilterListener getFilterListener(String tag) {
return ctx.getFilterListener(tag);
}
@Override
public AggregateListener getAggregateListener(String tag) {
return ctx.getAggregateListener(tag);
}
@Override
public OpenJPAConfiguration getConfiguration() {
return ctx.getStoreContext().getConfiguration();
}
@Override
public QueryContext getQueryContext() {
return ctx;
}
};
}
/**
* Allow direct setting of parsed state for facades that do parsing.
* The facade should call this method twice: once with the query string,
* and again with the parsed state.
*/
@Override
public boolean setQuery(Object query) {
_parsed = query;
return true;
}
@Override
public FilterListener getFilterListener(String tag) {
for (FilterListener listener : _listeners)
if (listener.getTag().equals(tag))
return listener;
return null;
}
@Override
public Object newCompilation() {
if (_parsed != null)
return _parsed;
return _parser.parse(ctx.getQueryString(), this);
}
@Override
public Object getCompilation() {
return _parsed;
}
@Override
public void populateFromCompilation(Object comp) {
_parser.populate(comp, this);
}
@Override
public void invalidateCompilation() {
_parsed = null;
}
@Override
public boolean supportsInMemoryExecution() {
return true;
}
@Override
public Executor newInMemoryExecutor(ClassMetaData meta, boolean subs) {
return new InMemoryExecutor(this, meta, subs, _parser,
ctx.getCompilation(), new InMemoryExpressionFactory());
}
@Override
public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs) {
return new DataStoreExecutor(this, meta, subs, _parser,
ctx.getCompilation());
}
////////////////////////
// Methods for Override
////////////////////////
/**
* Execute the given expression against the given candidate extent.
*
* @param ex current executor
* @param base the base type the query should match
* @param types the independent candidate types
* @param subclasses true if subclasses should be included in the results
* @param facts the expression factory used to build the query for
* each base type
* @param parsed the parsed query values
* @param params parameter values, or empty array
* @param range result range
* @return a provider for matching objects
*/
protected ResultObjectProvider executeQuery(Executor ex,
ClassMetaData base, ClassMetaData[] types, boolean subclasses,
ExpressionFactory[] facts, QueryExpressions[] parsed, Object[] params,
Range range) {
throw new UnsupportedException();
}
/**
* Execute the given expression against the given candidate extent
* and delete the instances.
*
* @param ex current executor
* @param base the base type the query should match
* @param types the independent candidate types
* @param subclasses true if subclasses should be included in the results
* @param facts the expression factory used to build the query for
* each base type
* @param parsed the parsed query values
* @param params parameter values, or empty array
* @return a number indicating the number of instances deleted,
* or null to execute the delete in memory
*/
protected Number executeDelete(Executor ex, ClassMetaData base,
ClassMetaData[] types, boolean subclasses, ExpressionFactory[] facts,
QueryExpressions[] parsed, Object[] params) {
return null;
}
/**
* Execute the given expression against the given candidate extent
* and updates the instances.
*
* @param ex current executor
* @param base the base type the query should match
* @param types the independent candidate types
* @param subclasses true if subclasses should be included in the results
* @param facts the expression factory used to build the query for
* each base type
* @param parsed the parsed query values
* @param params parameter values, or empty array
* @return a number indicating the number of instances updated,
* or null to execute the update in memory.
*/
protected Number executeUpdate(Executor ex, ClassMetaData base,
ClassMetaData[] types, boolean subclasses, ExpressionFactory[] facts,
QueryExpressions[] parsed, Object[] params) {
return null;
}
/**
* Return the commands that will be sent to the datastore in order
* to execute the query, typically in the database's native language.
*
* @param base the base type the query should match
* @param types the independent candidate types
* @param subclasses true if subclasses should be included in the results
* @param facts the expression factory used to build the query for
* each base type
* @param parsed the parsed query values
* @param params parameter values, or empty array
* @param range result range
* @return a textual description of the query to execute
*/
protected String[] getDataStoreActions(ClassMetaData base,
ClassMetaData[] types, boolean subclasses, ExpressionFactory[] facts,
QueryExpressions[] parsed, Object[] params, Range range) {
return StoreQuery.EMPTY_STRINGS;
}
/**
* Return the assignable types for the given metadata whose expression
* trees must be compiled independently.
*/
protected ClassMetaData[] getIndependentExpressionCandidates
(ClassMetaData type, boolean subclasses) {
return new ClassMetaData[]{ type };
}
/**
* Return an {@link ExpressionFactory} to use to create an expression to
* be executed against an extent. Each factory will be used to compile
* one filter only. The factory must be cachable.
*/
protected ExpressionFactory getExpressionFactory(ClassMetaData type) {
throw new UnsupportedException();
}
/**
* Provides support for queries that hold query information
* in a {@link QueryExpressions} instance.
*
* @author Marc Prud'hommeaux
*/
public static abstract class AbstractExpressionExecutor
extends AbstractExecutor
implements Executor {
/**
* Return the query expressions for one candidate type, or die if none.
*/
private QueryExpressions assertQueryExpression() {
QueryExpressions[] exp = getQueryExpressions();
if (exp == null || exp.length < 1)
throw new InvalidStateException(_loc.get("no-expressions"));
return exp[0];
}
/**
* Throw proper exception if given value is a collection/map/array.
*/
protected void assertNotContainer(Value val, StoreQuery q) {
// variables represent container elements, not the container itself
if (val.isVariable())
return;
Class> type;
if (val instanceof Path) {
FieldMetaData fmd = ((Path) val).last();
type = (fmd == null) ? val.getType() : fmd.getDeclaredType();
} else
type = val.getType();
switch (JavaTypes.getTypeCode(type)) {
case JavaTypes.ARRAY:
case JavaTypes.COLLECTION:
case JavaTypes.MAP:
throw new UserException(_loc.get("container-projection",
q.getContext().getQueryString()));
}
}
@Override
public final void validate(StoreQuery q) {
QueryExpressions exps = assertQueryExpression();
ValidateGroupingExpressionVisitor.validate(q.getContext(), exps);
}
@Override
public void getRange(StoreQuery q, Object[] params, Range range) {
QueryExpressions exps = assertQueryExpression();
if (exps.range.length == 0)
return;
if (exps.range.length == 2
&& exps.range[0] instanceof Constant
&& exps.range[1] instanceof Constant) {
try {
range.start = ((Number) ((Constant) exps.range[0]).
getValue(params)).longValue();
range.end = ((Number) ((Constant) exps.range[1]).
getValue(params)).longValue();
return;
} catch (ClassCastException | NullPointerException cce) {
// fall through to exception below
}
}
throw new UserException(_loc.get("only-range-constants",
q.getContext().getQueryString()));
}
@Override
public final Class> getResultClass(StoreQuery q) {
return assertQueryExpression().resultClass;
}
@Override
public final ResultShape> getResultShape(StoreQuery q) {
return assertQueryExpression().shape;
}
@Override
public final boolean[] getAscending(StoreQuery q) {
return assertQueryExpression().ascending;
}
@Override
public final String getAlias(StoreQuery q) {
return assertQueryExpression().alias;
}
@Override
public final String[] getProjectionAliases(StoreQuery q) {
return assertQueryExpression().projectionAliases;
}
@Override
public Class>[] getProjectionTypes(StoreQuery q) {
return null;
}
@Override
public final int getOperation(StoreQuery q) {
return assertQueryExpression().operation;
}
@Override
public final boolean isAggregate(StoreQuery q) {
return assertQueryExpression().isAggregate();
}
@Override
public final boolean isDistinct(StoreQuery q) {
return assertQueryExpression().isDistinct();
}
@Override
public final boolean hasGrouping(StoreQuery q) {
return assertQueryExpression().grouping.length > 0;
}
@Override
public final OrderedMap