1 23 24 package org.enhydra.xml.io; 25 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.io.PrintWriter ; 29 import java.util.Enumeration ; 30 import java.util.Vector ; 31 32 import org.enhydra.apache.xerces.readers.XCatalog; 33 import org.xml.sax.EntityResolver ; 34 import org.xml.sax.InputSource ; 35 import org.xml.sax.SAXException ; 36 37 53 public class XMLEntityResolver implements EntityResolver { 54 57 public static final String CLASSPATH_PROTOCOL = "file"; 58 59 62 public static final String CLASSPATH_PROTOCOL_PREFIX 63 = CLASSPATH_PROTOCOL + ":"; 64 65 69 public static final String DEFAULT_ENTITY_CATALOG 70 = CLASSPATH_PROTOCOL_PREFIX + "/org/enhydra/xml/catalog/default.xcat"; 71 72 77 public static final String LUTRIS_ENTITY_CATALOG 78 = CLASSPATH_PROTOCOL_PREFIX + "/org/enhydra/xml/catalog/lutris.xcat"; 79 80 83 private PrintWriter fDebugWriter = null; 84 85 88 private XCatalog fXCatalog = new XCatalog(); 89 90 93 private Vector fClassLoaders = new Vector (); 94 95 98 public void setDebugWriter(PrintWriter writer) { 99 fDebugWriter = writer; 100 } 101 102 105 public PrintWriter getDebugWriter() { 106 return fDebugWriter; 107 } 108 109 118 public void loadCatalog(InputSource source) 119 throws SAXException , IOException { 120 if (fDebugWriter != null) { 121 fDebugWriter.println("loadCatalog(" + InputSourceOps.getName(source) + ")"); 122 } 123 InputSource loadSource = searchClassPath(source); 125 if (loadSource == null) { 126 loadSource = source; 127 } 128 if (fDebugWriter != null) { 129 fDebugWriter.println("loading catalog from(" + InputSourceOps.getName(loadSource) + ")"); 130 } 131 fXCatalog.loadCatalog(loadSource); 132 } 133 134 138 public void setDefaultResolving() throws SAXException , IOException { 139 ClassLoader classLoader = XMLEntityResolver.class.getClassLoader(); 142 if (classLoader == null) { 143 classLoader = ClassLoader.getSystemClassLoader(); 144 } 145 addClassLoader(classLoader); 146 loadCatalog(new InputSource (DEFAULT_ENTITY_CATALOG)); 147 148 InputSource optSource = searchClassPath(LUTRIS_ENTITY_CATALOG); 150 if (optSource != null) { 151 loadCatalog(optSource); 152 } 153 } 154 155 161 public void addPublicMapping(String publicId, String systemId) { 162 fXCatalog.addPublicMapping(publicId, systemId); 163 } 164 165 170 public void removePublicMapping(System publicId) { 171 fXCatalog.removePublicMapping(publicId); 172 } 173 174 175 public Enumeration getPublicMappingKeys() { 176 return fXCatalog.getPublicMappingKeys(); 177 } 178 179 187 public String getPublicMapping(String publicId) { 188 return fXCatalog.getPublicMapping(publicId); 189 } 190 191 197 public void addSystemMapping(String systemId1, String systemId2) { 198 fXCatalog.addSystemMapping(systemId1, systemId2); 199 } 200 201 206 public void removeSystemMapping(String systemId) { 207 fXCatalog.removeSystemMapping(systemId); 208 } 209 210 211 public Enumeration getSystemMappingKeys() { 212 return fXCatalog.getSystemMappingKeys(); 213 } 214 215 223 public String getSystemMapping(String systemId) { 224 return fXCatalog.getSystemMapping(systemId); 225 } 226 227 231 public void addClassLoader(ClassLoader classLoader) { 232 fClassLoaders.add(classLoader); 233 } 234 235 238 public Enumeration getClassLoaders() { 239 return fClassLoaders.elements(); 240 } 241 242 245 private InputSource loadFromClassLoader(ClassLoader loader, 246 String resourceId) 247 throws IOException { 248 if (resourceId.startsWith("/")) { 250 resourceId = resourceId.substring(1); 251 } 252 InputStream in = loader.getResourceAsStream(resourceId); 253 if (in != null) { 254 return new ClosingInputSource(in); 255 } else { 256 return null; 257 } 258 } 259 260 263 private boolean isClassPathURL(String systemId) { 264 return ((systemId != null) && systemId.startsWith(CLASSPATH_PROTOCOL_PREFIX)); 265 } 266 267 270 private String parseClassPathURL(String url) { 271 return url.substring(CLASSPATH_PROTOCOL_PREFIX.length()); 272 } 273 274 280 private InputSource searchClassPath(String systemId) 281 throws IOException { 282 InputSource source = null; 283 if ((systemId != null) && isClassPathURL(systemId)) { 284 String resourceName = parseClassPathURL(systemId); 285 int len = fClassLoaders.size(); 286 for (int idx = 0; (idx < len) && (source == null); idx++) { 287 source = loadFromClassLoader((ClassLoader )fClassLoaders.get(idx), 288 resourceName); 289 } 290 if (source != null) { 291 source.setSystemId(systemId); 292 } 293 } 294 if (fDebugWriter != null) { 295 fDebugWriter.println("Entity " + ((source == null) ? "not " : "") 296 + "found searching " + fClassLoaders.size() 297 + " class loader(s): " + systemId 298 + " => " + InputSourceOps.getName(source)); 299 } 300 return source; 301 } 302 303 306 private InputSource searchClassPath(InputSource source) 307 throws IOException { 308 if ((source.getByteStream() != null) 309 || (source.getCharacterStream() != null)) { 310 return null; } else { 312 return searchClassPath(source.getSystemId()); 313 } 314 } 315 316 317 320 public InputSource resolveEntity(String publicId, 321 String systemId) 322 throws SAXException , IOException { 323 if (fDebugWriter != null) { 324 fDebugWriter.println("resolveEntity(" + publicId + ", " + systemId + ")"); 325 } 326 327 InputSource source; 328 InputSource catalogSource = fXCatalog.resolveEntity(publicId, 329 systemId); 330 if (catalogSource != null) { 331 if (fDebugWriter != null) { 332 fDebugWriter.println("XMLCatalog maps entity to: " + catalogSource.getSystemId()); } 334 source = searchClassPath(catalogSource); 335 if (source == null) { 336 source = catalogSource; } 338 } else { 339 source = searchClassPath(systemId); 340 } 341 if (fDebugWriter != null) { 342 fDebugWriter.println("Resolved: " + InputSourceOps.getName(source)); 343 } 344 return source; 345 } 346 } 347 | Popular Tags |