FileDocCategorySizeDatePackage
TraXLiaison.javaAPI DocApache Ant 1.7019350Wed Dec 13 06:16:20 GMT 2006org.apache.tools.ant.taskdefs.optional

TraXLiaison

public class TraXLiaison extends Object implements ErrorListener, org.apache.tools.ant.taskdefs.XSLTLoggerAware, org.apache.tools.ant.taskdefs.XSLTLiaison3
Concrete liaison for XSLT processor implementing TraX. (ie JAXP 1.1)
since
Ant 1.3

Fields Summary
private static final org.apache.tools.ant.util.FileUtils
FILE_UTILS
Helper for transforming filenames to URIs.
private org.apache.tools.ant.Project
project
The current Project
private String
factoryName
the name of the factory implementation class to use or null for default JAXP lookup.
private TransformerFactory
tfactory
The trax TransformerFactory
private org.apache.tools.ant.types.Resource
stylesheet
stylesheet to use for transformation
private org.apache.tools.ant.taskdefs.XSLTLogger
logger
private EntityResolver
entityResolver
possible resolver for publicIds
private Transformer
transformer
transformer to use for processing files
private Templates
templates
The In memory version of the stylesheet
private long
templatesModTime
The modification time of the stylesheet from which the templates are read
private URIResolver
uriResolver
possible resolver for URIs
private Vector
outputProperties
transformer output properties
private Hashtable
params
stylesheet parameters
private Vector
attributes
factory attributes
Constructors Summary
public TraXLiaison()
Constructor for TraXLiaison.

throws
Exception never


               
        
    
Methods Summary
public voidaddParam(java.lang.String name, java.lang.String value)
Add a parameter.

param
name the name of the parameter
param
value the value of the parameter

        params.put(name, value);
    
public voidconfigure(org.apache.tools.ant.taskdefs.XSLTProcess xsltTask)
Specific configuration for the TRaX liaison.

param
xsltTask the XSLTProcess task instance from which this liasion is to be configured.

        project = xsltTask.getProject();
        XSLTProcess.Factory factory = xsltTask.getFactory();
        if (factory != null) {
            setFactory(factory.getName());

            // configure factory attributes
            for (Enumeration attrs = factory.getAttributes();
                    attrs.hasMoreElements();) {
                XSLTProcess.Factory.Attribute attr =
                        (XSLTProcess.Factory.Attribute) attrs.nextElement();
                setAttribute(attr.getName(), attr.getValue());
            }
        }

        XMLCatalog xmlCatalog = xsltTask.getXMLCatalog();
        // use XMLCatalog as the entity resolver and URI resolver
        if (xmlCatalog != null) {
            setEntityResolver(xmlCatalog);
            setURIResolver(xmlCatalog);
        }


        // configure output properties
        for (Enumeration props = xsltTask.getOutputProperties();
                props.hasMoreElements();) {
            XSLTProcess.OutputProperty prop
                = (XSLTProcess.OutputProperty) props.nextElement();
            setOutputProperty(prop.getName(), prop.getValue());
        }
    
private voidcreateTransformer()
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)

        if (templates == null) {
            readTemplates();
        }

        transformer = templates.newTransformer();

        // configure the transformer...
        transformer.setErrorListener(this);
        if (uriResolver != null) {
            transformer.setURIResolver(uriResolver);
        }
        for (int i = 0; i < outputProperties.size(); i++) {
            final String[] pair = (String[]) outputProperties.elementAt(i);
            transformer.setOutputProperty(pair[0], pair[1]);
        }
    
public voiderror(javax.xml.transform.TransformerException e)
Log an error.

param
e the exception to log.

        logError(e, "Error");
    
public voidfatalError(javax.xml.transform.TransformerException e)
Log a fatal error.

param
e the exception to log.

        logError(e, "Fatal Error");
        throw new BuildException("Fatal error during transformation", e);
    
private javax.xml.transform.TransformerFactorygetFactory()
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

        if (tfactory != null) {
            return tfactory;
        }
        // not initialized yet, so create the factory
        if (factoryName == null) {
            tfactory = TransformerFactory.newInstance();
        } else {
            try {
                Class clazz = Class.forName(factoryName);
                tfactory = (TransformerFactory) clazz.newInstance();
            } catch (Exception e) {
                throw new BuildException(e);
            }
        }
        tfactory.setErrorListener(this);

        // specific attributes for the transformer
        for (int i = 0; i < attributes.size(); i++) {
            final Object[] pair = (Object[]) attributes.elementAt(i);
            tfactory.setAttribute((String) pair[0], pair[1]);
        }

        if (uriResolver != null) {
            tfactory.setURIResolver(uriResolver);
        }
        return tfactory;
    
private javax.xml.transform.SourcegetSource(java.io.InputStream is, java.io.File infile)
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.

        // 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)) {
                SAXParserFactory spFactory = SAXParserFactory.newInstance();
                spFactory.setNamespaceAware(true);
                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 javax.xml.transform.SourcegetSource(java.io.InputStream is, org.apache.tools.ant.types.Resource resource)

        // 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)) {
                SAXParserFactory spFactory = SAXParserFactory.newInstance();
                spFactory.setNamespaceAware(true);
                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;
    
protected java.lang.StringgetSystemId(java.io.File file)

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.

        return JAXPUtils.getSystemId(file);
    
private voidlogError(javax.xml.transform.TransformerException e, java.lang.String type)

        if (logger == null) {
            return;
        }

        StringBuffer msg = new StringBuffer();
        SourceLocator locator = e.getLocator();
        if (locator != null) {
            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");
            }
            int line = locator.getLineNumber();
            if (line != -1) {
                msg.append(":");
                msg.append(line);
                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());
    
private voidreadTemplates()
Read in templates from the stylesheet


        // 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();
            Source src = getSource(xslStream, stylesheet);
            templates = getFactory().newTemplates(src);
        } finally {
            if (xslStream != null) {
                xslStream.close();
            }
        }
    
private java.lang.StringresourceToURI(org.apache.tools.ant.types.Resource resource)

        if (resource instanceof FileResource) {
            File f = ((FileResource) resource).getFile();
            return FILE_UTILS.toURI(f.getAbsolutePath());
        }
        if (resource instanceof URLResource) {
            URL u = ((URLResource) resource).getURL();
            return String.valueOf(u);
        } else {
            return resource.getName();
        }
    
public voidsetAttribute(java.lang.String name, java.lang.Object value)
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

        final Object[] pair = new Object[]{name, value};
        attributes.addElement(pair);
    
public voidsetEntityResolver(org.xml.sax.EntityResolver aResolver)
Set the class to resolve entities during the transformation.

param
aResolver the resolver class.

        entityResolver = aResolver;
    
public voidsetFactory(java.lang.String name)
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

        factoryName = name;
    
public voidsetLogger(org.apache.tools.ant.taskdefs.XSLTLogger l)
Set a logger.

param
l a logger.

        logger = l;
    
public voidsetOutputProperty(java.lang.String name, java.lang.String value)
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

        final String[] pair = new String[]{name, value};
        outputProperties.addElement(pair);
    
public voidsetStylesheet(java.io.File stylesheet)
Set the stylesheet file.

param
stylesheet a File value
throws
Exception on error

        FileResource fr = new FileResource();
        fr.setProject(project);
        fr.setFile(stylesheet);
        setStylesheet(fr);
    
public voidsetStylesheet(org.apache.tools.ant.types.Resource stylesheet)
Set the stylesheet file.

param
stylesheet a {@link org.apache.tools.ant.types.Resource} value
throws
Exception on error

        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;
    
private voidsetTransformationParameters()
Sets the paramters for the transformer.

        for (final Enumeration enumeration = params.keys();
             enumeration.hasMoreElements();) {
            final String name = (String) enumeration.nextElement();
            final String value = (String) params.get(name);
            transformer.setParameter(name, value);
        }
    
public voidsetURIResolver(javax.xml.transform.URIResolver aResolver)
Set the class to resolve URIs during the transformation

param
aResolver a EntityResolver value

        uriResolver = aResolver;
    
public voidtransform(java.io.File infile, java.io.File outfile)
Transform an input file.

param
infile the file to transform
param
outfile the result file
throws
Exception on error

        if (transformer == null) {
            createTransformer();
        }

        InputStream fis = null;
        OutputStream fos = null;
        try {
            fis = new BufferedInputStream(new FileInputStream(infile));
            fos = new BufferedOutputStream(new FileOutputStream(outfile));
            StreamResult res = new StreamResult(fos);
            // not sure what could be the need of this...
            res.setSystemId(JAXPUtils.getSystemId(outfile));
            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.
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException ignored) {
                // ignore
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException ignored) {
                // ignore
            }
        }
    
public voidwarning(javax.xml.transform.TransformerException e)
Log a warning.

param
e the exception to log.

        logError(e, "Warning");