1 /***
2 * Copyright (c) 2002, CodeStreet LLC. All rights reserved.
3 * <p>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * <p>
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer. Redistributions in binary
9 * form must reproduce the above copyright notice, this list of conditions and
10 * the following disclaimer in the documentation and/or other materials provided
11 * with the distribution. Neither the name of CodeStreet LLC. nor the names of
12 * its contributors may be used to endorse or promote products derived from this
13 * software without specific prior written permission.
14 * <p>
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 * <p>
27 */
28 package com.codestreet.messageforge;
29
30 import java.lang.reflect.Method;
31 import java.lang.reflect.Modifier;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.Map;
35 import java.util.Iterator;
36
37 /***
38 * @author jawaid.hakim
39 */
40 public abstract class BeanFactory
41 {
42 /***
43 * Create bean information using reflection. All public getter/setter pairs
44 * are identified. In addition, if <code>private</code> array support has
45 * been requested then all getter/setter pairs that operate on arrays are
46 * also identified.
47 *
48 * @param name
49 * Bean name.
50 * @param bean
51 * Bean class.
52 * @return Bean information.
53 * @see #setAccessPrivateArrays(boolean)
54 */
55 public static RBeanInfo createBeanInfo(String name, Class bean)
56 {
57 try
58 {
59 RBeanInfo info = (RBeanInfo) beanInfo_.get(name);
60 if (info != null)
61 return info;
62
63 if (bean == null)
64 return null;
65
66 Map getters = EMPTY;
67 Map setters = EMPTY;
68
69 Class beanCls = bean;
70 Map allSetterMethods = new HashMap();
71 Method[] allPublicMethods = beanCls.getMethods();
72 for (int i = 0; i < allPublicMethods.length; ++i)
73 {
74 Method setterMethod = allPublicMethods[i];
75 String setterName = setterMethod.getName();
76 if (setterName.startsWith("set")
77 && !allSetterMethods.containsKey(setterName))
78 {
79 allSetterMethods.put(setterName, setterMethod);
80 }
81 }
82 Method[] declMethods = beanCls.getDeclaredMethods();
83 for (int i = 0; i < declMethods.length; ++i)
84 {
85 Method setterMethod = declMethods[i];
86 String setterName = setterMethod.getName();
87 if (setterName.startsWith("set")
88 && !allSetterMethods.containsKey(setterName))
89 {
90 allSetterMethods.put(setterName, setterMethod);
91 }
92 }
93
94 for (Iterator iter = allSetterMethods.values().iterator(); iter
95 .hasNext();)
96 {
97 Method setterMethod = (Method) iter.next();
98 String setterName = setterMethod.getName();
99 if (setterName.startsWith("set"))
100 {
101 int modifiers = setterMethod.getModifiers();
102 Class[] paramTypes = setterMethod.getParameterTypes();
103 if (paramTypes.length == 1 && !Modifier.isNative(modifiers))
104 {
105 boolean isPublic = Modifier.isPublic(modifiers);
106 boolean qualifies = isPublic;
107 if (!isPublic && processPrivateArrays)
108 {
109 qualifies = paramTypes[0].isArray();
110 if (qualifies)
111 {
112 try
113 {
114 setterMethod.setAccessible(true);
115 }
116 catch (Exception ex)
117 {
118 continue;
119 }
120 }
121 }
122 if (qualifies)
123 {
124 String getterName = setterName.replaceFirst("set",
125 "get");
126 Method getterMethod = null;
127 try
128 {
129 getterMethod = beanCls.getDeclaredMethod(
130 getterName, null);
131 }
132 catch (NoSuchMethodException ex)
133 {
134 try
135 {
136 getterMethod = beanCls.getMethod(
137 getterName, null);
138 }
139 catch (NoSuchMethodException ex2)
140 {
141 continue;
142 }
143 }
144
145 if (!isPublic)
146 {
147 try
148 {
149 getterMethod.setAccessible(true);
150 }
151 catch (Exception ex)
152 {
153 continue;
154 }
155 }
156 if (getters == EMPTY)
157 {
158 getters = new HashMap();
159 setters = new HashMap();
160 }
161 String propertyName = getterName.substring(3);
162 getters.put(propertyName, getterMethod);
163 setters.put(propertyName, setterMethod);
164 }
165 }
166 }
167 }
168
169 if (getters != EMPTY)
170 info = new RBeanInfo(name,
171 Collections.unmodifiableMap(getters), Collections
172 .unmodifiableMap(setters));
173 else
174 info = new RBeanInfo(name, EMPTY, EMPTY);
175
176 beanInfo_.put(name, info);
177
178 return info;
179 }
180 catch (Exception e)
181 {
182 return new RBeanInfo(name, EMPTY, EMPTY);
183 }
184 }
185
186 /***
187 * Set flag to indicate whether private array fields should be accessed.
188 * When this flag is set to <code>true</code> the bean factory identifies
189 * <code>private</code> getter/setter pais that operate on arrays. An
190 * attempt is made to set the accessibility for each identified pair to
191 * <code>true</code>. If the attempt to set the accessibility succeeds
192 * then the private getter/setter pair is added to the bean's information
193 * set.
194 *
195 * @param flag
196 * Flag to indicate whether private array fields should be
197 * accessed. Default is <code>true</code>. If this is set to
198 * <code>true</code> then <code>private</code> array fields
199 * will be accessed.
200 * @see #createBeanInfo(String, Class)
201 */
202 public static void setAccessPrivateArrays(boolean flag)
203 {
204 processPrivateArrays = flag;
205 }
206
207 private static Map beanInfo_ = new HashMap();
208
209 private static final Map EMPTY = Collections.unmodifiableMap(new HashMap());
210
211 public static boolean processPrivateArrays = false;
212 }
This page was automatically generated by Maven