001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.lib.xml;
020:
021: import javax.xml.parsers.DocumentBuilder;
022: import javax.xml.parsers.DocumentBuilderFactory;
023: import javax.xml.parsers.ParserConfigurationException;
024: import javax.xml.parsers.SAXParser;
025: import javax.xml.parsers.SAXParserFactory;
026:
027: import org.apache.commons.lang.exception.NestableRuntimeException;
028: import org.w3c.dom.Document;
029: import org.xml.sax.ErrorHandler;
030: import org.xml.sax.SAXException;
031:
032: /**
033: * The XMLFactory produces validating and non-validating DOM level 2
034: * and SAX level 2 parsers and XSL transformers through JAXP. It uses
035: * caching to avoid repeatedly paying the relatively expensive runtime costs
036: * associated with resolving the correct XML implementation through the
037: * JAXP configuration mechanisms.
038: *
039: * @author Abe White
040: * @nojavadoc
041: */
042: public class XMLFactory {
043:
044: // cache parsers and transformers in all possible configurations
045: private static SAXParserFactory[] _saxFactories = null;
046: private static DocumentBuilderFactory[] _domFactories = null;
047: private static ErrorHandler _validating;
048:
049: static {
050: _saxFactories = new SAXParserFactory[4];
051: _domFactories = new DocumentBuilderFactory[4];
052:
053: SAXParserFactory saxFactory;
054: DocumentBuilderFactory domFactory;
055: int arrIdx;
056: for (int validating = 0; validating < 2; validating++) {
057: for (int namespace = 0; namespace < 2; namespace++) {
058: arrIdx = factoryIndex(validating == 1, namespace == 1);
059:
060: saxFactory = SAXParserFactory.newInstance();
061: saxFactory.setValidating(validating == 1);
062: saxFactory.setNamespaceAware(namespace == 1);
063: _saxFactories[arrIdx] = saxFactory;
064:
065: domFactory = DocumentBuilderFactory.newInstance();
066: domFactory.setValidating(validating == 1);
067: domFactory.setNamespaceAware(namespace == 1);
068: _domFactories[arrIdx] = domFactory;
069: }
070: }
071: _validating = new ValidatingErrorHandler();
072: }
073:
074: /**
075: * Return a SAXParser with the specified configuration.
076: */
077: public static SAXParser getSAXParser(boolean validating,
078: boolean namespaceAware) {
079: SAXParser sp;
080: try {
081: sp = _saxFactories[factoryIndex(validating, namespaceAware)]
082: .newSAXParser();
083: } catch (ParserConfigurationException pce) {
084: throw new NestableRuntimeException(pce);
085: } catch (SAXException se) {
086: throw new NestableRuntimeException(se);
087: }
088:
089: if (validating) {
090: try {
091: sp.getXMLReader().setErrorHandler(_validating);
092: } catch (SAXException se) {
093: throw new NestableRuntimeException(se);
094: }
095: }
096:
097: return sp;
098: }
099:
100: /**
101: * Return a DocumentBuilder with the specified configuration.
102: */
103: public static DocumentBuilder getDOMParser(boolean validating,
104: boolean namespaceAware) {
105: DocumentBuilder db;
106: try {
107: db = _domFactories[factoryIndex(validating, namespaceAware)]
108: .newDocumentBuilder();
109: } catch (ParserConfigurationException pce) {
110: throw new NestableRuntimeException(pce);
111: }
112:
113: if (validating)
114: db.setErrorHandler(_validating);
115: return db;
116: }
117:
118: /**
119: * Return a new DOM Document.
120: */
121: public static Document getDocument() {
122: return getDOMParser(false, false).newDocument();
123: }
124:
125: /**
126: * Return the array index of the factory with the given properties.
127: */
128: private static int factoryIndex(boolean validating,
129: boolean namespaceAware) {
130: int arrayIndex = 0;
131: if (validating)
132: arrayIndex += 2;
133: if (namespaceAware)
134: arrayIndex += 1;
135: return arrayIndex;
136: }
137: }
|