Source for javax.xml.transform.TransformerFactory

   1: /* TransformerFactory.java -- 
   2:    Copyright (C) 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package javax.xml.transform;
  39: 
  40: import java.io.BufferedReader;
  41: import java.io.File;
  42: import java.io.FileInputStream;
  43: import java.io.InputStream;
  44: import java.io.InputStreamReader;
  45: import java.io.IOException;
  46: import java.util.Properties;
  47: 
  48: /**
  49:  * Factory for obtaining transformation contexts.
  50:  *
  51:  * @author (a href='mailto:dog@gnu.org'>Chris Burdess</a)
  52:  */
  53: public abstract class TransformerFactory
  54: {
  55: 
  56:   protected TransformerFactory()
  57:   {
  58:   }
  59: 
  60:   /**
  61:    * Creates a new factory instance.
  62:    * The implementation class to load is the first found in the following
  63:    * locations:
  64:    * <ol>
  65:    * <li>the <code>javax.xml.transform.TransformerFactory</code> system
  66:    * property</li>
  67:    * <li>the above named property value in the
  68:    * <code><i>$JAVA_HOME</i>/lib/jaxp.properties</code> file</li>
  69:    * <li>the class name specified in the
  70:    * <code>META-INF/services/javax.xml.parsers.DocumentBuilderFactory</code>
  71:    * system resource</li>
  72:    * <li>the default factory class</li>
  73:    * </ol>
  74:    */
  75:   public static TransformerFactory newInstance() 
  76:     throws TransformerFactoryConfigurationError
  77:   {
  78:     ClassLoader loader = Thread.currentThread().getContextClassLoader();
  79:     if (loader == null)
  80:       {
  81:         loader = TransformerFactory.class.getClassLoader();
  82:       }
  83:     String className = null;
  84:     int count = 0;
  85:     do
  86:       {
  87:         className = getFactoryClassName(loader, count++);
  88:         if (className != null)
  89:           {
  90:             try
  91:               {
  92:                 Class t = (loader != null) ? loader.loadClass(className) :
  93:                   Class.forName(className);
  94:                 return (TransformerFactory) t.newInstance();
  95:               }
  96:             catch (ClassNotFoundException e)
  97:               {
  98:                 className = null;
  99:               }
 100:             catch (Exception e)
 101:               { 
 102:                 throw new TransformerFactoryConfigurationError(e,
 103:                     "error instantiating class " + className);
 104:               } 
 105:           }
 106:       }
 107:     while (className == null && count < 3);
 108:     try
 109:       {
 110:         Class t =
 111:           Class.forName("gnu.xml.transform.TransformerFactoryImpl");
 112:         return (TransformerFactory) t.newInstance();
 113:       }
 114:     catch (Exception e)
 115:       {
 116:         throw new TransformerFactoryConfigurationError(e);
 117:       }
 118:   }
 119:   
 120:   private static String getFactoryClassName(ClassLoader loader, int attempt)
 121:   {
 122:     final String propertyName = "javax.xml.transform.TransformerFactory";
 123:     switch (attempt)
 124:       {
 125:         case 0:
 126:           return System.getProperty(propertyName);
 127:         case 1:
 128:           try
 129:             {
 130:               File file = new File(System.getProperty("java.home"));
 131:               file = new File(file, "lib");
 132:               file = new File(file, "jaxp.properties");
 133:               InputStream in = new FileInputStream(file);
 134:               Properties props = new Properties();
 135:               props.load(in);
 136:               in.close();
 137:               return props.getProperty(propertyName);
 138:             }
 139:           catch (IOException e)
 140:             {
 141:               return null;
 142:             }
 143:         case 2: 
 144:           try
 145:             {
 146:               String serviceKey = "/META-INF/services/" + propertyName;
 147:               InputStream in = (loader != null) ?
 148:                 loader.getResourceAsStream(serviceKey) :
 149:                 TransformerFactory.class.getResourceAsStream(serviceKey);
 150:               if (in != null)
 151:                 {
 152:                   BufferedReader r =
 153:                     new BufferedReader(new InputStreamReader(in));
 154:                   String ret = r.readLine();
 155:                   r.close();
 156:                   return ret;
 157:                 }
 158:             }
 159:           catch (IOException e)
 160:             {
 161:             }
 162:           return null;
 163:         default:
 164:           return null;
 165:       }
 166:   }
 167:   
 168:   /**
 169:    * Creates a new transformer using the specified stylesheet.
 170:    * @param source the source of an <a href='http://www.w3.org/TR/xslt'>XSLT
 171:    * stylesheet</a> specifying the transformation to apply
 172:    */
 173:   public abstract Transformer newTransformer(Source source) 
 174:     throws TransformerConfigurationException;
 175: 
 176:   /**
 177:    * Creates a new transformer that applies the identity transform.
 178:    */
 179:   public abstract Transformer newTransformer() 
 180:     throws TransformerConfigurationException;
 181: 
 182:   /**
 183:    * Creates a new compiled transformation using the specified stylesheet.
 184:    * @param source the source of an <a href='http://www.w3.org/TR/xslt'>XSLT
 185:    * stylesheet</a> specifying the transformation to apply
 186:    */
 187:   public abstract Templates newTemplates(Source source) 
 188:     throws TransformerConfigurationException;
 189: 
 190:   /**
 191:    * Returns a source object representing the XML resource specified by the
 192:    * <a href='http://www.w3.org/TR/xml-stylesheet/'>xml-stylesheet</a>
 193:    * processing instruction and matching the given criteria.
 194:    * Note that if multiple stylesheets are selected, the source represents a
 195:    * stylesheet composed of a list of imports.
 196:    * @param source the source XML document
 197:    * @param media the media attribute to match, or <code>null</code> to match
 198:    * the preferred templates
 199:    * @param title the title attribute to match, or <code>null</code> to match
 200:    * any
 201:    * @param charset the charset attribute to match, or <code>null</code> to
 202:    * match any
 203:    */
 204:   public abstract Source getAssociatedStylesheet(Source source, 
 205:                                                  String media,
 206:                                                  String title,
 207:                                                  String charset) 
 208:     throws TransformerConfigurationException;
 209: 
 210:   /**
 211:    * Set the resolver callback to be used by transformers obtained from
 212:    * this factory.
 213:    */
 214:   public abstract void setURIResolver(URIResolver resolver);
 215: 
 216:   /**
 217:    * Returns the resolver callback to be used by transformers obtained from
 218:    * this factory.
 219:    */
 220:   public abstract URIResolver getURIResolver();
 221: 
 222:   /**
 223:    * Sets a feature of transformers and templates obtained from this
 224:    * factory.
 225:    * Feature names are fully qualified URIs, and may depend on the factory
 226:    * implementation.
 227:    * @param name the name of the feature
 228:    * @param value the feature state
 229:    * @exception TransformerConfigurationException if the feature is
 230:    * unsupported
 231:    */
 232:   public abstract void setFeature(String name, boolean value)
 233:     throws TransformerConfigurationException;
 234: 
 235:   /**
 236:    * Returns the state of a feature in the factory implementation.
 237:    * Feature names are fully qualified URIs, and may depend on the factory
 238:    * implementation. JAXP also predefines several features, including the
 239:    * constants in {@link javax.xml.XMLConstants} and
 240:    * <ul>
 241:    * <li>{@link javax.xml.transform.dom.DOMSource#FEATURE}</li>
 242:    * <li>{@link javax.xml.transform.dom.DOMResult#FEATURE}</li>
 243:    * <li>{@link javax.xml.transform.sax.SAXSource#FEATURE}</li>
 244:    * <li>{@link javax.xml.transform.sax.SAXResult#FEATURE}</li>
 245:    * <li>{@link javax.xml.transform.sax.SAXTransformerFactory#FEATURE}</li>
 246:    * <li>{@link javax.xml.transform.sax.SAXTransformerFactory#FEATURE_XMLFILTER}</li>
 247:    * <li>{@link javax.xml.transform.stream.StreamSource#FEATURE}</li>
 248:    * <li>{@link javax.xml.transform.stream.StreamResult#FEATURE}</li>
 249:    * </ul>
 250:    * The latter expose various capabilities of the factory implementation.
 251:    */
 252:   public abstract boolean getFeature(String name);
 253: 
 254:   /**
 255:    * Set a named attribute on the underlying implementation.
 256:    * @param name the attribute name
 257:    * @param value the value to assign
 258:    * @exception IllegalArgumentException if the attribute is not supported
 259:    */
 260:   public abstract void setAttribute(String name, Object value)
 261:     throws IllegalArgumentException;
 262: 
 263:   /**
 264:    * Retrieve the specified named attribute value.
 265:    * @param name the attribute name
 266:    * @exception IllegalArgumentException if the attribute is not supported
 267:    */
 268:   public abstract Object getAttribute(String name) 
 269:     throws IllegalArgumentException;
 270: 
 271:   /**
 272:    * Sets the callback to be used by transformers obtained from this factory
 273:    * to report transformation errors.
 274:    */
 275:   public abstract void setErrorListener(ErrorListener listener) 
 276:     throws IllegalArgumentException;
 277: 
 278:   /**
 279:    * Returns the callback to be used by transformers obtained from this
 280:    * factory to report transformation errors.
 281:    */
 282:   public abstract ErrorListener getErrorListener();
 283: 
 284: }