GRAILS-1019: Allowing expressions to be used with the 'disabled' attribute for g...
[grails.git] / src / persistence / org / codehaus / groovy / grails / orm / hibernate / cfg / GrailsHibernateUtil.java
blob64d0e91f94ca9da1f926c72ee6bd56263c7bc95e
1 /* Copyright 2004-2005 Graeme Rocher
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
15 package org.codehaus.groovy.grails.orm.hibernate.cfg;
17 import groovy.lang.GroovyObject;
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.codehaus.groovy.grails.commons.DomainClassArtefactHandler;
21 import org.codehaus.groovy.grails.commons.GrailsApplication;
22 import org.codehaus.groovy.grails.commons.GrailsDomainClass;
23 import org.codehaus.groovy.grails.commons.metaclass.DynamicMethods;
24 import org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator;
25 import org.codehaus.groovy.grails.orm.hibernate.GrailsHibernateDomainClass;
26 import org.codehaus.groovy.grails.orm.hibernate.metaclass.DomainClassMethods;
27 import org.hibernate.Criteria;
28 import org.hibernate.EntityMode;
29 import org.hibernate.FetchMode;
30 import org.hibernate.SessionFactory;
31 import org.hibernate.criterion.Order;
32 import org.hibernate.metadata.ClassMetadata;
33 import org.springframework.beans.SimpleTypeConverter;
34 import org.springframework.context.ApplicationContext;
36 import java.beans.IntrospectionException;
37 import java.lang.reflect.Modifier;
38 import java.util.Collection;
39 import java.util.HashMap;
40 import java.util.Iterator;
41 import java.util.Map;
43 /**
44 * A class containing utility methods for configuring Hibernate inside Grails
46 * @author Graeme Rocher
47 * @since 0.4
48 * <p/>
49 * Created: Jan 19, 2007
50 * Time: 6:21:01 PM
52 public class GrailsHibernateUtil {
53 private static final Log LOG = LogFactory.getLog(GrailsHibernateUtil.class);
54 public static SimpleTypeConverter converter = new SimpleTypeConverter();
55 public static final String ARGUMENT_MAX = "max";
56 public static final String ARGUMENT_OFFSET = "offset";
57 public static final String ARGUMENT_ORDER = "order";
58 public static final String ARGUMENT_SORT = "sort";
59 public static final String ORDER_DESC = "desc";
60 public static final String ORDER_ASC = "asc";
61 public static final String ARGUMENT_FETCH = "fetch";
62 public static final String ARGUMENT_IGNORE_CASE = "ignoreCase";
64 public static void configureDynamicMethods(SessionFactory sessionFactory, GrailsApplication application) {
65 LOG.trace("Configuring dynamic methods");
66 // if its not a grails domain class and one written in java then add it
67 // to grails
68 Collection classMetaData = sessionFactory.getAllClassMetadata().values();
69 for (Iterator i = classMetaData.iterator(); i.hasNext();) {
70 ClassMetadata cmd = (ClassMetadata) i.next();
72 Class persistentClass = cmd.getMappedClass(EntityMode.POJO);
73 configureDynamicMethodsFor(sessionFactory, application, persistentClass);
78 /**
79 * Configures dynamic methods on all Hibernate mapped domain classes that are found in the application context
81 * @param applicationContext The session factory instance
82 * @param application The grails application instance
84 public static void configureDynamicMethods(ApplicationContext applicationContext, GrailsApplication application) {
85 LOG.trace("Configuring dynamic methods");
86 if (applicationContext == null)
87 throw new IllegalArgumentException("Cannot configure dynamic methods for null ApplicationContext");
89 SessionFactory sessionFactory = (SessionFactory) applicationContext.getBean(GrailsRuntimeConfigurator.SESSION_FACTORY_BEAN);
91 configureDynamicMethods(sessionFactory, application);
94 public static DynamicMethods configureDynamicMethodsFor(SessionFactory sessionFactory, GrailsApplication application, Class persistentClass) {
95 if (LOG.isTraceEnabled()) {
96 LOG.trace("Registering dynamic methods on class [" + persistentClass + "]");
98 DynamicMethods dm = null;
99 try {
100 dm = new DomainClassMethods(application, persistentClass, sessionFactory, application.getClassLoader());
101 } catch (IntrospectionException e) {
102 LOG.warn("Introspection exception registering dynamic methods for [" + persistentClass + "]:" + e.getMessage(), e);
104 return dm;
107 public static void configureHibernateDomainClasses(SessionFactory sessionFactory, GrailsApplication application) {
108 Map hibernateDomainClassMap = new HashMap();
109 for (Iterator i = sessionFactory.getAllClassMetadata().values().iterator(); i.hasNext();) {
110 ClassMetadata classMetadata = (ClassMetadata) i.next();
111 configureDomainClass(sessionFactory, application, classMetadata, classMetadata.getMappedClass(EntityMode.POJO), hibernateDomainClassMap);
113 configureInheritanceMappings(hibernateDomainClassMap);
116 public static void configureInheritanceMappings(Map hibernateDomainClassMap) {
117 // now get through all domainclasses, and add all subclasses to root class
118 for (Iterator it = hibernateDomainClassMap.values().iterator(); it.hasNext();) {
119 GrailsDomainClass baseClass = (GrailsDomainClass) it.next();
120 if (!baseClass.isRoot()) {
121 Class superClass = baseClass
122 .getClazz().getSuperclass();
125 while (!superClass.equals(Object.class) && !superClass.equals(GroovyObject.class)) {
126 GrailsDomainClass gdc = (GrailsDomainClass) hibernateDomainClassMap.get(superClass.getName());
128 if (gdc == null || gdc.getSubClasses() == null) {
129 LOG.error("did not find superclass names when mapping inheritance....");
130 break;
132 gdc.getSubClasses().add(baseClass);
133 superClass = superClass.getSuperclass();
139 private static void configureDomainClass(SessionFactory sessionFactory, GrailsApplication application, ClassMetadata cmd, Class persistentClass, Map hibernateDomainClassMap) {
140 if (!Modifier.isAbstract(persistentClass.getModifiers())) {
141 LOG.trace("Configuring domain class [" + persistentClass + "]");
142 GrailsDomainClass dc = (GrailsDomainClass) application.getArtefact(DomainClassArtefactHandler.TYPE, persistentClass.getName());
143 if (dc == null) {
144 // a patch to add inheritance to this system
145 GrailsHibernateDomainClass ghdc = new
146 GrailsHibernateDomainClass(persistentClass, sessionFactory, cmd);
148 hibernateDomainClassMap.put(persistentClass.getName(),
149 ghdc);
151 dc = (GrailsDomainClass) application.addArtefact(DomainClassArtefactHandler.TYPE, ghdc);
156 public static void populateArgumentsForCriteria(Criteria c, Map argMap) {
158 Integer maxParam = null;
159 Integer offsetParam = null;
160 if(argMap.containsKey(ARGUMENT_MAX)) {
161 maxParam = (Integer)converter.convertIfNecessary(argMap.get(ARGUMENT_MAX),Integer.class);
163 if(argMap.containsKey(ARGUMENT_OFFSET)) {
164 offsetParam = (Integer)converter.convertIfNecessary(argMap.get(ARGUMENT_OFFSET),Integer.class);
166 String orderParam = (String)argMap.get(ARGUMENT_ORDER);
167 Object fetchObj = argMap.get(ARGUMENT_FETCH);
168 if(fetchObj instanceof Map) {
169 Map fetch = (Map)fetchObj;
170 for (Iterator i = fetch.keySet().iterator(); i.hasNext();) {
171 String associationName = (String) i.next();
172 c.setFetchMode(associationName, getFetchMode(fetch.get(associationName)));
176 final String sort = (String)argMap.get(ARGUMENT_SORT);
177 final String order = ORDER_DESC.equalsIgnoreCase(orderParam) ? ORDER_DESC : ORDER_ASC;
178 final int max = maxParam == null ? -1 : maxParam.intValue();
179 final int offset = offsetParam == null ? -1 : offsetParam.intValue();
180 if(max > -1)
181 c.setMaxResults(max);
182 if(offset > -1)
183 c.setFirstResult(offset);
184 if(sort != null) {
185 boolean ignoreCase = true;
186 Object caseArg = argMap.get(ARGUMENT_IGNORE_CASE);
187 if(caseArg instanceof Boolean) {
188 ignoreCase = ((Boolean)caseArg).booleanValue();
190 if(ORDER_DESC.equals(order)) {
191 c.addOrder( ignoreCase ? Order.desc(sort).ignoreCase() : Order.desc(sort));
193 else {
194 c.addOrder( ignoreCase ? Order.asc(sort).ignoreCase() : Order.asc(sort) );
200 * Will retrieve the fetch mode for the specified instance other wise return the
201 * default FetchMode
203 * @param object The object, converted to a string
204 * @return The FetchMode
206 public static FetchMode getFetchMode(Object object) {
207 String name = object != null ? object.toString() : "default";
208 if(name.equals(FetchMode.JOIN.toString()) || name.equals("eager")) {
209 return FetchMode.JOIN;
211 else if(name.equals(FetchMode.SELECT.toString()) || name.equals("lazy")) {
212 return FetchMode.SELECT;
214 return FetchMode.DEFAULT;