/** * Example license header for Java files * * http://www.andromda.org/ */ // // Attention: Generated code! Do not modify by hand! // Generated by: HibernateSearch.vsl in andromda-spring-cartridge. // package org.andromda.spring; /** * Implements a generic search mechanism based on the Hibernate Criteria API. The * CriteriaSearch allows adding parameters which function as where clause. The * parameters are analysed 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 net.sf.hibernate.Criteria * @see net.sf.hibernate.expression.Expression */ public class CriteriaSearch { private CriteriaSearchConfiguration configuration; private net.sf.hibernate.Criteria rootCriteria; private java.util.Map childCriteriaMap; private java.util.List orderList; private Class resultType; private static final class ParameterComparator implements java.util.Comparator { 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. */ protected net.sf.hibernate.Criteria getRootCriteria() { return this.rootCriteria; } /** * Constructor for CriteriaSearch. Creates a CriteriaSearch with a default * CriteriaSearchConfiguration. * * @param session The Hibernate session. * @param resultType The Class of the result. */ public CriteriaSearch(net.sf.hibernate.Session session, Class resultType) { this.configuration = new CriteriaSearchConfiguration(); this.resultType = resultType; this.rootCriteria = session.createCriteria(this.resultType); this.childCriteriaMap = new java.util.HashMap(); this.orderList = new java.util.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 net.sf.hibernate.HibernateException */ public java.util.Set executeAsSet() throws net.sf.hibernate.HibernateException { return new java.util.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 net.sf.hibernate.HibernateException */ public java.util.List executeAsList() throws net.sf.hibernate.HibernateException { // add ordering if (this.orderList.size() > 0) { java.util.Collections.sort(this.orderList, new ParameterComparator()); for (java.util.Iterator orderIterator = this.orderList.iterator(); orderIterator.hasNext();) { CriteriaSearchParameter parameter = (CriteriaSearchParameter)orderIterator.next(); int direction = parameter.getOrderDirection(); if (direction == CriteriaSearchParameter.ORDER_ASC) { this.getParameterCriteria(parameter).addOrder(net.sf.hibernate.expression.Order.asc(this.getParameterName(parameter))); } else { this.getParameterCriteria(parameter).addOrder(net.sf.hibernate.expression.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-seperated path e.g. person.address.street). * @throws net.sf.hibernate.HibernateException */ public void addParameter(Object parameterValue, String parameterPattern) throws net.sf.hibernate.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-seperated path e.g. person.address.street). * @throws net.sf.hibernate.HibernateException */ public void addParameter(String parameterValue, String parameterPattern) throws net.sf.hibernate.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 net.sf.hibernate.HibernateException */ public void addParameter(CriteriaSearchParameter parameter) throws net.sf.hibernate.HibernateException { if (considerParameter(parameter)) { final net.sf.hibernate.Criteria parameterCriteria = this.getParameterCriteria(parameter); final java.lang.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() != CriteriaSearchParameter.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 net.sf.hibernate.Criteria getParameterCriteria(final CriteriaSearchParameter parameter) throws net.sf.hibernate.HibernateException { String[] path = CriteriaSearchParameter.PATTERN.split(parameter.getParameterPattern()); net.sf.hibernate.Criteria parameterCriteria = this.rootCriteria; net.sf.hibernate.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 Class type = this.resultType; for (int index = 0; index < (path.length - 1); index++) { final String childEntityName = path[index]; final java.util.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]; java.lang.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 java.lang.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 Class type = this.resultType; for (int index = 0; index < (path.length - 1); index++) { final String childEntityName = path[index]; final java.util.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]; java.lang.System.arraycopy(path, index, restOfPath, 0, number); parameterName = org.apache.commons.lang.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) || (parameter.getParameterValue() != null); } /** * Adds an Expression to a Criteria. * * @param criteria * @param parameterName * @param parameterValue * @param comparator * @param matchMode */ private void addExpression( net.sf.hibernate.Criteria criteria, String parameterName, Object parameterValue, int comparator, net.sf.hibernate.expression.MatchMode matchMode) { switch (comparator) { case CriteriaSearchParameter.NOT_NULL_COMPARATOR: { criteria.add(net.sf.hibernate.expression.Expression.isNotNull(parameterName)); break; } case CriteriaSearchParameter.NULL_COMPARATOR: { criteria.add(net.sf.hibernate.expression.Expression.isNull(parameterName)); break; } default: { if (parameterValue != null) { switch (comparator) { case CriteriaSearchParameter.LIKE_COMPARATOR: { if ((matchMode != null) && (parameterValue instanceof String)) { criteria.add(net.sf.hibernate.expression.Expression.like( parameterName, (String)parameterValue, matchMode)); } else { criteria.add(net.sf.hibernate.expression.Expression.like(parameterName, parameterValue)); } break; } case CriteriaSearchParameter.INSENSITIVE_LIKE_COMPARATOR: { if ((matchMode != null) && (parameterValue instanceof String)) { criteria.add(net.sf.hibernate.expression.Expression.ilike( parameterName, (String)parameterValue, matchMode)); } else { criteria.add(net.sf.hibernate.expression.Expression.ilike(parameterName, parameterValue)); } break; } case CriteriaSearchParameter.EQUAL_COMPARATOR: { criteria.add(net.sf.hibernate.expression.Expression.eq(parameterName, parameterValue)); break; } case CriteriaSearchParameter.GREATER_THAN_OR_EQUAL_COMPARATOR: { criteria.add(net.sf.hibernate.expression.Expression.ge(parameterName, parameterValue)); break; } case CriteriaSearchParameter.GREATER_THAN_COMPARATOR: { criteria.add(net.sf.hibernate.expression.Expression.gt(parameterName, parameterValue)); break; } case CriteriaSearchParameter.LESS_THAN_OR_EQUAL_COMPARATOR: { criteria.add(net.sf.hibernate.expression.Expression.le(parameterName, parameterValue)); break; } case CriteriaSearchParameter.LESS_THAN_COMPARATOR: { criteria.add(net.sf.hibernate.expression.Expression.lt(parameterName, parameterValue)); break; } case CriteriaSearchParameter.IN_COMPARATOR: { if (parameterValue instanceof java.util.Collection) { criteria.add(net.sf.hibernate.expression.Expression.in(parameterName, (java.util.Collection)parameterValue)); } break; } case CriteriaSearchParameter.NOT_IN_COMPARATOR: { if (parameterValue instanceof java.util.Collection) { criteria.add(net.sf.hibernate.expression.Expression.not(net.sf.hibernate.expression.Expression.in(parameterName, (java.util.Collection)parameterValue))); } break; } } } else { criteria.add(net.sf.hibernate.expression.Expression.isNull(parameterName)); } } } } /** * Adds an Expression 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 conjuction 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( net.sf.hibernate.Criteria criteria, String parameterName, Object[] parameterValues, int comparator, net.sf.hibernate.expression.MatchMode matchMode) { if (parameterValues != null) { net.sf.hibernate.expression.Disjunction disjunction = null; net.sf.hibernate.expression.Conjunction conjunction = null; switch (comparator) { case CriteriaSearchParameter.LIKE_COMPARATOR: { disjunction = net.sf.hibernate.expression.Expression.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(net.sf.hibernate.expression.Expression.like( parameterName, stringParameterValues[index], matchMode)); } else { disjunction.add(net.sf.hibernate.expression.Expression .isNull(parameterName)); } } } else { for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(net.sf.hibernate.expression.Expression.like( parameterName, parameterValues[index])); } else { disjunction.add(net.sf.hibernate.expression.Expression .isNull(parameterName)); } } } break; } case CriteriaSearchParameter.INSENSITIVE_LIKE_COMPARATOR: { disjunction = net.sf.hibernate.expression.Expression.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(net.sf.hibernate.expression.Expression.ilike( parameterName, stringParameterValues[index], matchMode)); } else { disjunction.add(net.sf.hibernate.expression.Expression .isNull(parameterName)); } } } else { for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(net.sf.hibernate.expression.Expression.ilike( parameterName, parameterValues[index])); } else { disjunction.add(net.sf.hibernate.expression.Expression .isNull(parameterName)); } } } break; } case CriteriaSearchParameter.EQUAL_COMPARATOR: { disjunction = net.sf.hibernate.expression.Expression.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(net.sf.hibernate.expression.Expression.eq(parameterName, parameterValues[index])); } else { disjunction.add(net.sf.hibernate.expression.Expression.isNull(parameterName)); } } break; } case CriteriaSearchParameter.GREATER_THAN_OR_EQUAL_COMPARATOR: { disjunction = net.sf.hibernate.expression.Expression.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(net.sf.hibernate.expression.Expression.ge(parameterName, parameterValues[index])); } else { disjunction.add(net.sf.hibernate.expression.Expression.isNull(parameterName)); } } break; } case CriteriaSearchParameter.GREATER_THAN_COMPARATOR: { disjunction = net.sf.hibernate.expression.Expression.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(net.sf.hibernate.expression.Expression.gt(parameterName, parameterValues[index])); } else { disjunction.add(net.sf.hibernate.expression.Expression.isNull(parameterName)); } } break; } case CriteriaSearchParameter.LESS_THAN_OR_EQUAL_COMPARATOR: { disjunction = net.sf.hibernate.expression.Expression.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(net.sf.hibernate.expression.Expression.le(parameterName, parameterValues[index])); } else { disjunction.add(net.sf.hibernate.expression.Expression.isNull(parameterName)); } } break; } case CriteriaSearchParameter.LESS_THAN_COMPARATOR: { disjunction = net.sf.hibernate.expression.Expression.disjunction(); for (int index = 0; index < parameterValues.length; index++) { if (parameterValues[index] != null) { disjunction.add(net.sf.hibernate.expression.Expression.lt(parameterName, parameterValues[index])); } else { disjunction.add(net.sf.hibernate.expression.Expression.isNull(parameterName)); } } break; } case CriteriaSearchParameter.IN_COMPARATOR: { criteria.add(net.sf.hibernate.expression.Expression.in(parameterName, parameterValues)); break; } case CriteriaSearchParameter.NOT_IN_COMPARATOR: { criteria.add(net.sf.hibernate.expression.Expression.not(net.sf.hibernate.expression.Expression.in(parameterName, parameterValues))); break; } } if (disjunction != null) { criteria.add(disjunction); } if (conjunction != null) { criteria.add(conjunction); } } else { criteria.add(net.sf.hibernate.expression.Expression.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 net.sf.hibernate.HibernateException */ private net.sf.hibernate.Criteria locateCriteria(String childEntityName, net.sf.hibernate.Criteria parentCriteria) throws net.sf.hibernate.HibernateException { if (this.childCriteriaMap.containsKey(childEntityName)) { return (net.sf.hibernate.Criteria) this.childCriteriaMap.get(childEntityName); } net.sf.hibernate.Criteria childCriteria = parentCriteria.createCriteria(childEntityName); if (this.configuration.isForceEagerLoading()) { parentCriteria.setFetchMode(childEntityName, net.sf.hibernate.FetchMode.EAGER); } // 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(net.sf.hibernate.Criteria.DISTINCT_ROOT_ENTITY); this.childCriteriaMap.put(childEntityName, childCriteria); return childCriteria; } /** * Returns the configuration of this search. * * @return configuration */ public CriteriaSearchConfiguration getConfiguration() { return this.configuration; } }