View Javadoc

1   /*
2    * Copyright 2004-2005, 2007-2008 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * 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, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package net.sf.morph.reflect.reflectors;
17  
18  import java.util.Arrays;
19  import java.util.Iterator;
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.morph.reflect.BeanReflector;
26  import net.sf.morph.reflect.CompositeReflector;
27  import net.sf.morph.reflect.ContainerReflector;
28  import net.sf.morph.reflect.DecoratedReflector;
29  import net.sf.morph.reflect.GrowableContainerReflector;
30  import net.sf.morph.reflect.IndexedContainerReflector;
31  import net.sf.morph.reflect.InstantiatingReflector;
32  import net.sf.morph.reflect.MutableIndexedContainerReflector;
33  import net.sf.morph.reflect.NoReflectorFoundException;
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   * 
43   * 
44   * @author Matt Sgarlata
45   * @since Morph 1.1 (Oct 25, 2007)
46   */
47  public class StubbornDelegatingReflector extends BaseCompositeReflector implements
48          DecoratedReflector, StrictlyTypedComposite, SpecializableComposite,
49          BeanReflector, ContainerReflector, GrowableContainerReflector,
50          IndexedContainerReflector, InstantiatingReflector,
51          MutableIndexedContainerReflector, CompositeReflector, Cloneable {
52  
53  	/**
54  	 * Construct a new SimpleDelegatingReflector.
55  	 */
56  	public StubbornDelegatingReflector() {
57  		this(null);
58  	}
59  
60  	/**
61  	 * Construct a new SimpleDelegatingReflector.
62  	 * @param components
63  	 */
64  	public StubbornDelegatingReflector(Object[] components) {
65  		setComponents(components);
66  	}
67  
68  // internal state initialization/validation
69  
70  	protected void initializeImpl() throws Exception {
71  		super.initializeImpl();
72  		getComponentValidator().validate(this);
73  	}
74  
75  	protected Class[] getReflectableClassesImpl() {
76  		Set set = ContainerUtils.createOrderedSet();
77  		Object[] reflectors = getComponents();
78  		for (int i = 0; i < reflectors.length; i++) {
79  			Class[] reflectableClasses = ((Reflector) reflectors[i]).getReflectableClasses();
80  			for (int j = 0; j < reflectableClasses.length; j++) {
81  				set.add(reflectableClasses[j]);
82  			}
83  		}
84  		return (Class[]) set.toArray(new Class[set.size()]);
85  	}
86  
87  // bean reflectors
88  
89  	protected Object getImpl(Object bean, String propertyName) throws Exception {
90  		Object[] reflectors = getComponents();
91  		boolean reflectorFound = false;
92  		Object value = null;
93  		for (int i=0; i<reflectors.length; i++) {
94  			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], bean, BeanReflector.class)) {				
95  				reflectorFound = true;
96  				BeanReflector beanReflector = (BeanReflector) reflectors[i];
97  				value = beanReflector.get(bean, propertyName);
98  				if (value != null) {
99  					return value;
100 				}
101 			}
102 		}
103 		
104 		if (reflectorFound) {
105 			// value will be null, but returning value here for the sake of
106 			// clarity
107 			return value;
108 		}
109 		else {
110 			throw new NoReflectorFoundException(bean, BeanReflector.class);
111 		}
112 	}
113 	
114 	protected String[] getPropertyNamesImpl(Object bean) throws Exception {
115 		Set propertyNames = ContainerUtils.createOrderedSet();
116 		Object[] reflectors = getComponents();
117 		boolean reflectorFound = false;
118 		for (int i=0; i<reflectors.length; i++) {
119 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], bean, BeanReflector.class)) {
120 				reflectorFound = true;
121 				BeanReflector beanReflector = (BeanReflector) reflectors[i];
122 				String[] propertyNamesArray = beanReflector.getPropertyNames(bean);
123 				List propertyNamesList = Arrays.asList(propertyNamesArray);
124 				propertyNames.addAll(propertyNamesList);
125 			}
126 		}
127 		if (reflectorFound) {
128 			return (String[]) propertyNames.toArray(new String[propertyNames.size()]);
129 		}
130 		else {
131 			throw new NoReflectorFoundException(bean, BeanReflector.class);
132 		}
133 	}
134 
135 	/**
136 	 * Default implementation finds the first reflector that returns a non-null
137 	 * value for the given property and returns the type of that value.  If no
138 	 * non-null value could be found, returns the type that is returned by
139 	 * the first BeanReflector that is a component of this reflector.
140 	 */
141 	protected Class getTypeImpl(Object bean, String propertyName)
142 		throws Exception {
143 		// first search for a non-null value
144 		Object[] reflectors = getComponents();
145 		Object value = null;
146 		for (int i=0; i<reflectors.length; i++) {
147 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], bean, BeanReflector.class)) {				
148 				BeanReflector beanReflector = (BeanReflector) reflectors[i];
149 				value = beanReflector.get(bean, propertyName);
150 				if (value != null) {
151 					break;
152 				}
153 			}
154 		}	
155 		// if a non-null value was found, return that value's type
156 		if (value != null) {
157 			return ClassUtils.getClass(value);
158 		}
159 		
160 		// if no non-null value was found, return the type of that is returned
161 		// by the first BeanReflector that is a component of this reflector
162 		reflectors = getComponents();
163 		for (int i=0; i<reflectors.length; i++) {
164 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], bean, BeanReflector.class)) {				
165 				BeanReflector reflector = (BeanReflector) reflectors[i];
166 				return reflector.getType(bean, propertyName);
167 			}
168 		}
169 		
170 		throw new NoReflectorFoundException(bean, BeanReflector.class);
171 	}
172 
173 	protected boolean isReadableImpl(Object bean, String propertyName)
174 		throws Exception {
175 		Object[] reflectors = getComponents();
176 		boolean reflectorFound = false;
177 		for (int i=0; i<reflectors.length; i++) {
178 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], bean, BeanReflector.class)) {
179 				reflectorFound = true;
180 				BeanReflector beanReflector = (BeanReflector) reflectors[i];
181 				if (beanReflector.isReadable(bean, propertyName)) {
182 					return true;
183 				}
184 			}
185 		}
186 		
187 		if (reflectorFound) {
188 			// if we reached here without returning true, the property isn't
189 			// readable
190 			return false;
191 		}
192 		else {
193 			throw new NoReflectorFoundException(bean, BeanReflector.class);
194 		}
195 	}
196 
197 	protected boolean isWriteableImpl(Object bean, String propertyName)
198 		throws Exception {
199 		Object[] reflectors = getComponents();
200 		boolean reflectorFound = false;
201 		for (int i=0; i<reflectors.length; i++) {
202 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], bean, BeanReflector.class)) {
203 				reflectorFound = true;
204 				BeanReflector reflector = (BeanReflector) reflectors[i];
205 				if (reflector.isWriteable(bean, propertyName)) {
206 					return true;
207 				}
208 			}
209 		}
210 		
211 		if (reflectorFound) {
212 			// if we reached here without returning true, the property isn't
213 			// readable
214 			return false;
215 		}
216 		else {
217 			throw new NoReflectorFoundException(bean, BeanReflector.class);
218 		}
219 	}
220 
221 	protected void setImpl(Object bean, String propertyName, Object value)
222 		throws Exception {
223 		Object[] reflectors = getComponents();
224 		Exception exception = null;
225 		for (int i=0; i<reflectors.length; i++) {
226 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], bean, BeanReflector.class)) {				
227 				BeanReflector reflector = (BeanReflector) reflectors[i];
228 				if (reflector.isWriteable(bean, propertyName)) {
229 					try {
230 						reflector.set(bean, propertyName, value);
231 						return;
232 					}
233 					catch (ReflectionException e) {
234 						exception = e;
235 					}					
236 				}
237 			}
238 		}
239 		
240 		if (exception == null) {
241 			throw new NoReflectorFoundException(bean, BeanReflector.class);
242 		}
243 		else {
244 			throw exception;
245 		}
246 	}
247 
248 // container reflectors
249 
250 	protected Iterator getIteratorImpl(Object container) throws Exception {
251 		Object[] reflectors = getComponents();
252 		Exception exception = null;
253 		for (int i=0; i<reflectors.length; i++) {
254 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], container, ContainerReflector.class)) {				
255 				ContainerReflector reflector = (ContainerReflector) reflectors[i];
256 				try {
257 					return reflector.getIterator(container);
258 				}
259 				catch (ReflectionException e) {
260 					exception = e;
261 				}					
262 			}
263 		}
264 		
265 		if (exception == null) {
266 			throw new NoReflectorFoundException(container, ContainerReflector.class);
267 		}
268 		else {
269 			throw exception;
270 		}
271 	}
272 
273 	protected Class getContainedTypeImpl(Class clazz) throws Exception {
274 		Object[] reflectors = getComponents();
275 		Exception exception = null;
276 		for (int i=0; i<reflectors.length; i++) {
277 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], clazz, ContainerReflector.class)) {				
278 				ContainerReflector reflector = (ContainerReflector) reflectors[i];
279 				try {
280 					return reflector.getContainedType(clazz);
281 				}
282 				catch (ReflectionException e) {
283 					exception = e;
284 				}					
285 			}
286 		}
287 		
288 		if (exception == null) {
289 			throw new NoReflectorFoundException(clazz, ContainerReflector.class);
290 		}
291 		else {
292 			throw exception;
293 		}
294 	}
295 
296 // sizable reflectors
297 
298 	protected int getSizeImpl(Object container) throws Exception {
299 		Object[] reflectors = getComponents();
300 		Exception exception = null;
301 		for (int i=0; i<reflectors.length; i++) {
302 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], container, ContainerReflector.class)) {				
303 				SizableReflector reflector = (SizableReflector) reflectors[i];
304 				try {
305 					return reflector.getSize(container);
306 				}
307 				catch (ReflectionException e) {
308 					exception = e;
309 				}					
310 			}
311 		}
312 		
313 		if (exception == null) {
314 			throw new NoReflectorFoundException(container, ContainerReflector.class);
315 		}
316 		else {
317 			throw exception;
318 		}
319 	}
320 
321 // growable reflectors
322 
323 	protected boolean addImpl(Object container, Object value) throws Exception {
324 		Object[] reflectors = getComponents();
325 		Exception exception = null;
326 		for (int i=0; i<reflectors.length; i++) {
327 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], container, GrowableContainerReflector.class)) {				
328 				GrowableContainerReflector reflector = (GrowableContainerReflector) reflectors[i];
329 				try {
330 					return reflector.add(container, value);
331 				}
332 				catch (ReflectionException e) {
333 					exception = e;
334 				}					
335 			}
336 		}
337 		
338 		if (exception == null) {
339 			throw new NoReflectorFoundException(container, GrowableContainerReflector.class);
340 		}
341 		else {
342 			throw exception;
343 		}
344 	}
345 
346 // indexed reflectors
347 
348 	protected Object getImpl(Object container, int index) throws Exception {
349 		Object[] reflectors = getComponents();
350 		Exception exception = null;
351 		for (int i=0; i<reflectors.length; i++) {
352 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], container, IndexedContainerReflector.class)) {				
353 				IndexedContainerReflector reflector = (IndexedContainerReflector) reflectors[i];
354 				try {
355 					return reflector.get(container, index);
356 				}
357 				catch (ReflectionException e) {
358 					exception = e;
359 				}					
360 			}
361 		}
362 		
363 		if (exception == null) {
364 			throw new NoReflectorFoundException(container, IndexedContainerReflector.class);
365 		}
366 		else {
367 			throw exception;
368 		}
369 	}
370 
371 // mutable indexed reflectors
372 
373 	protected Object setImpl(Object container, int index, Object propertyValue)
374 		throws Exception {
375 		Exception exception = null;
376 		Object[] reflectors = getComponents();
377 		for (int i=0; i<reflectors.length; i++) {
378 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], container, MutableIndexedContainerReflector.class)) {				
379 				MutableIndexedContainerReflector reflector = (MutableIndexedContainerReflector) reflectors[i];
380 				try {
381 					return reflector.set(container, index, propertyValue);
382 				}
383 				catch (ReflectionException e) {
384 					exception = e;
385 				}					
386 			}
387 		}
388 		
389 		if (exception == null) {
390 			throw new NoReflectorFoundException(container, MutableIndexedContainerReflector.class);
391 		}
392 		else {
393 			throw exception;
394 		}
395 	}
396 	
397 // instantiating reflectors	
398 
399 	protected Object newInstanceImpl(Class clazz, Object parameters) throws Exception {
400 		Object[] reflectors = getComponents();
401 		Exception exception = null;
402 		for (int i=0; i<reflectors.length; i++) {
403 			if (ReflectorUtils.isReflectable((Reflector) reflectors[i], clazz, InstantiatingReflector.class)) {				
404 				InstantiatingReflector reflector = (InstantiatingReflector) reflectors[i];
405 				try {
406 					return reflector.newInstance(clazz, parameters);
407 				}
408 				catch (ReflectionException e) {
409 					exception = e;
410 				}					
411 			}
412 		}
413 		
414 		if (exception == null) {
415 			throw new NoReflectorFoundException(clazz, InstantiatingReflector.class);
416 		}
417 		else {
418 			throw exception;
419 		}
420 	}
421 
422 	public boolean isReflectableImpl(Class reflectedType, Class reflectorType)
423 			throws ReflectionException {
424 		Object[] reflectors = getComponents();
425 		for (int i=0; i<reflectors.length; i++) {
426 			Reflector reflector = (Reflector) reflectors[i];
427 			if (ReflectorUtils.isReflectable(reflector, reflectedType, reflectorType)) {
428 				return true;
429 			}
430 		}
431 		return false;
432 	}
433 
434 }