package fr.inist; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; 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.DefaultHandler; import com.saxonica.config.EnterpriseTransformerFactory; import net.sf.saxon.lib.FeatureKeys; import net.sf.saxon.lib.Validation; import net.sf.saxon.trans.XPathException; public class SaxonXSLT { public static void main(String[] args) throws IOException { // write your code here String source = args[0]; String style = args[1]; String output = args[2]; String schema = args[3]; File fIn = new File(source); File fOut = new File(output); File fXslt = new File(style); File fSchema = new File(schema); if (style==null) { System.out.println("No xslt supplied"); usage(); return; } if (source==null) { System.out.println("No input supplied"); usage(); return; } if (output==null) { System.out.println("No output supplied"); usage(); return; } if (!fOut.isDirectory() || !fOut.exists()) { System.out.println("output must be a valid directory"); usage(); return; } if (!fIn.exists()) { System.out.println("input must be a valid file or directory"); usage(); return; } if (!fXslt.exists()) { System.out.println("output must be a valid file"); usage(); return; } SaxonXSLT saxonXslt; saxonXslt = new SaxonXSLT(fIn, fXslt, fOut); if (schema != null) { System.out.println("We will try to validate generated files thanks to "+schema); if (!fSchema.exists()) { System.out.println("schema must be a valid file"); usage(); return; } else { saxonXslt.setSchema(fSchema); System.out.println("schema : "+fSchema.getAbsolutePath()); System.out.println("hasSchema() : "+saxonXslt.hasSchema()); } } saxonXslt.processInput(); } public static void usage() { System.out.print("usage : java SaxonXSLT <input> <xslt> <output> [<schema>] (input can be file or dir, output must be a dir)"); } private File fIn, fXslt, fOut, fSchema; private String outputPath; private String inputPath; public SaxonXSLT(File in, File xslt, File out) { this.fIn = in; this.fXslt = xslt; this.fOut = out; // Path outPath = FileSystems.getDefault().getPath(fOut.getAbsolutePath()); this.outputPath = fOut.getAbsolutePath(); this.inputPath = (fIn.isDirectory()) ? fIn.getAbsolutePath() : fIn.getParentFile().getAbsolutePath(); System.out.println("inputPath="+inputPath); } public void processInput() throws IOException { this.processNode(fIn); } public void processNode(File node) throws IOException { File[] nodes = node.listFiles(); for (File subNode : nodes) { if (subNode.isDirectory()) { processNode(subNode); } else { Path p = FileSystems.getDefault().getPath(subNode.getAbsolutePath()); String contentType = Files.probeContentType(p); if (subNode.getName().toLowerCase().endsWith(".xml") || contentType.equalsIgnoreCase("application/xml") || contentType.equalsIgnoreCase("text/xml") ) { this.apply(subNode); } } } } public int apply(File source) { try { Templates pss = tryCache(fXslt); Transformer transformer = pss.newTransformer(); // String path = getServletContext().getRealPath(source); File sourceFile = source; if (!sourceFile.exists()) { throw new XPathException("Source file " + source + " not found"); } //deactivation of DTD validation XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); xmlReader.setEntityResolver(new EntityResolver() { public InputSource resolveEntity(String pid, String sid) throws SAXException { return new InputSource(new ByteArrayInputStream(new byte[] {})); } }); Source xmlSource = new SAXSource(xmlReader, new InputSource(new FileReader(sourceFile))); String sourceDirPath = source.getParentFile().getAbsolutePath(); String relativeInputDir = sourceDirPath.substring(inputPath.length()); File xmlOut = new File(outputPath + File.separator + relativeInputDir, sourceFile.getName()); // System.out.println("transformation de "+source.getAbsolutePath()+" en "+xmlOut.getAbsolutePath()); transformer.transform(xmlSource, new StreamResult(xmlOut)); System.out.println("Transformation OK, consulter le fichier "+xmlOut); if (hasSchema()) { return validate(xmlOut); } } catch (Exception err) { System.out.println("Transformation KO sur le fichier "+source); System.err.println("Echec XSLT sur le fichier "+source); System.err.println(err.getMessage()); err.printStackTrace(); return 1; } return 0; } public int validate(File fileToValidate) { try { System.setProperty("javax.xml.transform.TransformerFactory", "com.saxonica.config.EnterpriseTransformerFactory"); TransformerFactory factory = TransformerFactory.newInstance(); factory.setAttribute(FeatureKeys.SCHEMA_VALIDATION, new Integer( Validation.STRICT)); StreamSource schema = new StreamSource(fSchema.toURI().toString()); ((EnterpriseTransformerFactory) factory).addSchema(schema); Transformer trans = factory.newTransformer(); StreamSource source = new StreamSource(fileToValidate.toURI().toString()); SAXResult sink = new SAXResult(new DefaultHandler()); trans.transform(source, sink); } catch (TransformerException err) { System.out.println("Validation KO sur le fichier "+fileToValidate.getAbsolutePath()); System.err.println("Erreur de validation sur le fichier "+fileToValidate.getAbsolutePath()); System.err.println(err.getMessage()); return 1; } System.out.println("Validation OK sur le fichier "+fileToValidate.getAbsolutePath()); return 0; } /** * Maintain prepared stylesheets in memory for reuse */ private synchronized static Templates tryCache(File xslFile) throws TransformerException { // String path = getServletContext().getRealPath(xslPath); if (!xslFile.exists()) { throw new XPathException("Stylesheet " + xslFile.getAbsolutePath() + " not found"); } String path = xslFile.getAbsolutePath(); Templates x = (Templates)cache.get(path); if (x==null) { TransformerFactory factory = TransformerFactory.newInstance(); x = factory.newTemplates(new StreamSource(new File(path))); cache.put(path, x); } return x; } public File getSchema() { return fSchema; } public void setSchema(File fSchema) { this.fSchema = fSchema; } public boolean hasSchema() { return (this.fSchema != null); } private static HashMap<String, Templates> cache = new HashMap<String, Templates>(20); }