1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.domain.hibernate;
17
18 import org.acegisecurity.domain.validation.IntrospectionManager;
19 import org.acegisecurity.domain.validation.ValidationRegistryManager;
20
21 import org.hibernate.EntityMode;
22 import org.hibernate.Hibernate;
23 import org.hibernate.HibernateException;
24 import org.hibernate.SessionFactory;
25
26 import org.hibernate.metadata.ClassMetadata;
27
28 import org.hibernate.type.Type;
29
30 import org.springframework.beans.factory.InitializingBean;
31
32 import org.springframework.orm.hibernate3.HibernateSystemException;
33
34 import org.springframework.util.Assert;
35
36 import java.util.Collection;
37 import java.util.Iterator;
38 import java.util.List;
39 import java.util.Map;
40
41
42 /***
43 * {@link IntrospectionManager} that uses Hibernate metadata to locate
44 * children.
45 *
46 * <p>
47 * Add children objects are added to the <code>List</code> of children objects
48 * to validate, irrespective of whether a save/update/delete operation will
49 * cascade to them. This is not a perfect solution, but addresses most
50 * real-world validation requirements (you can always implement your own
51 * <code>IntrospectionManager</code> if you prefer).
52 * </p>
53 *
54 * <p>
55 * This implementation only adds properties of a parent object that have a
56 * Hibernate {@link net.sf.hibernate.type.Type} that indicates it is an object
57 * type (ie {@link net.sf.hibernate.type.Type#isObjectType()}).
58 * </p>
59 *
60 * @author Matthew Porter
61 * @author Ben Alex
62 */
63 public class IntrospectionManagerHibernate implements IntrospectionManager,
64 InitializingBean {
65
66
67 private SessionFactory[] sessionFactories;
68 private ValidationRegistryManager validationRegistryManager;
69
70
71
72 public void setSessionFactories(SessionFactory[] sessionFactorys) {
73 this.sessionFactories = sessionFactorys;
74 }
75
76 public SessionFactory[] getSessionFactories() {
77 return this.sessionFactories;
78 }
79
80 public void setValidationRegistryManager(
81 ValidationRegistryManager validationRegistryManager) {
82 this.validationRegistryManager = validationRegistryManager;
83 }
84
85 public ValidationRegistryManager getValidationRegistryManager() {
86 return validationRegistryManager;
87 }
88
89 public void afterPropertiesSet() throws Exception {
90 Assert.notNull(validationRegistryManager, "ValidationRegistryManager is required");
91 Assert.notNull(sessionFactories, "SessionFactories are required");
92 Assert.notEmpty(sessionFactories, "SessionFactories are required");
93
94
95 for (int i = 0; i < sessionFactories.length; i++) {
96 Map<String,ClassMetadata> metadataMap = this.sessionFactories[i].getAllClassMetadata();
97 Collection<String> mappedClasses = metadataMap.keySet();
98
99 for (Iterator<String> iter = mappedClasses.iterator(); iter.hasNext();) {
100 String className = iter.next();
101 this.validationRegistryManager.findValidator(Class.forName(className));
102 }
103 }
104 }
105
106 public void obtainImmediateChildren(Object parentObject, List<Object> allObjects) {
107 Assert.notNull(parentObject,
108 "Violation of interface contract: parentObject null");
109 Assert.notNull(allObjects,
110 "Violation of interface contract: allObjects null");
111
112 ClassMetadata classMetadata = null;
113
114 try {
115 classMetadata = findMetadata(parentObject.getClass());
116
117 if (classMetadata != null) {
118 String[] propertyNames = classMetadata.getPropertyNames();
119
120 for (int i = 0; i < propertyNames.length; i++) {
121 Type propertyType = classMetadata.getPropertyType(propertyNames[i]);
122
123
124
125
126 if (this.validationRegistryManager.findValidator(
127 propertyType.getReturnedClass()) != null) {
128 Object childObject = classMetadata.getPropertyValue(parentObject, propertyNames[i], EntityMode.POJO);
129 if (childObject != null && Hibernate.isInitialized(childObject)) {
130 allObjects.add(childObject);
131 }
132 }
133 }
134 }
135 } catch (HibernateException he) {
136 throw new HibernateSystemException(he);
137 }
138 }
139
140 private ClassMetadata findMetadata(Class clazz) throws HibernateSystemException {
141 for (int i = 0; i < sessionFactories.length; i++) {
142 ClassMetadata result = sessionFactories[i].getClassMetadata(clazz);
143 if (result != null) {
144 return result;
145 }
146 }
147 return null;
148 }
149 }