1 /* XMLOutputFactory.java --
2    Copyright (C) 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.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_PREFIX_DEFAULTING =
81     "javax.xml.stream.isPrefixDefaulting";
82 
XMLOutputFactory()83   protected XMLOutputFactory()
84   {
85   }
86 
87   /**
88    * Creates a new <b>output</b> factory.
89    * The implementation class to load is the first found in the following
90    * locations:
91    * <ol>
92    * <li>the <code>javax.xml.stream.XMLOutputFactory</code> system
93    * property</li>
94    * <li>the above named property value in the
95    * <code><i>$JAVA_HOME</i>/lib/stax.properties</code> file</li>
96    * <li>the class name specified in the
97    * <code>META-INF/services/javax.xml.stream.XMLOutputFactory</code>
98    * system resource</li>
99    * <li>the default factory class</li>
100    * </ol>
101    */
newInstance()102   public static XMLOutputFactory newInstance()
103     throws FactoryConfigurationError
104   {
105     ClassLoader loader = Thread.currentThread().getContextClassLoader();
106     if (loader == null)
107       {
108         loader = XMLOutputFactory.class.getClassLoader();
109       }
110     String className = null;
111     int count = 0;
112     do
113       {
114         className = getFactoryClassName(loader, count++);
115         if (className != null)
116           {
117             try
118               {
119                 Class t = (loader != null) ? loader.loadClass(className) :
120                   Class.forName(className);
121                 return (XMLOutputFactory) t.newInstance();
122               }
123             catch (ClassNotFoundException e)
124               {
125                 className = null;
126               }
127             catch (Exception e)
128               {
129                 throw new FactoryConfigurationError(e,
130                      "error instantiating class " + className);
131               }
132           }
133       }
134     while (className == null && count < 3);
135     return new gnu.xml.stream.XMLOutputFactoryImpl();
136   }
137 
getFactoryClassName(ClassLoader loader, int attempt)138   private static String getFactoryClassName(ClassLoader loader, int attempt)
139   {
140     final String propertyName = "javax.xml.stream.XMLOutputFactory";
141     switch (attempt)
142       {
143         case 0:
144           return System.getProperty(propertyName);
145         case 1:
146           try
147             {
148               File file = new File(System.getProperty("java.home"));
149               file = new File(file, "lib");
150               file = new File(file, "stax.properties");
151               InputStream in = new FileInputStream(file);
152               Properties props = new Properties();
153               props.load(in);
154               in.close();
155               return props.getProperty(propertyName);
156             }
157           catch (IOException e)
158             {
159               return null;
160             }
161         case 2:
162           try
163             {
164               String serviceKey = "/META-INF/services/" + propertyName;
165               InputStream in = (loader != null) ?
166                  loader.getResourceAsStream(serviceKey) :
167                 XMLOutputFactory.class.getResourceAsStream(serviceKey);
168               if (in != null)
169                 {
170                   BufferedReader r =
171                      new BufferedReader(new InputStreamReader(in));
172                   String ret = r.readLine();
173                   r.close();
174                   return ret;
175                 }
176             }
177           catch (IOException e)
178             {
179             }
180           return null;
181         default:
182           return null;
183       }
184   }
185 
186   /**
187    * Creates a new <b>input</b> factory.
188    * This appears to be an API design bug.
189    * @see javax.xml.stream.XMLInputFactory.newInstance(String,ClassLoader)
190    */
newInstance(String factoryId, ClassLoader classLoader)191   public static XMLInputFactory newInstance(String factoryId,
192                                             ClassLoader classLoader)
193     throws FactoryConfigurationError
194   {
195     return XMLInputFactory.newInstance(factoryId, classLoader);
196   }
197 
198   /**
199    * Creates a new stream writer.
200    */
createXMLStreamWriter(Writer stream)201   public abstract XMLStreamWriter createXMLStreamWriter(Writer stream)
202     throws XMLStreamException;
203 
204   /**
205    * Creates a new stream writer.
206    */
createXMLStreamWriter(OutputStream stream)207   public abstract XMLStreamWriter createXMLStreamWriter(OutputStream stream)
208     throws XMLStreamException;
209 
210   /**
211    * Creates a new stream writer.
212    */
createXMLStreamWriter(OutputStream stream, String encoding)213   public abstract XMLStreamWriter createXMLStreamWriter(OutputStream stream,
214                                                         String encoding)
215     throws XMLStreamException;
216 
217   /**
218    * Creates a new stream writer.
219    * @exception UnsupportedOperationException if this method is not
220    * supported
221    */
222   //public abstract XMLStreamWriter createXMLStreamWriter(Result result)
223   //  throws XMLStreamException;
224 
225   /**
226    * Creates a new event writer.
227    * @exception UnsupportedOperationException if this method is not
228    * supported
229    */
230   //public abstract XMLEventWriter createXMLEventWriter(Result result)
231   //  throws XMLStreamException;
232 
233   /**
234    * Creates a new event writer.
235    */
createXMLEventWriter(OutputStream stream)236   public abstract XMLEventWriter createXMLEventWriter(OutputStream stream)
237     throws XMLStreamException;
238 
239   /**
240    * Creates a new event writer.
241    */
createXMLEventWriter(OutputStream stream, String encoding)242   public abstract XMLEventWriter createXMLEventWriter(OutputStream stream,
243                                                       String encoding)
244     throws XMLStreamException;
245 
246   /**
247    * Creates a new event writer.
248    */
createXMLEventWriter(Writer stream)249   public abstract XMLEventWriter createXMLEventWriter(Writer stream)
250     throws XMLStreamException;
251 
252   /**
253    * Sets the implementation-specific property of the given name.
254    * @exception IllegalArgumentException if the property is not supported
255    */
setProperty(String name, Object value)256   public abstract void setProperty(String name, Object value)
257     throws IllegalArgumentException;
258 
259   /**
260    * Returns the implementation-specific property of the given name.
261    * @exception IllegalArgumentException if the property is not supported
262    */
getProperty(String name)263   public abstract Object getProperty(String name)
264     throws IllegalArgumentException;
265 
266   /**
267    * Indicates whether writers created by this factory will perform prefix
268    * defaulting.
269    * @see #IS_PREFIX_DEFAULTING
270    */
isPrefixDefaulting()271   public abstract boolean isPrefixDefaulting();
272 
273   /**
274    * Indicates whether the specified property is supported.
275    */
isPropertySupported(String name)276   public abstract boolean isPropertySupported(String name);
277 
278   /**
279    * Sets whether writers created by this factory will perform prefix
280    * defaulting.
281    * @see #IS_PREFIX_DEFAULTING
282    */
setPrefixDefaulting(boolean value)283   public abstract void setPrefixDefaulting(boolean value);
284 
285 }
286 
287