Newer
Older
saxon-xslt / src / fr / inist / SaxonXSLT.java
@niederle niederle on 22 May 2017 6 KB premier commit
package fr.inist;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.spi.FileTypeDetector;
import java.util.Enumeration;
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.OutputKeys;
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.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 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];
        File fIn = new File(source);
        File fOut = new File(output);
        File fXslt = new File(style);
    	
    	 
        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 = new SaxonXSLT(fIn, fXslt, fOut);
        saxonXslt.processInput();
        
    }
    
    public static void usage() {
    	System.out.print("usage : java SaxonXSLT <input> <xslt> <output> (input can be file or dir, output must be a dir)");
    }

    
    private File fIn, fXslt, fOut;
    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);
 
        } catch (Exception err) {
            System.out.println(err.getMessage());
            err.printStackTrace();
    		return 1;
        }
		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;
     }
  
     /**
     * Clear the cache. Useful if stylesheets have been modified, or simply if space is
     * running low. We let the garbage collector do the work.
     */
  
     private synchronized void clearCache() {
         cache = new HashMap(20);
     }
  
     private static HashMap<String, Templates> cache = new HashMap(20);
    
}