Frames | No Frames |
1: /* DocumentBuilderFactory.java -- 2: Copyright (C) 2004, 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.parsers; 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.util.Properties; 47: import javax.xml.validation.Schema; 48: 49: /** 50: * Factory for obtaining document builders. 51: * Instances of this class are <em>not</em> guaranteed to be thread safe. 52: * 53: * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> 54: */ 55: public abstract class DocumentBuilderFactory 56: { 57: 58: private boolean namespaceAware; 59: private boolean validating; 60: private boolean ignoringElementContentWhitespace; 61: private boolean expandEntityReferences = true; 62: private boolean ignoringComments; 63: private boolean coalescing; 64: private Schema schema; 65: private boolean xIncludeAware; 66: 67: protected DocumentBuilderFactory() 68: { 69: } 70: 71: /** 72: * Creates a new factory instance. 73: * The implementation class to load is the first found in the following 74: * locations: 75: * <ol> 76: * <li>the <code>javax.xml.parsers.DocumentBuilderFactory</code> system 77: * property</li> 78: * <li>the above named property value in the 79: * <code><i>$JAVA_HOME</i>/lib/jaxp.properties</code> file</li> 80: * <li>the class name specified in the 81: * <code>META-INF/services/javax.xml.parsers.DocumentBuilderFactory</code> 82: * system resource</li> 83: * <li>the default factory class</li> 84: * </ol> 85: */ 86: public static DocumentBuilderFactory newInstance() 87: { 88: ClassLoader loader = Thread.currentThread().getContextClassLoader(); 89: if (loader == null) 90: { 91: loader = DocumentBuilderFactory.class.getClassLoader(); 92: } 93: String className = null; 94: int count = 0; 95: do 96: { 97: className = getFactoryClassName(loader, count++); 98: if (className != null) 99: { 100: try 101: { 102: Class<?> t = (loader != null) ? loader.loadClass(className) : 103: Class.forName(className); 104: return (DocumentBuilderFactory) t.newInstance(); 105: } 106: catch (ClassNotFoundException e) 107: { 108: className = null; 109: } 110: catch (Exception e) 111: { 112: throw new FactoryConfigurationError(e, 113: "error instantiating class " + className); 114: } 115: } 116: } 117: while (className == null && count < 3); 118: return new gnu.xml.dom.DomDocumentBuilderFactory(); 119: } 120: 121: private static String getFactoryClassName(ClassLoader loader, int attempt) 122: { 123: final String propertyName = "javax.xml.parsers.DocumentBuilderFactory"; 124: switch (attempt) 125: { 126: case 0: 127: return System.getProperty(propertyName); 128: case 1: 129: try 130: { 131: File file = new File(System.getProperty("java.home")); 132: file = new File(file, "lib"); 133: file = new File(file, "jaxp.properties"); 134: InputStream in = new FileInputStream(file); 135: Properties props = new Properties(); 136: props.load(in); 137: in.close(); 138: return props.getProperty(propertyName); 139: } 140: catch (IOException e) 141: { 142: return null; 143: } 144: case 2: 145: try 146: { 147: String serviceKey = "/META-INF/services/" + propertyName; 148: InputStream in = (loader != null) ? 149: loader.getResourceAsStream(serviceKey) : 150: DocumentBuilderFactory.class.getResourceAsStream(serviceKey); 151: if (in != null) 152: { 153: BufferedReader r = 154: new BufferedReader(new InputStreamReader(in)); 155: String ret = r.readLine(); 156: r.close(); 157: return ret; 158: } 159: } 160: catch (IOException e) 161: { 162: } 163: return null; 164: default: 165: return null; 166: } 167: } 168: 169: /** 170: * Creates a new document builder instance using the currently specified 171: * factory configuration. 172: * @exception ParserConfigurationException if the specified configuration 173: * is not supported 174: */ 175: public abstract DocumentBuilder newDocumentBuilder() 176: throws ParserConfigurationException; 177: 178: /** 179: * Sets whether document builders obtained from this factory will be XML 180: * Namespace aware. 181: */ 182: public void setNamespaceAware(boolean awareness) 183: { 184: namespaceAware = awareness; 185: } 186: 187: /** 188: * Sets whether document builders obtained from this factory will validate 189: * their input. 190: */ 191: public void setValidating(boolean validating) 192: { 193: this.validating = validating; 194: } 195: 196: /** 197: * Sets whether document builders obtained from this factory will 198: * eliminate whitespace within elements that have an element-only content 199: * model. 200: */ 201: public void setIgnoringElementContentWhitespace(boolean whitespace) 202: { 203: ignoringElementContentWhitespace = whitespace; 204: } 205: 206: /** 207: * Sets whether document builders obtained from this factory will expand 208: * entity reference nodes. 209: */ 210: public void setExpandEntityReferences(boolean expandEntityRef) 211: { 212: expandEntityReferences = expandEntityRef; 213: } 214: 215: /** 216: * Sets whether document builders obtained from this factory will discard 217: * comment nodes. 218: */ 219: public void setIgnoringComments(boolean ignoreComments) 220: { 221: ignoringComments = ignoreComments; 222: } 223: 224: /** 225: * Sets whether document builders obtained from this factory will convert 226: * CDATA sections to text nodes and normalize adjacent text nodes into a 227: * single text node. 228: */ 229: public void setCoalescing(boolean coalescing) 230: { 231: this.coalescing = coalescing; 232: } 233: 234: /** 235: * Indicates whether document builders obtained from this factory will be 236: * XML Namespace aware. 237: */ 238: public boolean isNamespaceAware() 239: { 240: return namespaceAware; 241: } 242: 243: /** 244: * Indicates whether document builders obtained from this factory will 245: * validate their input. 246: */ 247: public boolean isValidating() 248: { 249: return validating; 250: } 251: 252: /** 253: * Indicates whether document builders obtained from this factory will 254: * eliminate whitespace within elements that have an element-only content 255: * model. 256: */ 257: public boolean isIgnoringElementContentWhitespace() 258: { 259: return ignoringElementContentWhitespace; 260: } 261: 262: /** 263: * Indicates whether document builders obtained from this factory will 264: * expand entity reference nodes. 265: */ 266: public boolean isExpandEntityReferences() 267: { 268: return expandEntityReferences; 269: } 270: 271: /** 272: * Indicates whether document builders obtained from this factory will 273: * discard comment nodes. 274: */ 275: public boolean isIgnoringComments() 276: { 277: return ignoringComments; 278: } 279: 280: /** 281: * Indicates whether document builders obtained from this factory will 282: * convert CDATA sections to text nodes and normalize adjacent text nodes 283: * into a single text node. 284: */ 285: public boolean isCoalescing() 286: { 287: return coalescing; 288: } 289: 290: /** 291: * Set the named attribute on the underlying implementation. 292: * @param name the name of the attribute 293: * @param value the new value 294: * @exception IllegalArgumentException if the attribute is not recognized 295: */ 296: public abstract void setAttribute(String name, Object value) 297: throws IllegalArgumentException; 298: 299: /** 300: * Retrieves the named attribute value from the underlying implementation. 301: * @param name the name of the attribute 302: * @exception IllegalArgumentException if the attribute is not recognized 303: */ 304: public abstract Object getAttribute(String name) 305: throws IllegalArgumentException; 306: 307: // -- JAXP 1.3 methods -- 308: 309: /** 310: * Returns the schema. 311: * @see #setSchema 312: * @since 1.5 313: */ 314: public Schema getSchema() 315: { 316: return schema; 317: } 318: 319: /** 320: * Sets the schema. 321: * @see #getSchema 322: * @since 1.5 323: */ 324: public void setSchema(Schema schema) 325: { 326: this.schema = schema; 327: } 328: 329: /** 330: * Indicates whether parsers obtained from this factory will be XInclude 331: * aware. 332: * @since 1.5 333: */ 334: public boolean isXIncludeAware() 335: { 336: return xIncludeAware; 337: } 338: 339: /** 340: * Sets whether parsers obtained from this factory will be XInclude aware. 341: * @since 1.5 342: */ 343: public void setXIncludeAware(boolean state) 344: { 345: xIncludeAware = state; 346: } 347: 348: /** 349: * Sets the value of the specified feature. 350: * @param name the feature name (URI) 351: * @param value whether to enable the feature or not 352: * @exception ParserConfigurationException if the feature is not 353: * supported. 354: * @since 1.5 355: */ 356: public abstract void setFeature(String name, boolean value) 357: throws ParserConfigurationException; 358: 359: /** 360: * Returns the value of the specified feature. 361: * @param name the feature name (URI) 362: * @exception ParserConfigurationException if the feature is not 363: * supported. 364: * @since 1.5 365: */ 366: public abstract boolean getFeature(String name) 367: throws ParserConfigurationException; 368: 369: }