1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package de.fu_berlin.ties.io;
23
24 import java.lang.reflect.Constructor;
25 import java.lang.reflect.InvocationTargetException;
26 import java.util.LinkedHashMap;
27 import java.util.Map;
28
29 /***
30 * A map targeted at serialization and deserialiation of objects in
31 * human-readable formats. It that allows creating (deserializing) an object
32 * by passing itself to the constructor.
33 *
34 * <p>This class preserves the guarantees of {@link java.util.LinkedHashMap}:
35 * it allows both efficient retrieval of values by key/field name (due to the
36 * contained hash map) and iteration of key/value pairs in order of insertion
37 * (due to the contained linked list).
38 *
39 * <p><strong>Note that this implementation is not synchronized.</strong>
40 * If multiple threads access a field map concurrently, and at least one of the
41 * threads modifies the map structurally, it <em>must</em> be synchronized
42 * externally. This is typically accomplished by synchronizing on some object
43 * that naturally encapsulates the map. If no such object exists, the map
44 * should be "wrapped" using the
45 * {@link java.util.Collections#synchronizedMap(java.util.Map)} method.
46 *
47 * @author Christian Siefkes
48 * @version $Revision: 1.2 $, $Date: 2004/09/06 17:23:31 $, $Author: siefkes $
49 */
50 public class FieldMap extends LinkedHashMap<String, Object> {
51
52 /***
53 * Creates a new instance.
54 */
55 public FieldMap() {
56 super();
57 }
58
59 /***
60 * Creates a new instance with the same mappings as the specified map.
61 * @param map the map whose mappings are to be placed in this map
62 * @throws NullPointerException if the specified map is null
63 */
64 public FieldMap(final Map<String, Object> map) throws NullPointerException {
65 super(map);
66 }
67
68 /***
69 * Creates (deserializes) an object of a specified type by calling a
70 * constructor of the class that accepts a field map as single argument
71 * and passing itself as parameter. Only classes that provide a suitable
72 * constructor can be instantiated this way.
73 *
74 * @param type the class of the object to create; must have a constructor
75 * whose only argument is a <code>FieldMap</code>
76 * @return the created object; the returned object will be an instance of
77 * the specified class
78 * @throws InstantiationException if instantiation failed
79 * @throws SecurityException if access to the required reflection
80 * information is denied
81 */
82 public Object createObject(final Class type) throws InstantiationException,
83 SecurityException {
84 try {
85
86 final Constructor cons = type.getConstructor(
87 new Class[] {FieldMap.class});
88
89 return cons.newInstance(new Object[] {this});
90 } catch (IllegalAccessException iae) {
91 final InstantiationException ie =
92 new InstantiationException(iae.toString());
93 ie.initCause(iae);
94 throw ie;
95 } catch (InvocationTargetException ite) {
96 final InstantiationException ie =
97 new InstantiationException(ite.toString());
98 ie.initCause(ite);
99 throw ie;
100 } catch (ExceptionInInitializerError eiie) {
101 final InstantiationException ie =
102 new InstantiationException(eiie.toString());
103 ie.initCause(eiie);
104 throw ie;
105 } catch (NoSuchMethodException nsme) {
106 final InstantiationException ie =
107 new InstantiationException(nsme.toString());
108 ie.initCause(nsme);
109 throw ie;
110 }
111 }
112
113 }