Source for javax.xml.stream.XMLOutputFactory

   1: /* XMLOutputFactory.java -- 
   2:    Copyright (C) 2005,2006  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:    * 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:    */
 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: 
 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:    */
 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:    */
 201:   public abstract XMLStreamWriter createXMLStreamWriter(Writer stream)
 202:     throws XMLStreamException;
 203: 
 204:   /**
 205:    * Creates a new stream writer.
 206:    */
 207:   public abstract XMLStreamWriter createXMLStreamWriter(OutputStream stream)
 208:     throws XMLStreamException;
 209: 
 210:   /**
 211:    * Creates a new stream writer.
 212:    */
 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:    */
 236:   public abstract XMLEventWriter createXMLEventWriter(OutputStream stream)
 237:     throws XMLStreamException;
 238: 
 239:   /**
 240:    * Creates a new event writer.
 241:    */
 242:   public abstract XMLEventWriter createXMLEventWriter(OutputStream stream,
 243:                                                       String encoding)
 244:     throws XMLStreamException;
 245: 
 246:   /**
 247:    * Creates a new event writer.
 248:    */
 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:    */
 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:    */
 263:   public abstract Object getProperty(String name)
 264:     throws IllegalArgumentException;
 265: 
 266:   /**
 267:    * Indicates whether the specified property is supported.
 268:    */
 269:   public abstract boolean isPropertySupported(String name);
 270: 
 271: }