001 /* TransformerFactory.java -- 002 Copyright (C) 2004, 2005 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 package javax.xml.transform; 039 040 import java.io.BufferedReader; 041 import java.io.File; 042 import java.io.FileInputStream; 043 import java.io.InputStream; 044 import java.io.InputStreamReader; 045 import java.io.IOException; 046 import java.util.Properties; 047 048 /** 049 * Factory for obtaining transformation contexts. 050 * 051 * @author (a href='mailto:dog@gnu.org'>Chris Burdess</a) 052 */ 053 public abstract class TransformerFactory 054 { 055 056 protected TransformerFactory() 057 { 058 } 059 060 /** 061 * Creates a new factory instance. 062 * The implementation class to load is the first found in the following 063 * locations: 064 * <ol> 065 * <li>the <code>javax.xml.transform.TransformerFactory</code> system 066 * property</li> 067 * <li>the above named property value in the 068 * <code><i>$JAVA_HOME</i>/lib/jaxp.properties</code> file</li> 069 * <li>the class name specified in the 070 * <code>META-INF/services/javax.xml.parsers.DocumentBuilderFactory</code> 071 * system resource</li> 072 * <li>the default factory class</li> 073 * </ol> 074 */ 075 public static TransformerFactory newInstance() 076 throws TransformerFactoryConfigurationError 077 { 078 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 079 if (loader == null) 080 { 081 loader = TransformerFactory.class.getClassLoader(); 082 } 083 String className = null; 084 int count = 0; 085 do 086 { 087 className = getFactoryClassName(loader, count++); 088 if (className != null) 089 { 090 try 091 { 092 Class<?> t = (loader != null) ? loader.loadClass(className) : 093 Class.forName(className); 094 return (TransformerFactory) t.newInstance(); 095 } 096 catch (ClassNotFoundException e) 097 { 098 className = null; 099 } 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 }