Source for javax.xml.stream.XMLOutputFactory

   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: }