1 19 package org.enhydra.zeus; 20 21 import java.io.IOException ; 22 import java.lang.reflect.Method ; 23 import java.lang.reflect.InvocationTargetException ; 24 import java.util.HashMap ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.Map ; 28 29 import org.enhydra.zeus.util.ClassUtils; 31 import org.enhydra.zeus.util.NamingUtils; 32 33 import org.jdom.Attribute; 35 import org.jdom.Document; 36 import org.jdom.DocType; 37 import org.jdom.Element; 38 import org.jdom.JDOMException; 39 import org.jdom.Namespace; 40 import org.jdom.input.SAXBuilder; 41 42 59 public class Unmarshaller { 60 61 62 protected boolean debug = false; 63 64 65 private Map implClasses; 66 67 68 private String javaPackage; 69 70 74 protected String namePrefix; 75 76 81 public Unmarshaller() { 82 implClasses = new HashMap (); 83 namePrefix = ""; 84 } 85 86 99 public void setImplClass(String interfaceName, String implClassName) { 100 implClasses.put(interfaceName, implClassName); 101 } 102 103 113 public void setNamePrefix(String namePrefix) { 114 if (namePrefix != null) { 115 this.namePrefix = namePrefix; 116 } 117 } 118 119 130 public String getNamePrefix() { 131 return namePrefix; 132 } 133 134 147 public String getImplClass(String interfaceName) { 148 String implClass = (String )implClasses.get(interfaceName); 149 if (implClass == null) { 150 implClass = new StringBuffer () 152 .append(namePrefix) 153 .append(interfaceName) 154 .append("Impl") 155 .toString(); 156 } 157 return implClass; 158 } 159 160 167 public String getJavaPackage() { 168 if (javaPackage == null) { 169 javaPackage = ""; 170 } 171 return javaPackage; 172 } 173 174 182 public void setJavaPackage(String javaPackage) { 183 this.javaPackage = javaPackage; 184 } 185 186 204 public UnmarshalledObject unmarshal(Source sourceXML) throws IOException { 205 Document doc = sourceXML.getDocument(); 207 Element rootElement = doc.getRootElement(); 208 209 Object obj = getJavaRepresentation(rootElement); 211 212 DocType docType = doc.getDocType(); 214 if (docType != null) { 215 return new UnmarshalledObject(obj, 216 docType.getPublicID(), 217 docType.getSystemID()); 218 } else { 219 return new UnmarshalledObject(obj); 220 } 221 } 222 223 233 private Object getJavaRepresentation(Element element) 234 throws IOException { 235 236 if (debug) { 238 System.out.println("Unmarshaller.getJavaRepresentation: " + 239 element.getName()); 240 } 241 242 Object obj = null; 243 String className = null; 244 try { 245 Namespace ns = element.getNamespace(); 246 247 className = getImplClass(NamingUtils.getJavaClassName( 249 element.getName())); 250 251 Class objectClass; 252 253 String pkg = getJavaPackage(); 255 if (pkg.equals("")) { 256 objectClass = getClass().getClassLoader().loadClass(className); 257 } else { 258 objectClass = 259 getClass().getClassLoader().loadClass(new StringBuffer () 260 .append(pkg) 261 .append(".") 262 .append(className) 263 .toString()); 264 } 265 266 obj = objectClass.newInstance(); 268 269 List attributes = element.getAttributes(); 271 Method [] methods = objectClass.getMethods(); 272 273 for (Iterator i = attributes.iterator(); i.hasNext(); ) { 274 Attribute att = (Attribute)i.next(); 275 276 if (debug) { 278 System.out.println( 279 " Processing attribute : " + att.getName()); 280 } 281 282 if ((!att.getNamespace().equals(ns)) && 284 (!att.getNamespace().equals(Namespace.NO_NAMESPACE))) { 285 continue; 286 } 287 288 String methodName = new StringBuffer () 291 .append("set") 292 .append(NamingUtils.getJavaClassName(att.getName())) 293 .toString(); 294 295 for (int j=0; j<methods.length; j++) { 297 if (methods[j].getName().equals(methodName)) { 298 Class [] paramTypes = methods[j].getParameterTypes(); 300 Class paramType = paramTypes[0]; 301 302 Object param = 304 ClassUtils.getParameter(att.getValue(), paramType); 305 306 methods[j].invoke(obj, new Object [] { param }); 308 } 309 } 310 } 311 312 List children = element.getChildren(); 314 315 for (Iterator i = children.iterator(); i.hasNext(); ) { 316 Element child = (Element)i.next(); 317 if (debug) { 319 System.out.println(" Processing Child Element: " + 320 child.getName()); 321 } 322 323 if ((!child.getNamespace().equals(ns)) && 325 (!child.getNamespace().equals(Namespace.NO_NAMESPACE))) { 326 continue; 327 } 328 329 String singularMethodName = new StringBuffer () 331 .append("set") 332 .append(NamingUtils.getJavaClassName(child.getName())) 333 .toString(); 334 String listMethodName = new StringBuffer () 335 .append("add") 336 .append(NamingUtils.getJavaClassName(child.getName())) 337 .toString(); 338 339 for (int j=0; j<methods.length; j++) { 341 if (methods[j].getName().equals(singularMethodName)) { 342 Class [] paramTypes = methods[j].getParameterTypes(); 344 Class paramType = paramTypes[0]; 345 346 Object param = null; 348 349 if (isSimpleElement(child)) { 350 param = child.getTextTrim(); 351 } else { 352 param = getJavaRepresentation(child); 353 } 354 355 try { 359 methods[j].invoke(obj, new Object [] { param }); 360 } catch (IllegalArgumentException ilex) { 361 param = getJavaRepresentation(child); 362 methods[j].invoke(obj, new Object [] { param }); 363 } 364 365 break; 366 } else if (methods[j].getName().equals(listMethodName)) { 367 Class [] paramTypes = methods[j].getParameterTypes(); 368 Class paramType = paramTypes[0]; 369 370 Object param = null; 372 if (isSimpleElement(child)) { 373 param = child.getTextTrim(); 374 } else { 375 param = getJavaRepresentation(child); 376 } 377 378 try { 382 methods[j].invoke(obj, new Object [] { param }); 383 } catch (IllegalArgumentException ilex) { 384 param = getJavaRepresentation(child); 385 } 386 387 break; 388 } 389 } 390 } 391 392 String content = element.getTextTrim(); 394 if ((content != null) && (content.length() > 0)) { 395 String methodName = "setValue"; 396 Method method 397 = objectClass.getMethod(methodName, 398 new Class [] { String .class }); 399 method.invoke(obj, new Object [] { content }); 400 } 401 402 } catch (ClassNotFoundException e) { 403 throw new IOException ("The class that the XML instance document " + 404 "should be unmarshalled as an instance of, " + 405 className + 406 ", must be generated and on the classpath. " + 407 "The current classpath is '" + 408 System.getProperty("java.class.path") + "'."); 409 } catch (InstantiationException e) { 410 throw new IOException ("Could not create a new instance of the " + 411 "class " + className); 412 } catch (IllegalAccessException e) { 413 throw new IOException ("Could not access the class " + className); 414 } catch (IllegalArgumentException e) { 415 throw new IOException ("Could not pass arguments to mutator " + 416 "method on new instance."); 417 } catch (InvocationTargetException e) { 418 throw new IOException ("Error in accessing mutator on new " + 419 "instance of class."); 420 } catch (NoSuchMethodException e) { 421 throw new IOException ( 422 "Error in setting data method on new instance of class."); 423 } 424 return obj; 425 } 426 427 436 private boolean isSimpleElement(Element element) { 437 boolean simple = true; 438 if (element.getChildren().isEmpty()) { 439 List attributes = element.getAttributes(); 440 int size = attributes.size(); 441 Attribute attr = null; 442 String typeStr = "dt_"; 443 444 for (int i = 0; i < size; i++) { 447 attr = (Attribute)attributes.get(i); 448 if (!attr.getName().startsWith(typeStr)) { 449 simple = false; 450 break; 451 } 452 } 453 } else { 454 simple = false; 455 } 456 return simple; 457 } 458 } 459 | Popular Tags |