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.xml.io;
23
24 import java.lang.reflect.Constructor;
25 import java.lang.reflect.InvocationTargetException;
26
27 import org.dom4j.Attribute;
28 import org.dom4j.Element;
29 import org.dom4j.Namespace;
30 import org.dom4j.QName;
31 import org.dom4j.tree.DefaultElement;
32
33 /***
34 * An XML element that is targeted at storing an Java object.
35 *
36 * @author Christian Siefkes
37 * @version $Revision: 1.1 $, $Date: 2004/12/06 18:00:41 $, $Author: siefkes $
38 */
39 public class ObjectElement extends DefaultElement {
40
41 /***
42 * The name of the attribute used to store the Java class of an object:
43 * {@value}.
44 */
45 public static final String JAVA_CLASS_ATTRIBUTE = "java";
46
47
48 /***
49 * Creates (deserializes) an object of a specified type by calling a
50 * constructor of the class that accepts an XML element as single argument
51 * and passing itself as parameter. Only classes that provide a suitable
52 * constructor can be instantiated this way.
53 *
54 * @param type the class of the object to create; must have a constructor
55 * whose only argument is an {@link Element}
56 * @return the created object; the returned object will be an instance of
57 * the specified class
58 * @throws InstantiationException if instantiation failed
59 * @throws SecurityException if access to the required reflection
60 * information is denied
61 */
62 public static final Object createObject(final Element element,
63 final Class type)
64 throws InstantiationException, SecurityException {
65 try {
66
67 final Constructor cons = type.getConstructor(
68 new Class[] {Element.class});
69
70 return cons.newInstance(new Object[] {element});
71 } catch (IllegalAccessException iae) {
72 final InstantiationException ie =
73 new InstantiationException(iae.toString());
74 ie.initCause(iae);
75 throw ie;
76 } catch (InvocationTargetException ite) {
77 final InstantiationException ie =
78 new InstantiationException(ite.toString());
79 ie.initCause(ite);
80 throw ie;
81 } catch (ExceptionInInitializerError eiie) {
82 final InstantiationException ie =
83 new InstantiationException(eiie.toString());
84 ie.initCause(eiie);
85 throw ie;
86 } catch (NoSuchMethodException nsme) {
87 final InstantiationException ie =
88 new InstantiationException(nsme.toString());
89 ie.initCause(nsme);
90 throw ie;
91 }
92 }
93
94
95 /***
96 * Creates a new instance.
97 *
98 * @param name the name of the element
99 * @param javaClass the class of the object to store
100 */
101 public ObjectElement(final String name, final Class javaClass) {
102 super(name);
103 addAttribute(JAVA_CLASS_ATTRIBUTE, javaClass.getName());
104 }
105
106 /***
107 * Creates a new instance.
108 *
109 * @param qname the qualified name of the element
110 * @param javaClass the class of the object to store
111 */
112 public ObjectElement(final QName qname, final Class javaClass) {
113 super(qname);
114 addAttribute(JAVA_CLASS_ATTRIBUTE, javaClass.getName());
115 }
116
117 /***
118 * Creates a new instance.
119 *
120 * @param name the local name of the element
121 * @param namespace the namespace of the element
122 * @param javaClass the class of the object to store
123 */
124 public ObjectElement(final String name, final Namespace namespace,
125 final Class javaClass) {
126 super(name, namespace);
127 addAttribute(JAVA_CLASS_ATTRIBUTE, javaClass.getName());
128 }
129
130 /***
131 * Creates (deserializes) an object of a specified type by calling a
132 * constructor of the class that accepts an XML element as single argument
133 * and passing itself as parameter. Only classes that provide a suitable
134 * constructor can be instantiated this way.
135 *
136 * @return the created object
137 * @throws InstantiationException if instantiation failed
138 * @throws SecurityException if access to the required reflection
139 * information is denied
140 * @throws ClassNotFoundException if the class specified in the
141 * {@link #JAVA_CLASS_ATTRIBUTE} is not available on this system
142 * @throws IllegalStateException if the java class attribute has been
143 * removed (by calling {@link #unsetJavaClassAttrib()}
144 */
145 public final Object createObject() throws InstantiationException,
146 SecurityException, ClassNotFoundException, IllegalStateException {
147 return createObject(this, javaClass());
148 }
149
150 /***
151 * Returns the name of the {@link Class} of the stored object.
152 *
153 * @return the class name of the stored object; or <code>null</code> if
154 * {@link #unsetJavaClassAttrib()} has been called before
155 */
156 public String javaClassName() {
157 return attributeValue(JAVA_CLASS_ATTRIBUTE);
158 }
159
160 /***
161 * Returns the {@link Class} of the stored object.
162 *
163 * @return the class of the stored object
164 * @throws ClassNotFoundException if the class cannot be located
165 * @throws IllegalStateException if the java class attribute has been
166 * removed (by calling {@link #unsetJavaClassAttrib()}
167 */
168 public Class javaClass()
169 throws ClassNotFoundException, IllegalStateException {
170 final String className = javaClassName();
171
172 if (className != null) {
173 return Class.forName(className);
174 } else {
175 throw new IllegalStateException(
176 "Java class attribute has been unset");
177 }
178 }
179
180 /***
181 * Unsets the attribute representing the {@link Class} of the stored object.
182 * @return <code>true</code> if the attribute was successfully removed
183 * (first call to this method); <code>false</code> if there was no such
184 * attribute (later calls to this method)
185 */
186 public boolean unsetJavaClassAttrib() {
187
188 final Attribute javaAttrib = attribute(JAVA_CLASS_ATTRIBUTE);
189
190 if (javaAttrib != null) {
191 return remove(javaAttrib);
192 } else {
193 return false;
194 }
195 }
196
197 }