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 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.ParserConfigurationException; 20import javax.xml.parsers.SAXParser; 21import javax.xml.parsers.SAXParserFactory; 22 23import org.w3c.dom.DOMImplementation; 24import org.w3c.dom.Document; 25import org.xml.sax.AttributeList; 26import org.xml.sax.Attributes; 27import org.xml.sax.DocumentHandler; 28import org.xml.sax.SAXException; 29import 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 */ 35public 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