Frames | No Frames |
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: 83: protected XMLOutputFactory() 84: { 85: } 86: 87: /** 88: * Creates a new <b>output</b> factory. 89: * @see #newInstance(String,ClassLoader) 90: */ 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: */ 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: 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: */ 209: public abstract XMLStreamWriter createXMLStreamWriter(Writer stream) 210: throws XMLStreamException; 211: 212: /** 213: * Creates a new stream writer. 214: */ 215: public abstract XMLStreamWriter createXMLStreamWriter(OutputStream stream) 216: throws XMLStreamException; 217: 218: /** 219: * Creates a new stream writer. 220: */ 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: */ 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: */ 238: public abstract XMLEventWriter createXMLEventWriter(Result result) 239: throws XMLStreamException; 240: 241: /** 242: * Creates a new event writer. 243: */ 244: public abstract XMLEventWriter createXMLEventWriter(OutputStream stream) 245: throws XMLStreamException; 246: 247: /** 248: * Creates a new event writer. 249: */ 250: public abstract XMLEventWriter createXMLEventWriter(OutputStream stream, 251: String encoding) 252: throws XMLStreamException; 253: 254: /** 255: * Creates a new event writer. 256: */ 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: */ 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: */ 271: public abstract Object getProperty(String name) 272: throws IllegalArgumentException; 273: 274: /** 275: * Indicates whether the specified property is supported. 276: */ 277: public abstract boolean isPropertySupported(String name); 278: 279: }