1 7 package org.jboss.xml.binding; 8 9 import org.jboss.logging.Logger; 10 import org.xml.sax.SAXException ; 11 12 import javax.xml.parsers.ParserConfigurationException ; 13 import javax.xml.namespace.QName ; 14 import java.lang.reflect.Method ; 15 import java.util.List ; 16 import java.util.ArrayList ; 17 import java.util.Map ; 18 import java.util.Collections ; 19 import java.util.HashMap ; 20 import java.util.LinkedList ; 21 import java.util.Properties ; 22 import java.io.Reader ; 23 import java.io.Writer ; 24 import java.io.InputStreamReader ; 25 import java.io.InputStream ; 26 import java.io.IOException ; 27 import java.net.URI ; 28 import java.net.URL ; 29 import java.net.MalformedURLException ; 30 31 35 public abstract class AbstractMarshaller 36 implements Marshaller 37 { 38 private static final Logger log = Logger.getLogger(AbstractMarshaller.class); 39 40 protected String version = VERSION; 41 protected String encoding = ENCODING; 42 protected List rootQNames = new ArrayList (); 43 44 private Map classMappings = Collections.EMPTY_MAP; 45 46 private Properties props; 47 48 50 public void marshal(String schemaUri, ObjectModelProvider provider, Object root, Writer writer) throws IOException , 51 ParserConfigurationException , 52 SAXException 53 { 54 URL url = null; 55 try 56 { 57 url = new URL (schemaUri); 58 } 59 catch(MalformedURLException e) 60 { 61 throw new IllegalArgumentException ("Malformed schema URI " + schemaUri + ": " + e.getMessage()); 62 } 63 64 InputStream is; 65 try 66 { 67 is = url.openStream(); 68 } 69 catch(IOException e) 70 { 71 throw new IllegalStateException ("Failed to open input stream for schema " + schemaUri + ": " + e.getMessage()); 72 } 73 74 try 75 { 76 InputStreamReader reader = new InputStreamReader (is); 77 marshal(reader, provider, root, writer); 78 } 79 finally 80 { 81 is.close(); 82 } 83 } 84 85 public void mapClassToNamespace(Class cls, 86 String root, 87 String namespaceUri, 88 Reader schemaReader, 89 ObjectModelProvider provider) 90 { 91 if(classMappings == Collections.EMPTY_MAP) 92 { 93 classMappings = new HashMap (); 94 } 95 96 ClassMapping mapping = new ClassMapping( 97 cls, 98 root, 99 namespaceUri, 100 schemaReader, 101 null, 102 provider instanceof GenericObjectModelProvider ? 103 (GenericObjectModelProvider)provider : 104 new DelegatingObjectModelProvider(provider) 105 ); 106 classMappings.put(mapping.cls, mapping); 107 } 108 109 public void mapClassToNamespace(Class cls, 110 String root, 111 String namespaceUri, 112 String schemaUrl, 113 ObjectModelProvider provider) 114 { 115 if(classMappings == Collections.EMPTY_MAP) 116 { 117 classMappings = new HashMap (); 118 } 119 120 ClassMapping mapping = new ClassMapping( 121 cls, 122 root, 123 namespaceUri, 124 null, 125 schemaUrl, 126 provider instanceof GenericObjectModelProvider ? 127 (GenericObjectModelProvider)provider : 128 new DelegatingObjectModelProvider(provider) 129 ); 130 classMappings.put(mapping.cls, mapping); 131 } 132 133 public void setVersion(String version) 134 { 135 this.version = version; 136 } 137 138 public void setEncoding(String encoding) 139 { 140 this.encoding = encoding; 141 } 142 143 public void mapPublicIdToSystemId(String publicId, String systemId) 144 { 145 throw new UnsupportedOperationException (); 146 } 147 148 public void addRootElement(String namespaceUri, String prefix, String name) 149 { 150 QName qName = new QName (namespaceUri, name, prefix); 151 rootQNames.add(qName); 152 } 153 154 public void setProperty(String name, String value) 155 { 156 if(props == null) 157 { 158 props = new Properties (); 159 } 160 props.setProperty(name, value); 161 } 162 163 public String getProperty(String name) 164 { 165 return props == null ? null : props.getProperty(name); 166 } 167 168 170 protected boolean propertyIsTrueOrNotSet(String name) 171 { 172 String value = getProperty(name); 173 return value == null || "true".equalsIgnoreCase(value); 174 } 175 176 protected void writeXmlVersion(Writer writer) throws IOException 177 { 178 String xmlVersion = getProperty(Marshaller.PROP_OUTPUT_XML_VERSION); 179 if(xmlVersion == null || "true".equalsIgnoreCase(xmlVersion)) 180 { 181 writer.write("<?xml version=\""); 182 writer.write(version); 183 writer.write("\" encoding=\""); 184 writer.write(encoding); 185 writer.write("\"?>\n"); 186 } 187 } 188 protected ClassMapping getClassMapping(Class cls) 189 { 190 return (ClassMapping)classMappings.get(cls); 191 } 192 193 static final Object provideChildren(ObjectModelProvider provider, 194 Object parent, 195 String namespaceUri, 196 String name) 197 { 198 Class providerClass = provider.getClass(); 199 Class parentClass = parent.getClass(); 200 String methodName = "getChildren"; 201 202 Object container = null; 203 Method method = getProviderMethod(providerClass, 204 methodName, 205 new Class []{parentClass, String .class, String .class} 206 ); 207 if(method != null) 208 { 209 try 210 { 211 container = method.invoke(provider, new Object []{parent, namespaceUri, name}); 212 } 213 catch(Exception e) 214 { 215 log.error("Failed to invoke method " + methodName, e); 216 throw new IllegalStateException ("Failed to invoke method " + methodName); 217 } 218 } 219 else if(log.isTraceEnabled()) 220 { 221 log.trace("No " + methodName + " for " + name); 222 } 223 return container; 224 } 225 226 static final Object provideValue(ObjectModelProvider provider, 227 Object parent, 228 String namespaceUri, 229 String name) 230 { 231 Class providerClass = provider.getClass(); 232 Class parentClass = parent.getClass(); 233 String methodName = "getElementValue"; 234 235 Object value = null; 236 Method method = getProviderMethod(providerClass, 237 methodName, 238 new Class []{parentClass, String .class, String .class} 239 ); 240 if(method != null) 241 { 242 try 243 { 244 value = method.invoke(provider, new Object []{parent, namespaceUri, name}); 245 } 246 catch(Exception e) 247 { 248 throw new IllegalStateException ("Failed to invoke method " + methodName); 249 } 250 } 251 else if(log.isTraceEnabled()) 252 { 253 log.trace("No " + methodName + " for " + name); 254 } 255 return value; 256 } 257 258 static final Object provideAttributeValue(ObjectModelProvider provider, 259 Object object, 260 String namespaceUri, 261 String name) 262 { 263 Class providerClass = provider.getClass(); 264 Class objectClass = object.getClass(); 265 String methodName = "getAttributeValue"; 266 267 Object value = null; 268 Method method = getProviderMethod(providerClass, 269 methodName, 270 new Class []{objectClass, String .class, String .class} 271 ); 272 if(method != null) 273 { 274 try 275 { 276 value = method.invoke(provider, new Object []{object, namespaceUri, name}); 277 } 278 catch(Exception e) 279 { 280 throw new IllegalStateException ("Failed to invoke method " + methodName); 281 } 282 } 283 else if(log.isTraceEnabled()) 284 { 285 log.trace("No " + methodName + " for " + name); 286 } 287 return value; 288 } 289 290 private static final Method getProviderMethod(Class providerClass, String methodName, Class [] args) 291 { 292 Method method = null; 293 try 294 { 295 method = providerClass.getMethod(methodName, args); 296 } 297 catch(NoSuchMethodException e) 298 { 299 } 301 return method; 302 } 303 304 306 protected class ClassMapping 307 { 308 public final Class cls; 309 public final String root; 310 public final String namespaceUri; 311 public final Reader schemaReader; 312 public final String schemaUrl; 313 public final GenericObjectModelProvider provider; 314 315 public ClassMapping(Class cls, 316 String root, 317 String namespaceUri, 318 Reader schemaReader, 319 String schemaUrl, 320 GenericObjectModelProvider provider) 321 { 322 this.cls = cls; 323 this.root = root; 324 this.namespaceUri = namespaceUri; 325 this.schemaReader = schemaReader; 326 this.schemaUrl = schemaUrl; 327 this.provider = provider; 328 } 329 330 public boolean equals(Object o) 331 { 332 if(this == o) 333 { 334 return true; 335 } 336 if(!(o instanceof ClassMapping)) 337 { 338 return false; 339 } 340 341 final ClassMapping classMapping = (ClassMapping)o; 342 343 if(cls != null ? !cls.equals(classMapping.cls) : classMapping.cls != null) 344 { 345 return false; 346 } 347 if(namespaceUri != null ? !namespaceUri.equals(classMapping.namespaceUri) : classMapping.namespaceUri != null) 348 { 349 return false; 350 } 351 352 return true; 353 } 354 355 public int hashCode() 356 { 357 int result; 358 result = (cls != null ? cls.hashCode() : 0); 359 result = 29 * result + (namespaceUri != null ? namespaceUri.hashCode() : 0); 360 return result; 361 } 362 } 363 364 protected static interface Stack 365 { 366 void clear(); 367 368 void push(Object o); 369 370 Object pop(); 371 372 Object peek(); 373 374 boolean isEmpty(); 375 } 376 377 protected static class StackImpl 378 implements Stack 379 { 380 private LinkedList list = new LinkedList (); 381 382 public void clear() 383 { 384 list.clear(); 385 } 386 387 public void push(Object o) 388 { 389 list.addLast(o); 390 } 391 392 public Object pop() 393 { 394 return list.removeLast(); 395 } 396 397 public Object peek() 398 { 399 return list.getLast(); 400 } 401 402 public boolean isEmpty() 403 { 404 return list.isEmpty(); 405 } 406 } 407 } 408 | Popular Tags |