Source for javax.xml.stream.XMLInputFactory

   1: /* XMLInputFactory.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.Reader;
  47: import java.util.Properties;
  48: import javax.xml.stream.util.XMLEventAllocator;
  49: import javax.xml.transform.Source;
  50: 
  51: /**
  52:  * Factory for creating stream and event readers from various kinds of input
  53:  * source.
  54:  * <h3>Parameters</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.isValidating</td>
  65:  * <td>Controls DTD validation</td>
  66:  * <td>Boolean</td>
  67:  * <td>Boolean.FALSE</td>
  68:  * <td>no</td>
  69:  * </tr>
  70:  * <tr>
  71:  * <td>javax.xml.stream.isNamespaceAware</td>
  72:  * <td>Controls namespace processing for XML 1.0</td>
  73:  * <td>Boolean</td>
  74:  * <td>Boolean.TRUE</td>
  75:  * <td>true is required, false is optional</td>
  76:  * </tr>
  77:  * <tr>
  78:  * <td>javax.xml.stream.isCoalescing</td>
  79:  * <td>Controls coalescing (normalization of adjacent character data)</td>
  80:  * <td>Boolean</td>
  81:  * <td>Boolean.FALSE</td>
  82:  * <td>yes</td>
  83:  * </tr>
  84:  * <tr>
  85:  * <td>javax.xml.stream.isReplacingEntityReferences</td>
  86:  * <td>Controls replacement of entity references with their replacement
  87:  * text</td>
  88:  * <td>Boolean</td>
  89:  * <td>Boolean.TRUE</td>
  90:  * <td>yes</td>
  91:  * </tr>
  92:  * <tr>
  93:  * <td>javax.xml.stream.isSupportingExternalEntities</td>
  94:  * <td>Controls whether to resolve external entities</td>
  95:  * <td>Boolean</td>
  96:  * <td>not specified</td>
  97:  * <td>yes</td>
  98:  * </tr>
  99:  * <tr>
 100:  * <td>javax.xml.stream.supportDTD</td>
 101:  * <td>Controls whether to support DTDs</td>
 102:  * <td>Boolean</td>
 103:  * <td>Boolean.TRUE</td>
 104:  * <td>yes</td>
 105:  * </tr>
 106:  * <tr>
 107:  * <td>javax.xml.stream.reporter</td>
 108:  * <td></td>
 109:  * <td>javax.xml.stream.XMLReporter</td>
 110:  * <td></td>
 111:  * <td>yes</td>
 112:  * </tr>
 113:  * <tr>
 114:  * <td>javax.xml.stream.resolver</td>
 115:  * <td></td>
 116:  * <td>javax.xml.stream.XMLResolver</td>
 117:  * <td></td>
 118:  * <td>yes</td>
 119:  * </tr>
 120:  * <tr>
 121:  * <td>javax.xml.stream.allocator</td>
 122:  * <td></td>
 123:  * <td>javax.xml.stream.util.XMLEventAllocator</td>
 124:  * <td></td>
 125:  * <td>yes</td>
 126:  * </tr>
 127:  * </table>
 128:  */
 129: public abstract class XMLInputFactory
 130: {
 131: 
 132:   /**
 133:    * Property used to control namespace support.
 134:    */
 135:   public static final String IS_NAMESPACE_AWARE =
 136:     "javax.xml.stream.isNamespaceAware";
 137: 
 138:   /**
 139:    * Property used to control DTD validation.
 140:    */
 141:   public static final String IS_VALIDATING = "javax.xml.stream.isValidating";
 142: 
 143:   /**
 144:    * Property used to control whether to coalesce adjacent text events.
 145:    */
 146:   public static final String IS_COALESCING = "javax.xml.stream.isCoalescing";
 147: 
 148:   /**
 149:    * Property used to control whether to replace entity references with
 150:    * their replacement text.
 151:    */
 152:   public static final String IS_REPLACING_ENTITY_REFERENCES =
 153:     "javax.xml.stream.isReplacingEntityReferences";
 154: 
 155:   /**
 156:    * Property used to control whether to resolve external entities.
 157:    */
 158:   public static final String IS_SUPPORTING_EXTERNAL_ENTITIES =
 159:     "javax.xml.stream.isSupportingExternalEntities";
 160: 
 161:   /**
 162:    * Property used to indicate whether to support DTDs.
 163:    */
 164:   public static final String SUPPORT_DTD = "javax.xml.stream.supportDTD";
 165: 
 166:   /**
 167:    * Property used to control the error reporter implementation.
 168:    */
 169:   public static final String REPORTER = "javax.xml.stream.reporter";
 170: 
 171:   /**
 172:    * Property used to control the entity resolver implementation.
 173:    */
 174:   public static final String RESOLVER = "javax.xml.stream.resolver";
 175: 
 176:   /**
 177:    * Property used to control the event allocator implementation.
 178:    */
 179:   public static final String ALLOCATOR = "javax.xml.stream.allocator";
 180: 
 181:   protected XMLInputFactory()
 182:   {
 183:   }
 184: 
 185:   /**
 186:    * Creates a new factory instance.
 187:    * @see #newInstance(String,ClassLoader)
 188:    */
 189:   public static XMLInputFactory newInstance()
 190:     throws FactoryConfigurationError
 191:   {
 192:     return newInstance(null, null);
 193:   }
 194: 
 195:   /**
 196:    * Creates a new factory instance.
 197:    * The implementation class to load is the first found in the following
 198:    * locations:
 199:    * <ol>
 200:    * <li>the <code>javax.xml.stream.XMLInputFactory</code> system
 201:    * property</li>
 202:    * <li>the above named property value in the
 203:    * <code><i>$JAVA_HOME</i>/lib/stax.properties</code> file</li>
 204:    * <li>the class name specified in the
 205:    * <code>META-INF/services/javax.xml.stream.XMLInputFactory</code>
 206:    * system resource</li>
 207:    * <li>the default factory class</li>
 208:    * </ol>
 209:    * @param factoryId name of the factory, same as a property name
 210:    * @param classLoader the class loader to use
 211:    * @return the factory implementation
 212:    * @exception FactoryConfigurationError if an instance of this factory
 213:    * cannot be loaded
 214:    */
 215:   public static XMLInputFactory newInstance(String factoryId,
 216:                                             ClassLoader classLoader)
 217:     throws FactoryConfigurationError
 218:   {
 219:     ClassLoader loader = classLoader;
 220:     if (loader == null)
 221:       {
 222:         loader = Thread.currentThread().getContextClassLoader();
 223:       }
 224:     if (loader == null)
 225:       {
 226:         loader = XMLInputFactory.class.getClassLoader();
 227:       }
 228:     String className = null;
 229:     int count = 0;
 230:     do
 231:       {
 232:         className = getFactoryClassName(loader, count++);
 233:         if (className != null)
 234:           {
 235:             try
 236:               {
 237:                 Class<?> t = (loader != null) ? loader.loadClass(className) :
 238:                   Class.forName(className);
 239:                 return (XMLInputFactory) t.newInstance();
 240:               }
 241:             catch (ClassNotFoundException e)
 242:               {
 243:                 className = null;
 244:               }
 245:             catch (Exception e)
 246:               {
 247:                 throw new FactoryConfigurationError(e,
 248:                      "error instantiating class " + className);
 249:               }
 250:           }
 251:       }
 252:     while (className == null && count < 3);
 253:     return new gnu.xml.stream.XMLInputFactoryImpl();
 254:   }
 255: 
 256:   private static String getFactoryClassName(ClassLoader loader, int attempt)
 257:   {
 258:     final String propertyName = "javax.xml.stream.XMLInputFactory";
 259:     switch (attempt)
 260:       {
 261:         case 0:
 262:           return System.getProperty(propertyName);
 263:         case 1:
 264:           try
 265:             {
 266:               File file = new File(System.getProperty("java.home"));
 267:               file = new File(file, "lib");
 268:               file = new File(file, "stax.properties");
 269:               InputStream in = new FileInputStream(file);
 270:               Properties props = new Properties();
 271:               props.load(in);
 272:               in.close();
 273:               return props.getProperty(propertyName);
 274:             }
 275:           catch (IOException e)
 276:             {
 277:               return null;
 278:             }
 279:         case 2:
 280:           try
 281:             {
 282:               String serviceKey = "/META-INF/services/" + propertyName;
 283:               InputStream in = (loader != null) ?
 284:                  loader.getResourceAsStream(serviceKey) :
 285:                 XMLInputFactory.class.getResourceAsStream(serviceKey);
 286:               if (in != null)
 287:                 {
 288:                   BufferedReader r =
 289:                      new BufferedReader(new InputStreamReader(in));
 290:                   String ret = r.readLine();
 291:                   r.close();
 292:                   return ret;
 293:                 }
 294:             }
 295:           catch (IOException e)
 296:             {
 297:             }
 298:           return null;
 299:         default:
 300:           return null;
 301:       }
 302:   }
 303: 
 304:   /**
 305:    * Creates a new stream reader.
 306:    */
 307:   public abstract XMLStreamReader createXMLStreamReader(Reader reader)
 308:     throws XMLStreamException;
 309: 
 310:   /**
 311:    * Creates a new stream reader.
 312:    */
 313:   public abstract XMLStreamReader createXMLStreamReader(Source source)
 314:     throws XMLStreamException;
 315: 
 316:   /**
 317:    * Creates a new stream reader.
 318:    */
 319:   public abstract XMLStreamReader createXMLStreamReader(InputStream stream)
 320:     throws XMLStreamException;
 321: 
 322:   /**
 323:    * Creates a new stream reader.
 324:    */
 325:   public abstract XMLStreamReader createXMLStreamReader(InputStream stream,
 326:                                                         String encoding)
 327:     throws XMLStreamException;
 328: 
 329:   /**
 330:    * Creates a new stream reader.
 331:    */
 332:   public abstract XMLStreamReader createXMLStreamReader(String systemId,
 333:                                                         InputStream stream)
 334:     throws XMLStreamException;
 335: 
 336:   /**
 337:    * Creates a new stream reader.
 338:    */
 339:   public abstract XMLStreamReader createXMLStreamReader(String systemId,
 340:                                                         Reader reader)
 341:     throws XMLStreamException;
 342: 
 343:   /**
 344:    * Creates a new event reader.
 345:    */
 346:   public abstract XMLEventReader createXMLEventReader(Reader reader)
 347:     throws XMLStreamException;
 348: 
 349:   /**
 350:    * Creates a new event reader.
 351:    */
 352:   public abstract XMLEventReader createXMLEventReader(String systemId,
 353:                                                       Reader reader)
 354:     throws XMLStreamException;
 355: 
 356:   /**
 357:    * Creates a new event reader.
 358:    */
 359:   public abstract XMLEventReader createXMLEventReader(XMLStreamReader reader)
 360:     throws XMLStreamException;
 361: 
 362:   /**
 363:    * Creates a new event reader.
 364:    */
 365:   public abstract XMLEventReader createXMLEventReader(Source source)
 366:     throws XMLStreamException;
 367: 
 368:   /**
 369:    * Creates a new event reader.
 370:    */
 371:   public abstract XMLEventReader createXMLEventReader(InputStream stream)
 372:     throws XMLStreamException;
 373: 
 374:   /**
 375:    * Creates a new event reader.
 376:    */
 377:   public abstract XMLEventReader createXMLEventReader(InputStream stream,
 378:                                                       String encoding)
 379:     throws XMLStreamException;
 380: 
 381:   /**
 382:    * Creates a new event reader.
 383:    */
 384:   public abstract XMLEventReader createXMLEventReader(String systemId,
 385:                                                       InputStream stream)
 386:     throws XMLStreamException;
 387: 
 388:   /**
 389:    * Create a new filtered reader.
 390:    */
 391:   public abstract XMLStreamReader createFilteredReader(XMLStreamReader reader,
 392:                                                        StreamFilter filter)
 393:     throws XMLStreamException;
 394: 
 395:   /**
 396:    * Create a new filtered reader.
 397:    */
 398:   public abstract XMLEventReader createFilteredReader(XMLEventReader reader,
 399:                                                       EventFilter filter)
 400:     throws XMLStreamException;
 401: 
 402:   /**
 403:    * Returns the entity resolver.
 404:    */
 405:   public abstract XMLResolver getXMLResolver();
 406: 
 407:   /**
 408:    * Sets the entity resolver.
 409:    */
 410:   public abstract void setXMLResolver(XMLResolver resolver);
 411: 
 412:   /**
 413:    * Returns the error reporter.
 414:    */
 415:   public abstract XMLReporter getXMLReporter();
 416: 
 417:   /**
 418:    * Sets the error reporter.
 419:    */
 420:   public abstract void setXMLReporter(XMLReporter reporter);
 421: 
 422:   /**
 423:    * Sets the implementation-specific property of the given name.
 424:    * @exception IllegalArgumentException if the property is not supported
 425:    */
 426:   public abstract void setProperty(String name, Object value)
 427:     throws IllegalArgumentException;
 428: 
 429:   /**
 430:    * Returns the implementation-specific property of the given name.
 431:    * @exception IllegalArgumentException if the property is not supported
 432:    */
 433:   public abstract Object getProperty(String name)
 434:     throws IllegalArgumentException;
 435: 
 436:   /**
 437:    * Indicates whether the specified property is supported.
 438:    */
 439:   public abstract boolean isPropertySupported(String name);
 440: 
 441:   /**
 442:    * Sets the event allocator.
 443:    */
 444:   public abstract void setEventAllocator(XMLEventAllocator allocator);
 445: 
 446:   /**
 447:    * Returns the event allocator.
 448:    */
 449:   public abstract XMLEventAllocator getEventAllocator();
 450: 
 451: }