1 19 package org.enhydra.zeus; 20 21 import org.enhydra.zeus.result.StreamResult; 22 import org.enhydra.zeus.util.CapitalizationUtils; 23 import org.enhydra.zeus.util.NamingUtils; 24 25 import java.io.IOException ; 26 import java.io.OutputStream ; 27 import java.lang.reflect.Field ; 28 import java.lang.reflect.Method ; 29 import java.lang.reflect.InvocationTargetException ; 30 import java.util.Iterator ; 31 import java.util.LinkedList ; 32 import java.util.List ; 33 34 import org.jdom.Attribute; 36 import org.jdom.Document; 37 import org.jdom.DocType; 38 import org.jdom.Element; 39 import org.jdom.output.XMLOutputter; 40 41 50 public class Marshaller { 51 52 53 protected List methodsToIgnore; 54 55 59 protected String namePrefix; 60 61 66 public Marshaller() { 67 methodsToIgnore = new LinkedList (); 68 methodsToIgnore.add("getClass"); 69 methodsToIgnore.add(new StringBuffer ("get") 70 .append(CapitalizationUtils.initialUpper( 71 ZeusDefaults.PCDATA_JAVA_NAME)) 72 .toString()); 73 namePrefix = ""; 74 } 75 76 87 public void ignoreMethod(String methodToIgnore) { 88 methodsToIgnore.add(methodToIgnore); 89 } 90 91 101 public void setNamePrefix(String namePrefix) { 102 if (namePrefix != null) { 103 this.namePrefix = namePrefix; 104 } 105 } 106 107 118 public String getNamePrefix() { 119 return namePrefix; 120 } 121 122 132 public void marshal(Object obj, Result result) 133 throws IOException { 134 135 if (obj instanceof UnmarshalledObject) { 136 marshal((UnmarshalledObject)obj, result); 137 } else { 138 marshal(new UnmarshalledObject(obj), result); 139 } 140 } 141 142 154 public void marshal(UnmarshalledObject obj, Result result) 155 throws IOException { 156 157 Element root = getXMLRepresentation(obj.getObject()); 159 Document doc = new Document(root); 160 161 String systemID = obj.getSystemID(); 163 String publicID = obj.getPublicID(); 164 if ((systemID != null) || (publicID != null)) { 165 DocType docType = new DocType(root.getName(), publicID, systemID); 166 doc.setDocType(docType); 167 } 168 169 if (result instanceof StreamResult) { 172 StreamResult streamResult = (StreamResult)result; 173 174 XMLOutputter outputter = new XMLOutputter(" ", true); 176 outputter.output(doc, streamResult.getWriter()); 177 streamResult.getWriter().flush(); 178 } else { 179 throw new IllegalArgumentException ( 180 "Marshaller currently only works with StreamResults."); 181 } 182 } 183 184 196 private Element getXMLRepresentation(Object obj) throws IOException { 197 Class objectClass = obj.getClass(); 198 199 String objectName = objectClass.getName(); 201 202 int index = -1; 204 if ((index = objectName.lastIndexOf('.')) != -1) { 205 objectName = objectName.substring((index + 1)); 206 } 207 208 boolean zeusGenerated = false; 210 String [] attributes = new String [0]; 211 String [] childElements = new String [0]; 212 try { 213 Field xmlName = 215 objectClass.getField(ZeusDefaults.XML_NAME_FIELD); 216 objectName = (String ) xmlName.get(obj); 217 218 Field attributesField = 220 objectClass.getField(ZeusDefaults.ATTRIBUTE_ARRAY_FIELD); 221 attributes = (String [])attributesField.get(obj); 222 223 Field elementsField = 225 objectClass.getField(ZeusDefaults.ELEMENT_ARRAY_FIELD); 226 childElements = (String [])elementsField.get(obj); 227 228 zeusGenerated = true; 229 } catch (NoSuchFieldException e) { 230 } catch (IllegalAccessException e) { 232 throw new IOException (e.getMessage()); 233 } catch (SecurityException e) { 234 throw new IOException (e.getMessage()); 235 } 236 237 if (objectName.startsWith(namePrefix)) { 239 objectName = objectName.substring(namePrefix.length()); 240 } 241 242 if ((index = objectName.indexOf("Impl")) != -1) { 244 objectName = objectName.substring(0, index); 245 } 246 247 Element element = new Element(objectName); 248 249 if (zeusGenerated) { 251 for (int i=0; i<attributes.length; i++) { 253 String attribute = attributes[i]; 254 255 String methodName = new StringBuffer ("get") 257 .append(CapitalizationUtils.initialUpper(attribute)) 258 .toString(); 259 260 try { 262 Method method = objectClass.getMethod(methodName, null); 263 String value = (String )method.invoke(obj, null); 264 265 if (value == null) { 266 continue; 267 } else { 268 element.setAttribute(attribute, value); 269 } 270 } catch (NoSuchMethodException e) { 271 throw new IOException ("An expected method, " + 272 methodName + ", was not found, and is required."); 273 } catch (IllegalAccessException e) { 274 throw new IOException (e.getMessage()); 275 } catch (InvocationTargetException e) { 276 throw new IOException (e.getMessage()); 277 } catch (SecurityException e) { 278 throw new IOException (e.getMessage()); 279 } 280 } 281 282 for (int i=0; i<childElements.length; i++) { 284 String childElementName = childElements[i]; 285 286 String methodName = new StringBuffer ("get") 288 .append(CapitalizationUtils.initialUpper(childElementName)) 289 .toString(); 290 291 try { 293 Method method = objectClass.getMethod(methodName, null); 294 Object value = method.invoke(obj, null); 295 296 if (value != null) { 297 String valueClassName = value.getClass().getName(); 299 Element childElement = null; 300 if (valueClassName.startsWith("java.lang")) { 301 childElement = new Element(childElementName); 303 childElement.setText(String.valueOf(value)); 304 } else { 305 childElement = getXMLRepresentation(value); 307 } 308 element.addContent(childElement); 309 310 continue; 312 } 313 } catch (NoSuchMethodException e) { 314 } catch (IllegalAccessException e) { 316 throw new IOException (e.getMessage()); 317 } catch (InvocationTargetException e) { 318 throw new IOException (e.getMessage()); 319 } catch (SecurityException e) { 320 throw new IOException (e.getMessage()); 321 } 322 323 methodName = new StringBuffer ("get") 326 .append(CapitalizationUtils.initialUpper(childElementName)) 327 .append("List") 328 .toString(); 329 330 try { 332 Method method = objectClass.getMethod(methodName, null); 333 List values = (List )method.invoke(obj, null); 334 Object value = null; 335 for (Iterator j = values.iterator(); j.hasNext(); ) { 336 value = j.next(); 337 if (value == null) { 338 continue; 339 } else { 340 String valueClassName = value.getClass().getName(); 342 Element childElement = null; 343 if (valueClassName.startsWith("java.lang")) { 344 childElement = new Element(childElementName); 346 childElement.setText(String.valueOf(value)); 347 } else { 348 childElement = getXMLRepresentation(value); 350 } 351 element.addContent(childElement); 352 353 continue; 355 } 356 } 357 358 continue; 360 } catch (NoSuchMethodException e) { 361 } catch (IllegalAccessException e) { 363 throw new IOException (e.getMessage()); 364 } catch (InvocationTargetException e) { 365 throw new IOException (e.getMessage()); 366 } catch (SecurityException e) { 367 throw new IOException (e.getMessage()); 368 } 369 } 370 371 372 String methodName = new StringBuffer ("get") 375 .append(CapitalizationUtils.initialUpper( 376 ZeusDefaults.PCDATA_JAVA_NAME)) 377 .toString(); 378 379 try { 381 Method method = objectClass.getMethod(methodName, null); 382 String value = (String )method.invoke(obj, null); 383 element.setText(value); 384 } catch (NoSuchMethodException e) { 385 } catch (IllegalAccessException e) { 388 throw new IOException (e.getMessage()); 389 } catch (InvocationTargetException e) { 390 throw new IOException (e.getMessage()); 391 } catch (SecurityException e) { 392 throw new IOException (e.getMessage()); 393 } 394 395 } else { 397 Method [] methods = objectClass.getMethods(); 398 for (int i=0; i<methods.length; i++) { 399 Method method = methods[i]; 401 String methodName = method.getName(); 402 if ((methodName.startsWith("get")) && 403 (!methodsToIgnore.contains(methodName)) && 404 (!methodName.endsWith("List"))) { 405 406 try { 408 Object o = method.invoke(obj, new Object [] { }); 409 if (o == null) { 411 continue; 412 } 413 414 String propertyName = 416 NamingUtils.getXMLElementNameFromAccessor( 417 method.getName()); 418 419 if (o.getClass().getName().startsWith("java.lang.")) { 421 element.setAttribute(propertyName, o.toString()); 423 } else { 424 element.addContent(getXMLRepresentation(o)); 426 } 427 } catch (IllegalAccessException e) { 428 throw new IOException (e.getMessage()); 429 } catch (InvocationTargetException e) { 430 throw new IOException (e.getMessage()); 431 } 432 } else if ((methodName.startsWith("get")) && 433 (methodName.endsWith("List"))) { 434 try { 436 List items = (List )method.invoke(obj, new Object [] { }); 437 for (Iterator j = items.iterator(); j.hasNext(); ) { 438 element.addContent(getXMLRepresentation(j.next())); 439 } 440 } catch (IllegalAccessException e) { 441 throw new IOException (e.getMessage()); 442 } catch (InvocationTargetException e) { 443 throw new IOException (e.getMessage()); 444 } 445 } else if (methodName.equals(new StringBuffer ("get") 446 .append(CapitalizationUtils.initialUpper( 447 ZeusDefaults.PCDATA_JAVA_NAME)) 448 .toString())) { 449 try { 451 String content = 452 (String )method.invoke(obj, new Object [] { }); 453 element.setText(content); 454 } catch (IllegalAccessException e) { 455 throw new IOException (e.getMessage()); 456 } catch (InvocationTargetException e) { 457 throw new IOException (e.getMessage()); 458 } 459 } 460 } 461 } 462 463 return element; 464 } 465 } 466 | Popular Tags |