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 
TransformerFactory()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    */
newInstance()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 
getFactoryClassName(ClassLoader loader, int attempt)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    */
newTransformer(Source source)173   public abstract Transformer newTransformer(Source source)
174     throws TransformerConfigurationException;
175 
176   /**
177    * Creates a new transformer that applies the identity transform.
178    */
newTransformer()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    */
newTemplates(Source source)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    */
getAssociatedStylesheet(Source source, String media, String title, String charset)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    */
setURIResolver(URIResolver resolver)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    */
getURIResolver()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    */
setFeature(String name, boolean value)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    */
getFeature(String name)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    */
setAttribute(String name, Object value)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    */
getAttribute(String name)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    */
setErrorListener(ErrorListener listener)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    */
getErrorListener()282   public abstract ErrorListener getErrorListener();
283 
284 }
285