Java tutorial
// // Copyright 2009 Robin Komiwes, Bruno Verachten, Christophe Cordenier // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package com.wooki.services.parsers; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Map; import javax.annotation.PostConstruct; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.log4j.Logger; import org.springframework.core.io.Resource; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; public class XHTMLToFormattingObjects implements Convertor, URIResolver, EntityResolver { private TransformerFactory tFactory = TransformerFactory.newInstance(); private Transformer transformer; private Resource xslStylesheet; private Map stylesheetParameters; private HttpClient httpClient; // Cache management private CacheManager cacheManager; private String cacheName; Cache cache; private Logger logger = Logger.getLogger(XHTMLToFormattingObjects.class); /** * This method is used to init the cache */ @PostConstruct public void initCache() { logger.debug("Start to init " + cacheName + " cache"); cache = cacheManager.getCache(cacheName); if (cache == null) { throw new IllegalArgumentException("Cache " + cacheName + " does not exist"); } // HTML DTDs putInCache("xhtml1-strict.dtd", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); putInCache("xhtml1-frameset.dtd", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"); putInCache("xhtml1-transitional.dtd", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"); // Entities putInCache("xhtml-lat1.ent", "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"); putInCache("xhtml-symbol.ent", "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"); putInCache("xhtml-special.ent", "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"); tFactory.setURIResolver(this); logger.debug("Init of " + cacheName + " is finished for xslt "/* * + xslStylesheet . * getDescription () */); } private void putInCache(String fileLocation, String systemId) { try { InputStream in = this.getClass().getResourceAsStream(fileLocation); ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); byte[] input = null; int available = 0; while ((available = in.available()) > 0) { int result; input = new byte[available]; result = in.read(input); baos.write(input); if (result == -1) break; } byte[] dtd = baos.toByteArray(); Element element = new Element(systemId, dtd); cache.put(element); } catch (IOException e) { e.printStackTrace(); logger.error("Didn't manage to put " + fileLocation + " in the \"" + cacheName + "\" cache for systemId " + systemId); logger.error(e.getLocalizedMessage()); } } public String getCacheName() { return cacheName; } public void setCacheName(String cacheName) { this.cacheName = cacheName; } public CacheManager getCacheManager() { return cacheManager; } public void setCacheManager(CacheManager cacheManager) { this.cacheManager = cacheManager; } public HttpClient getHttpClient() { return httpClient; } public void setHttpClient(HttpClient httpClient) { this.httpClient = httpClient; HttpClientParams params = httpClient.getParams(); // params. httpClient.setHttpConnectionManager(new MultiThreadedHttpConnectionManager()); } public Resource getXslStylesheet() { return xslStylesheet; } public void setXslStylesheet(Resource xslStylesheet) { this.xslStylesheet = xslStylesheet; } public Map getStylesheetParameters() { return stylesheetParameters; } public void setStylesheetParameters(Map stylesheetParameters) { this.stylesheetParameters = stylesheetParameters; } public InputStream performTransformation(Resource xmlDocument) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); StreamResult toReturn = new StreamResult(baos); // Use the TransformerFactory to instantiate a Transformer that will // work with the stylesheet you specify. This method call also processes // the stylesheet into // a compiled Templates object. try { URL url = this.xslStylesheet.getURL(); Element processedStylesheet = cache.get(url); if (processedStylesheet == null) { if (url.getProtocol().equals("http")) { GetMethod method = new GetMethod(url.toString()); this.httpClient.executeMethod(method); byte[] body = method.getResponseBody(); StreamSource input = new StreamSource(new ByteArrayInputStream(body)); input.setSystemId(url.toString()); tFactory.setURIResolver(this); transformer = tFactory.newTransformer(input); transformer.setURIResolver(this); processedStylesheet = new Element(this.xslStylesheet.getURL(), transformer); } else { StreamSource input = new StreamSource(this.xslStylesheet.getInputStream()); input.setSystemId(this.xslStylesheet.getFile()); transformer = tFactory.newTransformer(input); transformer.setURIResolver(this); processedStylesheet = new Element(this.xslStylesheet.getURL(), transformer); } cache.put(processedStylesheet); } else { transformer = (Transformer) processedStylesheet.getObjectValue(); } XMLReader reader = XMLReaderFactory.createXMLReader(); reader.setEntityResolver(this); // transformer. // Use the Transformer to apply the associated Templates object to // an // XML document (foo.xml) and write the output to a file. transformer.transform(new SAXSource(reader, new InputSource(xmlDocument.getInputStream())), toReturn); String result = new String(baos.toByteArray()); return new ByteArrayInputStream(baos.toByteArray()); } catch (TransformerConfigurationException e) { e.printStackTrace(); logger.error(e.getLocalizedMessage()); return null; } catch (IOException e) { e.printStackTrace(); logger.error(e.getLocalizedMessage()); return null; } catch (TransformerException e) { e.printStackTrace(); logger.error(e.getLocalizedMessage()); return null; } catch (SAXException e) { e.printStackTrace(); logger.error(e.getLocalizedMessage()); return null; } catch (Error e) { e.printStackTrace(); logger.error(e.getLocalizedMessage()); } return new ByteArrayInputStream(baos.toByteArray()); } public Source resolve(String href, String base) throws TransformerException { Source toReturn = null; if (base != null && base.contains("file://")) { String newPath = base.substring("file:///".length()).replace('/', File.separatorChar); newPath = newPath.substring(0, newPath.lastIndexOf(File.separatorChar)); File baseFile = new File(newPath); baseFile = new File( baseFile.getAbsolutePath() + File.separatorChar + href.replace('/', File.separatorChar)); try { toReturn = new StreamSource(new FileInputStream(baseFile)); } catch (FileNotFoundException e) { e.printStackTrace(); logger.error(e.getLocalizedMessage()); return null; } } else { if (base.contains("http://")) { String newUrl = base.substring(0, base.lastIndexOf('/') + 1); newUrl += href; HttpMethod get = new GetMethod(newUrl); try { httpClient.executeMethod(get); byte[] body = get.getResponseBody(); Element element = new Element(newUrl, body); cache.put(element); toReturn = new StreamSource(new BufferedInputStream(new ByteArrayInputStream(body))); } catch (HttpException e) { e.printStackTrace(); logger.error(e.getLocalizedMessage()); return null; } catch (IOException e) { e.printStackTrace(); logger.error(e.getLocalizedMessage()); return null; } toReturn.setSystemId(newUrl); } else { toReturn = new StreamSource(XHTMLToFormattingObjects.class.getResourceAsStream(href)); } } return toReturn; } public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { InputSource toReturn = null; Element cachedValue = cache.get(systemId); if (cachedValue == null) { if (systemId.contains("http://")) { HttpMethod get = new GetMethod(systemId); httpClient.executeMethod(get); byte[] body = get.getResponseBody(); Element element = new Element(systemId, body); cache.put(element); toReturn = new InputSource(new BufferedInputStream(new ByteArrayInputStream(body))); toReturn.setSystemId(systemId); } else if (systemId.contains("file://")) { String newPath = systemId.substring("file:///".length()).replace('/', File.separatorChar); File baseFile = new File(newPath); try { toReturn = new InputSource(new FileInputStream(baseFile)); } catch (FileNotFoundException e) { e.printStackTrace(); logger.error(e.getLocalizedMessage()); return null; } } } else { toReturn = new InputSource( new BufferedInputStream(new ByteArrayInputStream((byte[]) cachedValue.getObjectValue()))); toReturn.setSystemId(systemId); } return toReturn; } }