Home | History | Annotate | Download | only in domts
      1 /*
      2  * Copyright (c) 2002 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 
     13 package org.w3c.domts;
     14 
     15 import java.lang.reflect.Constructor;
     16 import java.lang.reflect.InvocationTargetException;
     17 import java.lang.reflect.Method;
     18 
     19 import javax.xml.parsers.ParserConfigurationException;
     20 import javax.xml.parsers.SAXParser;
     21 import javax.xml.parsers.SAXParserFactory;
     22 
     23 import org.w3c.dom.DOMImplementation;
     24 import org.w3c.dom.Document;
     25 import org.xml.sax.AttributeList;
     26 import org.xml.sax.Attributes;
     27 import org.xml.sax.DocumentHandler;
     28 import org.xml.sax.SAXException;
     29 import org.xml.sax.helpers.DefaultHandler;
     30 
     31 /**
     32  *   This class implements the generic parser and configuation
     33  *   class for the HTML DOM L2 implementation in Xerces-J
     34  */
     35 public class XercesHTML2DocumentBuilderFactory
     36     extends DOMTestDocumentBuilderFactory {
     37 
     38   private SAXParserFactory factory;
     39   private Constructor htmlBuilderConstructor;
     40   private Method getHTMLDocumentMethod;
     41   private DOMImplementation domImpl;
     42   private static final Class[] NO_CLASSES = new Class[0];
     43   private static final Object[] NO_OBJECTS = new Object[0];
     44 
     45   /**
     46    * Creates a implementation of DOMTestDocumentBuilderFactory
     47    * using org.apache.html.dom.HTMLBuilder
     48    * @param settings array of settings, may be null.
     49    */
     50   public XercesHTML2DocumentBuilderFactory(DocumentBuilderSetting[] settings) throws
     51       DOMTestIncompatibleException {
     52     super(settings);
     53 
     54     try {
     55       ClassLoader classLoader = ClassLoader.getSystemClassLoader();
     56       Class htmlBuilderClass =
     57           classLoader.loadClass("org.apache.html2.dom.HTMLBuilder");
     58 
     59       htmlBuilderConstructor =
     60           htmlBuilderClass.getConstructor(NO_CLASSES);
     61 
     62       getHTMLDocumentMethod =
     63           htmlBuilderClass.getMethod("getHTMLDocument", NO_CLASSES);
     64 
     65       Class htmlDOMImpl =
     66           classLoader.loadClass(
     67           "org.apache.html2.dom.HTMLDOMImplementationImpl");
     68       Method method =
     69           htmlDOMImpl.getMethod("getHTMLDOMImplementation", NO_CLASSES);
     70       domImpl = (DOMImplementation) method.invoke(null, NO_OBJECTS);
     71 
     72       Class saxFactoryClass =
     73           classLoader.loadClass(
     74           "org.apache.xerces.jaxp.SAXParserFactoryImpl");
     75       factory = (SAXParserFactory) saxFactoryClass.newInstance();
     76     }
     77     catch (InvocationTargetException ex) {
     78       throw new DOMTestIncompatibleException(
     79           ex.getTargetException(),
     80           null);
     81     }
     82     catch (Exception ex) {
     83       throw new DOMTestIncompatibleException(ex, null);
     84     }
     85 
     86     //
     87     //    apply settings to selected document builder
     88     //         may throw exception if incompatible
     89     if (settings != null) {
     90       for (int i = 0; i < settings.length; i++) {
     91         //        settings[i].applySetting(factory);
     92       }
     93     }
     94     try {
     95       factory.newSAXParser();
     96     }
     97     catch (ParserConfigurationException ex) {
     98       throw new DOMTestIncompatibleException(ex, null);
     99     }
    100     catch (SAXException ex) {
    101       throw new DOMTestIncompatibleException(ex, null);
    102     }
    103   }
    104 
    105   public DOMTestDocumentBuilderFactory newInstance(DocumentBuilderSetting[]
    106       newSettings) throws DOMTestIncompatibleException {
    107     if (newSettings == null) {
    108       return this;
    109     }
    110     DocumentBuilderSetting[] mergedSettings = mergeSettings(newSettings);
    111     return new XercesHTML2DocumentBuilderFactory(mergedSettings);
    112   }
    113 
    114   private class HTMLHandler
    115       extends DefaultHandler
    116       implements AttributeList {
    117     private final DocumentHandler htmlBuilder;
    118     private final Method getHTMLDocumentMethod;
    119     private Attributes currentAttributes;
    120 
    121     public HTMLHandler(
    122         Constructor htmlBuilderConstructor,
    123         Method getHTMLDocumentMethod) throws Exception {
    124       htmlBuilder =
    125           (DocumentHandler) htmlBuilderConstructor.newInstance(
    126           new Object[0]);
    127       this.getHTMLDocumentMethod = getHTMLDocumentMethod;
    128     }
    129 
    130     public void startDocument() throws SAXException {
    131       htmlBuilder.startDocument();
    132     }
    133 
    134     public void endDocument() throws SAXException {
    135       htmlBuilder.endDocument();
    136     }
    137 
    138     public void startElement(
    139         String uri,
    140         String localName,
    141         String qName,
    142         Attributes attributes) throws SAXException {
    143       currentAttributes = attributes;
    144       htmlBuilder.startElement(qName, this);
    145     }
    146 
    147     public void endElement(String uri, String localName, String qName) throws
    148         SAXException {
    149       htmlBuilder.endElement(qName);
    150     }
    151 
    152     public void characters(char ch[], int start, int length) throws
    153         SAXException {
    154       htmlBuilder.characters(ch, start, length);
    155     }
    156 
    157     public void ignorableWhitespace(char ch[], int start, int length) throws
    158         SAXException {
    159       htmlBuilder.ignorableWhitespace(ch, start, length);
    160     }
    161 
    162     public void processingInstruction(String target, String data) throws
    163         SAXException {
    164       htmlBuilder.processingInstruction(target, data);
    165     }
    166 
    167     public Document getHTMLDocument() throws Exception {
    168       return (Document) getHTMLDocumentMethod.invoke(
    169           htmlBuilder,
    170           NO_OBJECTS);
    171     }
    172 
    173     public int getLength() {
    174       return currentAttributes.getLength();
    175     }
    176 
    177     public String getName(int i) {
    178       return currentAttributes.getQName(i);
    179     }
    180 
    181     public String getType(int i) {
    182       return currentAttributes.getType(i);
    183     }
    184 
    185     public String getValue(int i) {
    186       return currentAttributes.getValue(i);
    187     }
    188 
    189     public String getType(String name) {
    190       return currentAttributes.getType(name);
    191     }
    192 
    193     public String getValue(String name) {
    194       return currentAttributes.getValue(name);
    195     }
    196 
    197   }
    198 
    199   public Document load(java.net.URL url) throws DOMTestLoadException {
    200     Document doc = null;
    201     try {
    202       SAXParser parser = factory.newSAXParser();
    203       HTMLHandler handler =
    204           new HTMLHandler(htmlBuilderConstructor, getHTMLDocumentMethod);
    205       parser.parse(url.toString(), handler);
    206       doc = handler.getHTMLDocument();
    207     }
    208     catch (Exception ex) {
    209       throw new DOMTestLoadException(ex);
    210     }
    211     return doc;
    212   }
    213 
    214   public DOMImplementation getDOMImplementation() {
    215     return domImpl;
    216   }
    217 
    218   public boolean hasFeature(String feature, String version) {
    219     return domImpl.hasFeature(feature, version);
    220   }
    221 
    222   public boolean isCoalescing() {
    223     return false;
    224   }
    225 
    226   public boolean isExpandEntityReferences() {
    227     return false;
    228   }
    229 
    230   public boolean isIgnoringElementContentWhitespace() {
    231     return false;
    232   }
    233 
    234   public boolean isNamespaceAware() {
    235     return factory.isNamespaceAware();
    236   }
    237 
    238   public boolean isValidating() {
    239     return factory.isValidating();
    240   }
    241 
    242   public static DocumentBuilderSetting[] getConfiguration1() {
    243     return new DocumentBuilderSetting[] {
    244         DocumentBuilderSetting.notCoalescing,
    245         DocumentBuilderSetting.notExpandEntityReferences,
    246         DocumentBuilderSetting.notIgnoringElementContentWhitespace,
    247         DocumentBuilderSetting.notNamespaceAware,
    248         DocumentBuilderSetting.notValidating};
    249   }
    250 
    251   public static DocumentBuilderSetting[] getConfiguration2() {
    252     return new DocumentBuilderSetting[] {
    253         DocumentBuilderSetting.notCoalescing,
    254         DocumentBuilderSetting.expandEntityReferences,
    255         DocumentBuilderSetting.ignoringElementContentWhitespace,
    256         DocumentBuilderSetting.namespaceAware,
    257         DocumentBuilderSetting.validating};
    258 
    259   }
    260 
    261 }
    262