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.lang.reflect.Constructor;
16import java.lang.reflect.InvocationTargetException;
17import java.lang.reflect.Method;
18
19import javax.xml.parsers.SAXParser;
20import javax.xml.parsers.SAXParserFactory;
21
22import org.w3c.dom.DOMImplementation;
23import org.w3c.dom.Document;
24
25/**
26 *   This class implements the generic parser and configuation
27 *   abstract class for the DOM implementation of Batik.
28 *
29 *   @author Curt Arnold
30 */
31public class BatikTestDocumentBuilderFactory
32    extends DOMTestDocumentBuilderFactory {
33
34  /**  dom factory.  */
35  private Object domFactory;
36
37  /**  xml reader.    */
38  private org.xml.sax.XMLReader xmlReader;
39
40  /**  reflective method to create document in Batik.   **/
41  private Method createDocument;
42
43  /**  dom implementation from Batik.   **/
44  private DOMImplementation domImpl;
45
46  /**
47   * Creates a Batik implementation of DOMTestDocumentBuilderFactory.
48   * @param settings array of settings, may be null.
49   * @throws DOMTestIncompatibleException
50   *     If implementation does not support the specified settings
51   */
52  public BatikTestDocumentBuilderFactory(
53      DocumentBuilderSetting[] settings) throws DOMTestIncompatibleException {
54    super(settings);
55    domImpl = null;
56
57    //
58    //   get the JAXP specified SAX parser's class name
59    //
60    SAXParserFactory saxFactory = SAXParserFactory.newInstance();
61    try {
62      SAXParser saxParser = saxFactory.newSAXParser();
63      xmlReader = saxParser.getXMLReader();
64    } catch (Exception ex) {
65      throw new DOMTestIncompatibleException(ex, null);
66    }
67    String xmlReaderClassName = xmlReader.getClass().getName();
68
69    //
70    //   can't change settings, so if not the same as
71    //      the default SAX parser then throw an exception
72    //
73    //    for(int i = 0; i < settings.length; i++) {
74    //      if(!settings[i].hasSetting(this)) {
75    //        TODO
76    //        throw new DOMTestIncompatibleException(null,settings[i]);
77    //      }
78    //    }
79    //
80    //   try loading Batik reflectively
81    //
82    try {
83      ClassLoader classLoader = ClassLoader.getSystemClassLoader();
84      Class domFactoryClass =
85          classLoader.loadClass(
86          "org.apache.batik.dom.svg.SAXSVGDocumentFactory");
87
88      Constructor domFactoryConstructor =
89          domFactoryClass.getConstructor(new Class[] {String.class});
90      domFactory =
91          domFactoryConstructor.newInstance(
92          new Object[] {xmlReaderClassName});
93      createDocument =
94          domFactoryClass.getMethod(
95          "createDocument",
96          new Class[] {String.class, java.io.InputStream.class});
97    } catch (InvocationTargetException ex) {
98      throw new DOMTestIncompatibleException(
99          ex.getTargetException(),
100          null);
101    } catch (Exception ex) {
102      throw new DOMTestIncompatibleException(ex, null);
103    }
104  }
105
106  /**
107   *    Create new instance of document builder factory
108   *    reflecting specified settings.
109   *    @param newSettings new settings
110   *    @return New instance
111   *    @throws DOMTestIncompatibleException
112   *         if settings are not supported by implementation
113   */
114  public DOMTestDocumentBuilderFactory newInstance(
115      DocumentBuilderSetting[] newSettings)
116        throws DOMTestIncompatibleException {
117    if (newSettings == null) {
118      return this;
119    }
120    DocumentBuilderSetting[] mergedSettings = mergeSettings(newSettings);
121    return new BatikTestDocumentBuilderFactory(mergedSettings);
122  }
123
124  /**
125   *    Loads specified URL.
126   *    @param url url to load
127   *    @return DOM document
128   *    @throws DOMTestLoadException if unable to load document
129   */
130  public Document load(java.net.URL url) throws DOMTestLoadException {
131    try {
132      java.io.InputStream stream = url.openStream();
133      return (org.w3c.dom.Document) createDocument.invoke(
134          domFactory,
135          new Object[] {url.toString(), stream});
136    } catch (InvocationTargetException ex) {
137      ex.printStackTrace();
138      throw new DOMTestLoadException(ex.getTargetException());
139    } catch (Exception ex) {
140      ex.printStackTrace();
141      throw new DOMTestLoadException(ex);
142    }
143  }
144
145  /**
146   *     Gets DOMImplementation.
147   *     @return DOM implementation, may be null
148   */
149  public DOMImplementation getDOMImplementation() {
150    //
151    //   get DOM implementation
152    //
153    if (domImpl == null) {
154      try {
155        Class svgDomImplClass =
156            ClassLoader.getSystemClassLoader().loadClass(
157            "org.apache.batik.dom.svg.SVGDOMImplementation");
158        Method getImpl =
159            svgDomImplClass.getMethod(
160            "getDOMImplementation",
161            new Class[0]);
162        domImpl =
163            (DOMImplementation) getImpl.invoke(null, new Object[0]);
164      } catch (Exception ex) {
165        return null;
166      }
167    }
168    return domImpl;
169  }
170
171  /**
172   *   Determines if the implementation supports the specified feature.
173   *   @param feature Feature
174   *   @param version Version
175   *   @return true if implementation supports the feature
176   */
177  public boolean hasFeature(String feature, String version) {
178    return getDOMImplementation().hasFeature(feature, version);
179  }
180
181  /**
182   *   Adds any specialized extension required by the implementation.
183   *   @param testFileName file name from test
184   *   @return possibly modified file name
185   */
186  public String addExtension(String testFileName) {
187    return testFileName + ".svg";
188  }
189
190  /**
191   *   Indicates whether the implementation combines text and cdata nodes.
192   *   @return true if coalescing
193   */
194  public boolean isCoalescing() {
195    return false;
196  }
197
198  /**
199   *   Indicates whether the implementation expands entity references.
200   *   @return true if expanding entity references
201   */
202  public boolean isExpandEntityReferences() {
203    return false;
204  }
205
206  /**
207   *   Indicates whether the implementation ignores
208   *       element content whitespace.
209   *   @return true if ignoring element content whitespace
210   */
211  public boolean isIgnoringElementContentWhitespace() {
212    return false;
213  }
214
215  /**
216   *   Indicates whether the implementation is namespace aware.
217   *   @return true if namespace aware
218   */
219  public boolean isNamespaceAware() {
220    return true;
221  }
222
223  /**
224   *   Indicates whether the implementation is validating.
225   *   @return true if validating
226   */
227  public boolean isValidating() {
228    return false;
229  }
230
231  /**
232   * Gets content type.
233   * @return content type, "image/svg+xml"
234   */
235  public String getContentType() {
236    return "image/svg+xml";
237  }
238
239}
240