View Javadoc

1   /*
2    * Copyright 2004-2005, 2007 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.lang.reflect.Array;
19  import java.util.Iterator;
20  
21  import net.sf.composite.util.ArrayIterator;
22  import net.sf.morph.Defaults;
23  import net.sf.morph.reflect.BeanReflector;
24  import net.sf.morph.reflect.ContainerReflector;
25  import net.sf.morph.reflect.IndexedContainerReflector;
26  import net.sf.morph.reflect.InstantiatingReflector;
27  import net.sf.morph.reflect.MutableIndexedContainerReflector;
28  import net.sf.morph.reflect.SizableReflector;
29  import net.sf.morph.util.ClassUtils;
30  
31  /**
32   * A container reflector for Arrays.
33   * 
34   * @author Matt Sgarlata
35   * @since Nov 20, 2004
36   */
37  public class ArrayReflector extends BaseContainerReflector implements ContainerReflector,
38  		IndexedContainerReflector, MutableIndexedContainerReflector, SizableReflector,
39  		BeanReflector, InstantiatingReflector {
40  	
41  	private SizableReflector sourceReflector;
42  	
43  	public ArrayReflector() {
44  	    super();
45  	    // by default use the best reflectors available to Morph to try to
46  	    // determine the size of the (optional) parameter to the newInstance
47  	    // method which indicates the size of the array to be created.  If
48  	    // a static list of reflectors is enumerated here, new reflectors
49  	    // added to morph won't automatically get added here (as was recently
50  	    // the case with the StringTokenizerReflector)
51  	    sourceReflector = Defaults.createSizableReflector();
52      }
53  	
54  	public ArrayReflector(SizableReflector sourceReflector) {
55  		super();
56  		this.sourceReflector = sourceReflector;
57  	}
58  
59  	protected Class[] getReflectableClassesImpl() {
60  		return ClassUtils.ARRAY_TYPES;
61  	}
62  
63  	protected Iterator getIteratorImpl(Object container) throws Exception {
64  		return new ArrayIterator(container);
65  	}
66  	protected int getSizeImpl(Object container) throws Exception {
67  		return Array.getLength(container);
68  	}
69  
70  	protected Object getImpl(Object container, int index) throws Exception {
71  		return Array.get(container, index);
72  	}
73  
74  	protected Object setImpl(Object container, int index, Object propertyValue)
75  		throws Exception {
76  		Object oldValue = getImpl(container, index);
77  		Array.set(container, index, propertyValue);
78  		return oldValue;
79  	}
80  
81  	protected Class getContainedTypeImpl(Class clazz) throws Exception {
82  		return ClassUtils.getContainedClass(clazz);
83  	}
84  
85  	/**
86  	 * The default implementation is correct, but this is faster because it
87  	 * doesn't require looping through all the reflectable classes
88  	 */
89  	protected boolean isReflectableImpl(Class clazz) throws Exception {
90  		return clazz.isArray();
91  	}
92  
93  	protected Object newInstanceImpl(Class clazz, Object parameters) throws Exception {
94  		int length = parameters == null ? 0 : getSourceReflector().getSize(parameters);
95  		return ClassUtils.createArray(clazz.getComponentType(), length);
96  	}
97  
98  	public SizableReflector getSourceReflector() {
99      	return sourceReflector;
100     }
101 
102 	public void setSourceReflector(SizableReflector sourceReflector) {
103     	this.sourceReflector = sourceReflector;
104     }
105 }