///////////////////////////////////////////////////////////////////////////// // // Project ProjectForge Community Edition // www.projectforge.org // // Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de) // // ProjectForge is dual-licensed. // // This community edition is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation; version 3 of the License. // // This community edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General // Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, see http://www.gnu.org/licenses/. // ///////////////////////////////////////////////////////////////////////////// package org.projectforge.core; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Locale; import org.apache.commons.lang.StringUtils; import org.hibernate.Criteria; import org.hibernate.FetchMode; import org.hibernate.Session; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.projectforge.common.DateHelper; /** * Stores the expressions and settings for creating a hibernate criteria object. This template is useful for avoiding the need of a * hibernate session in the stripes action classes. * @author Kai Reinhard (k.reinhard@micromata.de) */ public class QueryFilter { private final List<Object> filterSettings = new ArrayList<Object>(); private int maxResults = -1; private String name; private String alias; private BaseSearchFilter filter; private FetchMode fetchMode; private String associationPath = null; private Locale locale; /** * Creates new QueryFilter with a new SearchFilter as filter. */ public QueryFilter() { this.filter = new BaseSearchFilter(); } public QueryFilter(final BaseSearchFilter filter) { this.filter = filter; } private QueryFilter(final String name) { this.name = name; } public String getName() { return name; } public String getAlias() { return alias; } public BaseSearchFilter getFilter() { return filter; } /** * Locale is needed for lucene stemmers (hibernate search). * @return */ public Locale getLocale() { if (locale == null) { return Locale.GERMAN; } return locale; } public void setLocale(final Locale locale) { this.locale = locale; } /** * If an error occured (e. g. lucene parse exception) this message will be returned. * @return */ public String getErrorMessage() { return filter.getErrorMessage(); } public void setErrorMessage(final String errorMessage) { filter.setErrorMessage(errorMessage); } public boolean hasErrorMessage() { return filter.hasErrorMessage(); } public void clearErrorMessage() { filter.clearErrorMessage(); } /** * @see org.hibernate.Criteria#add(Criterion) * @param criterion * @return */ public QueryFilter add(final Criterion criterion) { filterSettings.add(criterion); return this; } /** * @see org.hibernate.Criteria#addOrder(Order) * @param order * @return */ public QueryFilter addOrder(final Order order) { filterSettings.add(order); return this; } public void setFetchMode(final String associationPath, final FetchMode mode) { this.associationPath = associationPath; this.fetchMode = mode; } /** * Adds Expression.between for given time period. * @param dateField * @param year if <= 0 do nothing. * @param month if < 0 choose whole year, otherwise given month. (Calendar.MONTH); */ public void setYearAndMonth(final String dateField, final int year, final int month) { if (year > 0) { final Calendar cal = DateHelper.getUTCCalendar(); cal.set(Calendar.YEAR, year); java.sql.Date lo = null; java.sql.Date hi = null; if (month >= 0) { cal.set(Calendar.MONTH, month); cal.set(Calendar.DAY_OF_MONTH, 1); lo = new java.sql.Date(cal.getTimeInMillis()); final int lastDayOfMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH); cal.set(Calendar.DAY_OF_MONTH, lastDayOfMonth); hi = new java.sql.Date(cal.getTimeInMillis()); } else { cal.set(Calendar.DAY_OF_YEAR, 1); lo = new java.sql.Date(cal.getTimeInMillis()); final int lastDayOfYear = cal.getActualMaximum(Calendar.DAY_OF_YEAR); cal.set(Calendar.DAY_OF_YEAR, lastDayOfYear); hi = new java.sql.Date(cal.getTimeInMillis()); } add(Restrictions.between(dateField, lo, hi)); } } public Criteria buildCriteria(final Session session, final Class< ? > clazz) { final Criteria criteria = session.createCriteria(clazz); buildCriteria(criteria); return criteria; } private void buildCriteria(final Criteria criteria) { for (final Object obj : filterSettings) { if (obj instanceof Criterion) { criteria.add((Criterion) obj); } else if (obj instanceof Order) { criteria.addOrder((Order) obj); } else if (obj instanceof Alias) { final Alias alias = (Alias) obj; criteria.createAlias(alias.arg0, alias.arg1, alias.joinType); } else if (obj instanceof QueryFilter) { final QueryFilter filter = (QueryFilter) obj; Criteria subCriteria; if (StringUtils.isEmpty(filter.getAlias()) == true) { subCriteria = criteria.createCriteria(filter.getName()); } else { subCriteria = criteria.createCriteria(filter.getName(), filter.getAlias()); } filter.buildCriteria(subCriteria); } } if (associationPath != null) { criteria.setFetchMode(associationPath, fetchMode); } if (maxResults > 0) { criteria.setMaxResults(maxResults); } } /** * @see org.hibernate.Criteria#createAlias(String, String) */ public QueryFilter createAlias(final String arg0, final String arg1) { filterSettings.add(new Alias(arg0, arg1)); return this; } /** * @see org.hibernate.Criteria#createAlias(String, String, int) */ public QueryFilter createAlias(final String arg0, final String arg1, final int joinType) { filterSettings.add(new Alias(arg0, arg1, joinType)); return this; } public QueryFilter createCriteria(final String name) { final QueryFilter filter = new QueryFilter(name); filterSettings.add(filter); return filter; } public QueryFilter createCriteria(final String name, final String alias) { final QueryFilter filter = new QueryFilter(name); filter.alias = alias; filterSettings.add(filter); return filter; } /** * @see org.hibernate.Criteria#setMaxResults(int) * @param value * @return */ public QueryFilter setMaxResults(final int value) { this.maxResults = value; return this; } public int getMaxResults() { return maxResults; } class Alias { String arg0; String arg1; int joinType = Criteria.INNER_JOIN; Alias(final String arg0, final String arg1) { this.arg0 = arg0; this.arg1 = arg1; } Alias(final String arg0, final String arg1, final int joinType) { this.arg0 = arg0; this.arg1 = arg1; this.joinType = joinType; } }; }