All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ioc.commons.utils.jdo.JdoQueryHelper Maven / Gradle / Ivy

package org.ioc.commons.utils.jdo;

import java.util.ArrayList;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

/**
 * A JDO Query class which helps you to build JDO queries easily.
 * 
 * Usage examples:
 * 
    *
  • List example: * *
     * 
     * JdoQueryHelper jdh = JdoQueryHelper.newQuery(pm, MyElementCollection.class);
     * 
     * jdh.andParams("groupTarget.groupId=={0}", groupId);
     * jdh.andParams("capability=={0}", capability);
     * 
     * List<ElementCollection> collections = (List<ElementCollection>) jdh.execute();
     * 
     * 
    * *
  • *
  • Count example: * *
     * 
     * JdoQueryHelper qh = JdoQueryHelper.newQuery(pm, MyElement.class);
     * 
     * qh.andParams("fromDate>{0}", lastAccess);
     * qh.andParams("groupTarget=={0}", group);
     * qh.andParams("capabilityNewsType=={0}", capabilityNewsType);
     * 
     * qh.setResult("count(this)");
     * 
     * Number result = (Number) qh.execute();
     * 
     * long newsCount = (result != null) ? result.longValue() : 0;
     *  
     * 
     * 
    * *
  • *
  • Delete example: * *
     * 
     * JdoQueryHelper qH = JdoQueryHelper.newQuery(pm, Category.class);
     * 
     * Calendar before = Calendar.getInstance();
     * before.add(Calendar.DAY_OF_MONTH, -daysForConsideringUnused);
     * qH.andParams("fromDate < {0}", before.getTime());
     * qH.and("groups.isEmpty()");
     * 
     * return qH.deletePersistentAll();
     * 
     * 
    * *
  • *
  • List range (pagination): * *
     * 
     * JdoQueryHelper qh = JdoQueryHelper.newQuery(pm, MyElement.class);
     * 
     * qh.andParams("fromDate>{0}", lastAccess);
     * qh.andParams("groupTarget=={0}", group);
     * qh.andParams("capabilityNewsType=={0}", capabilityNewsType);
     * 
     * qh.setResult("count(this)");
     * Number total = (Number) qh.execute();
     * 
     * long newsCount = (total != null) ? total.longValue() : 0;
     * 
     * qh.setResult(null);
     * qh.setOrdering("capabilityNewsType asc, fromDate desc");
     * 
     * qh.setRange(rangeStart, rangeStart + rangeLength);
     * 
     * List<MyElement> partList = (List<MyElement>) qh.execute();
     * 
     * 
    * *
  • *
  • And, or and parenthesis usage: * *
     * 
     * JdoQueryHelper qh = JdoQueryHelper.newQuery(pm, MyElement.class);
     * 
     * Group group = userGroup.getGroup();
     * 
     * qh.andParams("groupTarget=={0}", group);
     * 
     * qh.and();
     * 
     * qh.openParenthesis();
     * 
     * for (UserGroupCapability capabilityInfo : capabilitiesInfo) {
     * 	Date lastAccess = capabilityInfo.getLastAccess();
     * 	Capability capability = capabilityInfo.getCapability();
     * 	Set<CapabilityNewsType> capabilityNewsTypes = capability.getCapabilityNewsTypes();
     * 
     * 	if (capabilityNewsTypes != null && !capabilityNewsTypes.isEmpty()) {
     * 		for (CapabilityNewsType capabilityNewsType : capabilityNewsTypes) {
     * 			qh.or();
     * 			qh.openParenthesis();
     * 	
     * 			qh.andParams("fromDate>{0}", lastAccess);
     * 			qh.andParams("capabilityNewsType=={0}", capabilityNewsType);
     * 	
     * 			qh.closeParenthesis();
     * 		}
     * 	}
     * }
     * 
     * qh.closeParenthesis();
     * 
     * qh.setResult("count(this)");
     * Number total = (Number) qh.execute();
     * 
     * long newsCount = (total != null) ? total.longValue() : 0; *
     * 
     * 
    *
  • *
* * @see #andSubquery(String, JdoQueryHelper, Class, String, String) * @author Jesús Lunar Pérez */ public class JdoQueryHelper { private static int nextId = 0; private StringBuffer filter = new StringBuffer(); private StringBuffer declaredParameters = new StringBuffer(); private StringBuffer declaredVariables = new StringBuffer(); private List values = new ArrayList(); private List paramNames = new ArrayList(); private List subqueryRefs; private Query q; private int closed; private int open; private boolean processed; private int id; private JdoQueryHelper(Query query) { this.q = query; this.id = nextId++; } public synchronized JdoQueryHelper openParenthesis() { this.processed = false; this.open++; filter.append("("); return this; } public synchronized JdoQueryHelper closeParenthesis() { this.processed = false; if (filter.toString().endsWith(" || ") || filter.toString().endsWith(" && ")) { /* * Elimina los últimos || o && */ filter.setLength(filter.length() - 4); } /* * Sólo lo cierra si estaba abierto sin haber sido cerrado y si no se va * a quedar vacío tal que () */ if (this.open > this.closed) { filter.append(")"); this.closed++; } if (filter.toString().endsWith("()")) { filter.setLength(filter.length() - 2); } return this; } private String getFilter() { if (filter.toString().endsWith(" || ") || filter.toString().endsWith(" && ")) { /* * Elimina los últimos || o && */ filter.setLength(filter.length() - 4); } if (filter.indexOf(" || ") == 0 || filter.indexOf(" && ") == 0) { filter.delete(0, 4); } filter = new StringBuffer(filter.toString().replaceAll("\\Q( || \\E", "(").replaceAll("\\Q( && \\E", "(")); return filter.toString(); } private String getDeclaredParameters() { if (declaredParameters.toString().endsWith(", ")) { declaredParameters.setLength(declaredParameters.length() - 2); } return declaredParameters.toString(); } private String getDeclaredVariables() { if (declaredVariables.toString().endsWith(", ")) { declaredVariables.setLength(declaredVariables.length() - 2); } return declaredVariables.toString(); } /** * Adds an "OR" operator plus a condition in the JDO query * * @param parameterizedString * Parameterized query using same format as {@link String#format(String, Object...)}} * @param args Args according to parametrizedString * @return This instance */ public synchronized JdoQueryHelper or(String parameterizedString, Object... args) { this.processed = false; filter.append(" || ").append(String.format(parameterizedString, args)); return this; } /** * Adds an "AND" operator plus a condition in the JDO query * * @param parameterizedString * Parameterized query using same format as {@link String#format(String, Object...)}} * @param args Args according to parametrizedString * @return This instance */ public synchronized JdoQueryHelper and(String parameterizedString, Object... args) { this.processed = false; filter.append(" && ").append(String.format(parameterizedString, args)); return this; } /** * Adds and "AND" operator in JDO query * * @return This instance */ public synchronized JdoQueryHelper and() { this.processed = false; filter.append(" && "); return this; } /** * Adds and "OR" operator in JDO query * * @return This instance */ public synchronized JdoQueryHelper or() { this.processed = false; filter.append(" || "); return this; } /** * Adds an "AND" operator plus a condition which contains parameters in the JDO query * * @param parameterizedString * Parameterized query using same format as {@link String#format(String, Object...)}} * @param args Args according to parametrizedString * @return This instance */ public synchronized JdoQueryHelper andParams(String parameterizedString, Object... args) { this.processed = false; Object[] params = appendParams(args); filter.append(" && ").append(String.format(parameterizedString, params)); return this; } /** * * @param parameterizedString * Parameterized query using same format as {@link String#format(String, Object...)}} * @param args Args according to parametrizedString * @return This instance */ public synchronized JdoQueryHelper orParams(String parameterizedString, Object... args) { this.processed = false; Object[] params = appendParams(args); filter.append(" || ").append(String.format(parameterizedString, params)); return this; } /** * * @param parameterizedString * Parameterized query using same format as {@link String#format(String, Object...)}} * @param args Args according to parametrizedString * @return This instance */ public synchronized JdoQueryHelper params(String parameterizedString, Object... args) { this.processed = false; Object[] params = appendParams(args); filter.append(String.format(parameterizedString, params)); return this; } private String[] appendParams(Object... args) { String[] params = null; if (args != null) { params = new String[args.length]; for (int i = 0; i < args.length; i++) { params[i] = String.format("arg%dParam_%d_", values.size(), this.id); paramNames.add(params[i]); values.add(args[i]); declaredParameters.append(String.format("%s %s, ", (args[i] != null) ? args[i].getClass().getName() : Object.class.getName(), params[i])); } } return params; } protected Object[] getValuesArray() { return this.values.toArray(); } /** * Genera y devuelve la consulta resultante. A partir de este punto la * consulta ya no será modificada más. Sucesivas llamadas a este método * devolveran la query generada la primera vez que se invocó. * * @return Query resultante. */ protected Query flushQuery() { if (!this.processed) { this.processed = true; q.setFilter(this.getFilter()); q.declareParameters(this.getDeclaredParameters()); q.declareVariables(this.getDeclaredVariables()); } return q; } /** * It gets a new instance for a {@link JdoQueryHelper} for query a class1 domain class using pm {@link PersistenceManager} * * @param pm Persistence manager to be used * @param class1 Domain class for the query * @return An instance for {@link JdoQueryHelper} */ public static JdoQueryHelper newQuery(PersistenceManager pm, Class class1) { JdoQueryHelper qh = new JdoQueryHelper(pm.newQuery(class1)); return qh; } /** * It adds a query which data source is given by a property (usually a list) * from the external query (fromOuterProperty parameter) * * The result of this query is stored in var specified by * subQueryResultVariableName parameter. * * Usage:

JdoQueryHelper qMaxDate = JdoQueryHelper.newQuery(pm, MyElement.class);

MyElementFilter filter = new MyElementFilter();

filter.setCapability(myElement.getCapability());

qMaxDate.setResult("max(this.fromDate)");

JdoQueryHelper qLastElement = JdoQueryHelper.newQuery(pm, MyElement.class);

qLastElement.andFilter(qMaxDate);

qLastElement.andSubquery("fromDate==fromDateVar", qMaxDate, Date.class, "fromDateVar", "this");

List<MyElement> result = (List<MyElement>) qLastElement.execute();
* * @param parameterizedString * Parameterized query using same format as {@link String#format(String, Object...)} * @param subQuery * Subquery which is appended * @param subQueryResultVariableClass * Data type of var which is passed as fromOuterProperty * parameter. Subquery must result into the same data type. * @param subQueryResultVariableName * Var which is going to store the subquery result. * @param fromOuterProperty * Data source used to get data from subquery. * @return This JdoQueryHelper instance. */ public synchronized JdoQueryHelper andSubquery(String parameterizedString, JdoQueryHelper subQuery, Class subQueryResultVariableClass, String subQueryResultVariableName, String fromOuterProperty) { this.processed = false; List refList = new ArrayList(); String varDeclaration = String.format("%s %s", subQueryResultVariableClass.getName(), subQueryResultVariableName); appendDeclaredVariables(varDeclaration); filter.append(" && ").append(String.format(parameterizedString, subQueryResultVariableName)); appendDeclaredParameters(subQuery.declaredParameters.toString()); appendDeclaredVariables(subQuery.declaredVariables.toString()); values.addAll(subQuery.values); refList.addAll(subQuery.paramNames); if (subQuery.subqueryRefs != null) { refList.addAll(subQuery.subqueryRefs); } q.addSubquery(subQuery.flushQuery(), varDeclaration, fromOuterProperty, (refList != null) ? refList.toArray(new String[refList.size()]) : null); return this; } public synchronized JdoQueryHelper andSubqueryRef(/*String parameterizedString, */Class paramClass, String paramName, String outterQueryRef) { this.processed = false; paramNames.add(paramName); declaredParameters.append(String.format("%s %s, ", paramClass.getName(), paramName)); if (subqueryRefs == null) { subqueryRefs = new ArrayList(); } subqueryRefs.add(outterQueryRef); return this; } @Override public String toString() { return String.format("\nfilter: %s\ndeclaredParameters: %s\ndeclaredVariables: %s\nvalues: %s", filter, declaredParameters, declaredVariables, values); } public void setResult(String result) { flushQuery(); q.setResult(result); } public Object execute() { flushQuery(); return q.executeWithArray(this.getValuesArray()); } public void setOrdering(String ordering) { flushQuery(); q.setOrdering(ordering); } public void setRange(long rangeStart, long rangeEnd) { flushQuery(); q.setRange(rangeStart, rangeEnd); } public long deletePersistentAll() { flushQuery(); return q.deletePersistentAll(this.getValuesArray()); } /** * Merge another query parameters into this. * * @param anotherQuery Another query. */ public void andFilter(JdoQueryHelper anotherQuery) { String otherQueryFilter = changeParamId(anotherQuery.getFilter(), anotherQuery.id, this.id); String otherDeclaredParameters = changeParamId(anotherQuery.declaredParameters.toString(), anotherQuery.id, this.id); String otherDeclaredVariables = changeParamId(anotherQuery.declaredVariables.toString(), anotherQuery.id, this.id); this.and(otherQueryFilter); appendDeclaredParameters(otherDeclaredParameters); appendDeclaredVariables(otherDeclaredVariables); values.addAll(anotherQuery.values); paramNames.addAll(anotherQuery.paramNames); if (anotherQuery.subqueryRefs != null) { if (subqueryRefs == null) { subqueryRefs = new ArrayList(); } subqueryRefs.addAll(anotherQuery.subqueryRefs); } } private String changeParamId(String filterText, int idSrc, int idDst) { String regex = String.format("\\QParam_%d_\\E", idSrc); String replacement = String.format("Param_%d_", idDst); String replaced = filterText.replaceAll(regex, replacement); return replaced; } private void appendDeclaredVariables(String otherDeclaredVariables) { if (declaredVariables.length() > 0 && !otherDeclaredVariables.trim().startsWith(",") && !declaredVariables.toString().trim().endsWith(",")) { declaredVariables.append(", "); } declaredVariables.append(otherDeclaredVariables); } private void appendDeclaredParameters(String otherDeclaredParameters) { if (declaredParameters.length() > 0 && !otherDeclaredParameters.trim().startsWith(",") && !declaredParameters.toString().trim().endsWith(",")) { declaredParameters.append(", "); } declaredParameters.append(otherDeclaredParameters); } public void setUnique(boolean unique) { q.setUnique(unique); } }