1 /* XMLOutputFactory.java -- 2 Copyright (C) 2005,2006,2009 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.stream; 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.io.OutputStream; 47 import java.io.Writer; 48 import java.util.Properties; 49 import javax.xml.transform.Result; 50 51 /** 52 * Factory for obtaining XML stream and event writers for various kinds of 53 * output sink. 54 * <h3>Configuration</h3> 55 * <table> 56 * <tr> 57 * <th>Name</th> 58 * <th>Description</th> 59 * <th>Type</th> 60 * <th>Default</th> 61 * <th>Required</th> 62 * </tr> 63 * <tr> 64 * <td>javax.xml.stream.isRepairingNamespaces</td> 65 * <td>default namespace prefixes</td> 66 * <td>Boolean</td> 67 * <td>Boolean.FALSE</td> 68 * <td>yes</td> 69 * </tr> 70 * </table> 71 */ 72 public abstract class XMLOutputFactory 73 { 74 75 /** 76 * Property used to control whether to default namespace prefixes. 77 * If true, the writer will create a namespace declaration for any 78 * attribute that doesn't have a namespace declaration in scope. 79 */ 80 public static final java.lang.String IS_REPAIRING_NAMESPACES = 81 "javax.xml.stream.isRepairingNamespaces"; 82 XMLOutputFactory()83 protected XMLOutputFactory() 84 { 85 } 86 87 /** 88 * Creates a new <b>output</b> factory. 89 * @see #newInstance(String,ClassLoader) 90 */ newInstance()91 public static XMLOutputFactory newInstance() 92 throws FactoryConfigurationError 93 { 94 return newInstance(null, null); 95 } 96 97 /** 98 * Creates a new <b>output</b> factory. 99 * The implementation class to load is the first found in the following 100 * locations: 101 * <ol> 102 * <li>the <code>javax.xml.stream.XMLOutputFactory</code> system 103 * property</li> 104 * <li>the above named property value in the 105 * <code><i>$JAVA_HOME</i>/lib/stax.properties</code> file</li> 106 * <li>the class name specified in the 107 * <code>META-INF/services/javax.xml.stream.XMLOutputFactory</code> 108 * system resource</li> 109 * <li>the default factory class</li> 110 * </ol> 111 * @param factoryId the name of the factory, same as the property 112 * @param classLoader the class loader to use 113 * @return a new factory instance 114 * @exception FactoryConfigurationError if an instance of this factory 115 * could not be loaded 116 */ newInstance(String factoryId, ClassLoader classLoader)117 public static XMLOutputFactory newInstance(String factoryId, 118 ClassLoader classLoader) 119 throws FactoryConfigurationError 120 { 121 if (classLoader == null) 122 { 123 classLoader = Thread.currentThread().getContextClassLoader(); 124 } 125 if (classLoader == null) 126 { 127 classLoader = XMLOutputFactory.class.getClassLoader(); 128 } 129 String className = null; 130 int count = 0; 131 do 132 { 133 className = getFactoryClassName(classLoader, count++); 134 if (className != null) 135 { 136 try 137 { 138 Class<?> t = (classLoader != null) ? 139 classLoader.loadClass(className) : 140 Class.forName(className); 141 return (XMLOutputFactory) t.newInstance(); 142 } 143 catch (ClassNotFoundException e) 144 { 145 className = null; 146 } 147 catch (Exception e) 148 { 149 throw new FactoryConfigurationError(e, 150 "error instantiating class " + className); 151 } 152 } 153 } 154 while (className == null && count < 3); 155 return new gnu.xml.stream.XMLOutputFactoryImpl(); 156 } 157 getFactoryClassName(ClassLoader loader, int attempt)158 private static String getFactoryClassName(ClassLoader loader, int attempt) 159 { 160 final String propertyName = "javax.xml.stream.XMLOutputFactory"; 161 switch (attempt) 162 { 163 case 0: 164 return System.getProperty(propertyName); 165 case 1: 166 try 167 { 168 File file = new File(System.getProperty("java.home")); 169 file = new File(file, "lib"); 170 file = new File(file, "stax.properties"); 171 InputStream in = new FileInputStream(file); 172 Properties props = new Properties(); 173 props.load(in); 174 in.close(); 175 return props.getProperty(propertyName); 176 } 177 catch (IOException e) 178 { 179 return null; 180 } 181 case 2: 182 try 183 { 184 String serviceKey = "/META-INF/services/" + propertyName; 185 InputStream in = (loader != null) ? 186 loader.getResourceAsStream(serviceKey) : 187 XMLOutputFactory.class.getResourceAsStream(serviceKey); 188 if (in != null) 189 { 190 BufferedReader r = 191 new BufferedReader(new InputStreamReader(in)); 192 String ret = r.readLine(); 193 r.close(); 194 return ret; 195 } 196 } 197 catch (IOException e) 198 { 199 } 200 return null; 201 default: 202 return null; 203 } 204 } 205 206 /** 207 * Creates a new stream writer. 208 */ createXMLStreamWriter(Writer stream)209 public abstract XMLStreamWriter createXMLStreamWriter(Writer stream) 210 throws XMLStreamException; 211 212 /** 213 * Creates a new stream writer. 214 */ createXMLStreamWriter(OutputStream stream)215 public abstract XMLStreamWriter createXMLStreamWriter(OutputStream stream) 216 throws XMLStreamException; 217 218 /** 219 * Creates a new stream writer. 220 */ createXMLStreamWriter(OutputStream stream, String encoding)221 public abstract XMLStreamWriter createXMLStreamWriter(OutputStream stream, 222 String encoding) 223 throws XMLStreamException; 224 225 /** 226 * Creates a new stream writer. 227 * @exception UnsupportedOperationException if this method is not 228 * supported 229 */ createXMLStreamWriter(Result result)230 public abstract XMLStreamWriter createXMLStreamWriter(Result result) 231 throws XMLStreamException; 232 233 /** 234 * Creates a new event writer. 235 * @exception UnsupportedOperationException if this method is not 236 * supported 237 */ createXMLEventWriter(Result result)238 public abstract XMLEventWriter createXMLEventWriter(Result result) 239 throws XMLStreamException; 240 241 /** 242 * Creates a new event writer. 243 */ createXMLEventWriter(OutputStream stream)244 public abstract XMLEventWriter createXMLEventWriter(OutputStream stream) 245 throws XMLStreamException; 246 247 /** 248 * Creates a new event writer. 249 */ createXMLEventWriter(OutputStream stream, String encoding)250 public abstract XMLEventWriter createXMLEventWriter(OutputStream stream, 251 String encoding) 252 throws XMLStreamException; 253 254 /** 255 * Creates a new event writer. 256 */ createXMLEventWriter(Writer stream)257 public abstract XMLEventWriter createXMLEventWriter(Writer stream) 258 throws XMLStreamException; 259 260 /** 261 * Sets the implementation-specific property of the given name. 262 * @exception IllegalArgumentException if the property is not supported 263 */ setProperty(String name, Object value)264 public abstract void setProperty(String name, Object value) 265 throws IllegalArgumentException; 266 267 /** 268 * Returns the implementation-specific property of the given name. 269 * @exception IllegalArgumentException if the property is not supported 270 */ getProperty(String name)271 public abstract Object getProperty(String name) 272 throws IllegalArgumentException; 273 274 /** 275 * Indicates whether the specified property is supported. 276 */ isPropertySupported(String name)277 public abstract boolean isPropertySupported(String name); 278 279 } 280