View Javadoc

1   /*
2    * @(#) DSOLIntrospector.java Apr 15, 2004
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
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 }