1/*
2 * Copyright (c) 2001-2004 World Wide Web Consortium,
3 * (Massachusetts Institute of Technology, Institut National de
4 * Recherche en Informatique et en Automatique, Keio University). All
5 * Rights Reserved. This program is distributed under the W3C's Software
6 * Intellectual Property License. This program is distributed in the
7 * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
8 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9 * PURPOSE.
10 * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
11 */
12
13package org.w3c.domts;
14
15import java.io.InputStream;
16import javax.xml.parsers.DocumentBuilder;
17import javax.xml.parsers.DocumentBuilderFactory;
18import javax.xml.parsers.ParserConfigurationException;
19
20import org.w3c.dom.DOMImplementation;
21import org.w3c.dom.Document;
22import org.xml.sax.SAXException;
23import org.xml.sax.SAXParseException;
24
25/**
26 *   This class implements the generic parser and configuation
27 *   abstract class for JAXP supporting parsers.
28 */
29public class JAXPDOMTestDocumentBuilderFactory
30    extends DOMTestDocumentBuilderFactory {
31
32  private DocumentBuilderFactory factory;
33  private DocumentBuilder builder;
34
35  /**
36   * Creates a JAXP implementation of DOMTestDocumentBuilderFactory.
37   * @param factory null for default JAXP provider.  If not null,
38   * factory will be mutated in constructor and should be released
39   * by calling code upon return.
40   * @param settings array of settings, may be null.
41   */
42  public JAXPDOMTestDocumentBuilderFactory(
43      DocumentBuilderFactory baseFactory,
44      DocumentBuilderSetting[] settings) throws DOMTestIncompatibleException {
45    super(settings);
46    if (baseFactory == null) {
47      factory = DocumentBuilderFactory.newInstance();
48    }
49    else {
50      factory = baseFactory;
51    }
52    //
53    //    apply settings to selected document builder
54    //         may throw exception if incompatible
55    if (settings != null) {
56      for (int i = 0; i < settings.length; i++) {
57        settings[i].applySetting(factory);
58      }
59    }
60    try {
61      this.builder = factory.newDocumentBuilder();
62    }
63    catch (ParserConfigurationException ex) {
64      throw new DOMTestIncompatibleException(ex, null);
65    }
66  }
67
68  protected DOMTestDocumentBuilderFactory createInstance(DocumentBuilderFactory
69      newFactory,
70      DocumentBuilderSetting[] mergedSettings) throws
71      DOMTestIncompatibleException {
72    return new JAXPDOMTestDocumentBuilderFactory(newFactory, mergedSettings);
73  }
74
75  public DOMTestDocumentBuilderFactory newInstance(DocumentBuilderSetting[]
76      newSettings) throws DOMTestIncompatibleException {
77    if (newSettings == null) {
78      return this;
79    }
80    DocumentBuilderSetting[] mergedSettings = mergeSettings(newSettings);
81    DocumentBuilderFactory newFactory = factory.newInstance();
82    return createInstance(newFactory, mergedSettings);
83  }
84
85  private class LoadErrorHandler
86      implements org.xml.sax.ErrorHandler {
87    private SAXException parseException;
88    private int errorCount;
89    private int warningCount;
90    public LoadErrorHandler() {
91      parseException = null;
92      errorCount = 0;
93      warningCount = 0;
94    }
95
96    public void error(SAXParseException ex) {
97      errorCount++;
98      if (parseException == null) {
99        parseException = ex;
100      }
101    }
102
103    public void warning(SAXParseException ex) {
104      warningCount++;
105    }
106
107    public void fatalError(SAXParseException ex) {
108      if (parseException == null) {
109        parseException = ex;
110      }
111    }
112
113    public SAXException getFirstException() {
114      return parseException;
115    }
116  }
117
118  public Document load(java.net.URL url) throws DOMTestLoadException {
119    Document doc = null;
120    Exception parseException = null;
121    try {
122      LoadErrorHandler errorHandler = new LoadErrorHandler();
123      builder.setErrorHandler(errorHandler);
124      InputStream stream = url.openStream();
125      doc = builder.parse(stream, url.toString());
126      stream.close();
127      parseException = errorHandler.getFirstException();
128    }
129    catch (Exception ex) {
130      parseException = ex;
131    }
132    builder.setErrorHandler(null);
133    if (parseException != null) {
134      throw new DOMTestLoadException(parseException);
135    }
136    return doc;
137  }
138
139  public DOMImplementation getDOMImplementation() {
140    return builder.getDOMImplementation();
141  }
142
143  public boolean hasFeature(String feature, String version) {
144    return builder.getDOMImplementation().hasFeature(feature, version);
145  }
146
147  public boolean isCoalescing() {
148    return factory.isCoalescing();
149  }
150
151  public boolean isExpandEntityReferences() {
152    return factory.isExpandEntityReferences();
153  }
154
155  public boolean isIgnoringElementContentWhitespace() {
156    return factory.isIgnoringElementContentWhitespace();
157  }
158
159  public boolean isNamespaceAware() {
160    return factory.isNamespaceAware();
161  }
162
163  public boolean isValidating() {
164    return factory.isValidating();
165  }
166
167  public static DocumentBuilderSetting[] getConfiguration1() {
168    return new DocumentBuilderSetting[] {
169        DocumentBuilderSetting.notCoalescing,
170        DocumentBuilderSetting.notExpandEntityReferences,
171        DocumentBuilderSetting.notIgnoringElementContentWhitespace,
172        DocumentBuilderSetting.notNamespaceAware,
173        DocumentBuilderSetting.notValidating};
174  }
175
176  public static DocumentBuilderSetting[] getConfiguration2() {
177    return new DocumentBuilderSetting[] {
178        DocumentBuilderSetting.notCoalescing,
179        DocumentBuilderSetting.expandEntityReferences,
180        DocumentBuilderSetting.ignoringElementContentWhitespace,
181        DocumentBuilderSetting.namespaceAware,
182        DocumentBuilderSetting.validating};
183
184  }
185
186}
187