001: /*
002: * $Id: DocumentBuilderImpl.java,v 1.1 2002/02/15 23:44:28 skavish Exp $
003: *
004: * The Apache Software License, Version 1.1
005: *
006: *
007: * Copyright (c) 2000 The Apache Software Foundation. All rights
008: * reserved.
009: *
010: * Redistribution and use in source and binary forms, with or without
011: * modification, are permitted provided that the following conditions
012: * are met:
013: *
014: * 1. Redistributions of source code must retain the above copyright
015: * notice, this list of conditions and the following disclaimer.
016: *
017: * 2. Redistributions in binary form must reproduce the above copyright
018: * notice, this list of conditions and the following disclaimer in
019: * the documentation and/or other materials provided with the
020: * distribution.
021: *
022: * 3. The end-user documentation included with the redistribution,
023: * if any, must include the following acknowledgment:
024: * "This product includes software developed by the
025: * Apache Software Foundation (http://www.apache.org/)."
026: * Alternately, this acknowledgment may appear in the software itself,
027: * if and wherever such third-party acknowledgments normally appear.
028: *
029: * 4. The names "Xerces" and "Apache Software Foundation" must
030: * not be used to endorse or promote products derived from this
031: * software without prior written permission. For written
032: * permission, please contact apache@apache.org.
033: *
034: * 5. Products derived from this software may not be called "Apache",
035: * nor may "Apache" appear in their name, without prior written
036: * permission of the Apache Software Foundation.
037: *
038: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
039: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
040: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
041: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
042: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
043: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
044: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
045: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
046: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
047: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
048: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
049: * SUCH DAMAGE.
050: * ====================================================================
051: *
052: * This software consists of voluntary contributions made by many
053: * individuals on behalf of the Apache Software Foundation and was
054: * originally based on software copyright (c) 1999, Sun Microsystems, Inc.,
055: * http://www.sun.com. For more information on the Apache Software
056: * Foundation, please see <http://www.apache.org/>.
057: */
058:
059: package org.openlaszlo.iv.flash.xml.apache;
060:
061: import java.io.IOException;
062: import javax.xml.parsers.DocumentBuilder;
063: import javax.xml.parsers.DocumentBuilderFactory;
064: import javax.xml.parsers.ParserConfigurationException;
065:
066: import org.w3c.dom.Document;
067: import org.w3c.dom.DOMImplementation;
068: import org.w3c.dom.DocumentType;
069:
070: import org.xml.sax.XMLReader;
071: import org.xml.sax.InputSource;
072: import org.xml.sax.SAXException;
073: import org.xml.sax.SAXParseException;
074: import org.xml.sax.EntityResolver;
075: import org.xml.sax.ErrorHandler;
076: import org.xml.sax.helpers.DefaultHandler;
077:
078: import org.apache.xerces.parsers.DOMParser;
079: import org.apache.xerces.dom.DOMImplementationImpl;
080:
081: /**
082: * Standard DocumentBuilderImpl from apache.
083: * <p>
084: * Modifications for JGenerator:<br>
085: * - ignore fatal errors in parser<br>
086: * - pool of DOM parser with locking and releasing<br>
087: *
088: * @author Dmitry Skavish
089: * @author Rajiv Mordani
090: * @author Edwin Goei
091: */
092: public class DocumentBuilderImpl extends DocumentBuilder {
093:
094: /** Size of parser's pool */
095: private static final int MAX_PARSERS = 5;
096:
097: /* Xerces features */
098: private static final String XERCES_FEATURE_PREFIX = "http://apache.org/xml/features/";
099: private static final String CREATE_ENTITY_REF_NODES_FEATURE = "dom/create-entity-ref-nodes";
100: private static final String INCLUDE_IGNORABLE_WHITESPACE = "dom/include-ignorable-whitespace";
101: private static final String CONTINUE_AFTER_FATAL_ERROR = "continue-after-fatal-error";
102: private static final String VALIDATING_PARSER = "http://xml.org/sax/features/validation";
103: private static final String NAMESPACE_AWARE = "http://xml.org/sax/features/namespaces";
104:
105: private DocumentBuilderFactory dbf;
106:
107: private EntityResolver er = null;
108: private ErrorHandler eh = null;
109:
110: /* Parsers' pool */
111: private DOMParser[] parsers = new DOMParser[MAX_PARSERS];
112: private boolean[] locks = new boolean[MAX_PARSERS];
113:
114: private boolean namespaceAware = false;
115: private boolean validating = false;
116:
117: DocumentBuilderImpl(DocumentBuilderFactory dbf)
118: throws ParserConfigurationException {
119: this .dbf = dbf;
120: this .validating = dbf.isValidating();
121: this .namespaceAware = dbf.isNamespaceAware();
122: }
123:
124: /**
125: * Non-preferred: use the getDOMImplementation() method instead of this
126: * one to get a DOM Level 2 DOMImplementation object and then use DOM
127: * Level 2 methods to create a DOM Document object.
128: */
129: public Document newDocument() {
130: return new org.apache.xerces.dom.DocumentImpl();
131: }
132:
133: public DOMImplementation getDOMImplementation() {
134: return DOMImplementationImpl.getDOMImplementation();
135: }
136:
137: public Document parse(InputSource is) throws SAXException,
138: IOException {
139: if (is == null) {
140: throw new IllegalArgumentException(
141: "InputSource cannot be null");
142: }
143:
144: DOMParser parser = lockDOMParser();
145: try {
146: parser.parse(is);
147: Document doc = parser.getDocument();
148: return doc;
149: } finally {
150: releaseDOMParser(parser);
151: }
152: }
153:
154: public boolean isNamespaceAware() {
155: return namespaceAware;
156: }
157:
158: public boolean isValidating() {
159: return validating;
160: }
161:
162: public void setEntityResolver(org.xml.sax.EntityResolver er) {
163: this .er = er;
164: }
165:
166: public void setErrorHandler(org.xml.sax.ErrorHandler eh) {
167: // If app passes in a ErrorHandler of null, then ignore all errors
168: // and warnings
169: this .eh = (eh == null) ? new DefaultHandler() : eh;
170: }
171:
172: /**
173: * Create DOM parser
174: *
175: * @return created parser
176: * @exception ParserConfigurationException
177: */
178: private DOMParser createDOMParser() throws SAXException {
179: DOMParser domParser = new DOMParser();
180:
181: domParser.setFeature(VALIDATING_PARSER, false);
182:
183: // "namespaceAware" == SAX Namespaces feature
184: domParser.setFeature(NAMESPACE_AWARE, namespaceAware);
185:
186: // Set various parameters obtained from DocumentBuilderFactory
187: domParser.setFeature(XERCES_FEATURE_PREFIX
188: + INCLUDE_IGNORABLE_WHITESPACE, !dbf
189: .isIgnoringElementContentWhitespace());
190: domParser.setFeature(XERCES_FEATURE_PREFIX
191: + CREATE_ENTITY_REF_NODES_FEATURE, !dbf
192: .isExpandEntityReferences());
193: domParser.setFeature(XERCES_FEATURE_PREFIX
194: + CONTINUE_AFTER_FATAL_ERROR, true);
195:
196: // XXX No way to control dbf.isIgnoringComments() or
197: // dbf.isCoalescing()
198:
199: if (er != null)
200: domParser.setEntityResolver(er);
201: if (eh != null)
202: domParser.setErrorHandler(eh);
203:
204: return domParser;
205: }
206:
207: private synchronized DOMParser lockDOMParser() throws SAXException {
208: for (;;) {
209: for (int i = 0; i < MAX_PARSERS; i++) {
210: if (!locks[i]) {
211: if (parsers[i] == null) {
212: parsers[i] = createDOMParser();
213: }
214: locks[i] = true;
215: return parsers[i];
216: }
217: }
218: try {
219: wait();
220: } catch (InterruptedException e) {
221: }
222: }
223: }
224:
225: private synchronized void releaseDOMParser(DOMParser p) {
226: for (int i = 0; i < MAX_PARSERS; i++) {
227: if (parsers[i] == p) {
228: locks[i] = false;
229: notify();
230: break;
231: }
232: }
233: }
234:
235: }
|