1 /* 2 * Copyright (c) 2002-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 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 org.w3c.dom.DOMImplementation; 20 import org.w3c.dom.Document; 21 22 /** 23 * This class implements the generic parser builder 24 * for JTidy (http://sf.net/projects/JTidy) which reads HTML 25 * and supports the fundamental DOM interfaces but not either HTML L1 DOM 26 * or HTML L2 DOM 27 */ 28 public class JTidyDocumentBuilderFactory 29 extends DOMTestDocumentBuilderFactory { 30 31 private final Constructor tidyConstructor; 32 private final Method parseDOMMethod; 33 private final DOMImplementation domImpl; 34 private static final Class[] NO_CLASSES = new Class[0]; 35 private static final Object[] NO_OBJECTS = new Object[0]; 36 37 /** 38 * Creates a implementation of DOMTestDocumentBuilderFactory 39 * using JTidy's HTML parser and DOM implementation 40 * @param settings array of settings, may be null. 41 */ 42 public JTidyDocumentBuilderFactory( 43 DocumentBuilderSetting[] settings) throws DOMTestIncompatibleException { 44 super(settings); 45 46 try { 47 ClassLoader classLoader = ClassLoader.getSystemClassLoader(); 48 Class tidyClass = classLoader.loadClass("org.w3c.tidy.Tidy"); 49 50 tidyConstructor = 51 tidyClass.getConstructor(NO_CLASSES); 52 53 parseDOMMethod = 54 tidyClass.getMethod("parseDOM", 55 new Class[] {java.io.InputStream.class, 56 java.io.OutputStream.class}); 57 58 // 59 // JTidy doesn't implement DOMImplementation so 60 // we will do it here 61 domImpl = new JTidyDOMImplementation(); 62 63 } 64 catch (Exception ex) { 65 throw new DOMTestIncompatibleException(ex, null); 66 } 67 68 // 69 // apply settings to selected document builder 70 // may throw exception if incompatible 71 if (settings != null) { 72 for (int i = 0; i < settings.length; i++) { 73 // settings[i].applySetting(factory); 74 } 75 } 76 } 77 78 public DOMTestDocumentBuilderFactory newInstance(DocumentBuilderSetting[] 79 newSettings) throws DOMTestIncompatibleException { 80 if (newSettings == null) { 81 return this; 82 } 83 DocumentBuilderSetting[] mergedSettings = mergeSettings(newSettings); 84 return new JTidyDocumentBuilderFactory(mergedSettings); 85 } 86 87 public Document load(java.net.URL url) throws DOMTestLoadException { 88 Document doc = null; 89 try { 90 java.io.InputStream stream = url.openStream(); 91 Object tidyObj = tidyConstructor.newInstance(new Object[0]); 92 doc = (Document) parseDOMMethod.invoke(tidyObj, 93 new Object[] {stream, null}); 94 } 95 catch (InvocationTargetException ex) { 96 throw new DOMTestLoadException(ex.getTargetException()); 97 } 98 catch (Exception ex) { 99 throw new DOMTestLoadException(ex); 100 } 101 return doc; 102 } 103 104 public DOMImplementation getDOMImplementation() { 105 return domImpl; 106 } 107 108 public boolean hasFeature(String feature, String version) { 109 return domImpl.hasFeature(feature, version); 110 } 111 112 public String getContentType() { 113 return "text/html"; 114 } 115 116 public boolean isCoalescing() { 117 return false; 118 } 119 120 public boolean isExpandEntityReferences() { 121 return false; 122 } 123 124 public boolean isIgnoringElementContentWhitespace() { 125 return false; 126 } 127 128 public boolean isNamespaceAware() { 129 return false; 130 } 131 132 public boolean isValidating() { 133 return false; 134 } 135 } 136