stefano 02/04/10 05:56:23 Modified: src/java/org/apache/cocoon/components/xslt XSLTProcessor.java XSLTProcessorImpl.java Log: Added a setTransformerFactory() method to the component interface and changed the implementation behavior accordingly Revision Changes Path 1.7 +22 -3 xml-cocoon2/src/java/org/apache/cocoon/components/xslt/XSLTProcessor.java Index: XSLTProcessor.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xslt/XSLTProcessor.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- XSLTProcessor.java 22 Feb 2002 07:00:15 -0000 1.6 +++ XSLTProcessor.java 10 Apr 2002 12:56:23 -0000 1.7 @@ -64,7 +64,7 @@ * This is the interface of the XSLT processor in Cocoon. * * @author <a href="mailto:[EMAIL PROTECTED]">Ovidiu Predescu</a> - * @version CVS $Id: XSLTProcessor.java,v 1.6 2002/02/22 07:00:15 cziegeler Exp $ + * @version CVS $Id: XSLTProcessor.java,v 1.7 2002/04/10 12:56:23 stefano Exp $ * @version 1.0 * @since July 11, 2001 */ @@ -76,6 +76,12 @@ String ROLE = "org.apache.cocoon.components.xslt.XSLTProcessor"; /** + * The default factory identifier. (simply used as a pointer, the actual + * content is not meaningful) + */ + String DEFAULT_FACTORY = "default"; + + /** * Set the {@link org.apache.cocoon.environment.SourceResolver} for * this instance. The <code>resolver</code> is invoked to return a * <code>Source</code> object, given an HREF. @@ -85,6 +91,18 @@ void setSourceResolver(SourceResolver resolver); /** + * Set the TransformerFactory for this instance. + * The <code>factory</code> is invoked to return a + * <code>TransformerHandler</code> to perform the transformation. + * + * @param classname the name of the class implementing + * <code>TransformerFactory</code> value. If an error is found + * or the indicated class doesn't implement the required interface + * the original factory of the component is maintained. + */ + void setTransformerFactory(String classname); + + /** * <p>Return a <code>TransformerHandler</code> for a given * stylesheet <code>Source</code>. This can be used in a pipeline to * handle the transformation of a stream of SAX events. See {@link @@ -106,10 +124,11 @@ TransformerHandler getTransformerHandler(Source stylesheet, XMLFilter filter) throws ProcessingException; - + /** * Same as {@link #getTransformerHandler(Source,XMLFilter)}, with - * <code>filter</code> set to <code>null</code>. + * <code>filter</code> set to <code>null</code> and <code>factory</code> + * set to <code>null</code>. * * @param stylesheet a <code>Source</code> value * @return a <code>TransformerHandler</code> value 1.19 +79 -54 xml-cocoon2/src/java/org/apache/cocoon/components/xslt/XSLTProcessorImpl.java Index: XSLTProcessorImpl.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xslt/XSLTProcessorImpl.java,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- XSLTProcessorImpl.java 6 Apr 2002 02:37:29 -0000 1.18 +++ XSLTProcessorImpl.java 10 Apr 2002 12:56:23 -0000 1.19 @@ -91,6 +91,7 @@ import java.io.IOException; import java.io.StringWriter; import java.io.Writer; +import java.util.HashMap; /** * This class defines the implementation of the {@link XSLTProcessor} @@ -117,7 +118,8 @@ * (<code>TransformerFactory.newInstance()</code>). * * @author <a href="mailto:[EMAIL PROTECTED]">Ovidiu Predescu</a> - * @version CVS $Id: XSLTProcessorImpl.java,v 1.18 2002/04/06 02:37:29 vgritsenko Exp $ + * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a> + * @version CVS $Id: XSLTProcessorImpl.java,v 1.19 2002/04/10 12:56:23 stefano Exp $ * @version 1.0 * @since July 11, 2001 */ @@ -134,11 +136,11 @@ /** The store service instance */ protected Store store; - /** The trax TransformerFactory */ - protected SAXTransformerFactory tfactory; - - /** The factory class used to create tfactory */ - protected Class tfactoryClass; + /** The trax TransformerFactory lookup table*/ + protected HashMap factories; + + /** The trax TransformerFactory this component uses */ + protected SAXTransformerFactory factory; /** Is the store turned on? (default is on) */ protected boolean useStore = true; @@ -146,6 +148,7 @@ /** Is incremental processing turned on? (default for Xalan: no) */ protected boolean incrementalProcessing = false; + /** The source resolver used by this processor **/ protected SourceResolver resolver; /** @@ -155,7 +158,7 @@ throws ComponentException { this.manager = manager; this.getLogger().debug("XSLTProcessorImpl component initialized."); - this.store = (Store)manager.lookup(Store.TRANSIENT_CACHE); + this.store = (Store) manager.lookup(Store.TRANSIENT_CACHE); } /** @@ -168,8 +171,7 @@ } this.manager = null; - this.tfactoryClass = null; - this.tfactory = null; + this.resolver = null; } /** @@ -179,33 +181,29 @@ throws ParameterException { this.useStore = params.getParameterAsBoolean("use-store", true); this.incrementalProcessing = params.getParameterAsBoolean("incremental-processing", false); - - String factoryName = params.getParameter("transformer-factory", null); - if (factoryName == null) { - // Will use default TRAX mechanism - this.tfactoryClass = null; - } else { - // Will use specific class - getLogger().debug("Using factory " + factoryName); - try { - this.tfactoryClass = ClassUtils.loadClass(factoryName); - } catch(ClassNotFoundException cnfe) { - throw new ParameterException("Cannot load TransformerFactory class", cnfe); - } - - if (! TransformerFactory.class.isAssignableFrom(tfactoryClass)) { - throw new ParameterException("Class " + factoryName + " isn't a TransformerFactory"); - } - } + this.factory = getTransformerFactory(params.getParameter("transformer-factory", DEFAULT_FACTORY)); } + /** + * Set the source resolver used by this component + */ + public void setSourceResolver(SourceResolver resolver) { + this.resolver = resolver; + } + + /** + * Set the transformer factory used by this component + */ + public void setTransformerFactory(String classname) { + this.factory = getTransformerFactory(classname); + } + public TransformerHandler getTransformerHandler(Source stylesheet) throws ProcessingException { return getTransformerHandler(stylesheet, null); } - public TransformerHandler getTransformerHandler(Source stylesheet, - XMLFilter filter) + public TransformerHandler getTransformerHandler(Source stylesheet, XMLFilter filter) throws ProcessingException { try { final String id = stylesheet.getSystemId(); @@ -217,8 +215,12 @@ // Create a Templates ContentHandler to handle parsing of the // stylesheet. - TemplatesHandler templatesHandler - = getTransformerFactory().newTemplatesHandler(); + TemplatesHandler templatesHandler = this.factory.newTemplatesHandler(); + + // Set the system ID for the template handler since some + // TrAX implementations (XSLTC) rely on this in order to obtain + // a meaningful identifier for the Templates instances. + templatesHandler.setSystemId(id); if (filter != null) { filter.setContentHandler(templatesHandler); @@ -243,7 +245,7 @@ } } - TransformerHandler handler = getTransformerFactory().newTransformerHandler(templates); + TransformerHandler handler = this.factory.newTransformerHandler(templates); /* (VG) From http://java.sun.com/j2se/1.4/docs/api/javax/xml/transform/TransformerFactory.html#newTemplates(javax.xml.transform.Source) @@ -316,26 +318,43 @@ } /** - * Helper for TransformerFactory. - */ - private SAXTransformerFactory getTransformerFactory() throws Exception { - if(tfactory == null) { - if (tfactoryClass == null) { - tfactory = (SAXTransformerFactory)TransformerFactory.newInstance(); - } else { - tfactory = (SAXTransformerFactory)tfactoryClass.newInstance(); - } - tfactory.setErrorListener(new TraxErrorHandler(getLogger())); - tfactory.setURIResolver(this); - // TODO: If we will support this feature with a different - // transformer than Xalan we'll have to set that corresponding - // feature - if (tfactory.getClass().getName().equals("org.apache.xalan.processor.TransformerFactoryImpl")) { - tfactory.setAttribute("http://xml.apache.org/xalan/features/incremental", - new Boolean (incrementalProcessing)); + * Get the TransformerFactory associated with the given classname. If + * the class can't be found or the given class doesn't implement + * the required interface, the default factory is returned. + */ + private SAXTransformerFactory getTransformerFactory(String factoryName) { + SAXTransformerFactory _factory; + + if ((factoryName == null) || (factoryName == XSLTProcessor.DEFAULT_FACTORY)) { + _factory = (SAXTransformerFactory) TransformerFactory.newInstance(); + } else { + try { + _factory = (SAXTransformerFactory) ClassUtils.loadClass(factoryName).newInstance(); + } catch (ClassNotFoundException cnfe) { + this.getLogger().error("Cannot find the requested TrAX factory '" + factoryName + "'. Using default TrAX Transformer Factory instead."); + if (this.factory != null) return this.factory; + _factory = (SAXTransformerFactory) TransformerFactory.newInstance(); + } catch (ClassCastException cce) { + this.getLogger().error("The indicated class '" + factoryName + "' is not a TrAX Transformer Factory. Using default TrAX Transformer Factory instead."); + if (this.factory != null) return this.factory; + _factory = (SAXTransformerFactory) TransformerFactory.newInstance(); + } catch (Exception e) { + this.getLogger().error("Error found loading the requested TrAX Transformer Factory '" + factoryName + "'. Using default TrAX Transformer Factory instead."); + if (this.factory != null) return this.factory; + _factory = (SAXTransformerFactory) TransformerFactory.newInstance(); } } - return tfactory; + + _factory.setErrorListener(new TraxErrorHandler(getLogger())); + _factory.setURIResolver(this); + + // FIXME (SM): implementation-specific parameter passing should be + // made more extensible. + if (_factory.getClass().getName().equals("org.apache.xalan.processor.TransformerFactoryImpl")) { + _factory.setAttribute("http://xml.apache.org/xalan/features/incremental", new Boolean (incrementalProcessing)); + } + + return _factory; } private Templates getTemplates(Source stylesheet, String id) @@ -345,6 +364,11 @@ getLogger().debug("XSLTProcessorImpl getTemplates: stylesheet " + id); + // we must augment the template ID with the factory classname since one + // transformer implementation cannot handle the instances of a + // template created by another one. + id += factory.getClass().getName(); + Templates templates = null; // only stylesheets with a last modification date are stored if (stylesheet.getLastModified() != 0) { @@ -374,6 +398,11 @@ if (!useStore) return; + // we must augment the template ID with the factory classname since one + // transformer implementation cannot handle the instances of a + // template created by another one. + id += factory.getClass().getName(); + // only stylesheets with a last modification date are stored if (stylesheet.getLastModified() != 0) { @@ -456,9 +485,5 @@ } finally { if (xslSource != null) xslSource.recycle(); } - } - - public void setSourceResolver(SourceResolver resolver) { - this.resolver = resolver; } }
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]