1 22 package org.jboss.xb.binding.sunday.unmarshalling; 23 24 import java.net.URL ; 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.Map ; 28 29 import org.jboss.logging.Logger; 30 import org.jboss.util.xml.JBossEntityResolver; 31 import org.w3c.dom.ls.LSInput ; 32 import org.xml.sax.InputSource ; 33 34 41 public class DefaultSchemaResolver implements SchemaBindingResolver 42 { 43 private static Logger log = Logger.getLogger(DefaultSchemaResolver.class); 44 45 private String baseURI; 46 private JBossEntityResolver resolver; 47 private boolean cacheResolvedSchemas = true; 48 private Map schemasByUri = Collections.EMPTY_MAP; 49 private Map schemaInitByUri = Collections.EMPTY_MAP; 50 private Map schemaParseAnnotationsByUri = Collections.EMPTY_MAP; 51 52 public DefaultSchemaResolver() 53 { 54 this(new JBossEntityResolver()); 55 } 56 57 public DefaultSchemaResolver(JBossEntityResolver resolver) 58 { 59 this.resolver = resolver; 60 } 61 62 65 public boolean isCacheResolvedSchemas() 66 { 67 return cacheResolvedSchemas; 68 } 69 70 77 public void setCacheResolvedSchemas(boolean cacheResolvedSchemas) 78 { 79 this.cacheResolvedSchemas = cacheResolvedSchemas; 80 if(!cacheResolvedSchemas) 81 { 82 schemasByUri = Collections.EMPTY_MAP; 83 } 84 } 85 86 94 public void addSchemaLocation(String nsUri, String location) 95 { 96 resolver.registerLocalEntity(nsUri, location); 97 } 98 99 100 106 public void removeSchemaLocation(String nsUri) 107 { 108 resolver.registerLocalEntity(nsUri, null); 109 } 110 111 117 public void addSchemaParseAnnotations(String nsUri, Boolean value) 118 { 119 if (nsUri == null) 120 throw new IllegalArgumentException ("Null namespace uri"); 121 if (value == null) 122 throw new IllegalArgumentException ("Null value"); 123 switch(schemaParseAnnotationsByUri.size()) 124 { 125 case 0: 126 schemaParseAnnotationsByUri = Collections.singletonMap(nsUri, value); 127 break; 128 case 1: 129 schemaParseAnnotationsByUri = new HashMap (schemaParseAnnotationsByUri); 130 default: 131 schemaParseAnnotationsByUri.put(nsUri, value); 132 } 133 } 134 135 141 public Boolean removeSchemaParseAnnotations(String nsUri) 142 { 143 if (nsUri == null) 144 throw new IllegalArgumentException ("Null namespace uri"); 145 return (Boolean ) schemaParseAnnotationsByUri.remove(nsUri); 146 } 147 148 159 public void addSchemaInitializer(String nsUri, String sbiClassName) throws Exception 160 { 161 if (sbiClassName == null) 162 throw new IllegalArgumentException ("Null class name"); 163 Class clazz = Thread.currentThread().getContextClassLoader().loadClass(sbiClassName); 164 Object object = clazz.newInstance(); 165 if (object instanceof SchemaBindingInitializer == false) 166 throw new IllegalArgumentException (clazz.getName() + " is not an instance of " + SchemaBindingInitializer.class.getName()); 167 SchemaBindingInitializer sbi = (SchemaBindingInitializer) object; 168 addSchemaInitializer(nsUri, sbi); 169 } 170 171 181 public void addSchemaInitializer(String nsUri, SchemaBindingInitializer sbi) 182 { 183 if (nsUri == null) 184 throw new IllegalArgumentException ("Null namespace uri"); 185 if (sbi == null) 186 throw new IllegalArgumentException ("Null schema binding initializer"); 187 switch(schemaInitByUri.size()) 188 { 189 case 0: 190 schemaInitByUri = Collections.singletonMap(nsUri, sbi); 191 break; 192 case 1: 193 schemaInitByUri = new HashMap (schemaInitByUri); 194 default: 195 schemaInitByUri.put(nsUri, sbi); 196 } 197 } 198 199 205 public SchemaBindingInitializer removeSchemaInitializer(String nsUri) 206 { 207 if (nsUri == null) 208 throw new IllegalArgumentException ("Null namespace uri"); 209 return (SchemaBindingInitializer)schemaInitByUri.remove(nsUri); 210 } 211 212 public String getBaseURI() 213 { 214 return baseURI; 215 } 216 217 public void setBaseURI(String baseURI) 218 { 219 this.baseURI = baseURI; 220 } 221 222 230 public SchemaBinding resolve(String nsURI, String baseURI, String schemaLocation) 231 { 232 SchemaBinding schema = (SchemaBinding)schemasByUri.get(nsURI); 233 if(schema != null) 234 { 235 return schema; 236 } 237 238 InputSource is = getInputSource(nsURI, baseURI, schemaLocation); 239 240 if (is != null) 241 { 242 if( baseURI == null ) 243 baseURI = this.baseURI; 244 245 Boolean processAnnotationsBoolean = (Boolean ) schemaParseAnnotationsByUri.get(nsURI); 246 boolean processAnnotations = (processAnnotationsBoolean == null) ? true : processAnnotationsBoolean.booleanValue(); 247 schema = XsdBinder.bind(is.getByteStream(), null, baseURI, processAnnotations); 248 } 249 250 if(schema != null) 251 { 252 schema.setSchemaResolver(this); 253 SchemaBindingInitializer sbi = (SchemaBindingInitializer)schemaInitByUri.get(nsURI); 254 if(sbi != null) 255 { 256 schema = sbi.init(schema); 257 } 258 259 if(schema != null && cacheResolvedSchemas) 260 { 261 if(schemasByUri == Collections.EMPTY_MAP) 262 { 263 schemasByUri = new HashMap (); 264 } 265 schemasByUri.put(nsURI, schema); 266 } 267 } 268 269 if(log.isTraceEnabled()) 270 { 271 log.trace("resolved schema: " + schema); 272 } 273 274 return schema; 275 } 276 277 public LSInput resolveAsLSInput(String nsURI, String baseURI, String schemaLocation) 278 { 279 LSInput lsInput = null; 280 InputSource is = getInputSource(nsURI, baseURI, schemaLocation); 281 if (is != null) 282 { 283 String publicId = is.getPublicId(); 284 String systemId = is.getSystemId(); 285 lsInput = new LSInputAdaptor(publicId, systemId, baseURI); 286 lsInput.setCharacterStream(is.getCharacterStream()); 287 lsInput.setByteStream(is.getByteStream()); 288 lsInput.setEncoding(is.getEncoding()); 289 } 290 return lsInput; 291 } 292 293 private InputSource getInputSource(String nsURI, String baseURI, String schemaLocation) 294 { 295 boolean trace = log.isTraceEnabled(); 296 InputSource is = null; 297 298 if( trace ) 299 log.trace("getInputSource, nsURI="+nsURI+", baseURI="+baseURI+", schemaLocation="+schemaLocation); 300 301 try 303 { 304 is = resolver.resolveEntity(nsURI, schemaLocation); 305 if (trace) 306 log.trace("Resolved schema using namespace as publicId and schemaLocation as systemId"); 307 } 308 catch (Exception e) 309 { 310 if (trace) 311 log.trace("Failed to use nsUri/schemaLocation", e); 312 } 313 314 if(baseURI == null) 316 { 317 baseURI = this.baseURI; 318 } 319 320 if (is == null && baseURI != null && schemaLocation != null) 321 { 322 try 323 { 324 URL url = new URL (baseURI); 325 url = new URL (url, schemaLocation); 326 String resolvedSchemaLocation = url.toString(); 327 if (schemaLocation.equals(resolvedSchemaLocation) == false) 329 { 330 is = resolver.resolveEntity(null, url.toString()); 331 if( trace && is != null ) 332 log.trace("Resolved schema location using baseURI"); 333 } 334 } 335 catch (Exception e) 336 { 337 if (trace) 338 log.trace("Failed to use schema location with baseURI", e); 339 } 340 } 341 342 if (is == null && nsURI != null) 344 { 345 try 346 { 347 is = resolver.resolveEntity(null, nsURI); 348 if( trace && is != null ) 349 log.trace("Resolved namespace as system id"); 350 } 351 catch (Exception e) 352 { 353 if (trace) 354 log.trace("Failed to use namespace as system id", e); 355 } 356 } 357 if( trace ) 358 { 359 log.trace("getInputSource, nsURI="+nsURI+", baseURI=" 360 +baseURI+", schemaLocation="+schemaLocation+", is="+is); 361 } 362 return is; 363 } 364 } 365 | Popular Tags |