Source code: com/arranger/jarl/util/ObjectUtil.java
1 package com.arranger.jarl.util;
2
3 import org.w3c.dom.Element;
4
5 import java.io.*;
6 import java.lang.reflect.Field;
7 import java.util.Collection;
8 import java.util.Iterator;
9 import java.awt.geom.Point2D;
10 import java.awt.*;
11
12 import com.arranger.jarl.base.Time;
13
14 /**
15 * ObjectUtil created on Feb 20, 2003
16 */
17 public class ObjectUtil {
18
19 public static IConversionFunction PRIMITIVE_CONVERSION = new PrimitiveConversionFunction();
20 public static IConversionFunction NORMALIZING_CONVERSION = new NormalizingConversionFunction(NormalizingConversionFunction.DEFAULT_NORM);
21 public static IConversionFunction POINT2D_CONVERSION = new Point2DConversionFunction();
22 public static IConversionFunction COORDS_CONVERSION = new CoordsConversionFunction();
23 public static IConversionFunction COLOR_CONVERSION = new ColorConversionFunction();
24 public static IConversionFunction TIME_CONVERSION = new TimeConversionFunction();
25 protected static ClassLoader m_classLoader = null;
26
27
28 /**
29 * use some reflection to get the named property
30 *
31 * @return the int if found, -1 otherwise
32 * @see ObjectUtil#getStaticProperty
33 */
34 public static int getNamedValue(Class clazz, String name) {
35
36 Object obj = getStaticProperty(clazz, name);
37 if ((obj != null) && (obj instanceof Integer)) {
38 return ((Integer) obj).intValue();
39 } else {
40 return -1;
41 }
42 }
43
44 /**
45 * Returns the named static variable.
46 *
47 * Usage:
48 * <code>
49 * Object value = ObjectUtil.getStaticProperty(ObjectUtil.class, "PUBLIC");
50 * </code>
51 */
52 public static Object getStaticProperty(Class clazz, String fieldName) {
53 try {
54 Field field = clazz.getField(fieldName);
55 if (field == null) {
56 return null;
57 }
58
59 return field.get(field);
60 } catch (Exception e) {
61 Debug.warn(e.getMessage());
62 }
63
64 return null;
65 }
66
67 /**
68 * Gets a priviledged property from an object
69 * For static properties, pass a null for instance
70 *
71 * @return true if successful, false otherwise
72 */
73 public static boolean setPrivilegedProperty(Object instance, Class clazz, String propertyName, Object value) throws IllegalAccessException {
74
75 if (clazz == null) {
76 return false;
77 }
78
79 Field[] fields = clazz.getDeclaredFields();
80 for (int index = 0; index < fields.length; index++) {
81 Field field = fields[index];
82 if (field.getName().equals(propertyName)) {
83 field.setAccessible(true);
84 if (instance == null) {
85 field.set(clazz, value);
86 } else {
87 field.set(instance, value);
88 }
89 return true;
90 }
91 }
92
93 // We didn't find this field in the specified class,
94 // now I should try to work with super-class
95 Class superClass = clazz.getSuperclass();
96 if (superClass != null) {
97 return setPrivilegedProperty(instance, superClass, propertyName, value);
98 } else {
99 return false;
100 }
101 }
102
103 public static Field getField(Object instance, Class clazz, String name) throws IllegalAccessException {
104 if (clazz == null) {
105 return null;
106 }
107
108 Field[] fields = clazz.getDeclaredFields();
109 for (int index = 0; index < fields.length; index++) {
110 Field field = fields[index];
111 if (field.getName().equals(name)) {
112 field.setAccessible(true);
113 return field;
114 }
115 }
116
117 // We didn't find this field in the specified class,
118 // now I should try to work with super-class
119 Class superClass = clazz.getSuperclass();
120 if (superClass != null) {
121 return getField(instance, superClass, name);
122 } else {
123 return null;
124 }
125 }
126
127 /**
128 * Retrieves a privilged property
129 * @return null if not found, the object otherwise
130 */
131 public static Object getPrivilegedProperty(Object instance, String propertyName) throws IllegalAccessException {
132 Class clazz = instance.getClass();
133 Field[] fields;
134 while (clazz != null) {
135 fields = clazz.getDeclaredFields();
136 for (int index = 0; index < fields.length; index++) {
137 Field field = fields[index];
138 if (field.getName().equals(propertyName)) {
139 field.setAccessible(true);
140 return field.get(instance);
141 }
142 }
143 clazz = clazz.getSuperclass();
144 }
145
146 return null;
147 }
148
149 /**
150 * Retrieves a privilged property
151 * @return null if not found, the object otherwise
152 */
153 public static Object getPrivilegedProperty(Class staticClass, String propertyName) throws IllegalAccessException {
154 Class clazz = staticClass;
155 Field[] fields;
156 while (clazz != null) {
157 fields = clazz.getDeclaredFields();
158 for (int index = 0; index < fields.length; index++) {
159 Field field = fields[index];
160 if (field.getName().equals(propertyName)) {
161 field.setAccessible(true);
162 return field.get(clazz);
163 }
164 }
165 clazz = clazz.getSuperclass();
166 }
167
168 return null;
169 }
170
171 /**
172 * Only merge unique members of the collection
173 * @param source
174 * @param dest
175 */
176 public static void mergeCollections(Collection source, Collection dest) {
177 for (Iterator it = source.iterator(); it.hasNext();) {
178 Object srcObj = it.next();
179 if (!dest.contains(srcObj)) {
180 dest.add(srcObj);
181 }
182 }
183 }
184
185
186 /**
187 * Won't throw a classNotFoundException
188 */
189 public static Object createObject(String className) {
190 try {
191 Class clazz = loadClass(className);
192 return clazz.newInstance();
193 } catch (Exception e) {
194 Debug.warn("Failed to createObject: " + className + e.getMessage());
195 }
196 return null;
197 }
198
199 public static Class loadClass(String className) throws ClassNotFoundException {
200 return getClassLoader().loadClass(className);
201 }
202
203 public static ClassLoader getClassLoader() {
204 if (m_classLoader == null) {
205 m_classLoader = Thread.currentThread().getContextClassLoader();
206 }
207 return m_classLoader;
208 }
209
210 public static void setClassLoader(ClassLoader classLoader) {
211 m_classLoader = classLoader;
212 }
213
214 public static Object load(String location) throws IOException {
215 InputStream is = null;
216 Object obj = null;
217 try {
218 is = IOUtil.getInputStream(location);
219 obj = load(is);
220 } finally {
221 if (is != null) {
222 is.close();
223 }
224 }
225 return obj;
226 }
227
228 public static void save(Object object, String location) throws IOException {
229 OutputStream os = null;
230 try {
231 os = IOUtil.getOutputStream(location);
232 save(object, os);
233 } finally {
234 if (os != null) {
235 os.close();
236 }
237 }
238 }
239
240 /**
241 * Load an object from an array of bytes.
242 * The inputStream will be closed
243 * @param is the array of bytes that constitute the object
244 * @return an Object that was loaded from the array of bytes, or null if an error occurred
245 */
246 public static Object load(InputStream is) throws IOException {
247 Object obj = null;
248 try {
249 ObjectInputStream reader = new ClassLoaderObjectInputStream(is);
250 obj = reader.readObject();
251 reader.close();
252 } catch (Exception e) {
253 Debug.warn(e.getMessage());
254 if (e instanceof IOException) {
255 throw (IOException) e;
256 } else {
257 throw new IOException(e.getMessage());
258 }
259 }
260
261 return obj;
262 }
263
264 /**
265 * Serialize an object to an array of bytes.
266 * @param object the object to serialize. Must implement Serializable
267 */
268 public static void save(Object object, OutputStream outputStream) {
269
270 try {
271 ObjectOutputStream writer = new ObjectOutputStream(outputStream);
272 writer.writeObject(object);
273 writer.close();
274 } catch (IOException e) {
275 Debug.warn(e.getMessage());
276 }
277 }
278
279 public static boolean initializeField(String attributeName,
280 Element configElement,
281 Object object,
282 IConversionFunction conversionFunction) {
283 String result = conversionFunction.getValue(configElement, attributeName);
284 if (StringTools.isEmpty(result)) {
285 return false;
286 }
287
288 try {
289 Field field = getField(object, object.getClass(), "m_" + attributeName);
290 conversionFunction.setField(field, result, object);
291 } catch (Exception e) {
292 throw new IllegalStateException(e.getMessage());
293 }
294
295 return true;
296 }
297
298 public static void initializeFieldStrict(String attributeName,
299 Element configElement,
300 Object object,
301 IConversionFunction conversionFunction) {
302 String result = conversionFunction.getValue(configElement, attributeName);
303 if (StringTools.isEmpty(result)) {
304 throw new IllegalStateException("Could not find attribute: " + attributeName);
305 }
306
307 try {
308 Field field = getField(object, object.getClass(), "m_" + attributeName);
309 conversionFunction.setField(field, result, object);
310 } catch (Exception e) {
311 throw new IllegalStateException(e.getMessage());
312 }
313 }
314
315 protected static class ClassLoaderObjectInputStream extends ObjectInputStream {
316
317 public ClassLoaderObjectInputStream(InputStream in) throws IOException, StreamCorruptedException {
318 super(in);
319 }
320
321 protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException {
322 return ObjectUtil.loadClass(v.getName());
323 }
324 }
325
326 /**
327 * Used in conjunction with {@link #initializeField}
328 */
329 public interface IConversionFunction {
330
331 /**
332 * get a value
333 */
334 public String getValue(Element element, String attribute);
335
336 /**
337 * Sets the data member using reflection
338 * @param field the field object
339 * @param configData the text of the relevant config Data
340 * @param object the object to set the data on
341 */
342 public void setField(Field field, String configData, Object object) throws Exception;
343 }
344
345 public abstract static class BaseConversionFunction implements IConversionFunction {
346
347 public String getValue(Element element, String attribute) {
348 return element.getAttribute(attribute);
349 }
350 }
351
352 public static class PrimitiveConversionFunction extends BaseConversionFunction {
353
354 public void setField(Field field, String configData, Object object) throws Exception {
355 Class fieldClass = field.getType();
356 if (fieldClass == Boolean.class || fieldClass == boolean.class) {
357 boolean value = "true".equals(configData);
358 field.setBoolean(object, value);
359 } else if (fieldClass == Integer.class || fieldClass == int.class) {
360 int value = Integer.parseInt(configData);
361 field.setInt(object, value);
362 } else if (fieldClass == Float.class || fieldClass == float.class) {
363 float value = Float.parseFloat(configData);
364 field.setFloat(object, value);
365 } else if (fieldClass == Double.class || fieldClass == double.class) {
366 double value = Double.parseDouble(configData);
367 field.setDouble(object, value);
368 } else if (fieldClass == String.class) {
369 field.set(object, configData);
370 } else {
371 throw new IllegalStateException("don't know what to do here");
372 }
373 }
374 }
375
376 /**
377 * @see WidgetUtil#normalize
378 */
379 public static class NormalizingConversionFunction extends PrimitiveConversionFunction {
380
381 protected static final double DEFAULT_NORM = 1.0;
382 protected double m_baseValue;
383
384 public NormalizingConversionFunction(double baseValue) {
385 m_baseValue = baseValue;
386 }
387
388 public void setField(Field field, String configData, Object object) throws Exception {
389 double result = WidgetUtil.normalize(m_baseValue, configData);
390 super.setField(field, String.valueOf(result), object);
391 }
392 }
393
394 /**
395 * @see WidgetUtil#getPointFromString
396 */
397 public static class Point2DConversionFunction extends BaseConversionFunction {
398
399 public void setField(Field field, String configData, Object object) throws Exception {
400 Point2D point2D = WidgetUtil.getPointFromString(configData);
401 field.set(object, point2D);
402 }
403 }
404
405 /**
406 * @see PaintUtil#getPaintFromValue
407 */
408 public static class ColorConversionFunction extends BaseConversionFunction {
409 public String getValue(Element element, String attribute) {
410 String value = super.getValue(element, attribute);
411 if (StringTools.isEmpty(value)) {
412 return super.getValue(element, attribute + "Data");
413 } else {
414 return value;
415 }
416 }
417
418 public void setField(Field field, String configData, Object object) throws Exception {
419 Paint paint = PaintUtil.getPaintFromValue(configData);
420 field.set(object, paint);
421 }
422 }
423
424 /**
425 * @see WidgetUtil#getCoordsFromString
426 */
427 public static class CoordsConversionFunction extends BaseConversionFunction {
428 public void setField(Field field, String configData, Object object) throws Exception {
429 Point2D[] points = WidgetUtil.getCoordsFromString(configData);
430 field.set(object, points);
431 }
432 }
433
434 /**
435 * @see
436 */
437 public static class TimeConversionFunction extends BaseConversionFunction {
438 public void setField(Field field, String configData, Object object) throws Exception {
439 Time time = Time.getTime(configData);
440 field.set(object, time);
441 }
442 }
443 }