KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > directwebremoting > hibernate > H3BeanConverter


1 /*
2  * Copyright 2005 Joe Walker
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.directwebremoting.hibernate;
17
18 import java.beans.BeanInfo JavaDoc;
19 import java.beans.IntrospectionException JavaDoc;
20 import java.beans.Introspector JavaDoc;
21 import java.beans.PropertyDescriptor JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import org.directwebremoting.convert.BeanConverter;
27 import org.directwebremoting.convert.PlainProperty;
28 import org.directwebremoting.extend.Converter;
29 import org.directwebremoting.extend.MarshallException;
30 import org.directwebremoting.util.Logger;
31 import org.hibernate.Hibernate;
32 import org.hibernate.engine.SessionImplementor;
33 import org.hibernate.proxy.HibernateProxy;
34 import org.hibernate.proxy.LazyInitializer;
35
36 /**
37  * BeanConverter that works with Hibernate to get BeanInfo.
38  * @author Joe Walker [joe at getahead dot ltd dot uk]
39  */

40 public class H3BeanConverter extends BeanConverter implements Converter
41 {
42     /* (non-Javadoc)
43      * @see org.directwebremoting.convert.BeanConverter#getPropertyMapFromObject(java.lang.Object, boolean, boolean)
44      */

45     public Map JavaDoc getPropertyMapFromObject(Object JavaDoc example, boolean readRequired, boolean writeRequired) throws MarshallException
46     {
47         Class JavaDoc clazz = getClass(example);
48
49         try
50         {
51             BeanInfo JavaDoc info = Introspector.getBeanInfo(clazz);
52             PropertyDescriptor JavaDoc[] descriptors = info.getPropertyDescriptors();
53
54             Map JavaDoc properties = new HashMap JavaDoc();
55             for (int i = 0; i < descriptors.length; i++)
56             {
57                 PropertyDescriptor JavaDoc descriptor = descriptors[i];
58                 String JavaDoc name = descriptor.getName();
59
60                 // We don't marshall getClass()
61
if (name.equals("class"))
62                 {
63                     continue;
64                 }
65
66                 // And this is something added by hibernate
67
if (name.equals("hibernateLazyInitializer"))
68                 {
69                     continue;
70                 }
71
72                 // Access rules mean we might not want to do this one
73
if (!isAllowedByIncludeExcludeRules(name))
74                 {
75                     continue;
76                 }
77
78                 if (readRequired && descriptor.getReadMethod() == null)
79                 {
80                     continue;
81                 }
82
83                 if (writeRequired && descriptor.getWriteMethod() == null)
84                 {
85                     continue;
86                 }
87
88                 if (!assumeSession)
89                 {
90                     // We don't marshall un-initialized properties for
91
// Hibernate3
92
String JavaDoc propertyName = descriptor.getName();
93                     Method JavaDoc method = findGetter(example, propertyName);
94
95                     if (method == null)
96                     {
97                         log.warn("Failed to find property: " + propertyName);
98
99                         properties.put(name, new PlainProperty(propertyName, null));
100                         continue;
101                     }
102
103                     if (!Hibernate.isPropertyInitialized(example, propertyName))
104                     {
105                         properties.put(name, new PlainProperty(propertyName, null));
106                         continue;
107                     }
108
109                     // This might be a lazy-collection so we need to double check
110
Object JavaDoc retval = method.invoke(example, new Object JavaDoc[] {});
111                     if (!Hibernate.isInitialized(retval))
112                     {
113                         properties.put(name, new PlainProperty(propertyName, null));
114                         continue;
115                     }
116                 }
117
118                 properties.put(name, new H3PropertyDescriptorProperty(descriptor));
119             }
120
121             return properties;
122         }
123         catch (Exception JavaDoc ex)
124         {
125             throw new MarshallException(clazz, ex);
126         }
127     }
128
129     /**
130      * Hibernate makes {@link Class#getClass()} diffficult ...
131      * @param example The class that we want to call {@link Class#getClass()} on
132      * @return The type of the given object
133      */

134     public Class JavaDoc getClass(Object JavaDoc example)
135     {
136         if (example instanceof HibernateProxy)
137         {
138             HibernateProxy proxy = (HibernateProxy) example;
139             LazyInitializer initializer = proxy.getHibernateLazyInitializer();
140             SessionImplementor implementor = initializer.getSession();
141
142             if (initializer.isUninitialized())
143             {
144                 try
145                 {
146                     // getImplementation is going to want to talk to a session
147
if (implementor.isClosed())
148                     {
149                         // Give up and return example.getClass();
150
return example.getClass();
151                     }
152                 }
153                 catch (NoSuchMethodError JavaDoc ex)
154                 {
155                     // We must be using Hibernate 3.0/3.1 which doesn't have
156
// this method
157
}
158             }
159
160             return initializer.getImplementation().getClass();
161         }
162         else
163         {
164             return example.getClass();
165         }
166     }
167
168     /**
169      * Cache the method if possible, using the classname and property name to
170      * allow for similar named methods.
171      * @param data The bean to introspect
172      * @param property The property to get the accessor for
173      * @return The getter method
174      * @throws IntrospectionException
175      */

176     protected Method JavaDoc findGetter(Object JavaDoc data, String JavaDoc property) throws IntrospectionException JavaDoc
177     {
178         String JavaDoc key = data.getClass().getName() + ":" + property;
179
180         Method JavaDoc method = (Method JavaDoc) methods.get(key);
181         if (method == null)
182         {
183             PropertyDescriptor JavaDoc[] props = Introspector.getBeanInfo(data.getClass()).getPropertyDescriptors();
184             for (int i = 0; i < props.length; i++)
185             {
186                 if (props[i].getName().equalsIgnoreCase(property))
187                 {
188                     method = props[i].getReadMethod();
189                 }
190             }
191
192             methods.put(key, method);
193         }
194
195         return method;
196     }
197
198     /**
199      * @param assumeSession the assumeSession to set
200      */

201     public void setAssumeSession(boolean assumeSession)
202     {
203         this.assumeSession = assumeSession;
204     }
205
206     /**
207      * Do we assume there is an open session and read properties?
208      */

209     protected boolean assumeSession = false;
210
211     /**
212      * The cache of method lookups that we've already done
213      */

214     protected static final Map JavaDoc methods = new HashMap JavaDoc();
215
216     /**
217      * The log stream
218      */

219     private static final Logger log = Logger.getLogger(H3BeanConverter.class);
220 }
221
Popular Tags