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