001: /* ***** BEGIN LICENSE BLOCK *****
002: * Version: MPL 1.1
003: * The contents of this file are subject to the Mozilla Public License Version
004: * 1.1 (the "License"); you may not use this file except in compliance with
005: * the License. You may obtain a copy of the License at
006: * http://www.mozilla.org/MPL/
007: *
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: * for the specific language governing rights and limitations under the
011: * License.
012: *
013: * The Original Code is Riot.
014: *
015: * The Initial Developer of the Original Code is
016: * Neteye GmbH.
017: * Portions created by the Initial Developer are Copyright (C) 2006
018: * the Initial Developer. All Rights Reserved.
019: *
020: * Contributor(s):
021: * Felix Gnass [fgnass at neteye dot de]
022: *
023: * ***** END LICENSE BLOCK ***** */
024: package org.riotfamily.riot.hibernate.dao;
025:
026: import java.util.Collection;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030:
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033: import org.hibernate.Query;
034: import org.riotfamily.common.beans.PropertyUtils;
035: import org.riotfamily.riot.dao.ListParams;
036: import org.riotfamily.riot.dao.Order;
037: import org.riotfamily.riot.dao.RiotDao;
038: import org.riotfamily.riot.dao.SortableDao;
039: import org.riotfamily.riot.dao.SwappableItemDao;
040: import org.riotfamily.riot.hibernate.support.HibernateSupport;
041: import org.riotfamily.riot.hibernate.support.HibernateUtils;
042: import org.riotfamily.riot.list.support.EmptyListParams;
043: import org.springframework.util.Assert;
044:
045: /**
046: * RiotDao implementation based on Hibernate.
047: */
048: public class HqlDao extends HibernateSupport implements RiotDao,
049: SortableDao, SwappableItemDao {
050:
051: private static final Log log = LogFactory.getLog(HqlDao.class);
052:
053: private Class entityClass;
054:
055: private boolean polymorph = true;
056:
057: private String where;
058:
059: private String positionProperty;
060:
061: private boolean setPositionOnSave;
062:
063: /**
064: * @return Returns the itemClass.
065: */
066: public Class getEntityClass() {
067: return entityClass;
068: }
069:
070: /**
071: * @param itemClass The itemClass to set.
072: */
073: public void setEntityClass(Class itemClass) {
074: this .entityClass = itemClass;
075: }
076:
077: /**
078: * @return Returns the polymorph.
079: */
080: public boolean isPolymorph() {
081: return polymorph;
082: }
083:
084: /**
085: * @param polymorph The polymorph to set.
086: */
087: public void setPolymorph(boolean polymorph) {
088: this .polymorph = polymorph;
089: }
090:
091: /**
092: * @return Returns the where.
093: */
094: public String getWhere() {
095: return where;
096: }
097:
098: /**
099: * @param where The where to set.
100: */
101: public void setWhere(String where) {
102: this .where = where;
103: }
104:
105: /**
106: * @deprecated The objectId is now obtained using Hibernate meta data.
107: */
108: public void setIdProperty(String idProperty) {
109: }
110:
111: public void setPositionProperty(String positionProperty) {
112: this .positionProperty = positionProperty;
113: }
114:
115: public String getObjectId(Object item) {
116: return HibernateUtils.getIdAsString(getSessionFactory(), item);
117: }
118:
119: /**
120: * Returns a list of items.
121: */
122: public Collection list(Object parent, ListParams params) {
123: return listInternal(parent, params);
124: }
125:
126: protected List listInternal(Object parent, ListParams params) {
127: Query query = createQuery(buildHql(parent, params));
128: setQueryParameters(query, parent, params);
129: if (params.getPageSize() > 0) {
130: query.setFirstResult(params.getOffset());
131: query.setMaxResults(params.getPageSize());
132: }
133: return query.list();
134: }
135:
136: /**
137: * Returns the total number of items.
138: */
139: public int getListSize(Object parent, ListParams params) {
140: Query query = createQuery(buildCountHql(parent, params));
141: setQueryParameters(query, parent, params);
142: Number size = (Number) query.uniqueResult();
143: if (size == null) {
144: return 0;
145: }
146: return size.intValue();
147: }
148:
149: protected void setQueryParameters(Query query, Object parent,
150: ListParams params) {
151:
152: if (params.getFilter() != null) {
153: if (params.getFilter() instanceof Map) {
154: Map filterMap = (Map) params.getFilter();
155: query.setProperties(filterMap);
156: } else {
157: query.setProperties(params.getFilter());
158: }
159:
160: HibernateUtils.setCollectionValueParams(query, params
161: .getFilteredProperties(), params.getFilter());
162: }
163: if (params.getSearch() != null) {
164: query.setParameter("search", params.getSearch()
165: .toLowerCase().replace('*', '%')
166: + "%");
167: }
168: }
169:
170: /**
171: * Builds a HQL query string to retrieve the maximal position property value
172: */
173: protected String buildMaxPositionHql(Object parent) {
174: StringBuffer hql = new StringBuffer();
175: hql.append("select max(").append(positionProperty).append(
176: ") from ");
177: hql.append(entityClass.getName());
178: hql.append(" as this");
179: HibernateUtils.appendHql(hql, "where", getWhereClause(parent,
180: new EmptyListParams()));
181: log.info(hql);
182: return hql.toString();
183: }
184:
185: /**
186: * Builds a HQL query string to retrieve the total number of items.
187: */
188: protected String buildCountHql(Object parent, ListParams params) {
189: StringBuffer hql = new StringBuffer();
190: hql.append("select count(this) from ");
191: hql.append(entityClass.getName());
192: hql.append(" as this");
193: HibernateUtils.appendHql(hql, "where", getWhereClause(parent,
194: params));
195: log.info(hql);
196: return hql.toString();
197: }
198:
199: /**
200: * Builds a HQL query string to retrieve a list of items.
201: */
202: protected String buildHql(Object parent, ListParams params) {
203: StringBuffer hql = new StringBuffer();
204: hql.append("select this from ");
205: hql.append(entityClass.getName());
206: hql.append(" as this");
207: HibernateUtils.appendHql(hql, "where", getWhereClause(parent,
208: params));
209: HibernateUtils.appendHql(hql, "order by", getOrderBy(params));
210: log.info(hql);
211: return hql.toString();
212: }
213:
214: protected String getWhereClause(Object parent, ListParams params) {
215: StringBuffer sb = new StringBuffer();
216: HibernateUtils.appendHql(sb, null, where);
217:
218: if (params.getFilter() != null) {
219: String filter = HibernateUtils.getExampleWhereClause(params
220: .getFilter(), "this", params
221: .getFilteredProperties());
222:
223: HibernateUtils.appendHql(sb, "and", filter);
224: }
225:
226: if (params.getSearch() != null) {
227: String search = HibernateUtils.getSearchWhereClause("this",
228: params.getSearchProperties(), "search");
229:
230: HibernateUtils.appendHql(sb, "and", search);
231: }
232:
233: if (!polymorph) {
234: HibernateUtils.appendHql(sb, "and", "(this.class = ")
235: .append(entityClass.getName()).append(')');
236: }
237:
238: return sb.toString();
239: }
240:
241: protected String getOrderBy(ListParams params) {
242: StringBuffer sb = new StringBuffer();
243: if (params.hasOrder()) {
244: Iterator it = params.getOrder().iterator();
245: while (it.hasNext()) {
246: Order order = (Order) it.next();
247: if (!order.isCaseSensitive()) {
248: sb.append(" lower(");
249: }
250: sb.append(" this.");
251: sb.append(order.getProperty());
252: if (!order.isCaseSensitive()) {
253: sb.append(" ) ");
254: }
255: sb.append(' ');
256: sb.append(order.isAscending() ? "asc" : "desc");
257: if (it.hasNext()) {
258: sb.append(',');
259: }
260: }
261: }
262: return sb.toString();
263: }
264:
265: protected void setPositionIfNeeded(Object entity, Object parent) {
266: if (setPositionOnSave) {
267: Query query = createQuery(buildMaxPositionHql(parent));
268: Number maxPosition = (Number) query.uniqueResult();
269:
270: PropertyUtils.setProperty(entity, positionProperty,
271: new Integer(maxPosition != null ? maxPosition
272: .intValue() + 1 : 0));
273: }
274: }
275:
276: public void save(Object entity, Object parent) {
277: setPositionIfNeeded(entity, parent);
278: getSession().save(entity);
279: }
280:
281: public void delete(Object entity, Object parent) {
282: getSession().delete(entity);
283: }
284:
285: public Object load(String objectId) {
286: Assert.notNull(objectId,
287: "A non-null id must be passed to load()");
288: return HibernateUtils.get(getSession(), entityClass, objectId);
289: }
290:
291: public void update(Object entity) {
292: getSession().update(entity);
293: }
294:
295: public void swapEntity(Object item, Object parent,
296: ListParams params, int swapWith) {
297:
298: Assert.notNull(positionProperty,
299: "A positionProperty must be specified.");
300:
301: List items = listInternal(parent, params);
302: Object nextItem = items.get(swapWith);
303:
304: Object pos1 = PropertyUtils.getProperty(item, positionProperty);
305: Object pos2 = PropertyUtils.getProperty(nextItem,
306: positionProperty);
307:
308: PropertyUtils.setProperty(item, positionProperty, pos2);
309: PropertyUtils.setProperty(nextItem, positionProperty, pos1);
310:
311: getSession().update(item);
312: getSession().update(nextItem);
313: }
314:
315: /**
316: * @param setPositionOnSave the setPositionOnSave to set
317: */
318: public void setSetPositionOnSave(boolean setPositionOnSave) {
319: this .setPositionOnSave = setPositionOnSave;
320: }
321:
322: protected boolean isSetPositionOnSave() {
323: return setPositionOnSave;
324: }
325:
326: }
|