Please wait. This can take some minutes ...
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.
com.querydsl.jdo.AbstractJDOQuery Maven / Gradle / Ivy
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed 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 com.querydsl.jdo;
import java.io.Closeable;
import java.io.IOException;
import java.util.*;
import javax.annotation.Nullable;
import javax.jdo.JDOUserException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import com.google.common.collect.Lists;
import com.mysema.commons.lang.CloseableIterator;
import com.mysema.commons.lang.IteratorAdapter;
import com.querydsl.core.*;
import com.querydsl.core.support.FetchableSubQueryBase;
import com.querydsl.core.types.*;
/**
* Abstract base class for custom implementations of the {@link JDOQLQuery} interface.
*
* @author tiwe
*
* @param result type
* @param concrete subclass
*/
public abstract class AbstractJDOQuery> extends FetchableSubQueryBase implements JDOQLQuery {
private static final Logger logger = LoggerFactory.getLogger(JDOQuery.class);
private final Closeable closeable = new Closeable() {
@Override
public void close() throws IOException {
AbstractJDOQuery.this.close();
}
};
private final boolean detach;
private List orderedConstants = new ArrayList();
@Nullable
private final PersistenceManager persistenceManager;
private final List queries = new ArrayList(2);
private final JDOQLTemplates templates;
protected final Set fetchGroups = new HashSet();
@Nullable
protected Integer maxFetchDepth;
@Nullable
private FactoryExpression> projection;
public AbstractJDOQuery(@Nullable PersistenceManager persistenceManager) {
this(persistenceManager, JDOQLTemplates.DEFAULT, new DefaultQueryMetadata(), false);
}
@SuppressWarnings("unchecked")
public AbstractJDOQuery(
@Nullable PersistenceManager persistenceManager,
JDOQLTemplates templates,
QueryMetadata metadata, boolean detach) {
super(new JDOQueryMixin(metadata));
this.queryMixin.setSelf((Q) this);
this.templates = templates;
this.persistenceManager = persistenceManager;
this.detach = detach;
}
/**
* Add the fetch group to the set of active fetch groups.
*
* @param fetchGroupName fetch group name
* @return the current object
*/
@Override
public Q addFetchGroup(String fetchGroupName) {
fetchGroups.add(fetchGroupName);
return queryMixin.getSelf();
}
/**
* Close the query and related resources
*/
@Override
public void close() {
for (Query query : queries) {
query.closeAll();
}
}
@Override
public long fetchCount() {
try {
Query query = createQuery(true);
query.setUnique(true);
Long rv = (Long) execute(query, true);
if (rv != null) {
return rv;
} else {
throw new QueryException("Query returned null");
}
} finally {
reset();
}
}
private Expression> getSource() {
return queryMixin.getMetadata().getJoins().get(0).getTarget();
}
private Query createQuery(boolean forCount) {
Expression> source = getSource();
// serialize
JDOQLSerializer serializer = new JDOQLSerializer(getTemplates(), source);
serializer.serialize(queryMixin.getMetadata(), forCount, false);
logQuery(serializer.toString(), serializer.getConstantToLabel());
// create Query
Query query = persistenceManager.newQuery(serializer.toString());
orderedConstants = serializer.getConstants();
queries.add(query);
if (!forCount) {
Expression> projection = queryMixin.getMetadata().getProjection();
if (projection instanceof FactoryExpression) {
this.projection = (FactoryExpression>) projection;
}
if (!fetchGroups.isEmpty()) {
query.getFetchPlan().setGroups(fetchGroups);
}
if (maxFetchDepth != null) {
query.getFetchPlan().setMaxFetchDepth(maxFetchDepth);
}
}
return query;
}
protected void logQuery(String queryString, Map parameters) {
if (logger.isDebugEnabled()) {
String normalizedQuery = queryString.replace('\n', ' ');
MDC.put(MDC_QUERY, normalizedQuery);
MDC.put(MDC_PARAMETERS, String.valueOf(parameters));
logger.debug(normalizedQuery);
}
}
protected void cleanupMDC() {
MDC.remove(MDC_QUERY);
MDC.remove(MDC_PARAMETERS);
}
@SuppressWarnings("unchecked")
private T detach(T results) {
if (results instanceof Collection) {
return (T) persistenceManager.detachCopyAll((Collection>) results);
} else {
return persistenceManager.detachCopy(results);
}
}
private Object project(FactoryExpression> expr, Object row) {
if (row == null) {
return null;
} else if (row.getClass().isArray()) {
return expr.newInstance((Object[]) row);
} else {
return expr.newInstance(new Object[]{row});
}
}
@Nullable
private Object execute(Query query, boolean forCount) {
Object rv;
if (!orderedConstants.isEmpty()) {
rv = query.executeWithArray(orderedConstants.toArray());
} else {
rv = query.execute();
}
if (isDetach()) {
rv = detach(rv);
}
if (projection != null && !forCount) {
if (rv instanceof List) {
List> original = (List>) rv;
rv = Lists.newArrayList();
for (Object o : original) {
((List) rv).add(project(projection, o));
}
} else {
rv = project(projection, rv);
}
}
return rv;
}
@Override
public Q from(EntityPath>... args) {
return queryMixin.from(args);
}
@Override
public Q from(CollectionExpression, U> path, Path alias) {
return queryMixin.from(ExpressionUtils.as((Path) path, alias));
}
public JDOQLTemplates getTemplates() {
return templates;
}
public boolean isDetach() {
return detach;
}
@Override
public CloseableIterator iterate() {
return new IteratorAdapter(fetch().iterator(), closeable);
}
@Override
public List fetch() {
try {
Object rv = execute(createQuery(false), false);
@SuppressWarnings("unchecked") // Compile time checking of user code mandates it to be T
List result = rv instanceof List ? (List) rv : Collections.singletonList((T) rv);
return result;
} finally {
reset();
}
}
@Override
public QueryResults fetchResults() {
try {
Query countQuery = createQuery(true);
countQuery.setUnique(true);
countQuery.setResult("count(this)");
long total = (Long) execute(countQuery, true);
if (total > 0) {
QueryModifiers modifiers = queryMixin.getMetadata().getModifiers();
Query query = createQuery(false);
return new QueryResults((List) execute(query, false), modifiers, total);
} else {
return QueryResults.emptyResults();
}
} finally {
reset();
}
}
private void reset() {
cleanupMDC();
}
/**
* Set the maximum fetch depth when fetching.
* A value of 0 has no meaning and will throw a {@link JDOUserException}.
* A value of -1 means that no limit is placed on fetching.
* A positive integer will result in that number of references from the
* initial object to be fetched.
*
* @param depth fetch depth
* @return the current object
*/
@Override
public Q setMaxFetchDepth(int depth) {
maxFetchDepth = depth;
return queryMixin.getSelf();
}
@Override
public String toString() {
if (!queryMixin.getMetadata().getJoins().isEmpty()) {
Expression> source = getSource();
JDOQLSerializer serializer = new JDOQLSerializer(getTemplates(), source);
serializer.serialize(queryMixin.getMetadata(), false, false);
return serializer.toString().trim();
} else {
return super.toString();
}
}
@Nullable
@Override
public T fetchOne() {
if (getMetadata().getModifiers().getLimit() == null) {
limit(2);
}
try {
Query query = createQuery(false);
Object rv = execute(query, false);
if (rv instanceof List) {
@SuppressWarnings("unchecked") // Compile time checking of user code mandates this
List list = (List) rv;
if (!list.isEmpty()) {
if (list.size() > 1) {
throw new NonUniqueResultException();
}
return list.get(0);
} else {
return null;
}
} else {
// it is not a List typed expression
@SuppressWarnings("unchecked") // Compile time checking of user code mandates this
T result = (T) rv;
return result;
}
} finally {
reset();
}
}
}