com.buschmais.xo.impl.query.XOQueryImpl Maven / Gradle / Ivy
The newest version!
package com.buschmais.xo.impl.query;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.*;
import com.buschmais.xo.api.Query;
import com.buschmais.xo.api.ResultIterator;
import com.buschmais.xo.api.XOException;
import com.buschmais.xo.api.XOTransaction;
import com.buschmais.xo.api.annotation.Flush;
import com.buschmais.xo.api.metadata.type.DatastoreEntityMetadata;
import com.buschmais.xo.api.metadata.type.DatastoreRelationMetadata;
import com.buschmais.xo.impl.SessionContext;
import com.buschmais.xo.impl.plugin.QueryLanguagePluginRepository;
import com.buschmais.xo.impl.transaction.TransactionalResultIterator;
import com.buschmais.xo.spi.datastore.DatastoreQuery;
import com.buschmais.xo.spi.datastore.DatastoreSession;
import com.buschmais.xo.spi.plugin.QueryLanguagePlugin;
import com.buschmais.xo.spi.session.InstanceManager;
import static java.util.Comparator.comparing;
/**
* Implementation of a {@link com.buschmais.xo.api.Query}.
*
* @param
* The result type.
* @param
* The query language type.
* @param
* The query expression type.
* @param
* The entity type.
* @param
* The relation type.
*/
public class XOQueryImpl implements Query {
private Class extends Annotation> queryLanguage = null;
private Boolean flush = null;
private final QE expression;
private final SessionContext, Entity, ?, ?, ?, Relation, ?, ?, ?> sessionContext;
private final QueryLanguagePluginRepository queryLanguagePluginManager;
private final Class> returnType;
private final Collection extends Class>> returnTypes;
private final InstanceManager, Entity> entityInstanceManager;
private final InstanceManager, Relation> relationInstanceManager;
private Map parameters = null;
public XOQueryImpl(SessionContext, Entity, ?, ?, ?, Relation, ?, ?, ?> sessionContext, QE expression, Class> returnType,
Collection extends Class>> returnTypes) {
this.sessionContext = sessionContext;
this.entityInstanceManager = sessionContext.getEntityInstanceManager();
this.relationInstanceManager = sessionContext.getRelationInstanceManager();
this.queryLanguagePluginManager = sessionContext.getPluginRepositoryManager()
.getPluginManager(QueryLanguagePlugin.class);
this.expression = expression;
this.returnType = returnType;
this.returnTypes = returnTypes;
}
public XOQueryImpl(SessionContext, Entity, ?, ?, ?, Relation, ?, ?, ?> sessionContext, QE expression) {
this(sessionContext, expression, null, Collections.emptyList());
}
public XOQueryImpl(SessionContext, Entity, ?, ?, ?, Relation, ?, ?, ?> sessionContext, QE expression, Class> returnType) {
this(sessionContext, expression, returnType, Collections.emptyList());
}
@Override
public Query using(Class extends Annotation> queryLanguage) {
this.queryLanguage = queryLanguage;
return sessionContext.getInterceptorFactory()
.addInterceptor(this, Query.class);
}
@Override
public Query withParameter(String name, Object value) {
if (parameters == null) {
parameters = new HashMap<>();
}
Object oldValue = parameters.put(name, convertParameter(value));
if (oldValue != null) {
throw new XOException("Parameter '" + name + "' has already been assigned to value '" + value + "'.");
}
return sessionContext.getInterceptorFactory()
.addInterceptor(this, Query.class);
}
@Override
public Query withParameters(Map parameters) {
if (parameters == null) {
throw new XOException("Parameters must not be null.");
}
if (this.parameters != null) {
throw new XOException("Parameters have already been assigned: " + parameters);
}
Map convertedParameters = new HashMap<>(parameters.size(), 1);
for (Map.Entry parameterEntry : parameters.entrySet()) {
String name = parameterEntry.getKey();
Object value = parameterEntry.getValue();
value = convertParameter(value);
convertedParameters.put(name, value);
}
this.parameters = convertedParameters;
return sessionContext.getInterceptorFactory()
.addInterceptor(this, Query.class);
}
@Override
public Query flush(boolean flush) {
this.flush = flush;
return this;
}
@Override
public Result execute() {
DatastoreSession, Entity, ? extends DatastoreEntityMetadata>, ?, ?, Relation, ? extends DatastoreRelationMetadata>, ?, ?> datastoreSession = sessionContext.getDatastoreSession();
if (queryLanguage == null) {
queryLanguage = datastoreSession.getDefaultQueryLanguage();
}
DatastoreQuery query;
QueryLanguagePlugin queryLanguagePlugin = (QueryLanguagePlugin) queryLanguagePluginManager.get(queryLanguage);
if (queryLanguagePlugin != null) {
query = queryLanguagePlugin.createQuery(sessionContext.getDatastoreSession());
} else {
query = (DatastoreQuery) sessionContext.getDatastoreSession()
.createQuery(queryLanguage);
}
Map effectiveParameters = parameters != null ? parameters : Collections.emptyMap();
ResultIterator