KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > framework > WrapDynaClass


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
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
17 package org.oddjob.framework;
18
19
20 import java.beans.PropertyDescriptor JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.ObjectInputStream JavaDoc;
23 import java.io.ObjectOutputStream JavaDoc;
24 import java.io.Serializable JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.List JavaDoc;
28
29 import org.apache.commons.beanutils.DynaBean;
30 import org.apache.commons.beanutils.DynaClass;
31 import org.apache.commons.beanutils.DynaProperty;
32 import org.apache.commons.beanutils.PropertyUtils;
33
34
35 /**
36  * <p>Implementation of <code>DynaClass</code> for DynaBeans that wrap
37  * standard JavaBean instances.</p>
38  * <p>
39  * Based on the BeanUtils version but Serializable.
40  *
41  * @author Rob Gorodon, based on the original from BeanUtils.
42  */

43
44 public class WrapDynaClass implements DynaClass, Serializable JavaDoc {
45     private static final long serialVersionUID = 20051114;
46
47     // ----------------------------------------------------------- Constructors
48

49
50     /**
51      * Construct a new WrapDynaClass for the specified JavaBean class. This
52      * constructor is private; WrapDynaClass instances will be created as
53      * needed via calls to the <code>createDynaClass(Class)</code> method.
54      *
55      * @param beanClass JavaBean class to be introspected around
56      */

57     private WrapDynaClass(Class JavaDoc beanClass) {
58
59         this.beanClassName = beanClass.getName();
60         introspect(beanClass);
61
62     }
63
64
65     // ----------------------------------------------------- Instance Variables
66

67
68     /**
69      * The JavaBean <code>Class</code> which is represented by this
70      * <code>WrapDynaClass</code>.
71      */

72     private final String JavaDoc beanClassName;
73
74     /**
75      * The set of dynamic properties that are part of this DynaClass.
76      */

77     private DynaProperty properties[] = null;
78
79
80     /**
81      * The set of dynamic properties that are part of this DynaClass,
82      * keyed by the property name. Individual descriptor instances will
83      * be the same instances as those in the <code>properties</code> list.
84      */

85     private HashMap JavaDoc propertiesMap = new HashMap JavaDoc();
86
87
88     // ------------------------------------------------------- Static Variables
89

90
91     /**
92      * The set of <code>WrapDynaClass</code> instances that have ever been
93      * created, keyed by the underlying bean Class.
94      */

95     private static HashMap JavaDoc dynaClasses = new HashMap JavaDoc();
96
97
98     // ------------------------------------------------------ DynaClass Methods
99

100
101     /**
102      * Return the name of this DynaClass (analogous to the
103      * <code>getName()</code> method of <code>java.lang.Class</code), which
104      * allows the same <code>DynaClass</code> implementation class to support
105      * different dynamic classes, with different sets of properties.
106      */

107     public String JavaDoc getName() {
108         return (this.beanClassName);
109     }
110
111
112     /**
113      * Return a property descriptor for the specified property, if it exists;
114      * otherwise, return <code>null</code>.
115      *
116      * @param name Name of the dynamic property for which a descriptor
117      * is requested
118      *
119      * @exception IllegalArgumentException if no property name is specified
120      */

121     public DynaProperty getDynaProperty(String JavaDoc name) {
122         if (name == null) {
123             throw new IllegalArgumentException JavaDoc
124                     ("No property name specified");
125         }
126         return ((DynaProperty) propertiesMap.get(name));
127     }
128
129
130     /**
131      * <p>Return an array of <code>ProperyDescriptors</code> for the properties
132      * currently defined in this DynaClass. If no properties are defined, a
133      * zero-length array will be returned.</p>
134      *
135      * <p><strong>FIXME</strong> - Should we really be implementing
136      * <code>getBeanInfo()</code> instead, which returns property descriptors
137      * and a bunch of other stuff?</p>
138      */

139     public DynaProperty[] getDynaProperties() {
140         return (properties);
141     }
142
143     /**
144      * Unsupported.
145      *
146      * @throws UnsupportedOperationException Always.
147      */

148     public DynaBean newInstance()
149             throws UnsupportedOperationException JavaDoc {
150         throw new UnsupportedOperationException JavaDoc("Can't create bean instances with this DynaClass.");
151     }
152
153
154     // --------------------------------------------------------- Static Methods
155

156
157     /**
158      * Clear our cache of WrapDynaClass instances.
159      */

160     public static void clear() {
161         synchronized (dynaClasses) {
162             dynaClasses.clear();
163         }
164     }
165
166
167     /**
168      * Create (if necessary) and return a new <code>WrapDynaClass</code>
169      * instance for the specified bean class.
170      *
171      * @param beanClass Bean class for which a WrapDynaClass is requested
172      */

173     public static WrapDynaClass createDynaClass(Class JavaDoc beanClass) {
174
175         synchronized (dynaClasses) {
176             WrapDynaClass dynaClass =
177                     (WrapDynaClass) dynaClasses.get(beanClass);
178             if (dynaClass == null) {
179                 dynaClass = new WrapDynaClass(beanClass);
180                 dynaClasses.put(beanClass, dynaClass);
181             }
182             return (dynaClass);
183         }
184
185     }
186
187
188     // ------------------------------------------------------ Protected Methods
189

190
191     /**
192      * Introspect our bean class to identify the supported properties.
193      */

194     protected void introspect(Class JavaDoc beanClass) {
195
196         // Look up the property descriptors for this bean class
197
PropertyDescriptor JavaDoc regulars[] =
198                 PropertyUtils.getPropertyDescriptors(beanClass);
199         if (regulars == null) {
200             regulars = new PropertyDescriptor JavaDoc[0];
201         }
202
203         // Construct corresponding DynaProperty information
204
List JavaDoc propertyList = new ArrayList JavaDoc();
205         for (int i = 0; i < regulars.length; i++) {
206             if (regulars[i].getReadMethod() == null) {
207                 continue;
208             }
209             DynaProperty dynaProperty = new DynaProperty(regulars[i].getName(),
210                     regulars[i].getPropertyType());
211             propertyList.add(dynaProperty);
212             propertiesMap.put(dynaProperty.getName(),
213                     dynaProperty);
214         }
215         properties = (DynaProperty[]) propertyList.toArray(new DynaProperty[0]);
216     }
217
218     /*
219      * Custom serialization.
220      */

221     private void writeObject(ObjectOutputStream JavaDoc s)
222     throws IOException JavaDoc {
223         s.defaultWriteObject();
224     }
225     
226     /*
227      * Custom serialization.
228      */

229     private void readObject(ObjectInputStream JavaDoc s)
230     throws IOException JavaDoc, ClassNotFoundException JavaDoc {
231         s.defaultReadObject();
232     }
233
234 }
235
Popular Tags