package dk.kb.yggdrasil.xslt; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * Implements a caching XML entity resolver. Resolves and caches DTD and XSD. */ public class XmlEntityResolver implements EntityResolver { /** Logging mechanism. */ private static Logger logger = LoggerFactory.getLogger(XmlEntityResolver.class.getName()); /** Path to cache directory. */ protected File cacheDir; /** * Construct a caching XML entity resolver instance. * @param cacheDir path to cache directory */ public XmlEntityResolver(File cacheDir) { this.cacheDir = cacheDir; if (!cacheDir.exists()) { boolean createDirsSuccess = cacheDir.mkdirs(); logger.debug("Created dir '" + cacheDir.getAbsolutePath() + "' successfully: " + createDirsSuccess); } } @Override public synchronized InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { logger.info("Resolving: " + systemId + " (\"" + publicId + "\")"); if (systemId != null) { int pos = systemId.lastIndexOf("/"); if (pos != -1) { String res = systemId.substring(pos + 1); File file = new File(cacheDir, res); if (file.exists() && file.isFile()) { /* * Load cached dtd. */ try { logger.info(" Loading cached: " + file.getAbsolutePath()); return new InputSource(new BufferedReader(new InputStreamReader(new FileInputStream(file), Charset.defaultCharset()))); } catch (FileNotFoundException e) { logger.warn(e.toString(), e); return null; } } else { /* * Attempt to cache dtd. */ URL url; InputStream in = null; FileOutputStream out = null; try { byte[] buffer = new byte[1024]; int len; url = new URL(systemId); in = url.openStream(); out = new FileOutputStream(file); while ((len = in.read( buffer, 0, 1024)) != -1) { out.write(buffer, 0, len); } logger.info(" Saving cached: " + file.getAbsolutePath()); return new InputSource(new BufferedReader(new InputStreamReader(new FileInputStream(file), Charset.defaultCharset()))); } catch (MalformedURLException e) { logger.warn(e.toString(), e); return null; } catch (IOException e) { logger.warn(e.toString(), e); return null; } finally { try { if (out != null) { out.close(); out = null; } if (in != null) { in.close(); in = null; } } catch (IOException e) { logger.warn("Issue closing the input and output streams.", e); } } } } } return null; } }