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