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.support;
025:
026: import java.io.Serializable;
027: import java.util.Collection;
028: import java.util.Iterator;
029: import java.util.Map;
030:
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033: import org.hibernate.Criteria;
034: import org.hibernate.EntityMode;
035: import org.hibernate.Hibernate;
036: import org.hibernate.Query;
037: import org.hibernate.Session;
038: import org.hibernate.SessionFactory;
039: import org.hibernate.criterion.Expression;
040: import org.hibernate.metadata.ClassMetadata;
041: import org.riotfamily.common.beans.PropertyUtils;
042: import org.riotfamily.riot.security.AccessController;
043: import org.springframework.util.StringUtils;
044:
045: public final class HibernateUtils {
046:
047: public static final String LIVE_MODE_FILTER_NAME = "liveMode";
048:
049: public static final String PUBLISHED_PARAM_NAME = "published";
050:
051: private static Log log = LogFactory.getLog(HibernateUtils.class);
052:
053: private HibernateUtils() {
054: }
055:
056: public static Object get(Session session, Class beanClass, String id) {
057: SessionFactory sf = session.getSessionFactory();
058: Serializable serialId = convertId(beanClass, id, sf);
059: return session.get(beanClass, serialId);
060: }
061:
062: public static Serializable convertId(Class beanClass, String id,
063: SessionFactory sessionFactory) {
064:
065: Class identifierClass = sessionFactory.getClassMetadata(
066: beanClass).getIdentifierType().getReturnedClass();
067:
068: return (Serializable) PropertyUtils
069: .convert(id, identifierClass);
070: }
071:
072: public static String getIdAsString(SessionFactory sessionFactory,
073: Object bean) {
074: Class clazz = Hibernate.getClass(bean);
075: ClassMetadata metadata = sessionFactory.getClassMetadata(clazz);
076: return metadata.getIdentifier(bean, EntityMode.POJO).toString();
077: }
078:
079: /**
080: * Returns a HQL term that can be used within a where-clause to perform
081: * a query-by-example.
082: * @since 6.4
083: */
084: public static String getExampleWhereClause(Object example,
085: String alias, String[] propertyNames) {
086:
087: if (example == null || propertyNames == null) {
088: return null;
089: }
090: StringBuffer hql = new StringBuffer();
091: Map properties;
092: if (example instanceof Map) {
093: properties = (Map) example;
094: } else {
095: properties = PropertyUtils.getProperties(example,
096: propertyNames);
097: }
098: for (int i = 0; i < propertyNames.length; i++) {
099: String name = propertyNames[i];
100: Object value = properties.get(name);
101: if (value != null) {
102: if (hql.length() > 0) {
103: hql.append(" and ");
104: }
105: if (value instanceof Collection) {
106: Collection c = (Collection) value;
107: hql.append("1 = 1");
108: for (int j = 0; j < c.size(); j++) {
109: hql.append(" and :").append(name).append("_")
110: .append(j).append(" in elements(")
111: .append(alias).append('.').append(name)
112: .append(')');
113: }
114: } else {
115: hql.append(alias).append('.').append(name);
116: hql.append(" = :").append(name);
117: }
118: }
119: }
120: return hql.length() > 0 ? hql.toString() : null;
121: }
122:
123: /**
124: * Sets collection values as individual query parameters. Use this method
125: * together with {@link #getExampleWhereClause(Object, String, String[])}
126: * when your example contains collections.
127: * <p>
128: * The method iterates over the provides names array and inspects the given
129: * bean (or map). If there's a property (or map entry) of the type
130: * <code>java.util.Collection</code>, the methods iterates over the
131: * collection and sets a query parameter for each item. The name is suffixed
132: * with an underscore and the item's index.
133: *
134: * @since 6.4
135: */
136: public static void setCollectionValueParams(Query query,
137: String[] names, Object object) {
138:
139: for (int i = 0; i < names.length; i++) {
140: String name = names[i];
141: Object value;
142: if (object instanceof Map) {
143: value = ((Map) object).get(name);
144: } else {
145: value = PropertyUtils.getProperty(object, name);
146: }
147: if (value instanceof Collection) {
148: int j = 0;
149: Iterator values = ((Collection) value).iterator();
150: while (values.hasNext()) {
151: query.setParameter(name + "_" + j++, values.next());
152: }
153: }
154: }
155: }
156:
157: /**
158: * Returns a HQL term that can be used within a where-clause to perform
159: * a search. Example: <code>"(lower(<alias>.<property[0]>)
160: * like :<searchParamName> or lower(<alias>.<property[1]>)
161: * like :<searchParamName> or ...)"</code>
162: * @since 6.4
163: */
164: public static String getSearchWhereClause(String alias,
165: String[] propertyNames, String searchParamName) {
166:
167: if (propertyNames == null || propertyNames.length == 0) {
168: return null;
169: }
170: StringBuffer hql = new StringBuffer("(");
171: for (int i = 0; i < propertyNames.length; i++) {
172: String name = propertyNames[i];
173: if (i > 0) {
174: hql.append(" or ");
175: }
176: hql.append("lower(").append(alias).append('.').append(name);
177: hql.append(") like :").append(searchParamName);
178: }
179: hql.append(')');
180: return hql.toString();
181: }
182:
183: /**
184: * Appends the given term to the StringBuffer. If the buffer is not empty,
185: * the provided expression is inserted right before the term (surrounded
186: * by spaces).
187: * @since 6.4
188: */
189: public static StringBuffer appendHql(StringBuffer hql,
190: String expression, String term) {
191:
192: if (StringUtils.hasText(term)) {
193: if (expression != null && hql.length() > 0) {
194: hql.append(' ').append(expression).append(' ');
195: }
196: hql.append(term);
197: }
198: return hql;
199: }
200:
201: public static void addEqOrNull(Criteria c, String name, Object val) {
202: if (val != null) {
203: c.add(Expression.eq(name, val));
204: } else {
205: c.add(Expression.isNull(name));
206: }
207: }
208:
209: public static boolean isLiveModeFilterDefined(SessionFactory sf) {
210: return sf.getDefinedFilterNames().contains(
211: LIVE_MODE_FILTER_NAME);
212: }
213:
214: public static void enableLiveModeFilterIfNecessary(Session session) {
215: if (!AccessController.isAuthenticatedUser()) {
216: if (isLiveModeFilterDefined(session.getSessionFactory())) {
217: session.enableFilter(LIVE_MODE_FILTER_NAME)
218: .setParameter(PUBLISHED_PARAM_NAME,
219: Boolean.TRUE);
220: } else {
221: log.warn("No filter named " + LIVE_MODE_FILTER_NAME
222: + " defined for SessionFactory");
223: }
224: }
225: }
226: }
|