001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: /*
042: *
043: * The Apache Software License, Version 1.1
044: *
045: *
046: * Copyright (c) 2000-2004 The Apache Software Foundation. All rights
047: * reserved.
048: *
049: * Redistribution and use in source and binary forms, with or without
050: * modification, are permitted provided that the following conditions
051: * are met:
052: *
053: * 1. Redistributions of source code must retain the above copyright
054: * notice, this list of conditions and the following disclaimer.
055: *
056: * 2. Redistributions in binary form must reproduce the above copyright
057: * notice, this list of conditions and the following disclaimer in
058: * the documentation and/or other materials provided with the
059: * distribution.
060: *
061: * 3. The end-user documentation included with the redistribution,
062: * if any, must include the following acknowledgment:
063: * "This product includes software developed by the
064: * Apache Software Foundation (http://www.apache.org/)."
065: * Alternately, this acknowledgment may appear in the software itself,
066: * if and wherever such third-party acknowledgments normally appear.
067: *
068: * 4. The names "Xerces" and "Apache Software Foundation" must
069: * not be used to endorse or promote products derived from this
070: * software without prior written permission. For written
071: * permission, please contact apache@apache.org.
072: *
073: * 5. Products derived from this software may not be called "Apache",
074: * nor may "Apache" appear in their name, without prior written
075: * permission of the Apache Software Foundation.
076: *
077: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
078: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
079: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
080: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
081: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
082: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
083: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
084: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
085: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
086: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
087: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
088: * SUCH DAMAGE.
089: * ====================================================================
090: *
091: * This software consists of voluntary contributions made by many
092: * individuals on behalf of the Apache Software Foundation and was
093: * originally based on software copyright (c) 1999, Sun Microsystems, Inc.,
094: * http://www.sun.com. For more information on the Apache Software
095: * Foundation, please see <http://www.apache.org/>.
096: */
097:
098: // BEGIN RAVE MODIFICATIONS
099: package org.netbeans.modules.visualweb.designer.markup;
100:
101: //package org.apache.xerces.jaxp;
102: import org.apache.xerces.jaxp.*; // END RAVE MODIFICATIONS
103:
104: import java.io.IOException;
105: import java.util.Enumeration;
106: import java.util.Hashtable;
107:
108: import javax.xml.parsers.DocumentBuilder;
109: import javax.xml.parsers.DocumentBuilderFactory;
110:
111: import org.apache.xerces.dom.DOMImplementationImpl;
112: import org.apache.xerces.dom.DOMMessageFormatter;
113: import org.apache.xerces.impl.Constants;
114: import org.apache.xerces.parsers.DOMParser;
115: import org.w3c.dom.DOMImplementation;
116: import org.w3c.dom.Document;
117: import org.xml.sax.EntityResolver;
118: import org.xml.sax.ErrorHandler;
119: import org.xml.sax.InputSource;
120: import org.xml.sax.SAXException;
121: import org.xml.sax.SAXNotRecognizedException;
122: import org.xml.sax.SAXNotSupportedException;
123: import org.xml.sax.helpers.DefaultHandler;
124:
125: /**
126: * Shamelessly COPIED from org.apache.xerces.jaxp.DocumentBuilderImpl . I did that because
127: * I need to access the domParser field and change its document class name property,
128: * and couldn't find a way to do that with the standard provided DocumentBuilderImpl
129: * (Couldn't use reflection to break into the package private getDOMParser field, and
130: * it also doesn't have an accessible constructor I could use to subclass it.)
131: *
132: * @author Rajiv Mordani
133: * @author Edwin Goei
134: */
135: public class RaveDocumentBuilder extends DocumentBuilder implements
136: JAXPConstants {
137: private EntityResolver er = null;
138: private ErrorHandler eh = null;
139: private DOMParser domParser = null;
140:
141: public RaveDocumentBuilder(DocumentBuilderFactory dbf,
142: Hashtable dbfAttrs, boolean sourceDocument)
143: throws SAXNotRecognizedException, SAXNotSupportedException {
144: // BEGIN RAVE MODIFICATINS
145: //domParser = new DOMParser();
146: domParser = new RaveDomParser(sourceDocument);
147: // END RAVE MODIFICATINS
148:
149: // BEGIN RAVE MODIFICATINS
150: /* I don't care about validation (couldn't just leave the check in since
151: DefaultValidationErrorHandler is package private and don't feel like copying it)
152:
153: // If validating, provide a default ErrorHandler that prints
154: // validation errors with a warning telling the user to set an
155: // ErrorHandler
156: if (dbf.isValidating()) {
157: setErrorHandler(new DefaultValidationErrorHandler());
158: }
159: */
160: // END RAVE MODIFICATIONS
161: domParser.setFeature(Constants.SAX_FEATURE_PREFIX
162: + Constants.VALIDATION_FEATURE, dbf.isValidating());
163:
164: // "namespaceAware" == SAX Namespaces feature
165: domParser.setFeature(Constants.SAX_FEATURE_PREFIX
166: + Constants.NAMESPACES_FEATURE, dbf.isNamespaceAware());
167:
168: // Set various parameters obtained from DocumentBuilderFactory
169: domParser.setFeature(Constants.XERCES_FEATURE_PREFIX
170: + Constants.INCLUDE_IGNORABLE_WHITESPACE, !dbf
171: .isIgnoringElementContentWhitespace());
172: domParser.setFeature(Constants.XERCES_FEATURE_PREFIX
173: + Constants.CREATE_ENTITY_REF_NODES_FEATURE, !dbf
174: .isExpandEntityReferences());
175: domParser.setFeature(Constants.XERCES_FEATURE_PREFIX
176: + Constants.INCLUDE_COMMENTS_FEATURE, !dbf
177: .isIgnoringComments());
178: domParser.setFeature(Constants.XERCES_FEATURE_PREFIX
179: + Constants.CREATE_CDATA_NODES_FEATURE, !dbf
180: .isCoalescing());
181:
182: setDocumentBuilderFactoryAttributes(dbfAttrs);
183: }
184:
185: /**
186: * Set any DocumentBuilderFactory attributes of our underlying DOMParser
187: *
188: * Note: code does not handle possible conflicts between DOMParser
189: * attribute names and JAXP specific attribute names,
190: * eg. DocumentBuilderFactory.setValidating()
191: */
192: private void setDocumentBuilderFactoryAttributes(Hashtable dbfAttrs)
193: throws SAXNotSupportedException, SAXNotRecognizedException {
194: if (dbfAttrs == null) {
195: // Nothing to do
196: return;
197: }
198:
199: for (Enumeration e = dbfAttrs.keys(); e.hasMoreElements();) {
200: String name = (String) e.nextElement();
201: Object val = dbfAttrs.get(name);
202: if (val instanceof Boolean) {
203: // Assume feature
204: domParser.setFeature(name, ((Boolean) val)
205: .booleanValue());
206: } else {
207: // Assume property
208: if (JAXP_SCHEMA_LANGUAGE.equals(name)) {
209: // JAXP 1.2 support
210: //None of the properties will take effect till the setValidating(true) has been called
211: if (W3C_XML_SCHEMA.equals(val)) {
212: if (isValidating()) {
213: domParser
214: .setFeature(
215: Constants.XERCES_FEATURE_PREFIX
216: + Constants.SCHEMA_VALIDATION_FEATURE,
217: true);
218: // this should allow us not to emit DTD errors, as expected by the
219: // spec when schema validation is enabled
220: domParser.setProperty(JAXP_SCHEMA_LANGUAGE,
221: W3C_XML_SCHEMA);
222: }
223: }
224: } else if (JAXP_SCHEMA_SOURCE.equals(name)) {
225: if (isValidating()) {
226: String value = (String) dbfAttrs
227: .get(JAXP_SCHEMA_LANGUAGE);
228: if (value != null
229: && W3C_XML_SCHEMA.equals(value)) {
230: domParser.setProperty(name, val);
231: } else {
232: throw new IllegalArgumentException(
233: DOMMessageFormatter
234: .formatMessage(
235: DOMMessageFormatter.DOM_DOMAIN,
236: "jaxp-order-not-supported",
237: new Object[] {
238: JAXP_SCHEMA_LANGUAGE,
239: JAXP_SCHEMA_SOURCE }));
240: }
241: }
242: } else {
243: // Let Xerces code handle the property
244: domParser.setProperty(name, val);
245: }
246: }
247: }
248: }
249:
250: /**
251: * Non-preferred: use the getDOMImplementation() method instead of this
252: * one to get a DOM Level 2 DOMImplementation object and then use DOM
253: * Level 2 methods to create a DOM Document object.
254: */
255: public Document newDocument() {
256: return new org.apache.xerces.dom.DocumentImpl();
257: }
258:
259: public DOMImplementation getDOMImplementation() {
260: return DOMImplementationImpl.getDOMImplementation();
261: }
262:
263: public Document parse(InputSource is) throws SAXException,
264: IOException {
265: ClassLoader oldContextClassLoader = Thread.currentThread()
266: .getContextClassLoader();
267: boolean reset = false;
268: try {
269: // XXX #6472104 ClassLoader may be set to the project's ClassLoader earlier in the
270: // call stack when this is being called.
271: // XXX Using this module classloader as context for 'better performance',
272: // but to be kosher, the system classloader should be there (the one retrieved from global lookup).
273: ClassLoader this ClassLoader = this .getClass()
274: .getClassLoader();
275: if (oldContextClassLoader != this ClassLoader) {
276: Thread.currentThread().setContextClassLoader(
277: this ClassLoader);
278: reset = true;
279: }
280:
281: if (is == null) {
282: throw new IllegalArgumentException(DOMMessageFormatter
283: .formatMessage(DOMMessageFormatter.DOM_DOMAIN,
284: "jaxp-null-input-source", null));
285: }
286:
287: if (er != null) {
288: domParser.setEntityResolver(er);
289: }
290:
291: if (eh != null) {
292: domParser.setErrorHandler(eh);
293: }
294:
295: domParser.parse(is);
296: return domParser.getDocument();
297: } finally {
298: if (reset) {
299: Thread.currentThread().setContextClassLoader(
300: oldContextClassLoader);
301: }
302: }
303: }
304:
305: public boolean isNamespaceAware() {
306: try {
307: return domParser.getFeature(Constants.SAX_FEATURE_PREFIX
308: + Constants.NAMESPACES_FEATURE);
309: } catch (SAXException x) {
310: throw new IllegalStateException(x.getMessage());
311: }
312: }
313:
314: public boolean isValidating() {
315: try {
316: return domParser.getFeature(Constants.SAX_FEATURE_PREFIX
317: + Constants.VALIDATION_FEATURE);
318: } catch (SAXException x) {
319: throw new IllegalStateException(x.getMessage());
320: }
321: }
322:
323: public void setEntityResolver(org.xml.sax.EntityResolver er) {
324: this .er = er;
325: }
326:
327: public void setErrorHandler(org.xml.sax.ErrorHandler eh) {
328: // If app passes in a ErrorHandler of null, then ignore all errors
329: // and warnings
330: this .eh = (eh == null) ? new DefaultHandler() : eh;
331: }
332:
333: // package private
334: DOMParser getDOMParser() {
335: return domParser;
336: }
337: }
|