1 24 package org.ofbiz.entity.serialize; 25 26 import java.io.FileNotFoundException ; 27 import java.io.IOException ; 28 import java.io.Serializable ; 29 import java.lang.ref.WeakReference ; 30 import java.text.DateFormat ; 31 import java.text.ParseException ; 32 import java.text.SimpleDateFormat ; 33 import java.util.ArrayList ; 34 import java.util.Collection ; 35 import java.util.HashMap ; 36 import java.util.HashSet ; 37 import java.util.Hashtable ; 38 import java.util.Iterator ; 39 import java.util.LinkedList ; 40 import java.util.Locale ; 41 import java.util.Map ; 42 import java.util.Properties ; 43 import java.util.Stack ; 44 import java.util.TreeMap ; 45 import java.util.TreeSet ; 46 import java.util.Vector ; 47 import java.util.WeakHashMap ; 48 49 import javax.xml.parsers.ParserConfigurationException ; 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 ; 60 import org.w3c.dom.Element ; 61 import org.w3c.dom.Node ; 62 import org.xml.sax.SAXException ; 63 64 72 public class XmlSerializer { 73 public static final String module = XmlSerializer.class.getName(); 74 75 private static WeakReference simpleDateFormatter; 76 77 public static String serialize(Object object) throws SerializeException, FileNotFoundException , IOException { 78 Document document = UtilXml.makeEmptyXmlDocument("ofbiz-ser"); 79 Element rootElement = document.getDocumentElement(); 80 81 rootElement.appendChild(serializeSingle(object, document)); 82 return UtilXml.writeXmlDocument(document); 83 } 84 85 public static Object deserialize(String content, GenericDelegator delegator) 86 throws SerializeException, SAXException , ParserConfigurationException , IOException { 87 Document document = UtilXml.readXmlDocument(content, false); 89 if (document != null) { 90 Element rootElement = document.getDocumentElement(); 91 Node 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 element = (Element ) 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 serializeSingle(Object object, Document document) throws SerializeException { 108 if (document == null) return null; 109 110 if (object == null) return document.createElement("null"); 111 112 if (object instanceof String ) { 114 return makeElement("std-String", object, document); 115 } else if (object instanceof Integer ) { 116 return makeElement("std-Integer", object, document); 117 } else if (object instanceof Long ) { 118 return makeElement("std-Long", object, document); 119 } else if (object instanceof Float ) { 120 return makeElement("std-Float", object, document); 121 } else if (object instanceof Double ) { 122 return makeElement("std-Double", object, document); 123 } else if (object instanceof Boolean ) { 124 return makeElement("std-Boolean", object, document); 125 } else if (object instanceof Locale ) { 126 return makeElement("std-Locale", object, document); 127 } else if (object instanceof java.sql.Timestamp ) { 129 return makeElement("sql-Timestamp", object, document); 130 } else if (object instanceof java.sql.Date ) { 131 return makeElement("sql-Date", object, document); 132 } else if (object instanceof java.sql.Time ) { 133 return makeElement("sql-Time", object, document); 134 } else if (object instanceof java.util.Date ) { 135 DateFormat formatter = getDateFormat(); 137 String stringValue = null; 138 139 synchronized (formatter) { 140 stringValue = formatter.format((java.util.Date ) object); 141 } 142 return makeElement("std-Date", stringValue, document); 143 } else if (object instanceof Collection ) { 145 String elementName = null; 147 148 if (object instanceof ArrayList ) { 150 elementName = "col-ArrayList"; 151 } else if (object instanceof LinkedList ) { 152 elementName = "col-LinkedList"; 153 } else if (object instanceof Stack ) { 154 elementName = "col-Stack"; 155 } else if (object instanceof Vector ) { 156 elementName = "col-Vector"; 157 } else if (object instanceof TreeSet ) { 158 elementName = "col-TreeSet"; 159 } else if (object instanceof HashSet ) { 160 elementName = "col-HashSet"; 161 } else { 162 elementName = "col-Collection"; 164 } 165 166 168 Collection value = (Collection ) object; 169 Element element = document.createElement(elementName); 170 Iterator 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 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 ) { 186 String elementName = null; 188 189 if (object instanceof HashMap ) { 191 elementName = "map-HashMap"; 192 } else if (object instanceof Properties ) { 193 elementName = "map-Properties"; 194 } else if (object instanceof Hashtable ) { 195 elementName = "map-Hashtable"; 196 } else if (object instanceof WeakHashMap ) { 197 elementName = "map-WeakHashMap"; 198 } else if (object instanceof TreeMap ) { 199 elementName = "map-TreeMap"; 200 } else { 201 elementName = "map-Map"; 203 } 204 205 Element element = document.createElement(elementName); 206 Map value = (Map ) object; 207 Iterator iter = value.entrySet().iterator(); 208 209 while (iter.hasNext()) { 210 Map.Entry entry = (Map.Entry ) iter.next(); 211 212 Element entryElement = document.createElement("map-Entry"); 213 214 element.appendChild(entryElement); 215 216 Element key = document.createElement("map-Key"); 217 218 entryElement.appendChild(key); 219 key.appendChild(serializeSingle(entry.getKey(), document)); 220 Element 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 serializeCustom(Object object, Document document) throws SerializeException { 232 if (object instanceof Serializable ) { 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 byteHex = StringUtil.toHexString(objBytes); 238 Element 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 makeElement(String elementName, Object value, Document document) { 248 if (value == null) return document.createElement("null"); 249 Element element = document.createElement(elementName); 250 251 element.setAttribute("value", value.toString()); 252 return element; 253 } 254 255 public static Object deserializeSingle(Element element, GenericDelegator delegator) throws SerializeException { 256 String tagName = element.getTagName(); 257 258 if (tagName.equals("null")) return null; 259 260 if (tagName.startsWith("std-")) { 261 if ("std-String".equals(tagName)) { 263 return element.getAttribute("value"); 264 } else if ("std-Integer".equals(tagName)) { 265 String valStr = element.getAttribute("value"); 266 return Integer.valueOf(valStr); 267 } else if ("std-Long".equals(tagName)) { 268 String valStr = element.getAttribute("value"); 269 return Long.valueOf(valStr); 270 } else if ("std-Float".equals(tagName)) { 271 String valStr = element.getAttribute("value"); 272 return Float.valueOf(valStr); 273 } else if ("std-Double".equals(tagName)) { 274 String valStr = element.getAttribute("value"); 275 return Double.valueOf(valStr); 276 } else if ("std-Boolean".equals(tagName)) { 277 String valStr = element.getAttribute("value"); 278 return Boolean.valueOf(valStr); 279 } else if ("std-Locale".equals(tagName)) { 280 String valStr = element.getAttribute("value"); 281 return UtilMisc.parseLocale(valStr); 282 } else if ("std-Date".equals(tagName)) { 283 String valStr = element.getAttribute("value"); 284 DateFormat formatter = getDateFormat(); 285 java.util.Date value = null; 286 287 try { 288 synchronized (formatter) { 289 value = formatter.parse(valStr); 290 } 291 } catch (ParseException e) { 292 throw new SerializeException("Could not parse date String: " + valStr, e); 293 } 294 return value; 295 } 296 } else if (tagName.startsWith("sql-")) { 297 if ("sql-Timestamp".equals(tagName)) { 299 String valStr = element.getAttribute("value"); 300 return java.sql.Timestamp.valueOf(valStr); 301 } else if ("sql-Date".equals(tagName)) { 302 String valStr = element.getAttribute("value"); 303 return java.sql.Date.valueOf(valStr); 304 } else if ("sql-Time".equals(tagName)) { 305 String valStr = element.getAttribute("value"); 306 return java.sql.Time.valueOf(valStr); 307 } 308 } else if (tagName.startsWith("col-")) { 309 Collection value = null; 311 312 if ("col-ArrayList".equals(tagName)) { 313 value = new ArrayList (); 314 } else if ("col-LinkedList".equals(tagName)) { 315 value = new LinkedList (); 316 } else if ("col-Stack".equals(tagName)) { 317 value = new Stack (); 318 } else if ("col-Vector".equals(tagName)) { 319 value = new Vector (); 320 } else if ("col-TreeSet".equals(tagName)) { 321 value = new TreeSet (); 322 } else if ("col-HashSet".equals(tagName)) { 323 value = new HashSet (); 324 } else if ("col-Collection".equals(tagName)) { 325 value = new LinkedList (); 326 } 327 328 if (value == null) { 329 return deserializeCustom(element); 330 } else { 331 Node curChild = element.getFirstChild(); 332 333 while (curChild != null) { 334 if (curChild.getNodeType() == Node.ELEMENT_NODE) { 335 value.add(deserializeSingle((Element ) curChild, delegator)); 336 } 337 curChild = curChild.getNextSibling(); 338 } 339 return value; 340 } 341 } else if (tagName.startsWith("map-")) { 342 Map value = null; 344 345 if ("map-HashMap".equals(tagName)) { 346 value = new HashMap (); 347 } else if ("map-Properties".equals(tagName)) { 348 value = new Properties (); 349 } else if ("map-Hashtable".equals(tagName)) { 350 value = new Hashtable (); 351 } else if ("map-WeakHashMap".equals(tagName)) { 352 value = new WeakHashMap (); 353 } else if ("map-TreeMap".equals(tagName)) { 354 value = new TreeMap (); 355 } else if ("map-Map".equals(tagName)) { 356 value = new HashMap (); 357 } 358 359 if (value == null) { 360 return deserializeCustom(element); 361 } else { 362 Node curChild = element.getFirstChild(); 363 364 while (curChild != null) { 365 if (curChild.getNodeType() == Node.ELEMENT_NODE) { 366 Element curElement = (Element ) curChild; 367 368 if ("map-Entry".equals(curElement.getTagName())) { 369 Element mapKeyElement = UtilXml.firstChildElement(curElement, "map-Key"); 370 Element keyElement = null; 371 Node tempNode = mapKeyElement.getFirstChild(); 372 373 while (tempNode != null) { 374 if (tempNode.getNodeType() == Node.ELEMENT_NODE) { 375 keyElement = (Element ) 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 mapValueElement = UtilXml.firstChildElement(curElement, "map-Value"); 383 Element valueElement = null; 384 385 tempNode = mapValueElement.getFirstChild(); 386 while (tempNode != null) { 387 if (tempNode.getNodeType() == Node.ELEMENT_NODE) { 388 valueElement = (Element ) 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 deserializeCustom(Element element) throws SerializeException { 412 String tagName = element.getTagName(); 413 if ("cus-obj".equals(tagName)) { 414 String value = UtilXml.elementValue(element); 415 if (value != null) { 416 byte[] valueBytes = StringUtil.fromHexString(value); 417 if (valueBytes != null) { 418 Object 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 438 private static DateFormat getDateFormat() { 439 DateFormat formatter = null; 440 441 if (simpleDateFormatter != null) { 442 formatter = (DateFormat ) simpleDateFormatter.get(); 443 } 444 if (formatter == null) { 445 formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.S"); 446 simpleDateFormatter = new WeakReference (formatter); 447 } 448 return formatter; 449 } 450 } 451 | Popular Tags |