View Javadoc

1   /*
2    * Copyright (C) 2003-2004 Christian Siefkes <christian@siefkes.net>.
3    * Development of this software is supported by the German Research Society,
4    * Berlin-Brandenburg Graduate School in Distributed Information Systems
5    * (DFG grant no. GRK 316).
6    *
7    * This library is free software; you can redistribute it and/or
8    * modify it under the terms of the GNU Lesser General Public
9    * License as published by the Free Software Foundation; either
10   * version 2.1 of the License, or (at your option) any later version.
11   *
12   * This library is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this library; if not, visit
19   * http://www.gnu.org/licenses/lgpl.html or write to the Free Software
20   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
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              // load constructor with FieldMap as only argument
86              final Constructor cons = type.getConstructor(
87                      new Class[] {FieldMap.class});
88              // pass myself as single argument
89              return cons.newInstance(new Object[] {this});
90          } catch (IllegalAccessException iae) {        // repackage exception
91              final InstantiationException ie =
92                  new InstantiationException(iae.toString());
93              ie.initCause(iae);
94              throw ie;
95          } catch (InvocationTargetException ite) {     // repackage exception
96              final InstantiationException ie =
97                  new InstantiationException(ite.toString());
98              ie.initCause(ite);
99              throw ie;
100         } catch (ExceptionInInitializerError eiie) {  // repackage exception
101             final InstantiationException ie =
102                 new InstantiationException(eiie.toString());
103             ie.initCause(eiie);
104             throw ie;
105         } catch (NoSuchMethodException nsme) {        // repackage exception
106             final InstantiationException ie =
107                 new InstantiationException(nsme.toString());
108             ie.initCause(nsme);
109             throw ie;
110         }
111     }
112 
113 }