package net.databinder.models.hib;
/*---
Copyright 2008 The Scripps Research Institute
http://www.scripps.edu
* Databinder: a simple bridge from Wicket to Hibernate
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
---*/
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Criteria;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Order;
/**
* Abstract base class for building OrderedCriteriaBuilders. It handles the sorting.
* Subclasses should call super.buildUnordered() when overriding.
*
* Avoids problems with duplicate Aliases by having all the Criteria building code in one location.
*/
public abstract class BaseCriteriaBuildAndSort implements OrderingCriteriaBuilder, Serializable {
protected Set<String> aliases = new HashSet<String>();
protected String defaultSortProperty = null;
protected boolean sortAscending, sortCased;
public BaseCriteriaBuildAndSort() {
this(null, true, false);
}
public BaseCriteriaBuildAndSort(final String defaultSortProperty, final boolean sortAscending, final boolean sortCased) {
this.defaultSortProperty = defaultSortProperty;
this.sortAscending = sortAscending;
this.sortCased = sortCased;
}
public void buildOrdered(final Criteria criteria) {
buildUnordered(criteria);
String property = defaultSortProperty;
if (property != null) {
property = processProperty(criteria, property);
Order order = sortAscending ? Order.asc(property) : Order.desc(property);
order = sortCased ? order : order.ignoreCase();
criteria.addOrder(order);
}
}
public void buildUnordered(final Criteria criteria) {
aliases.clear();
}
protected String processProperty(final Criteria criteria, String property) {
if (property.contains(".")) {
// for 'dot' properties we need to add aliases
// e.g. for the property 'orderbook.order.item.name' we need to add an aliases for 'order' and 'order.item'
String path[] = property.split("\\.");
for (int ii = 0; ii < path.length - 1; ii++) {
StringBuffer sb = new StringBuffer();
for (int jj = 0; jj <= ii; jj++) {
if (sb.length() > 0) {
sb.append(".");
}
sb.append(path[jj]);
}
if (!aliases.contains(path[ii])) {
aliases.add(path[ii]);
criteria.createAlias(sb.toString(), path[ii], CriteriaSpecification.LEFT_JOIN);
}
}
// when we have a 'dot' property we want to sort by the sub tables field
// e.g. for the property 'orderbook.order.item.name' we need to sort by 'item.name'
if (path.length > 1) {
property = String.format("%s.%s", path[path.length - 2], path[path.length - 1]);
}
else {
property = path[path.length - 1];
}
}
return property;
}
}