/* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.riotfamily.core.dao.hibernate; import java.util.List; import org.hibernate.Query; import org.hibernate.SessionFactory; import org.riotfamily.common.beans.property.PropertyUtils; import org.riotfamily.core.dao.ListParams; import org.riotfamily.core.dao.Swapping; import org.riotfamily.core.screen.list.ListParamsImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.Assert; /** * RiotDao implementation based on Hibernate. */ public class HqlDao extends AbstractHqlDao implements Swapping { private Logger log = LoggerFactory.getLogger(HqlDao.class); private Class<?> entityClass; private boolean polymorph = true; private String select = "this"; private String where; private String positionProperty; private boolean setPositionOnSave; private boolean invertSorting; public HqlDao(SessionFactory sessionFactory) { super(sessionFactory); } public Class<?> getEntityClass() { return entityClass; } public void setEntityClass(Class<?> entityClass) { this.entityClass = entityClass; } @Override protected boolean isPolymorph() { return polymorph; } public void setPolymorph(boolean polymorph) { this.polymorph = polymorph; } @Override protected String getSelect() { return select; } public void setSelect(String select) { this.select = select; } @Override public String getWhere() { return where; } public void setWhere(String where) { this.where = where != null ? "(" + where + ")" : null; } public void setPositionProperty(String positionProperty) { this.positionProperty = positionProperty; } public void setSetPositionOnSave(boolean setPositionOnSave) { this.setPositionOnSave = setPositionOnSave; } protected boolean isSetPositionOnSave() { return setPositionOnSave; } public void setInvertSorting(boolean invertSorting) { this.invertSorting = invertSorting; } /** * Builds a HQL query string to retrieve the maximal position property value */ protected String buildMaxPositionHql(Object parent) { StringBuilder hql = new StringBuilder(); hql.append("select max(").append(positionProperty).append(") from "); hql.append(getEntityClass().getName()); hql.append(" as this"); HqlUtils.appendHql( hql, "where", getWhereClause(parent, new ListParamsImpl())); log.debug(hql.toString()); return hql.toString(); } protected void setPositionIfNeeded(Object entity, Object parent) { if (setPositionOnSave) { Query query = getSession().createQuery(buildMaxPositionHql(parent)); setQueryParameters(query, parent, new ListParamsImpl()); Number maxPosition = (Number) query.uniqueResult(); PropertyUtils.setProperty(entity, positionProperty, Integer.valueOf(maxPosition != null ? maxPosition.intValue() + 1 : 0)); } } @Override protected String getOrderBy(ListParams params) { if (positionProperty != null) { return invertSorting ? positionProperty + " desc" : positionProperty; } return super.getOrderBy(params); } @Override public void save(Object entity, Object parent) { setPositionIfNeeded(entity, parent); super.save(entity, parent); } public boolean canSwap(Object entity, Object parent, ListParams params, int swapWith) { List<?> items = listInternal(parent, new ListParamsImpl(params)); int i = items.indexOf(entity) + swapWith; return i >= 0 && i < items.size(); } public void swapEntity(Object entity, Object parent, ListParams params, int swapWith) { Assert.notNull(positionProperty, "A positionProperty must be specified."); List<?> items = listInternal(parent, new ListParamsImpl(params)); int i = items.indexOf(entity); Object nextItem = items.get(i + swapWith); Object pos1 = PropertyUtils.getProperty(entity, positionProperty); Object pos2 = PropertyUtils.getProperty(nextItem, positionProperty); PropertyUtils.setProperty(entity, positionProperty, pos2); PropertyUtils.setProperty(nextItem, positionProperty, pos1); } }