/* * eXist Open Source Native XML Database * Copyright (C) 2001-07 The eXist Project * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * $Id: TransformerFactoryAllocator.java 0000 2006-08-10 22:39:00 +0000 (Thu, 10 Aug 2006) deliriumsky $ */ package org.exist.xslt; import java.util.Enumeration; import java.util.Hashtable; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXTransformerFactory; import org.apache.log4j.Logger; import org.exist.storage.BrokerPool; /** * Allows the TransformerFactory that is used for XSLT to be * chosen through configuration settings in conf.xml * * Within eXist this class should be used instead of * directly calling SAXTransformerFactory.newInstance() directly * * @author Adam Retter <adam.retter@devon.gov.uk> * @author Andrzej Taramina <andrzej@chaeron.com> */ public class TransformerFactoryAllocator { private final static Logger LOG = Logger.getLogger( TransformerFactoryAllocator.class ); public static final String CONFIGURATION_ELEMENT_NAME = "transformer"; public final static String TRANSFORMER_CLASS_ATTRIBUTE = "class"; public final static String PROPERTY_TRANSFORMER_CLASS = "transformer.class"; public final static String CONFIGURATION_TRANSFORMER_ATTRIBUTE_ELEMENT_NAME = "attribute"; public final static String PROPERTY_TRANSFORMER_ATTRIBUTES = "transformer.attributes"; public final static String TRANSFORMER_CACHING_ATTRIBUTE = "caching"; public final static String PROPERTY_CACHING_ATTRIBUTE = "transformer.caching"; //private constructor private TransformerFactoryAllocator() { } /** * Get the TransformerFactory defined in conf.xml * If the class can't be found or the given class doesn't implement * the required interface, the default factory is returned. * * @param pool A database broker pool, used for reading the conf.xml configuration * * @return A SAXTransformerFactory, for which newInstance() can then be called * * * Typical usage: * * Instead of SAXTransformerFactory.newInstance() use * TransformerFactoryAllocator.getTransformerFactory(broker).newInstance() */ public static SAXTransformerFactory getTransformerFactory( BrokerPool pool ) { SAXTransformerFactory factory; //get the transformer class name from conf.xml String transformerFactoryClassName = (String)pool.getConfiguration().getProperty(PROPERTY_TRANSFORMER_CLASS); // if( LOG.isDebugEnabled() ) { // LOG.debug( "transformerFactoryClassName=" + transformerFactoryClassName ); // LOG.debug( "javax.xml.transform.TransformerFactory=" + System.getProperty( "javax.xml.transform.TransformerFactory" ) ); // } // was a TransformerFactory class specified? if( transformerFactoryClassName == null ) { //no, use the system default factory = (SAXTransformerFactory)TransformerFactory.newInstance(); } else { //try and load the specified TransformerFactory class try { factory = (SAXTransformerFactory)Class.forName( transformerFactoryClassName ).newInstance(); if( LOG.isDebugEnabled() ) { LOG.debug( "Set transformer factory: " + transformerFactoryClassName ); } Hashtable attributes = (Hashtable)pool.getConfiguration().getProperty( PROPERTY_TRANSFORMER_ATTRIBUTES ); Enumeration attrNames = attributes.keys(); while( attrNames.hasMoreElements() ) { String name = (String)attrNames.nextElement(); Object value = attributes.get( name ); try { factory.setAttribute( name, value ); if( LOG.isDebugEnabled() ) { LOG.debug( "Set transformer attribute: " + ", name: " + name + ", value: " + value ); } } catch( Exception e ) { LOG.warn( "Unable to set attribute for TransformerFactory: '" + transformerFactoryClassName + "', name: " + name + ", value: " + value + ", exception: " + e ); } } /* TODO uncomment below for testing eXist-XSLT or once the eXist-XSLT is ready for general consumption at the moment the XSLT extension is not on the classpath, which make compilation fail for everyone else otherwise! */ /* if(factory instanceof org.exist.xslt.TransformerFactoryImpl) factory.setAttribute(PROPERTY_BROKER_POOL, pool); */ } catch( ClassNotFoundException cnfe ) { if( LOG.isDebugEnabled() ) { LOG.debug("Cannot find the requested TrAX factory '" + transformerFactoryClassName + "'. Using default TrAX Transformer Factory instead." ); } //fallback to system default factory = (SAXTransformerFactory)TransformerFactory.newInstance(); } catch( ClassCastException cce ) { if( LOG.isDebugEnabled() ) { LOG.debug( "The indicated class '" + transformerFactoryClassName + "' is not a TrAX Transformer Factory. Using default TrAX Transformer Factory instead." ); } //fallback to system default factory = (SAXTransformerFactory)TransformerFactory.newInstance(); } catch( Exception e ) { if( LOG.isDebugEnabled() ) { LOG.debug( "Error found loading the requested TrAX Transformer Factory '" + transformerFactoryClassName + "'. Using default TrAX Transformer Factory instead: " + e ); } //fallback to system default factory = (SAXTransformerFactory)TransformerFactory.newInstance(); } } return( factory ); } }