/* * <p><b>License and Copyright: </b>The contents of this file is subject to the * same open source license as the Fedora Repository System at www.fedora-commons.org * Copyright © 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 by The Technical University of Denmark. * All rights reserved.</p> */ package dk.defxws.fedoragsearch.server; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import java.util.Date; 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.TransformerFactoryConfigurationError; import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import net.sf.saxon.Configuration; import net.sf.saxon.expr.XPathContext; import net.sf.saxon.lib.ExtensionFunctionCall; import net.sf.saxon.lib.ExtensionFunctionDefinition; import net.sf.saxon.om.Item; import net.sf.saxon.om.SequenceIterator; import net.sf.saxon.om.StructuredQName; import net.sf.saxon.trans.XPathException; import net.sf.saxon.tree.iter.SingletonIterator; import net.sf.saxon.value.SequenceType; import net.sf.saxon.value.StringValue; import org.apache.log4j.Logger; import dk.defxws.fedoragsearch.server.errors.ConfigException; import dk.defxws.fedoragsearch.server.errors.GenericSearchException; /** * performs the stylesheet transformations * * @author gsp@dtv.dk * @version */ public class GTransformer { private static final Logger logger = Logger.getLogger(GTransformer.class); int debuglength = 500; public GTransformer() { } public Transformer getTransformer(String xsltPath) throws ConfigException { return getTransformer(xsltPath, null); } public Transformer getTransformer(String xsltPath, URIResolver uriResolver) throws ConfigException { Transformer transformer = null; String xsltPathName = "/"+xsltPath+".xslt"; try { InputStream stylesheet = Config.class.getResourceAsStream(xsltPathName); if (stylesheet==null) { throw new ConfigException(xsltPathName+" not found"); } TransformerFactory tfactory; if ("saxon".equals(Config.getCurrentConfig().getXsltProcessor())) { tfactory = new net.sf.saxon.TransformerFactoryImpl(); if(tfactory instanceof net.sf.saxon.TransformerFactoryImpl) { Configuration conf = ((net.sf.saxon.TransformerFactoryImpl)tfactory).getConfiguration(); try { conf.registerExtensionFunction(new GenericOperationsImplDefinition()); } catch (XPathException e) { throw new ConfigException("getTransformer registerExtensionFunction "+xsltPathName+":\n", e); } ((net.sf.saxon.TransformerFactoryImpl)tfactory).setConfiguration(conf); } } else { tfactory = new org.apache.xalan.processor.TransformerFactoryImpl(); } StreamSource xslt = new StreamSource(stylesheet); transformer = tfactory.newTransformer(xslt); if (uriResolver!=null) transformer.setURIResolver(uriResolver); } catch (TransformerConfigurationException e) { throw new ConfigException("getTransformer "+xsltPathName+":\n", e); } catch (TransformerFactoryConfigurationError e) { throw new ConfigException("getTransformerFactory "+xsltPathName+":\n", e); } if (logger.isDebugEnabled()) logger.debug("getTransformer transformer="+transformer+" uriResolver="+uriResolver); return transformer; } public StringBuffer transform(String xsltPath, StringBuffer sb, String[] params, String systemId) throws GenericSearchException { if (logger.isDebugEnabled()) logger.debug("transform xsltPath="+xsltPath+" sb="+getDebugString(sb.toString())+" systemId="+systemId); StringReader sr = new StringReader(sb.toString()); StreamSource sourceStream = new StreamSource(sr, systemId); String xsltPathName = "/"+xsltPath+".xslt"; URL stylesheet = GTransformer.class.getResource(xsltPathName); if (stylesheet==null) { throw new ConfigException("transform "+xsltPathName+" not found"); } TransformerFactory tfactory = null; try { tfactory = TransformerFactory.newInstance(); } catch (TransformerFactoryConfigurationError e) { throw new ConfigException("transform "+xsltPathName+":\n", e); } StreamSource xslt = null; try { xslt = new StreamSource(stylesheet.openStream(), stylesheet.toString()); } catch (IOException e) { throw new ConfigException("transform "+xsltPathName+":\n", e); } Transformer transformer = null; try { transformer = tfactory.newTransformer(xslt); } catch (TransformerConfigurationException e) { throw new ConfigException("transform "+xsltPathName+":\n", e); } for (int i=0; i<params.length; i=i+2) { Object value = params[i+1]; if (value==null) value = ""; transformer.setParameter((String)params[i], value); } transformer.setParameter("DATETIME", new Date()); StreamResult destStream = new StreamResult(new StringWriter()); try { transformer.transform(sourceStream, destStream); } catch (Exception e) { throw new GenericSearchException("transform "+xsltPathName+":\n", e); } StringWriter sw = (StringWriter)destStream.getWriter(); StringBuffer result = sw.getBuffer(); if (logger.isDebugEnabled()) logger.debug("transform result=\n"+getDebugString(result.toString())); return result; } public void transform(String xsltName, StreamSource sourceStream, StreamResult destStream) throws GenericSearchException { Transformer transformer = getTransformer(xsltName); try { transformer.transform(sourceStream, destStream); } catch (TransformerException e) { throw new GenericSearchException("transform "+xsltName+".xslt:\n", e); } } public StringBuffer transform(String xsltName, Source sourceStream, Object[] params) throws GenericSearchException { return transform (xsltName, sourceStream, null, params); } public StringBuffer transform(String xsltName, Source sourceStream, URIResolver uriResolver, Object[] params) throws GenericSearchException { if (logger.isDebugEnabled()) logger.debug("xsltName="+xsltName); Transformer transformer = getTransformer(xsltName, uriResolver); for (int i=0; i<params.length; i=i+2) { Object value = params[i+1]; if (value==null) value = ""; transformer.setParameter((String)params[i], value); } transformer.setParameter("DATETIME", new Date()); StreamResult destStream = new StreamResult(new StringWriter()); try { transformer.transform(sourceStream, destStream); } catch (TransformerException e) { throw new GenericSearchException("transform "+xsltName+".xslt:\n", e); } StringWriter sw = (StringWriter)destStream.getWriter(); return sw.getBuffer(); } public void transformToFile(String xsltName, StreamSource sourceStream, Object[] params, String filePath) throws GenericSearchException { if (logger.isDebugEnabled()) logger.debug("xsltName="+xsltName); Transformer transformer = getTransformer(xsltName); for (int i=0; i<params.length; i=i+2) { Object value = params[i+1]; if (value==null) value = ""; transformer.setParameter((String)params[i], value); } transformer.setParameter("DATETIME", new Date()); StreamResult destStream = new StreamResult(new File(filePath)); try { transformer.transform(sourceStream, destStream); } catch (TransformerException e) { throw new GenericSearchException("transform "+xsltName+".xslt:\n", e); } } public StringBuffer transform(String xsltName, StreamSource sourceStream) throws GenericSearchException { return transform(xsltName, sourceStream, new String[]{}); } public StringBuffer transform(String xsltName, StringBuffer sb, String[] params) throws GenericSearchException { StringReader sr = new StringReader(sb.toString()); StringBuffer result = transform(xsltName, new StreamSource(sr), params); return result; } public StringBuffer transform(String xsltName, StringBuffer sb) throws GenericSearchException { return transform(xsltName, sb, new String[]{}); } private String getDebugString(String debugString) { String result = debugString; if (debugString.length()>debuglength) { result = result.substring(0,debuglength)+"...\n..."; } return result; } public class GenericOperationsImplDefinition extends ExtensionFunctionDefinition { private static final long serialVersionUID = -4369478473099836359L; @Override public SequenceType[] getArgumentTypes() { SequenceType args[] = new SequenceType[8]; for(int i = 0; i < 8; i++) { args[i] = SequenceType.SINGLE_STRING; } return args; } @Override public StructuredQName getFunctionQName() { return new StructuredQName("exts", "java:dk.defxws.fedoragsearch.server.GenericOperationsImpl", "getDatastreamText"); } @Override public SequenceType getResultType(SequenceType[] arg0) { return SequenceType.SINGLE_STRING; } @Override public ExtensionFunctionCall makeCallExpression() { return new GenericOperationsImplCall(); } } public class GenericOperationsImplCall extends ExtensionFunctionCall { private static final long serialVersionUID = -3144688173848090437L; @Override public SequenceIterator call(SequenceIterator[] arg0, XPathContext arg1) throws XPathException { Item item = StringValue.makeStringValue(new GenericOperationsImpl().getDatastreamText(arg0[0].next().getStringValue(), arg0[1].next().getStringValue(), arg0[2].next().getStringValue(), arg0[3].next().getStringValue(), arg0[4].next().getStringValue(), arg0[5].next().getStringValue(), arg0[6].next().getStringValue(), arg0[7].next().getStringValue())); return SingletonIterator.makeIterator(item); } } }