aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java650
1 files changed, 650 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java
new file mode 100644
index 00000000..8d9a44a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java
@@ -0,0 +1,650 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.tools.ant.taskdefs.optional;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Source;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.Templates;
+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 org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.XSLTLiaison4;
+import org.apache.tools.ant.taskdefs.XSLTLogger;
+import org.apache.tools.ant.taskdefs.XSLTLoggerAware;
+import org.apache.tools.ant.taskdefs.XSLTProcess;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.XMLCatalog;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.URLProvider;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ * Concrete liaison for XSLT processor implementing TraX. (ie JAXP 1.1)
+ *
+ * @since Ant 1.3
+ */
+public class TraXLiaison implements XSLTLiaison4, ErrorListener, XSLTLoggerAware {
+
+ /**
+ * Helper for transforming filenames to URIs.
+ *
+ * @since Ant 1.7
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * The current <code>Project</code>
+ */
+ private Project project;
+
+ /**
+ * the name of the factory implementation class to use
+ * or null for default JAXP lookup.
+ */
+ private String factoryName = null;
+
+ /** The trax TransformerFactory */
+ private TransformerFactory tfactory = null;
+
+ /** stylesheet to use for transformation */
+ private Resource stylesheet;
+
+ private XSLTLogger logger;
+
+ /** possible resolver for publicIds */
+ private EntityResolver entityResolver;
+
+ /** transformer to use for processing files */
+ private Transformer transformer;
+
+ /** The In memory version of the stylesheet */
+ private Templates templates;
+
+ /**
+ * The modification time of the stylesheet from which the templates
+ * are read
+ */
+ private long templatesModTime;
+
+ /** possible resolver for URIs */
+ private URIResolver uriResolver;
+
+ /** transformer output properties */
+ private final Vector outputProperties = new Vector();
+
+ /** stylesheet parameters */
+ private final Hashtable<String, Object> params = new Hashtable<String, Object>();
+
+ /** factory attributes */
+ private final Vector attributes = new Vector();
+
+ /** whether to suppress warnings */
+ private boolean suppressWarnings = false;
+
+ /** optional trace configuration. */
+ private XSLTProcess.TraceConfiguration traceConfiguration = null;
+
+ /**
+ * Constructor for TraXLiaison.
+ * @throws Exception never
+ */
+ public TraXLiaison() throws Exception {
+ }
+
+ /**
+ * Set the stylesheet file.
+ * @param stylesheet a <code>File</code> value
+ * @throws Exception on error
+ */
+ public void setStylesheet(final File stylesheet) throws Exception {
+ final FileResource fr = new FileResource();
+ fr.setProject(project);
+ fr.setFile(stylesheet);
+ setStylesheet(fr);
+ }
+
+ /**
+ * Set the stylesheet file.
+ * @param stylesheet a {@link org.apache.tools.ant.types.Resource} value
+ * @throws Exception on error
+ */
+ public void setStylesheet(final Resource stylesheet) throws Exception {
+ if (this.stylesheet != null) {
+ // resetting the stylesheet - reset transformer
+ transformer = null;
+
+ // do we need to reset templates as well
+ if (!this.stylesheet.equals(stylesheet)
+ || (stylesheet.getLastModified() != templatesModTime)) {
+ templates = null;
+ }
+ }
+ this.stylesheet = stylesheet;
+ }
+
+ /**
+ * Transform an input file.
+ * @param infile the file to transform
+ * @param outfile the result file
+ * @throws Exception on error
+ */
+ public void transform(final File infile, final File outfile) throws Exception {
+ if (transformer == null) {
+ createTransformer();
+ }
+
+ InputStream fis = null;
+ OutputStream fos = null;
+ try {
+ fis = new BufferedInputStream(new FileInputStream(infile));
+ fos = new BufferedOutputStream(new FileOutputStream(outfile));
+ final StreamResult res = new StreamResult(fos);
+ // not sure what could be the need of this...
+ res.setSystemId(JAXPUtils.getSystemId(outfile));
+ final Source src = getSource(fis, infile);
+
+ // set parameters on each transformation, maybe something has changed
+ //(e.g. value of file name parameter)
+ setTransformationParameters();
+
+ transformer.transform(src, res);
+ } finally {
+ // make sure to close all handles, otherwise the garbage
+ // collector will close them...whenever possible and
+ // Windows may complain about not being able to delete files.
+ FileUtils.close(fis);
+ FileUtils.close(fos);
+ }
+ }
+
+ /**
+ * Get the source instance from the stream and id of the file.
+ * @param is the stream containing the stylesheet data.
+ * @param infile the file that will be used for the systemid.
+ * @return the configured source instance matching the stylesheet.
+ * @throws ParserConfigurationException if a parser cannot be created which
+ * satisfies the requested configuration.
+ * @throws SAXException in case of problem detected by the SAX parser.
+ */
+ private Source getSource(final InputStream is, final File infile)
+ throws ParserConfigurationException, SAXException {
+ // todo: is this comment still relevant ??
+ // FIXME: need to use a SAXSource as the source for the transform
+ // so we can plug in our own entity resolver
+ Source src = null;
+ if (entityResolver != null) {
+ if (getFactory().getFeature(SAXSource.FEATURE)) {
+ final SAXParserFactory spFactory = SAXParserFactory.newInstance();
+ spFactory.setNamespaceAware(true);
+ final XMLReader reader = spFactory.newSAXParser().getXMLReader();
+ reader.setEntityResolver(entityResolver);
+ src = new SAXSource(reader, new InputSource(is));
+ } else {
+ throw new IllegalStateException("xcatalog specified, but "
+ + "parser doesn't support SAX");
+ }
+ } else {
+ // WARN: Don't use the StreamSource(File) ctor. It won't work with
+ // xalan prior to 2.2 because of systemid bugs.
+ src = new StreamSource(is);
+ }
+ src.setSystemId(JAXPUtils.getSystemId(infile));
+ return src;
+ }
+
+ private Source getSource(final InputStream is, final Resource resource)
+ throws ParserConfigurationException, SAXException {
+ // todo: is this comment still relevant ??
+ // FIXME: need to use a SAXSource as the source for the transform
+ // so we can plug in our own entity resolver
+ Source src = null;
+ if (entityResolver != null) {
+ if (getFactory().getFeature(SAXSource.FEATURE)) {
+ final SAXParserFactory spFactory = SAXParserFactory.newInstance();
+ spFactory.setNamespaceAware(true);
+ final XMLReader reader = spFactory.newSAXParser().getXMLReader();
+ reader.setEntityResolver(entityResolver);
+ src = new SAXSource(reader, new InputSource(is));
+ } else {
+ throw new IllegalStateException("xcatalog specified, but "
+ + "parser doesn't support SAX");
+ }
+ } else {
+ // WARN: Don't use the StreamSource(File) ctor. It won't work with
+ // xalan prior to 2.2 because of systemid bugs.
+ src = new StreamSource(is);
+ }
+ // The line below is a hack: the system id must an URI, but it is not
+ // cleat to get the URI of an resource, so just set the name of the
+ // resource as a system id
+ src.setSystemId(resourceToURI(resource));
+ return src;
+ }
+
+ private String resourceToURI(final Resource resource) {
+ final FileProvider fp = resource.as(FileProvider.class);
+ if (fp != null) {
+ return FILE_UTILS.toURI(fp.getFile().getAbsolutePath());
+ }
+ final URLProvider up = resource.as(URLProvider.class);
+ if (up != null) {
+ final URL u = up.getURL();
+ return String.valueOf(u);
+ } else {
+ return resource.getName();
+ }
+ }
+
+ /**
+ * Read in templates from the stylesheet
+ */
+ private void readTemplates()
+ throws IOException, TransformerConfigurationException,
+ ParserConfigurationException, SAXException {
+
+ // Use a stream so that you can close it yourself quickly
+ // and avoid keeping the handle until the object is garbaged.
+ // (always keep control), otherwise you won't be able to delete
+ // the file quickly on windows.
+ InputStream xslStream = null;
+ try {
+ xslStream
+ = new BufferedInputStream(stylesheet.getInputStream());
+ templatesModTime = stylesheet.getLastModified();
+ final Source src = getSource(xslStream, stylesheet);
+ templates = getFactory().newTemplates(src);
+ } finally {
+ if (xslStream != null) {
+ xslStream.close();
+ }
+ }
+ }
+
+ /**
+ * Create a new transformer based on the liaison settings
+ * @throws Exception thrown if there is an error during creation.
+ * @see #setStylesheet(java.io.File)
+ * @see #addParam(java.lang.String, java.lang.String)
+ * @see #setOutputProperty(java.lang.String, java.lang.String)
+ */
+ private void createTransformer() throws Exception {
+ if (templates == null) {
+ readTemplates();
+ }
+
+ transformer = templates.newTransformer();
+
+ // configure the transformer...
+ transformer.setErrorListener(this);
+ if (uriResolver != null) {
+ transformer.setURIResolver(uriResolver);
+ }
+ final int size = outputProperties.size();
+ for (int i = 0; i < size; i++) {
+ final String[] pair = (String[]) outputProperties.elementAt(i);
+ transformer.setOutputProperty(pair[0], pair[1]);
+ }
+
+ if (traceConfiguration != null) {
+ if ("org.apache.xalan.transformer.TransformerImpl"
+ .equals(transformer.getClass().getName())) {
+ try {
+ final Class traceSupport =
+ Class.forName("org.apache.tools.ant.taskdefs.optional."
+ + "Xalan2TraceSupport", true,
+ Thread.currentThread()
+ .getContextClassLoader());
+ final XSLTTraceSupport ts =
+ (XSLTTraceSupport) traceSupport.newInstance();
+ ts.configureTrace(transformer, traceConfiguration);
+ } catch (final Exception e) {
+ final String msg = "Failed to enable tracing because of " + e;
+ if (project != null) {
+ project.log(msg, Project.MSG_WARN);
+ } else {
+ System.err.println(msg);
+ }
+ }
+ } else {
+ final String msg = "Not enabling trace support for transformer"
+ + " implementation" + transformer.getClass().getName();
+ if (project != null) {
+ project.log(msg, Project.MSG_WARN);
+ } else {
+ System.err.println(msg);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the parameters for the transformer.
+ */
+ private void setTransformationParameters() {
+ for (final Enumeration enumeration = params.keys();
+ enumeration.hasMoreElements();) {
+ final String name = (String) enumeration.nextElement();
+ final Object value = params.get(name);
+ transformer.setParameter(name, value);
+ }
+ }
+
+ /**
+ * return the Transformer factory associated to this liaison.
+ * @return the Transformer factory associated to this liaison.
+ * @throws BuildException thrown if there is a problem creating
+ * the factory.
+ * @see #setFactory(String)
+ * @since Ant 1.5.2
+ */
+ private TransformerFactory getFactory() throws BuildException {
+ if (tfactory != null) {
+ return tfactory;
+ }
+ // not initialized yet, so create the factory
+ if (factoryName == null) {
+ tfactory = TransformerFactory.newInstance();
+ } else {
+ try {
+ Class clazz = null;
+ try {
+ clazz =
+ Class.forName(factoryName, true,
+ Thread.currentThread()
+ .getContextClassLoader());
+ } catch (final ClassNotFoundException cnfe) {
+ final String msg = "Failed to load " + factoryName
+ + " via the configured classpath, will try"
+ + " Ant's classpath instead.";
+ if (logger != null) {
+ logger.log(msg);
+ } else if (project != null) {
+ project.log(msg, Project.MSG_WARN);
+ } else {
+ System.err.println(msg);
+ }
+ }
+
+ if (clazz == null) {
+ clazz = Class.forName(factoryName);
+ }
+ tfactory = (TransformerFactory) clazz.newInstance();
+ } catch (final Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ try { // #51668, #52382
+ final Field _isNotSecureProcessing = tfactory.getClass().getDeclaredField("_isNotSecureProcessing");
+ _isNotSecureProcessing.setAccessible(true);
+ _isNotSecureProcessing.set(tfactory, Boolean.TRUE);
+ } catch (final Exception x) {
+ if (project != null) {
+ project.log(x.toString(), Project.MSG_DEBUG);
+ }
+ }
+
+ tfactory.setErrorListener(this);
+
+ // specific attributes for the transformer
+ final int size = attributes.size();
+ for (int i = 0; i < size; i++) {
+ final Object[] pair = (Object[]) attributes.elementAt(i);
+ tfactory.setAttribute((String) pair[0], pair[1]);
+ }
+
+ if (uriResolver != null) {
+ tfactory.setURIResolver(uriResolver);
+ }
+ return tfactory;
+ }
+
+
+ /**
+ * Set the factory name to use instead of JAXP default lookup.
+ * @param name the fully qualified class name of the factory to use
+ * or null for the default JAXP look up mechanism.
+ * @since Ant 1.6
+ */
+ public void setFactory(final String name) {
+ factoryName = name;
+ }
+
+ /**
+ * Set a custom attribute for the JAXP factory implementation.
+ * @param name the attribute name.
+ * @param value the value of the attribute, usually a boolean
+ * string or object.
+ * @since Ant 1.6
+ */
+ public void setAttribute(final String name, final Object value) {
+ final Object[] pair = new Object[]{name, value};
+ attributes.addElement(pair);
+ }
+
+ /**
+ * Set the output property for the current transformer.
+ * Note that the stylesheet must be set prior to calling
+ * this method.
+ * @param name the output property name.
+ * @param value the output property value.
+ * @since Ant 1.5
+ * @since Ant 1.5
+ */
+ public void setOutputProperty(final String name, final String value) {
+ final String[] pair = new String[]{name, value};
+ outputProperties.addElement(pair);
+ }
+
+ /**
+ * Set the class to resolve entities during the transformation.
+ * @param aResolver the resolver class.
+ */
+ public void setEntityResolver(final EntityResolver aResolver) {
+ entityResolver = aResolver;
+ }
+
+ /**
+ * Set the class to resolve URIs during the transformation
+ * @param aResolver a <code>EntityResolver</code> value
+ */
+ public void setURIResolver(final URIResolver aResolver) {
+ uriResolver = aResolver;
+ }
+
+ /**
+ * Add a parameter.
+ * @param name the name of the parameter
+ * @param value the value of the parameter
+ */
+ public void addParam(final String name, final String value) {
+ params.put(name, value);
+ }
+
+ /**
+ * Add a parameter.
+ * @param name the name of the parameter
+ * @param value the value of the parameter
+ * @since Ant 1.9.3
+ */
+ public void addParam(final String name, final Object value) {
+ params.put(name, value);
+ }
+
+ /**
+ * Set a logger.
+ * @param l a logger.
+ */
+ public void setLogger(final XSLTLogger l) {
+ logger = l;
+ }
+
+ /**
+ * Log an error.
+ * @param e the exception to log.
+ */
+ public void error(final TransformerException e) {
+ logError(e, "Error");
+ }
+
+ /**
+ * Log a fatal error.
+ * @param e the exception to log.
+ */
+ public void fatalError(final TransformerException e) {
+ logError(e, "Fatal Error");
+ throw new BuildException("Fatal error during transformation using " + stylesheet + ": " + e.getMessageAndLocation(), e);
+ }
+
+ /**
+ * Log a warning.
+ * @param e the exception to log.
+ */
+ public void warning(final TransformerException e) {
+ if (!suppressWarnings) {
+ logError(e, "Warning");
+ }
+ }
+
+ private void logError(final TransformerException e, final String type) {
+ if (logger == null) {
+ return;
+ }
+
+ final StringBuffer msg = new StringBuffer();
+ final SourceLocator locator = e.getLocator();
+ if (locator != null) {
+ final String systemid = locator.getSystemId();
+ if (systemid != null) {
+ String url = systemid;
+ if (url.startsWith("file:")) {
+ url = FileUtils.getFileUtils().fromURI(url);
+ }
+ msg.append(url);
+ } else {
+ msg.append("Unknown file");
+ }
+ final int line = locator.getLineNumber();
+ if (line != -1) {
+ msg.append(":");
+ msg.append(line);
+ final int column = locator.getColumnNumber();
+ if (column != -1) {
+ msg.append(":");
+ msg.append(column);
+ }
+ }
+ }
+ msg.append(": ");
+ msg.append(type);
+ msg.append("! ");
+ msg.append(e.getMessage());
+ if (e.getCause() != null) {
+ msg.append(" Cause: ");
+ msg.append(e.getCause());
+ }
+
+ logger.log(msg.toString());
+ }
+
+ // kept for backwards compatibility
+ /**
+ * @param file the filename to use for the systemid
+ * @return the systemid
+ * @deprecated since 1.5.x.
+ * Use org.apache.tools.ant.util.JAXPUtils#getSystemId instead.
+ */
+ @Deprecated
+ protected String getSystemId(final File file) {
+ return JAXPUtils.getSystemId(file);
+ }
+
+
+ /**
+ * Specific configuration for the TRaX liaison.
+ * @param xsltTask the XSLTProcess task instance from which this liaison
+ * is to be configured.
+ */
+ public void configure(final XSLTProcess xsltTask) {
+ project = xsltTask.getProject();
+ final XSLTProcess.Factory factory = xsltTask.getFactory();
+ if (factory != null) {
+ setFactory(factory.getName());
+
+ // configure factory attributes
+ for (final Enumeration attrs = factory.getAttributes();
+ attrs.hasMoreElements();) {
+ final XSLTProcess.Factory.Attribute attr =
+ (XSLTProcess.Factory.Attribute) attrs.nextElement();
+ setAttribute(attr.getName(), attr.getValue());
+ }
+ }
+
+ final XMLCatalog xmlCatalog = xsltTask.getXMLCatalog();
+ // use XMLCatalog as the entity resolver and URI resolver
+ if (xmlCatalog != null) {
+ setEntityResolver(xmlCatalog);
+ setURIResolver(xmlCatalog);
+ }
+
+
+ // configure output properties
+ for (final Enumeration props = xsltTask.getOutputProperties();
+ props.hasMoreElements();) {
+ final XSLTProcess.OutputProperty prop
+ = (XSLTProcess.OutputProperty) props.nextElement();
+ setOutputProperty(prop.getName(), prop.getValue());
+ }
+
+ suppressWarnings = xsltTask.getSuppressWarnings();
+
+ traceConfiguration = xsltTask.getTraceConfiguration();
+ }
+}