1
2
3
4
5
6
7 package nl.tudelft.simulation.introspection.fields;
8
9 import java.lang.reflect.Field;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Set;
15
16 import nl.tudelft.simulation.introspection.Introspector;
17 import nl.tudelft.simulation.introspection.Property;
18 import nl.tudelft.simulation.logger.Logger;
19
20 /***
21 * The IntrospectionField introspector provides a field manipulation
22 * implementation of the introspection interfaces. Its behavior adhers to the
23 * following:
24 * <ul>
25 * <li>Properties are discovered by searching for an object's fields
26 * (visibility neutral)</li>
27 * <li>Property value are manipulated by setting field values (visibility
28 * neutral)</li>
29 * </ul>
30 * <p>
31 * During construction, one can choose for either deep introspection (i.e.
32 * including fields from all superclasses), or regular introspection (inlude
33 * declared fields only). (c) copyright 2002-2005-2004 <a
34 * href="http://www.simulation.tudelft.nl">Delft University of Technology </a>,
35 * the Netherlands. <br>
36 * See for project information <a
37 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
38 * License of use: <a href="http://www.gnu.org/copyleft/lesser.html">Lesser
39 * General Public License (LGPL) </a>, no warranty.
40 *
41 * @author <a
42 * href="http://web.eur.nl/fbk/dep/dep1/Introduction/Staff/People/Lang">Niels
43 * Lang </a><a href="http://www.peter-jacobs.com/index.htm">Peter
44 * Jacobs </a>
45 * @version 1.1 Apr 15, 2004
46 * @since 1.5
47 */
48
49 public class FieldIntrospector implements Introspector
50 {
51 /*** useDeepIntrospection */
52 private boolean useDeepIntrospection = true;
53
54 /***
55 * constructs a new FieldIntrospector
56 */
57 public FieldIntrospector()
58 {
59 this(false);
60 }
61
62 /***
63 * constructs a new FieldIntrospector
64 *
65 * @param useDeepIntrospection whether to use deep introspection
66 */
67 public FieldIntrospector(final boolean useDeepIntrospection)
68 {
69 this.useDeepIntrospection = useDeepIntrospection;
70 }
71
72 /***
73 * @see nl.tudelft.simulation.introspection.Introspector#getProperties(Object)
74 */
75 public Property[] getProperties(final Object introspected)
76 {
77 Set<Property> props = new HashSet<Property>();
78 try
79 {
80 Field[] fields = collectFields(introspected.getClass());
81 for (int i = 0; i < fields.length; i++)
82 {
83 props.add(new FieldProperty(introspected, fields[i]));
84 }
85 } catch (Exception e)
86 {
87 Logger.warning(this, "getProperties", e);
88 }
89 return props.toArray(new Property[props.size()]);
90 }
91
92 /***
93 * Collect the fields for the given class, taking the preference for deep
94 * introspection into account.
95 *
96 * @param clasz the class to use
97 * @return Field[] the fields
98 */
99 private Field[] collectFields(final Class clasz)
100 {
101 List<Field> fields = new ArrayList<Field>(10);
102 this.addFields(fields, clasz, this.useDeepIntrospection);
103 return fields.toArray(new Field[fields.size()]);
104 }
105
106 /***
107 * Add fields of 'clasz' to the fieldList. Optionally iterate over the class
108 * hierarchy.
109 *
110 * @param fieldList the fieldList
111 * @param clasz the class
112 * @param iterate whether to iterate
113 */
114 private void addFields(final List<Field> fieldList, final Class< ? > clasz,
115 final boolean iterate)
116 {
117 fieldList.addAll(Arrays.asList(clasz.getDeclaredFields()));
118 if (iterate && clasz.getSuperclass() != null)
119 {
120 addFields(fieldList, clasz.getSuperclass(), iterate);
121 }
122 }
123
124 /***
125 * @see nl.tudelft.simulation.introspection.Introspector#getProperty(Object,
126 * String)
127 */
128 public Property getProperty(final Object introspected, final String property)
129 {
130 try
131 {
132 Field[] fields = collectFields(introspected.getClass());
133 for (int i = 0; i < fields.length; i++)
134 {
135 if (fields[i].getName().equals(property))
136 {
137 return new FieldProperty(introspected, fields[i]);
138 }
139 }
140 } catch (Exception e)
141 {
142 Logger.warning(this, "getProperty", e);
143 }
144 throw new IllegalArgumentException("Property '" + property
145 + "' not found for " + introspected);
146 }
147
148 /***
149 * @see nl.tudelft.simulation.introspection.Introspector#getPropertyNames(Object)
150 */
151 public String[] getPropertyNames(final Object introspected)
152 {
153 Set<String> props = new HashSet<String>();
154 try
155 {
156 Field[] fields = collectFields(introspected.getClass());
157 for (int i = 0; i < fields.length; i++)
158 {
159 props.add(fields[i].getName());
160 }
161 } catch (Exception e)
162 {
163 Logger.warning(this, "getPropertyNames", e);
164 }
165 return props.toArray(new String[props.size()]);
166 }
167 }