1 /*
2 * $HeadURL: $
3 * $Date: $
4 * $Revision: $
5 * $Author: $
6 *
7 * Copyright (c) 2006 MindTree Consulting Ltd.
8 *
9 * This file is part of Insight.
10 *
11 * Insight is free software: you can redistribute it and/or modify it under the
12 * terms of the GNU General Public License as published by the Free Software
13 * Foundation, either version 3 of the License, or (at your option) any later
14 * version.
15 *
16 * Insight is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
19 * Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * Insight. If not, see <http://www.gnu.org/licenses/>.
23 */
24 package com.mindtree.techworks.insight.reporting.verifiers;
25
26 import org.w3c.dom.Document;
27 import org.w3c.dom.Element;
28 import org.w3c.dom.NodeList;
29
30 import com.mindtree.techworks.insight.reporting.InitializationException;
31 import com.mindtree.techworks.insight.reporting.SerializationXmlUtils;
32 import com.mindtree.techworks.insight.reporting.jobs.Job;
33 import com.mindtree.techworks.insight.reporting.jobs.JobInitializationException;
34 import com.mindtree.techworks.insight.reporting.jobs.JobPersistanceHandler;
35
36 /**
37 * This is the default implementation of the <code>VerifierDeserializer</code>
38 * interface in the <code>Verifier</code> framework.
39 * <p>
40 * <code>Verifiers</code> may use the services of this class to deserialize them
41 * and to do that, they must:
42 * <ul>
43 * <li>Implement the <code>DefaultImplDeserializable</code> interface </li>
44 * <li>Return an instance of this class on the <code>#getDeserializer()</code>
45 * method.</li>
46 * <li>Their serialized form must exactly conform to the format described in
47 * the documentation of the <code>VerifierDeserializer</code> class.</li>
48 * </ul>
49 * </p>
50 * <p>
51 * The <code>Verifier</code> framework also uses this class for deserialization
52 * of any <code>Verifier</code>. The <code>#deserialize(String)</code> method
53 * looks at the serialized form of the <code>Verifier</code> and tries to get
54 * the instance of the Verifier and then calls the appropriate
55 * <code>VerifierDeserializer</code> for the <code>Verifier</code>.
56 * </p>
57 *
58 * @see com.mindtree.techworks.insight.reporting.verifiers.VerifierDeserializer
59 * @see com.mindtree.techworks.insight.reporting.verifiers.DefaultImplDeserializable
60 *
61 * @author <a href="mailto:bindul_bhowmik@mindtree.com">Bindul Bhowmik</a>
62 * @version $Revision: 27 $ $Date: 2007-12-16 04:58:03 -0700 (Sun, 16 Dec 2007) $
63 * @since Insight 1.5
64 */
65 public class VerifierDeserializerImpl implements VerifierDeserializer {
66
67 /**
68 * Inspects the serialized <code>Verifier</code> and calls the appropriate
69 * <code>VerifierDeserializer</code>. If the <code>Verifier</code>
70 * class cannot be found, or the serialized data is ill formatted, then the
71 * deserialization fails and the method throws a
72 * <code>VerifierInitializationException</code>.
73 *
74 * @param serializedVerifier
75 * The serialized form of the Verifier.
76 *
77 * @return The deserialized verifier.
78 *
79 * @throws VerifierInitializationException
80 * If the verifier cannot be deserialized.
81 */
82 public static Verifier deserialize (String serializedVerifier)
83 throws VerifierInitializationException {
84
85 Document document = null;
86 try {
87 document = SerializationXmlUtils.createDocument (serializedVerifier);
88 } catch (InitializationException e) {
89 throw new VerifierInitializationException (
90 "Error creating document", e);
91 }
92
93 // Try to initialize the Verifier and get its deserializer, and
94 // delegate the call to the deserializer
95 String className = null;
96 try {
97 className = SerializationXmlUtils
98 .getSerializedObjectClassName (document);
99 } catch (InitializationException e) {
100 throw new VerifierInitializationException (
101 "Could not get class for Verifier.", e);
102 }
103
104 try {
105 Verifier newVerifier = (Verifier) Class.forName (className)
106 .newInstance ();
107 VerifierDeserializer deserializer = newVerifier.getDeserializer ();
108
109 // Finally... deserialize the verifier!
110 return deserializer.deserializeVerifier (serializedVerifier);
111 } catch (InstantiationException e) {
112 throw new VerifierInitializationException (
113 "Could not get verifier class or instance.");
114 } catch (IllegalAccessException e) {
115 throw new VerifierInitializationException (
116 "Could not get verifier class or instance.");
117 } catch (ClassNotFoundException e) {
118 throw new VerifierInitializationException (
119 "Could not get verifier class or instance.");
120 }
121
122 }
123
124 /**
125 * Deserializes a verifier serialized in the format specified in
126 * {@link VerifierDeserializer VerifierDeserializer}. The
127 * <code>Verifier</code> needs to implement the
128 * <code>DefaultImplDeserializable</code> interface.
129 *
130 * @see com.mindtree.techworks.insight.reporting.verifiers.VerifierDeserializer#deserializeVerifier(String)
131 */
132 public Verifier deserializeVerifier (String serializedVerifier)
133 throws VerifierInitializationException {
134
135 // Get the verifier class
136 Document document = null;
137 try {
138 document = SerializationXmlUtils.createDocument (serializedVerifier);
139 } catch (InitializationException e) {
140 throw new VerifierInitializationException (
141 "Could not create XML document", e);
142 }
143
144 // Get the class name for the Verifier
145 String className = null;
146 try {
147 className = SerializationXmlUtils
148 .getSerializedObjectClassName (document);
149 } catch (InitializationException e) {
150 throw new VerifierInitializationException (
151 "Could not get class for Verifier.", e);
152 }
153
154 Verifier newVerifier = null;
155
156 try {
157 // Get the instance.
158 newVerifier = (Verifier) Class.forName (className).newInstance ();
159
160 } catch (InstantiationException e) {
161 throw new VerifierInitializationException (
162 "Could not get verifier class or instance.");
163 } catch (IllegalAccessException e) {
164 throw new VerifierInitializationException (
165 "Could not get verifier class or instance.");
166 } catch (ClassNotFoundException e) {
167 throw new VerifierInitializationException (
168 "Could not get verifier class or instance.");
169 }
170
171 // For this class to deserialize the verifier it needs to implement
172 // DefaultImplDeserializable
173 if ( !(newVerifier instanceof DefaultImplDeserializable)) {
174 throw new VerifierInitializationException (
175 "The verifier cannot be deserialized by this class - " +
176 "needs to implement DefaultImplDeserializable.");
177 }
178
179 DefaultImplDeserializable deserializable = (DefaultImplDeserializable) newVerifier;
180
181 // Get the fields element
182 Element documentElement = document.getDocumentElement (); // <verifier/>
183 NodeList fieldsList = documentElement.getElementsByTagName ("fields");
184
185 // We will take just the first one!
186 if (fieldsList.getLength () > 0) {
187 Element fieldsRoot = (Element) fieldsList.item (0);
188 NodeList fields = fieldsRoot.getElementsByTagName ("field");
189 for (int i = 0; i < fields.getLength (); i++ ) {
190 processField ((Element) fields.item (i), deserializable);
191 }
192 }
193
194 // Get the jobs
195 NodeList jobsList = documentElement.getElementsByTagName("jobs");
196 // We will take just the first one!
197 if (jobsList.getLength () > 0) {
198 Element jobsRoot = (Element) jobsList.item (0);
199 NodeList jobs = jobsRoot.getElementsByTagName (
200 JobPersistanceHandler.SERIALIZED_JOB_ROOT_TAG);
201 for (int i = 0; i < jobs.getLength (); i++ ) {
202 processJob ((Element) jobs.item (i), newVerifier);
203 }
204 }
205
206 return newVerifier;
207 }
208
209 // -------------------------------------------------------------------------
210 // Private Utility methods
211 // -------------------------------------------------------------------------
212
213 /**
214 * Process the section of the serialized <code>Verifier</code>
215 * corresponding to a single field in the <code>Verifier</code>. It uses
216 * the
217 * {@link DefaultImplDeserializable#deserializeField(String, String) DefaultImplDeserializable#deserializeField(String, String)}
218 * method to populate the fields. If a field is an array, then the method is
219 * called multiple times with the same <code>fieldName</code> but the
220 * different values of the <code>fieldValue</code>.
221 *
222 * @param field
223 * The <code>Element</code> representing the field to
224 * deserialize.
225 * @param deserializable
226 * The <code>Verifier</code> which is being deserialized.
227 * @throws VerifierInitializationException
228 * If there is an error deserializing the field.
229 */
230 private void processField (Element field,
231 DefaultImplDeserializable deserializable)
232 throws VerifierInitializationException {
233
234 // Get the name of the field - should be only one, taking the first one.
235 Element nameElement = (Element) field.getElementsByTagName ("name")
236 .item (0);
237
238 if (null == nameElement) {
239 throw new VerifierInitializationException (
240 "Each field needs a name!");
241 }
242
243 String name = SerializationXmlUtils.getTextValue (nameElement);
244
245 // Get the values... may be more than one!
246 NodeList values = field.getElementsByTagName ("value");
247 for (int i = 0; i < values.getLength (); i++ ) {
248 String value = SerializationXmlUtils.getTextValue ((Element) values
249 .item (i));
250
251 // Set the value
252 deserializable.deserializeField (name, value);
253 }
254 }
255
256 /**
257 * Process the section of the serialized <code>Verifier</code>
258 * corresponding to a single <code>Job</code> in the <code>Verifier</code>.
259 * The actual deserialization of the <code>Job</code> is delegated to the
260 * deserialization mechanism of the <code>Job</code>. The
261 * {@link Verifier#registerJob(Job) Verifier#registerJob(Job)} method is
262 * used to attach the deserialized <code>Job</code>s to the
263 * <code>Verifier</code> being deserialized.
264 *
265 * @param serializedJob
266 * The <code>Element</code> representing the serialized
267 * <code>Job</code>.
268 * @param verifier
269 * The <code>Verifier</code> being deserialized.
270 * @throws VerifierInitializationException
271 * If there is an exception deserializing the <code>Job</code>.
272 */
273 private void processJob (Element serializedJob, Verifier verifier)
274 throws VerifierInitializationException {
275
276 // Get the string version of the job
277 String jobString = null;
278 try {
279 jobString = SerializationXmlUtils.serializeXmlElement(serializedJob);
280 } catch (InitializationException e) {
281 throw new VerifierInitializationException (
282 "Could not serialize Job DOM Element for processing.", e);
283 }
284 Job deserializedJob = null;
285
286 // Delegate the processing to a Job deserializer!
287 try {
288 deserializedJob = JobPersistanceHandler.deserializeJob(jobString);
289 } catch (JobInitializationException e) {
290 // Just throw it
291 throw new VerifierInitializationException (
292 "Could not deserialize job", e);
293 }
294
295 // Add the Job to the verifier
296 verifier.registerJob(deserializedJob);
297
298 }
299 }