KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > entity > serialize > XmlSerializer


1 /*
2  * $Id: XmlSerializer.java 5462 2005-08-05 18:35:48Z jonesde $
3  *
4  * Copyright (c) 2001-2005 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */

24 package org.ofbiz.entity.serialize;
25
26 import java.io.FileNotFoundException JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.Serializable JavaDoc;
29 import java.lang.ref.WeakReference JavaDoc;
30 import java.text.DateFormat JavaDoc;
31 import java.text.ParseException JavaDoc;
32 import java.text.SimpleDateFormat JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.Collection JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.HashSet JavaDoc;
37 import java.util.Hashtable JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.LinkedList JavaDoc;
40 import java.util.Locale JavaDoc;
41 import java.util.Map JavaDoc;
42 import java.util.Properties JavaDoc;
43 import java.util.Stack JavaDoc;
44 import java.util.TreeMap JavaDoc;
45 import java.util.TreeSet JavaDoc;
46 import java.util.Vector JavaDoc;
47 import java.util.WeakHashMap JavaDoc;
48
49 import javax.xml.parsers.ParserConfigurationException JavaDoc;
50
51 import org.ofbiz.base.util.UtilMisc;
52 import org.ofbiz.base.util.UtilXml;
53 import org.ofbiz.base.util.Debug;
54 import org.ofbiz.base.util.UtilObject;
55 import org.ofbiz.base.util.StringUtil;
56 import org.ofbiz.entity.GenericDelegator;
57 import org.ofbiz.entity.GenericPK;
58 import org.ofbiz.entity.GenericValue;
59 import org.w3c.dom.Document JavaDoc;
60 import org.w3c.dom.Element JavaDoc;
61 import org.w3c.dom.Node JavaDoc;
62 import org.xml.sax.SAXException JavaDoc;
63
64 /**
65  * <p><b>Title:</b> XmlSerializer
66  * <p><b>Description:</b> Simple XML serialization/deserialization routines with embedded type information
67  *
68  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
69  * @version $Rev: 5462 $
70  * @since 2.0
71  */

72 public class XmlSerializer {
73     public static final String JavaDoc module = XmlSerializer.class.getName();
74
75     private static WeakReference JavaDoc simpleDateFormatter;
76
77     public static String JavaDoc serialize(Object JavaDoc object) throws SerializeException, FileNotFoundException JavaDoc, IOException JavaDoc {
78         Document JavaDoc document = UtilXml.makeEmptyXmlDocument("ofbiz-ser");
79         Element JavaDoc rootElement = document.getDocumentElement();
80
81         rootElement.appendChild(serializeSingle(object, document));
82         return UtilXml.writeXmlDocument(document);
83     }
84
85     public static Object JavaDoc deserialize(String JavaDoc content, GenericDelegator delegator)
86         throws SerializeException, SAXException JavaDoc, ParserConfigurationException JavaDoc, IOException JavaDoc {
87         // readXmlDocument with false second parameter to disable validation
88
Document JavaDoc document = UtilXml.readXmlDocument(content, false);
89         if (document != null) {
90             Element JavaDoc rootElement = document.getDocumentElement();
91             // find the first element below the root element, that should be the object
92
Node JavaDoc curChild = rootElement.getFirstChild();
93
94             while (curChild != null && curChild.getNodeType() != Node.ELEMENT_NODE) {
95                 curChild = curChild.getNextSibling();
96             }
97             if (curChild == null) return null;
98             Element JavaDoc element = (Element JavaDoc) curChild;
99
100             return deserializeSingle(element, delegator);
101         } else {
102             Debug.logWarning("Serialized document came back null", module);
103             return null;
104         }
105     }
106
107     public static Element JavaDoc serializeSingle(Object JavaDoc object, Document JavaDoc document) throws SerializeException {
108         if (document == null) return null;
109
110         if (object == null) return document.createElement("null");
111
112         // - Standard Objects -
113
if (object instanceof String JavaDoc) {
114             return makeElement("std-String", object, document);
115         } else if (object instanceof Integer JavaDoc) {
116             return makeElement("std-Integer", object, document);
117         } else if (object instanceof Long JavaDoc) {
118             return makeElement("std-Long", object, document);
119         } else if (object instanceof Float JavaDoc) {
120             return makeElement("std-Float", object, document);
121         } else if (object instanceof Double JavaDoc) {
122             return makeElement("std-Double", object, document);
123         } else if (object instanceof Boolean JavaDoc) {
124             return makeElement("std-Boolean", object, document);
125         } else if (object instanceof Locale JavaDoc) {
126             return makeElement("std-Locale", object, document);
127             // - SQL Objects -
128
} else if (object instanceof java.sql.Timestamp JavaDoc) {
129             return makeElement("sql-Timestamp", object, document);
130         } else if (object instanceof java.sql.Date JavaDoc) {
131             return makeElement("sql-Date", object, document);
132         } else if (object instanceof java.sql.Time JavaDoc) {
133             return makeElement("sql-Time", object, document);
134         } else if (object instanceof java.util.Date JavaDoc) {
135             // NOTE: make sure this is AFTER the java.sql date/time objects since they inherit from java.util.Date
136
DateFormat JavaDoc formatter = getDateFormat();
137             String JavaDoc stringValue = null;
138
139             synchronized (formatter) {
140                 stringValue = formatter.format((java.util.Date JavaDoc) object);
141             }
142             return makeElement("std-Date", stringValue, document);
143             // return makeElement("std-Date", object, document);
144
} else if (object instanceof Collection JavaDoc) {
145             // - Collections -
146
String JavaDoc elementName = null;
147
148             // these ARE order sensitive; for instance Stack extends Vector, so if Vector were first we would lose the stack part
149
if (object instanceof ArrayList JavaDoc) {
150                 elementName = "col-ArrayList";
151             } else if (object instanceof LinkedList JavaDoc) {
152                 elementName = "col-LinkedList";
153             } else if (object instanceof Stack JavaDoc) {
154                 elementName = "col-Stack";
155             } else if (object instanceof Vector JavaDoc) {
156                 elementName = "col-Vector";
157             } else if (object instanceof TreeSet JavaDoc) {
158                 elementName = "col-TreeSet";
159             } else if (object instanceof HashSet JavaDoc) {
160                 elementName = "col-HashSet";
161             } else {
162                 // no specific type found, do general Collection, will deserialize as LinkedList
163
elementName = "col-Collection";
164             }
165
166             // if (elementName == null) return serializeCustom(object, document);
167

168             Collection JavaDoc value = (Collection JavaDoc) object;
169             Element JavaDoc element = document.createElement(elementName);
170             Iterator JavaDoc iter = value.iterator();
171
172             while (iter.hasNext()) {
173                 element.appendChild(serializeSingle(iter.next(), document));
174             }
175             return element;
176         } else if (object instanceof GenericPK) {
177             // Do GenericEntity objects as a special case, use std XML import/export routines
178
GenericPK value = (GenericPK) object;
179
180             return value.makeXmlElement(document, "eepk-");
181         } else if (object instanceof GenericValue) {
182             GenericValue value = (GenericValue) object;
183
184             return value.makeXmlElement(document, "eeval-");
185         } else if (object instanceof Map JavaDoc) {
186             // - Maps -
187
String JavaDoc elementName = null;
188
189             // these ARE order sensitive; for instance Properties extends Hashtable, so if Hashtable were first we would lose the Properties part
190
if (object instanceof HashMap JavaDoc) {
191                 elementName = "map-HashMap";
192             } else if (object instanceof Properties JavaDoc) {
193                 elementName = "map-Properties";
194             } else if (object instanceof Hashtable JavaDoc) {
195                 elementName = "map-Hashtable";
196             } else if (object instanceof WeakHashMap JavaDoc) {
197                 elementName = "map-WeakHashMap";
198             } else if (object instanceof TreeMap JavaDoc) {
199                 elementName = "map-TreeMap";
200             } else {
201                 // serialize as a simple Map implementation if nothing else applies, these will deserialize as a HashMap
202
elementName = "map-Map";
203             }
204
205             Element JavaDoc element = document.createElement(elementName);
206             Map JavaDoc value = (Map JavaDoc) object;
207             Iterator JavaDoc iter = value.entrySet().iterator();
208
209             while (iter.hasNext()) {
210                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iter.next();
211
212                 Element JavaDoc entryElement = document.createElement("map-Entry");
213
214                 element.appendChild(entryElement);
215
216                 Element JavaDoc key = document.createElement("map-Key");
217
218                 entryElement.appendChild(key);
219                 key.appendChild(serializeSingle(entry.getKey(), document));
220                 Element JavaDoc mapValue = document.createElement("map-Value");
221
222                 entryElement.appendChild(mapValue);
223                 mapValue.appendChild(serializeSingle(entry.getValue(), document));
224             }
225             return element;
226         }
227
228         return serializeCustom(object, document);
229     }
230
231     public static Element JavaDoc serializeCustom(Object JavaDoc object, Document JavaDoc document) throws SerializeException {
232         if (object instanceof Serializable JavaDoc) {
233             byte[] objBytes = UtilObject.getBytes(object);
234             if (objBytes == null) {
235                 throw new SerializeException("Unable to serialize object; null byte array returned");
236             } else {
237                 String JavaDoc byteHex = StringUtil.toHexString(objBytes);
238                 Element JavaDoc element = document.createElement("cus-obj");
239                 element.appendChild(document.createCDATASection(byteHex));
240                 return element;
241             }
242         } else {
243             throw new SerializeException("Cannot serialize object of class " + object.getClass().getName());
244         }
245     }
246
247     public static Element JavaDoc makeElement(String JavaDoc elementName, Object JavaDoc value, Document JavaDoc document) {
248         if (value == null) return document.createElement("null");
249         Element JavaDoc element = document.createElement(elementName);
250
251         element.setAttribute("value", value.toString());
252         return element;
253     }
254
255     public static Object JavaDoc deserializeSingle(Element JavaDoc element, GenericDelegator delegator) throws SerializeException {
256         String JavaDoc tagName = element.getTagName();
257
258         if (tagName.equals("null")) return null;
259
260         if (tagName.startsWith("std-")) {
261             // - Standard Objects -
262
if ("std-String".equals(tagName)) {
263                 return element.getAttribute("value");
264             } else if ("std-Integer".equals(tagName)) {
265                 String JavaDoc valStr = element.getAttribute("value");
266                 return Integer.valueOf(valStr);
267             } else if ("std-Long".equals(tagName)) {
268                 String JavaDoc valStr = element.getAttribute("value");
269                 return Long.valueOf(valStr);
270             } else if ("std-Float".equals(tagName)) {
271                 String JavaDoc valStr = element.getAttribute("value");
272                 return Float.valueOf(valStr);
273             } else if ("std-Double".equals(tagName)) {
274                 String JavaDoc valStr = element.getAttribute("value");
275                 return Double.valueOf(valStr);
276             } else if ("std-Boolean".equals(tagName)) {
277                 String JavaDoc valStr = element.getAttribute("value");
278                 return Boolean.valueOf(valStr);
279             } else if ("std-Locale".equals(tagName)) {
280                 String JavaDoc valStr = element.getAttribute("value");
281                 return UtilMisc.parseLocale(valStr);
282             } else if ("std-Date".equals(tagName)) {
283                 String JavaDoc valStr = element.getAttribute("value");
284                 DateFormat JavaDoc formatter = getDateFormat();
285                 java.util.Date JavaDoc value = null;
286
287                 try {
288                     synchronized (formatter) {
289                         value = formatter.parse(valStr);
290                     }
291                 } catch (ParseException JavaDoc e) {
292                     throw new SerializeException("Could not parse date String: " + valStr, e);
293                 }
294                 return value;
295             }
296         } else if (tagName.startsWith("sql-")) {
297             // - SQL Objects -
298
if ("sql-Timestamp".equals(tagName)) {
299                 String JavaDoc valStr = element.getAttribute("value");
300                 return java.sql.Timestamp.valueOf(valStr);
301             } else if ("sql-Date".equals(tagName)) {
302                 String JavaDoc valStr = element.getAttribute("value");
303                 return java.sql.Date.valueOf(valStr);
304             } else if ("sql-Time".equals(tagName)) {
305                 String JavaDoc valStr = element.getAttribute("value");
306                 return java.sql.Time.valueOf(valStr);
307             }
308         } else if (tagName.startsWith("col-")) {
309             // - Collections -
310
Collection JavaDoc value = null;
311
312             if ("col-ArrayList".equals(tagName)) {
313                 value = new ArrayList JavaDoc();
314             } else if ("col-LinkedList".equals(tagName)) {
315                 value = new LinkedList JavaDoc();
316             } else if ("col-Stack".equals(tagName)) {
317                 value = new Stack JavaDoc();
318             } else if ("col-Vector".equals(tagName)) {
319                 value = new Vector JavaDoc();
320             } else if ("col-TreeSet".equals(tagName)) {
321                 value = new TreeSet JavaDoc();
322             } else if ("col-HashSet".equals(tagName)) {
323                 value = new HashSet JavaDoc();
324             } else if ("col-Collection".equals(tagName)) {
325                 value = new LinkedList JavaDoc();
326             }
327
328             if (value == null) {
329                 return deserializeCustom(element);
330             } else {
331                 Node JavaDoc curChild = element.getFirstChild();
332
333                 while (curChild != null) {
334                     if (curChild.getNodeType() == Node.ELEMENT_NODE) {
335                         value.add(deserializeSingle((Element JavaDoc) curChild, delegator));
336                     }
337                     curChild = curChild.getNextSibling();
338                 }
339                 return value;
340             }
341         } else if (tagName.startsWith("map-")) {
342             // - Maps -
343
Map JavaDoc value = null;
344
345             if ("map-HashMap".equals(tagName)) {
346                 value = new HashMap JavaDoc();
347             } else if ("map-Properties".equals(tagName)) {
348                 value = new Properties JavaDoc();
349             } else if ("map-Hashtable".equals(tagName)) {
350                 value = new Hashtable JavaDoc();
351             } else if ("map-WeakHashMap".equals(tagName)) {
352                 value = new WeakHashMap JavaDoc();
353             } else if ("map-TreeMap".equals(tagName)) {
354                 value = new TreeMap JavaDoc();
355             } else if ("map-Map".equals(tagName)) {
356                 value = new HashMap JavaDoc();
357             }
358
359             if (value == null) {
360                 return deserializeCustom(element);
361             } else {
362                 Node JavaDoc curChild = element.getFirstChild();
363
364                 while (curChild != null) {
365                     if (curChild.getNodeType() == Node.ELEMENT_NODE) {
366                         Element JavaDoc curElement = (Element JavaDoc) curChild;
367
368                         if ("map-Entry".equals(curElement.getTagName())) {
369                             Element JavaDoc mapKeyElement = UtilXml.firstChildElement(curElement, "map-Key");
370                             Element JavaDoc keyElement = null;
371                             Node JavaDoc tempNode = mapKeyElement.getFirstChild();
372
373                             while (tempNode != null) {
374                                 if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
375                                     keyElement = (Element JavaDoc) tempNode;
376                                     break;
377                                 }
378                                 tempNode = tempNode.getNextSibling();
379                             }
380                             if (keyElement == null) throw new SerializeException("Could not find an element under the map-Key");
381
382                             Element JavaDoc mapValueElement = UtilXml.firstChildElement(curElement, "map-Value");
383                             Element JavaDoc valueElement = null;
384
385                             tempNode = mapValueElement.getFirstChild();
386                             while (tempNode != null) {
387                                 if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
388                                     valueElement = (Element JavaDoc) tempNode;
389                                     break;
390                                 }
391                                 tempNode = tempNode.getNextSibling();
392                             }
393                             if (valueElement == null) throw new SerializeException("Could not find an element under the map-Value");
394
395                             value.put(deserializeSingle(keyElement, delegator), deserializeSingle(valueElement, delegator));
396                         }
397                     }
398                     curChild = curChild.getNextSibling();
399                 }
400                 return value;
401             }
402         } else if (tagName.startsWith("eepk-")) {
403             return delegator.makePK(element);
404         } else if (tagName.startsWith("eeval-")) {
405             return delegator.makeValue(element);
406         }
407
408         return deserializeCustom(element);
409     }
410
411     public static Object JavaDoc deserializeCustom(Element JavaDoc element) throws SerializeException {
412         String JavaDoc tagName = element.getTagName();
413         if ("cus-obj".equals(tagName)) {
414             String JavaDoc value = UtilXml.elementValue(element);
415             if (value != null) {
416                 byte[] valueBytes = StringUtil.fromHexString(value);
417                 if (valueBytes != null) {
418                     Object JavaDoc obj = UtilObject.getObject(valueBytes);
419                     if (obj != null) {
420                         return obj;
421                     }
422                 }
423             }
424             throw new SerializeException("Problem deserializing object from byte array + " + element.getTagName());
425         } else {
426             throw new SerializeException("Cannot deserialize element named " + element.getTagName());
427         }
428     }
429
430     /**
431      * Returns the DateFormat used to serialize and deserialize <code>java.util.Date</code> objects.
432      * This format is NOT used to format any of the java.sql subtypes of java.util.Date.
433      * A <code>WeakReference</code> is used to maintain a reference to the DateFormat object
434      * so that it can be created and garbage collected as needed.
435      *
436      * @return the DateFormat used to serialize and deserialize <code>java.util.Date</code> objects.
437      */

438     private static DateFormat JavaDoc getDateFormat() {
439         DateFormat JavaDoc formatter = null;
440
441         if (simpleDateFormatter != null) {
442             formatter = (DateFormat JavaDoc) simpleDateFormatter.get();
443         }
444         if (formatter == null) {
445             formatter = new SimpleDateFormat JavaDoc("yyyy-MM-dd HH:mm:ss.S");
446             simpleDateFormatter = new WeakReference JavaDoc(formatter);
447         }
448         return formatter;
449     }
450 }
451
Popular Tags