/** * Example license header for Java files * * http://andromda.sourceforge.net/ */ // // Attention: Generated code! Do not modify by hand! // Generated by hibernate/HibernateSearch.vsl in andromda-spring-cartridge on 09/18/2014 17:02:26-0400. Do not modify by hand!. // package org.andromda.spring; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.hibernate.Criteria; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.criterion.Conjunction; import org.hibernate.criterion.CriteriaSpecification; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Disjunction; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.SimpleExpression; /** * Implements a generic search mechanism based on the Hibernate Criteria API. The * CriteriaSearch allows adding parameters which function as where clause. The * parameters are analyzed whether they should be considered or not. This depends both on the actual * value of the parameter and on the configuration.
* The CriteriaSearch is expected to be a general solution for a basic search with * parameters connected by logical and. This search does not provide grouping. * * @author Stefan Reichert * @author Peter Friese * @author Chad Brandon * @see Criteria * @see Restrictions */ public class CriteriaSearch { private CriteriaSearchConfiguration configuration; private Criteria rootCriteria; private Map childCriteriaMap; private List orderList; @SuppressWarnings("rawtypes") private Class resultType; private static final class ParameterComparator implements Comparator { @Override public int compare(final Object object1, final Object object2) { final CriteriaSearchParameter parameter1 = (CriteriaSearchParameter)object1; final CriteriaSearchParameter parameter2 = (CriteriaSearchParameter)object2; final int relevance1 = parameter1.getOrderRelevance(); final int relevance2 = parameter2.getOrderRelevance(); int result = 0; if (relevance1 > relevance2) { result = 1; } else if (relevance1 < relevance2) { result = -1; } return result; } } /** * Exposes the root criteria to subclasses. * @return rootCriteria */ protected Criteria getRootCriteria() { return this.rootCriteria; } /** * Constructor for CriteriaSearch. Creates a CriteriaSearch with a default * CriteriaSearchConfiguration. * * @param session The Hibernate session. * @param resultTypeIn The Class of the result. */ public CriteriaSearch(Session session,@SuppressWarnings("rawtypes") Class resultTypeIn) { this.configuration = new CriteriaSearchConfiguration(); this.resultType = resultTypeIn; this.rootCriteria = session.createCriteria(this.resultType); this.childCriteriaMap = new HashMap(); this.orderList = new ArrayList(); } /** * Executes a HibernateQuery using the currently defined * CriteriaSearchParameters, and returns a java.util.Set * containing the query results. * * @return result The result of the query. * @throws HibernateException */ @SuppressWarnings({ "unchecked", "rawtypes" }) public Set executeAsSet() throws HibernateException { return new LinkedHashSet(this.executeAsList()); } /** * Executes a HibernateQuery using the currently defined * CriteriaSearchParameters, and returns a java.util.List * containing the query results. * * @return result The result of the query as a List * @throws HibernateException */ @SuppressWarnings({ "rawtypes", "synthetic-access" }) public List executeAsList() throws HibernateException { // add ordering if (this.orderList.size() > 0) { Collections.sort(this.orderList, new ParameterComparator()); for (final CriteriaSearchParameter parameter : this.orderList) { int direction = parameter.getOrderDirection(); if (direction == SearchParameter.ORDER_ASC) { this.getParameterCriteria(parameter).addOrder(Order.asc(this.getParameterName(parameter))); } else { this.getParameterCriteria(parameter).addOrder(Order.desc(this.getParameterName(parameter))); } } } // set the first result if configured if (this.configuration.getFirstResult() != null) { this.rootCriteria.setFirstResult(this.configuration.getFirstResult().intValue()); } // set the fetch size if configured if (this.configuration.getFetchSize() != null) { this.rootCriteria.setFetchSize(this.configuration.getFetchSize().intValue()); } // limit the maximum result if configured if (this.configuration.getMaximumResultSize() != null) { this.rootCriteria.setMaxResults(this.configuration.getMaximumResultSize().intValue()); } return this.rootCriteria.list(); } /** * Adds a CriteriaSearchParameter to this search. The parameter is connected to * the search by logical and. It is not considered if the value is null. * If the value is not null it is compared using the * CriteriaSearchParameter.EQUALS_COMPARATOR. * * @param parameterValue The value of the parameter. * @param parameterPattern The pattern of the parameter (dot-separated path e.g. person.address.street). * @throws HibernateException */ public void addParameter(Object parameterValue, String parameterPattern) throws HibernateException { addParameter(new CriteriaSearchParameter(parameterValue, parameterPattern)); } /** * Adds a CriteriaSearchParameter to this search. The parameter is connected to * the search by logical and. It is not considered if the value is null or * if the String empty. If the value is not null it is compared * using the CriteriaSearchParameter.LIKE_COMPARATOR. * * @param parameterValue The value of the parameter. * @param parameterPattern The pattern of the parameter (dot-separated path e.g. person.address.street). * @throws HibernateException */ public void addParameter(String parameterValue, String parameterPattern) throws HibernateException { addParameter(new CriteriaSearchParameter(parameterValue, parameterPattern)); } /** * Adds a CriteriaSearchParameter to this search. The parameter is connected to * the search by logical and. * * @param parameter The CriteriaSearchParameter to add. * @throws HibernateException */ public void addParameter(CriteriaSearchParameter parameter) throws HibernateException { if (considerParameter(parameter)) { final Criteria parameterCriteria = this.getParameterCriteria(parameter); final String parameterName = this.getParameterName(parameter); // check the type parameter value to add if(parameter.getParameterValue() instanceof Object[]) { addExpression( parameterCriteria, parameterName, (Object[])parameter.getParameterValue(), parameter.getComparator(), parameter.getMatchMode()); } else { addExpression( parameterCriteria, parameterName, parameter.getParameterValue(), parameter.getComparator(), parameter.getMatchMode()); } } // if the parameter is to be ordered, add it to the order list if (parameter.getOrderDirection() != SearchParameter.ORDER_UNSET) { this.orderList.add(parameter); } } /** * Retrieves the appropriate criteria object for the given parameter. * * @param parameter the parameter for which to retrieve the criteria. * @return the retrieved criteria. */ private Criteria getParameterCriteria(final CriteriaSearchParameter parameter) throws HibernateException { String[] path = CriteriaSearchParameter.PATTERN.split(parameter.getParameterPattern()); Criteria parameterCriteria = this.rootCriteria; Criteria childEntityCriteria; if (path.length > 1) { // We have a parameter affecting an attribute of an inner childEntity object so we need // to traverse to get the right criteria object childEntityCriteria = this.rootCriteria; // Evaluating the proper criteria object for the defined parameter @SuppressWarnings("rawtypes") Class type = this.resultType; for (int index = 0; index < (path.length - 1); index++) { final String childEntityName = path[index]; final Collection embeddedValues = CriteriaSearchProperties.getEmbeddedValues(type); if (embeddedValues != null && embeddedValues.contains(childEntityName)) { // - use the rest of the path as the parameter name final int number = path.length - index; final String[] restOfPath = new String[path.length - index]; System.arraycopy(path, index, restOfPath, 0, number); break; } type = CriteriaSearchProperties.getNavigableAssociationEndType(type, childEntityName); childEntityCriteria = locateCriteria(childEntityName, childEntityCriteria); } if (childEntityCriteria != null) { // We now have the right criteria object parameterCriteria = childEntityCriteria; } } return parameterCriteria; } /** * Retrieves the appropriate nested parameter name for the given parameter. * * @param parameter the parameter for which to retrieve the parameter name. * @return the parameter name. */ private String getParameterName(final CriteriaSearchParameter parameter) { // parsing the pattern of the parameter String[] path = CriteriaSearchParameter.PATTERN.split(parameter.getParameterPattern()); String parameterName = path[path.length - 1]; if (path.length > 1) { // We have a parameter affecting an attribute of an inner childEntity object so we need // to traverse to get the correct parameter name // Evaluating the proper criteria object for the defined parameter @SuppressWarnings("rawtypes") Class type = this.resultType; for (int index = 0; index < (path.length - 1); index++) { final String childEntityName = path[index]; final Collection embeddedValues = CriteriaSearchProperties.getEmbeddedValues(type); if (embeddedValues != null && embeddedValues.contains(childEntityName)) { // - use the rest of the path as the parameter name final int number = path.length - index; final String[] restOfPath = new String[path.length - index]; System.arraycopy(path, index, restOfPath, 0, number); parameterName = StringUtils.join(restOfPath, "."); break; } type = CriteriaSearchProperties.getNavigableAssociationEndType(type, childEntityName); } } return parameterName; } /** * Decides whether a paramter is considered as a criteria for a search depending on the type and * value of the parameterValue and searchIfIsNull. A * parameterValue of the type String is considered * null if being a NullPointer or empty. * * @param parameter The parameter to check. */ private boolean considerParameter(CriteriaSearchParameter parameter) { if (parameter.getParameterValue() instanceof String) { String stringParameterValue = (String) parameter.getParameterValue(); return (parameter.isSearchIfNull() || (stringParameterValue != null && stringParameterValue.length() > 0)); } if (parameter.getParameterValue() instanceof Object[]) { Object[] parameterValues = (Object[]) parameter.getParameterValue(); return (parameter.isSearchIfNull() || (parameterValues != null && parameterValues.length > 0)); } final int comparator = parameter.getComparator(); return (parameter.isSearchIfNull() || SearchParameter.NOT_NULL_COMPARATOR == comparator || SearchParameter.NULL_COMPARATOR == comparator || SearchParameter.EMPTY_COMPARATOR == comparator || SearchParameter.NOT_EMPTY_COMPARATOR == comparator) || (parameter.getParameterValue() != null); } /** * Adds an Restrictions to a Criteria. * * @param criteria * @param parameterName * @param parameterValue * @param comparator * @param matchMode */ private void addExpression( Criteria criteria, String parameterName, Object parameterValue, int comparator, MatchMode matchMode) { switch (comparator) { case SearchParameter.NOT_NULL_COMPARATOR: { criteria.add(Restrictions.isNotNull(parameterName)); break; } case SearchParameter.NULL_COMPARATOR: { criteria.add(Restrictions.isNull(parameterName)); break; } case SearchParameter.EMPTY_COMPARATOR: { criteria.add(Restrictions.isEmpty(parameterName)); break; } case SearchParameter.NOT_EMPTY_COMPARATOR: { criteria.add(Restrictions.isNotEmpty(parameterName)); break; } default: { if (parameterValue != null) { switch (comparator) { case SearchParameter.LIKE_COMPARATOR: { if ((matchMode != null) && (parameterValue instanceof String)) { criteria.add(Restrictions.like( parameterName, (String)parameterValue, matchMode)); } else { criteria.add(Restrictions.like(parameterName, parameterValue)); } break; } case SearchParameter.NOT_LIKE_COMPARATOR: { SimpleExpression expression; if ((matchMode != null) && (parameterValue instanceof String)) { expression = Restrictions.like( parameterName, (String)parameterValue, matchMode); } else { expression = Restrictions.like(parameterName, parameterValue); } criteria.add(Restrictions.not(expression)); break; } case SearchParameter.INSENSITIVE_LIKE_COMPARATOR: { if ((matchMode != null) && (parameterValue instanceof String)) { criteria.add(Restrictions.ilike( parameterName, (String)parameterValue, matchMode)); } else { criteria.add(Restrictions.ilike(parameterName, parameterValue)); } break; } case SearchParameter.NOT_INSENSITIVE_LIKE_COMPARATOR: { Criterion criterion; if ((matchMode != null) && (parameterValue instanceof String)) { criterion = Restrictions.ilike( parameterName, (String)parameterValue, matchMode); } else { criterion = Restrictions.ilike(parameterName, parameterValue); } criteria.add(Restrictions.not(criterion)); break; } case SearchParameter.EQUAL_COMPARATOR: { criteria.add(Restrictions.eq(parameterName, parameterValue)); break; } case SearchParameter.GREATER_THAN_OR_EQUAL_COMPARATOR: { criteria.add(Restrictions.ge(parameterName, parameterValue)); break; } case SearchParameter.GREATER_THAN_COMPARATOR: { criteria.add(Restrictions.gt(parameterName, parameterValue)); break; } case SearchParameter.LESS_THAN_OR_EQUAL_COMPARATOR: { criteria.add(Restrictions.le(parameterName, parameterValue)); break; } case SearchParameter.LESS_THAN_COMPARATOR: { criteria.add(Restrictions.lt(parameterName, parameterValue)); break; } case SearchParameter.IN_COMPARATOR: { if (parameterValue instanceof Collection) { criteria.add(Restrictions.in(parameterName, (Collection)parameterValue)); } break; } case SearchParameter.NOT_IN_COMPARATOR: { if (parameterValue instanceof Collection) { criteria.add(Restrictions.not(Restrictions.in(parameterName, (Collection)parameterValue))); } break; } case SearchParameter.NOT_EQUAL_COMPARATOR: { criteria.add(Restrictions.ne(parameterName, parameterValue)); break; } default: break; } } else { criteria.add(Restrictions.isNull(parameterName)); } } } } /** * Adds an Restrictions to a Criteria. The given parameterValues * represents either an array of String or another object. The different values in the * array are added to a disjunction or conjunction which is connected with logical and to the other criteria of the * search. * * @param criteria * @param parameterName * @param parameterValues * @param searchIfNull * @param comparator * @param matchMode */ private void addExpression( Criteria criteria, String parameterName, Object[] parameterValues, int comparator, MatchMode matchMode) { if (parameterValues != null) { Disjunction disjunction = null; Conjunction conjunction = null; switch (comparator) { case SearchParameter.LIKE_COMPARATOR: { disjunction = Restrictions.disjunction(); if ((matchMode != null) && (parameterValues instanceof String[])) { String[] stringParameterValues = (String[]) parameterValues; for (int index = 0; index < parameterValues.length; index++) { if (stringParameterValues[index] != null) { disjunction.add(Restrictions.like( parameterName, stringParameterValues[index], matchMode)); } else { disjunction.add(Restrictions .isNull(parameterName)); } } } else { for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(Restrictions.like( parameterName, parameterValues[index])); } else { disjunction.add(Restrictions .isNull(parameterName)); } } } break; } case SearchParameter.INSENSITIVE_LIKE_COMPARATOR: { disjunction = Restrictions.disjunction(); if ((matchMode != null) && (parameterValues instanceof String[])) { String[] stringParameterValues = (String[]) parameterValues; for (int index = 0; index < parameterValues.length; index++) { if (stringParameterValues[index] != null) { disjunction.add(Restrictions.ilike( parameterName, stringParameterValues[index], matchMode)); } else { disjunction.add(Restrictions .isNull(parameterName)); } } } else { for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(Restrictions.ilike( parameterName, parameterValues[index])); } else { disjunction.add(Restrictions .isNull(parameterName)); } } } break; } case SearchParameter.EQUAL_COMPARATOR: { disjunction = Restrictions.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(Restrictions.eq(parameterName, parameterValues[index])); } else { disjunction.add(Restrictions.isNull(parameterName)); } } break; } case SearchParameter.GREATER_THAN_OR_EQUAL_COMPARATOR: { disjunction = Restrictions.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(Restrictions.ge(parameterName, parameterValues[index])); } else { disjunction.add(Restrictions.isNull(parameterName)); } } break; } case SearchParameter.GREATER_THAN_COMPARATOR: { disjunction = Restrictions.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(Restrictions.gt(parameterName, parameterValues[index])); } else { disjunction.add(Restrictions.isNull(parameterName)); } } break; } case SearchParameter.LESS_THAN_OR_EQUAL_COMPARATOR: { disjunction = Restrictions.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(Restrictions.le(parameterName, parameterValues[index])); } else { disjunction.add(Restrictions.isNull(parameterName)); } } break; } case SearchParameter.LESS_THAN_COMPARATOR: { disjunction = Restrictions.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(Restrictions.lt(parameterName, parameterValues[index])); } else { disjunction.add(Restrictions.isNull(parameterName)); } } break; } case SearchParameter.IN_COMPARATOR: { criteria.add(Restrictions.in(parameterName, parameterValues)); break; } case SearchParameter.NOT_IN_COMPARATOR: { criteria.add(Restrictions.not(Restrictions.in(parameterName, parameterValues))); break; } case SearchParameter.NOT_EQUAL_COMPARATOR: { conjunction = Restrictions.conjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { conjunction.add(Restrictions.ne(parameterName, parameterValues[index])); } else { conjunction.add(Restrictions.isNotNull(parameterName)); } } break; } default: break; } if (disjunction != null) { criteria.add(disjunction); } if (conjunction != null) { criteria.add(conjunction); } } else { switch (comparator) { case SearchParameter.EMPTY_COMPARATOR: { criteria.add(Restrictions.isEmpty(parameterName)); break; } case SearchParameter.NOT_EMPTY_COMPARATOR: { criteria.add(Restrictions.isNotEmpty(parameterName)); break; } default: { criteria.add(Restrictions.isNull(parameterName)); } } } } /** * Locates a Criteria for a childEntityName. If a * Criteria exists for the childEntityName, it is returned. If * not, one is created and referenced in the childCriteriaMap under the * childEntityName. * * @param childEntityName * @param parentCriteria * @return criteria The Criteria for the childEntityName. * @throws HibernateException */ private Criteria locateCriteria(String childEntityName, Criteria parentCriteria) throws HibernateException { if (this.childCriteriaMap.containsKey(childEntityName)) { return this.childCriteriaMap.get(childEntityName); } Criteria childCriteria = parentCriteria.createCriteria(childEntityName); if (this.configuration.isForceEagerLoading()) { parentCriteria.setFetchMode(childEntityName, FetchMode.JOIN); } // Hibernate does not support a 'unique' identifier. As a search may contain outer joins, // duplicates in the resultList are possible. We eliminate any duplicates here, creating a // distinctified resultSet (Suggestion from Hibernate itself; see www.hibernate.org's FAQ's). parentCriteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); this.childCriteriaMap.put(childEntityName, childCriteria); return childCriteria; } /** * Returns the configuration of this search. * * @return configuration */ public CriteriaSearchConfiguration getConfiguration() { return this.configuration; } }