1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.morph.reflect.reflectors;
17
18 import java.util.Iterator;
19 import java.util.LinkedList;
20 import java.util.List;
21 import java.util.Set;
22
23 import net.sf.composite.SpecializableComposite;
24 import net.sf.composite.StrictlyTypedComposite;
25 import net.sf.composite.util.ObjectUtils;
26 import net.sf.morph.reflect.BeanReflector;
27 import net.sf.morph.reflect.CompositeReflector;
28 import net.sf.morph.reflect.ContainerReflector;
29 import net.sf.morph.reflect.DecoratedReflector;
30 import net.sf.morph.reflect.GrowableContainerReflector;
31 import net.sf.morph.reflect.IndexedContainerReflector;
32 import net.sf.morph.reflect.InstantiatingReflector;
33 import net.sf.morph.reflect.MutableIndexedContainerReflector;
34 import net.sf.morph.reflect.ReflectionException;
35 import net.sf.morph.reflect.Reflector;
36 import net.sf.morph.reflect.SizableReflector;
37 import net.sf.morph.util.ClassUtils;
38 import net.sf.morph.util.ContainerUtils;
39 import net.sf.morph.util.ReflectorUtils;
40
41 /**
42 * Reflector that can be used to combine multiple bean reflectors. By default,
43 * a new instance of this reflector will include all reflectors defined in
44 * Morph except the MapReflector (the MapBeanReflector is used
45 * instead).
46 *
47 * @author Matt Sgarlata
48 * @since Dec 13, 2004
49 */
50 public class SimpleDelegatingReflector extends BaseCompositeReflector implements
51 DecoratedReflector, StrictlyTypedComposite, SpecializableComposite,
52 BeanReflector, ContainerReflector, GrowableContainerReflector,
53 IndexedContainerReflector, InstantiatingReflector,
54 MutableIndexedContainerReflector, CompositeReflector, Cloneable {
55
56 /**
57 * Construct a new SimpleDelegatingReflector.
58 */
59 public SimpleDelegatingReflector() {
60 this(null, true);
61 }
62
63 /**
64 * Construct a new SimpleDelegatingReflector.
65 * @param components
66 */
67 public SimpleDelegatingReflector(Reflector[] components) {
68 this(components, false);
69 }
70
71 /**
72 * Construct a new SimpleDelegatingReflector.
73 * @param components
74 * @param appendDefaultComponents if true, the components returned from createDefaultComponents() will be added.
75 */
76 public SimpleDelegatingReflector(Reflector[] components, boolean appendDefaultComponents) {
77 if (appendDefaultComponents) {
78 Reflector[] defaultComponents = createDefaultComponents();
79 if (ObjectUtils.isEmpty(components)) {
80 components = defaultComponents;
81 }
82 else {
83
84 Reflector[] newComponents = (Reflector[]) ClassUtils.createArray(
85 getComponentType(), components.length + defaultComponents.length);
86 System.arraycopy(components, 0, newComponents, 0, components.length);
87 System.arraycopy(defaultComponents, 0, newComponents, components.length, defaultComponents.length);
88 components = newComponents;
89 }
90 }
91 setComponents(components);
92 }
93
94 protected Reflector[] createDefaultComponents() {
95 List componentList = new LinkedList();
96
97
98 componentList.add(new ListReflector());
99 componentList.add(new SortedSetReflector());
100 componentList.add(new SetReflector());
101 componentList.add(new StringTokenizerReflector());
102 componentList.add(new ResetableIteratorWrapperReflector());
103 componentList.add(new EnumerationReflector());
104 componentList.add(new IteratorReflector());
105
106 componentList.add(new ArrayReflector(this));
107 componentList.add(new CollectionReflector());
108
109
110 componentList.add(new ResultSetReflector());
111
112
113
114 componentList.add(new ContextReflector());
115
116
117
118 componentList.add(new MapReflector());
119
120
121 if (ClassUtils.isServletApiPresent()) {
122 componentList.add(new ServletRequestReflector());
123 componentList.add(new HttpSessionAttributeReflector());
124 componentList.add(new ServletContextAttributeReflector());
125 }
126 if (ClassUtils.isJspApiPresent()) {
127 componentList.add(new PageContextAttributeReflector());
128 }
129 if (ClassUtils.isBeanUtilsPresent()) {
130 componentList.add(new DynaBeanReflector());
131 }
132 componentList.add(new SimpleInstantiatingReflector());
133 componentList.add(new ObjectReflector());
134
135 return (Reflector[]) componentList.toArray(new Reflector[componentList.size()]);
136 }
137
138
139
140 protected void initializeImpl() throws Exception {
141 super.initializeImpl();
142 getComponentValidator().validate(this);
143 }
144
145 protected Class[] getReflectableClassesImpl() {
146 Set set = ContainerUtils.createOrderedSet();
147 Object[] reflectors = getComponents();
148 for (int i = 0; i < reflectors.length; i++) {
149 Class[] reflectableClasses = ((Reflector) reflectors[i]).getReflectableClasses();
150 for (int j = 0; j < reflectableClasses.length; j++) {
151 set.add(reflectableClasses[j]);
152 }
153 }
154 return (Class[]) set.toArray(new Class[set.size()]);
155 }
156
157
158
159 protected Object getImpl(Object bean, String propertyName) throws Exception {
160 return getBeanReflector(bean).get(bean, propertyName);
161 }
162
163 protected String[] getPropertyNamesImpl(Object bean) throws Exception {
164 return getBeanReflector(bean).getPropertyNames(bean);
165 }
166
167 protected Class getTypeImpl(Object bean, String propertyName)
168 throws Exception {
169 return getBeanReflector(bean).getType(bean, propertyName);
170 }
171
172 protected boolean isReadableImpl(Object bean, String propertyName)
173 throws Exception {
174 return getBeanReflector(bean).isReadable(bean, propertyName);
175 }
176
177 protected boolean isWriteableImpl(Object bean, String propertyName)
178 throws Exception {
179 return getBeanReflector(bean).isWriteable(bean, propertyName);
180 }
181
182 protected void setImpl(Object bean, String propertyName, Object value)
183 throws Exception {
184 getBeanReflector(bean).set(bean, propertyName, value);
185 }
186
187
188
189 protected Iterator getIteratorImpl(Object container) throws Exception {
190 return getContainerReflector(container).getIterator(container);
191 }
192
193 protected Class getContainedTypeImpl(Class clazz) throws Exception {
194 return getContainerReflectorForClass(clazz).getContainedType(clazz);
195 }
196
197
198
199 protected int getSizeImpl(Object container) throws Exception {
200 return getSizableReflector(container).getSize(container);
201 }
202
203
204
205 protected boolean addImpl(Object container, Object value) throws Exception {
206 return getGrowableContainerReflector(container).add(container, value);
207 }
208
209
210
211 protected Object getImpl(Object container, int index) throws Exception {
212 return getIndexedContainerReflector(container).get(container, index);
213 }
214
215
216
217 protected Object setImpl(Object container, int index, Object propertyValue)
218 throws Exception {
219 return getMutableIndexedContainerReflector(container).set(container, index, propertyValue);
220 }
221
222 protected Object newInstanceImpl(Class clazz, Object parameters) throws Exception {
223 InstantiatingReflector reflector = getInstantiatingReflectorForClass(clazz);
224 return reflector.newInstance(clazz, parameters);
225 }
226
227 public boolean isReflectableImpl(Class reflectedType, Class reflectorType)
228 throws ReflectionException {
229 return safeGetReflector(reflectorType, reflectedType) != null;
230 }
231
232 protected Reflector getReflector(Class reflectorType, Class reflectedType) {
233 Reflector result = safeGetReflector(reflectorType, reflectedType);
234 if (result == null) {
235 throw new ReflectionException("Could not find a "
236 + ClassUtils.getUnqualifiedClassName(reflectorType)
237 + " that can reflect "
238 + ObjectUtils.getObjectDescription(reflectedType));
239 }
240 return result;
241 }
242
243 private Reflector safeGetReflector(Class reflectorType, Class reflectedType) {
244 for (int i = 0; i < getComponents().length; i++) {
245 Reflector component = (Reflector) getComponents()[i];
246 if (ReflectorUtils.isReflectable(component, reflectedType, reflectorType)) {
247 if (log.isTraceEnabled()) {
248 log.trace("Using "
249 + component.getClass().getName()
250 + " to reflect "
251 + ObjectUtils.getObjectDescription(reflectedType));
252 }
253 return component;
254 }
255 }
256 return null;
257 }
258
259 protected BeanReflector getBeanReflector(Object bean) {
260 return (BeanReflector) getReflector(BeanReflector.class, bean.getClass());
261 }
262
263 protected ContainerReflector getContainerReflector(Object bean) {
264 return (ContainerReflector) getReflector(ContainerReflector.class, bean.getClass());
265 }
266
267 protected ContainerReflector getContainerReflectorForClass(Class reflectedClass) {
268 return (ContainerReflector) getReflector(ContainerReflector.class, reflectedClass);
269 }
270
271 protected GrowableContainerReflector getGrowableContainerReflector(Object bean) {
272 return (GrowableContainerReflector) getReflector(GrowableContainerReflector.class, bean.getClass());
273 }
274
275 protected SizableReflector getSizableReflector(Object bean) {
276 return (SizableReflector) getReflector(SizableReflector.class, bean.getClass());
277 }
278
279 protected IndexedContainerReflector getIndexedContainerReflector(Object bean) {
280 return (IndexedContainerReflector) getReflector(IndexedContainerReflector.class, bean.getClass());
281 }
282
283 protected MutableIndexedContainerReflector getMutableIndexedContainerReflector(Object bean) {
284 return (MutableIndexedContainerReflector) getReflector(MutableIndexedContainerReflector.class, bean.getClass());
285 }
286
287 protected InstantiatingReflector getInstantiatingReflectorForClass(Class clazz) {
288 return (InstantiatingReflector) getReflector(InstantiatingReflector.class, clazz);
289 }
290
291
292 public Object[] getComponents() {
293 if (super.getComponents() == null) {
294 setComponents(createDefaultComponents());
295 }
296 return super.getComponents();
297 }
298
299 }