blob: b6b537bbc4d917d5a48f0a5b5e7eb5289a45305e [file] [log] [blame]
/*
* Copyright (c) 2002 World Wide Web Consortium,
* (Massachusetts Institute of Technology, Institut National de
* Recherche en Informatique et en Automatique, Keio University). All
* Rights Reserved. This program is distributed under the W3C's Software
* Intellectual Property License. This program is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE.
* See W3C License http://www.w3.org/Consortium/Legal/ for more details.
*/
package org.w3c.domts;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.xml.sax.AttributeList;
import org.xml.sax.Attributes;
import org.xml.sax.DocumentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* This class implements the generic parser and configuation
* abstract class the HTML DOM implementation in Xerces-J
*/
public class XercesHTMLDocumentBuilderFactory
extends DOMTestDocumentBuilderFactory {
private SAXParserFactory factory;
private Constructor htmlBuilderConstructor;
private Method getHTMLDocumentMethod;
private DOMImplementation domImpl;
private static final Class[] NO_CLASSES = new Class[0];
private static final Object[] NO_OBJECTS = new Object[0];
/**
* Creates a implementation of DOMTestDocumentBuilderFactory
* using org.apache.html.dom.HTMLBuilder
* @param settings array of settings, may be null.
*/
public XercesHTMLDocumentBuilderFactory(DocumentBuilderSetting[] settings) throws
DOMTestIncompatibleException {
super(settings);
try {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class htmlBuilderClass =
classLoader.loadClass("org.apache.html.dom.HTMLBuilder");
htmlBuilderConstructor =
htmlBuilderClass.getConstructor(NO_CLASSES);
getHTMLDocumentMethod =
htmlBuilderClass.getMethod("getHTMLDocument", NO_CLASSES);
Class htmlDOMImpl =
classLoader.loadClass(
"org.apache.html.dom.HTMLDOMImplementationImpl");
Method method =
htmlDOMImpl.getMethod("getHTMLDOMImplementation", NO_CLASSES);
domImpl = (DOMImplementation) method.invoke(null, NO_OBJECTS);
Class saxFactoryClass =
classLoader.loadClass(
"org.apache.xerces.jaxp.SAXParserFactoryImpl");
factory = (SAXParserFactory) saxFactoryClass.newInstance();
}
catch (InvocationTargetException ex) {
throw new DOMTestIncompatibleException(
ex.getTargetException(),
null);
}
catch (Exception ex) {
throw new DOMTestIncompatibleException(ex, null);
}
//
// apply settings to selected document builder
// may throw exception if incompatible
if (settings != null) {
for (int i = 0; i < settings.length; i++) {
// settings[i].applySetting(factory);
}
}
try {
factory.newSAXParser();
}
catch (ParserConfigurationException ex) {
throw new DOMTestIncompatibleException(ex, null);
}
catch (SAXException ex) {
throw new DOMTestIncompatibleException(ex, null);
}
}
public DOMTestDocumentBuilderFactory newInstance(DocumentBuilderSetting[]
newSettings) throws DOMTestIncompatibleException {
if (newSettings == null) {
return this;
}
DocumentBuilderSetting[] mergedSettings = mergeSettings(newSettings);
return new XercesHTMLDocumentBuilderFactory(mergedSettings);
}
private class HTMLHandler
extends DefaultHandler
implements AttributeList {
private final DocumentHandler htmlBuilder;
private final Method getHTMLDocumentMethod;
private Attributes currentAttributes;
public HTMLHandler(
Constructor htmlBuilderConstructor,
Method getHTMLDocumentMethod) throws Exception {
htmlBuilder =
(DocumentHandler) htmlBuilderConstructor.newInstance(
new Object[0]);
this.getHTMLDocumentMethod = getHTMLDocumentMethod;
}
public void startDocument() throws SAXException {
htmlBuilder.startDocument();
}
public void endDocument() throws SAXException {
htmlBuilder.endDocument();
}
public void startElement(
String uri,
String localName,
String qName,
Attributes attributes) throws SAXException {
currentAttributes = attributes;
htmlBuilder.startElement(qName, this);
}
public void endElement(String uri, String localName, String qName) throws
SAXException {
htmlBuilder.endElement(qName);
}
public void characters(char ch[], int start, int length) throws
SAXException {
htmlBuilder.characters(ch, start, length);
}
public void ignorableWhitespace(char ch[], int start, int length) throws
SAXException {
htmlBuilder.ignorableWhitespace(ch, start, length);
}
public void processingInstruction(String target, String data) throws
SAXException {
htmlBuilder.processingInstruction(target, data);
}
public Document getHTMLDocument() throws Exception {
return (Document) getHTMLDocumentMethod.invoke(
htmlBuilder,
NO_OBJECTS);
}
public int getLength() {
return currentAttributes.getLength();
}
public String getName(int i) {
return currentAttributes.getQName(i);
}
public String getType(int i) {
return currentAttributes.getType(i);
}
public String getValue(int i) {
return currentAttributes.getValue(i);
}
public String getType(String name) {
return currentAttributes.getType(name);
}
public String getValue(String name) {
return currentAttributes.getValue(name);
}
}
public Document load(java.net.URL url) throws DOMTestLoadException {
Document doc = null;
try {
SAXParser parser = factory.newSAXParser();
HTMLHandler handler =
new HTMLHandler(htmlBuilderConstructor, getHTMLDocumentMethod);
parser.parse(url.toString(), handler);
doc = handler.getHTMLDocument();
}
catch (Exception ex) {
throw new DOMTestLoadException(ex);
}
return doc;
}
public DOMImplementation getDOMImplementation() {
return domImpl;
}
public boolean hasFeature(String feature, String version) {
return domImpl.hasFeature(feature, version);
}
public boolean isCoalescing() {
return false;
}
public boolean isExpandEntityReferences() {
return false;
}
public boolean isIgnoringElementContentWhitespace() {
return false;
}
public boolean isNamespaceAware() {
return factory.isNamespaceAware();
}
public boolean isValidating() {
return factory.isValidating();
}
public static DocumentBuilderSetting[] getConfiguration1() {
return new DocumentBuilderSetting[] {
DocumentBuilderSetting.notCoalescing,
DocumentBuilderSetting.notExpandEntityReferences,
DocumentBuilderSetting.notIgnoringElementContentWhitespace,
DocumentBuilderSetting.notNamespaceAware,
DocumentBuilderSetting.notValidating};
}
public static DocumentBuilderSetting[] getConfiguration2() {
return new DocumentBuilderSetting[] {
DocumentBuilderSetting.notCoalescing,
DocumentBuilderSetting.expandEntityReferences,
DocumentBuilderSetting.ignoringElementContentWhitespace,
DocumentBuilderSetting.namespaceAware,
DocumentBuilderSetting.validating};
}
}