1 18 package org.apache.batik.apps.svgbrowser; 19 20 import java.io.File ; 21 import java.io.StringReader ; 22 import java.io.StringWriter ; 23 24 import javax.xml.parsers.DocumentBuilder ; 25 import javax.xml.parsers.DocumentBuilderFactory ; 26 import javax.xml.transform.Source ; 27 import javax.xml.transform.Transformer ; 28 import javax.xml.transform.TransformerFactory ; 29 import javax.xml.transform.URIResolver ; 30 import javax.xml.transform.dom.DOMSource ; 31 import javax.xml.transform.stream.StreamResult ; 32 import javax.xml.transform.stream.StreamSource ; 33 34 import org.apache.batik.dom.svg.SAXSVGDocumentFactory; 35 import org.apache.batik.dom.svg.SVGDOMImplementation; 36 import org.apache.batik.dom.util.DOMUtilities; 37 import org.apache.batik.dom.util.HashTable; 38 import org.apache.batik.util.ParsedURL; 39 import org.apache.batik.util.SVGConstants; 40 import org.apache.batik.util.XMLResourceDescriptor; 41 import org.w3c.dom.Attr ; 42 import org.w3c.dom.Document ; 43 import org.w3c.dom.Element ; 44 import org.w3c.dom.NamedNodeMap ; 45 import org.w3c.dom.Node ; 46 import org.w3c.dom.ProcessingInstruction ; 47 import org.w3c.dom.svg.SVGDocument; 48 49 62 public class XMLInputHandler implements SquiggleInputHandler { 63 public static final String [] XVG_MIME_TYPES = 64 { "image/xml+xsl+svg" }; 65 66 public static final String [] XVG_FILE_EXTENSIONS = 67 { ".xml", ".xsl" }; 68 69 public static final String ERROR_NO_XML_STYLESHEET_PROCESSING_INSTRUCTION 70 = "XMLInputHandler.error.no.xml.stylesheet.processing.instruction"; 71 72 public static final String ERROR_TRANSFORM_OUTPUT_NOT_SVG 73 = "XMLInputHandler.error.transform.output.not.svg"; 74 75 public static final String ERROR_TRANSFORM_PRODUCED_NO_CONTENT 76 = "XMLInputHandler.error.transform.produced.no.content"; 77 78 public static final String ERROR_TRANSFORM_OUTPUT_WRONG_NS 79 = "XMLInputHandler.error.transform.output.wrong.ns"; 80 81 public static final String ERROR_RESULT_GENERATED_EXCEPTION 82 = "XMLInputHandler.error.result.generated.exception"; 83 84 public static final String XSL_PROCESSING_INSTRUCTION_TYPE 85 = "text/xsl"; 86 87 public static final String PSEUDO_ATTRIBUTE_TYPE 88 = "type"; 89 90 public static final String PSEUDO_ATTRIBUTE_HREF 91 = "href"; 92 93 96 public String [] getHandledMimeTypes() { 97 return XVG_MIME_TYPES; 98 } 99 100 103 public String [] getHandledExtensions() { 104 return XVG_FILE_EXTENSIONS; 105 } 106 107 110 public String getDescription() { 111 return ""; 112 } 113 114 117 public boolean accept(File f) { 118 return f.isFile() && accept(f.getPath()); 119 } 120 121 124 public boolean accept(ParsedURL purl) { 125 if (purl == null) { 126 return false; 127 } 128 129 133 String path = purl.getPath(); 134 return accept(path); 135 } 136 137 141 public boolean accept(String path) { 142 if (path == null) { 143 return false; 144 } 145 146 for (int i=0; i<XVG_FILE_EXTENSIONS.length; i++) { 147 if (path.endsWith(XVG_FILE_EXTENSIONS[i])) { 148 return true; 149 } 150 } 151 152 return false; 153 } 154 155 158 public void handle(ParsedURL purl, JSVGViewerFrame svgViewerFrame) throws Exception { 159 String uri = purl.toString(); 160 161 TransformerFactory tFactory 162 = TransformerFactory.newInstance(); 163 164 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 166 dbf.setValidating(false); 167 dbf.setNamespaceAware(true); 168 169 DocumentBuilder db = dbf.newDocumentBuilder(); 170 171 Document inDoc = db.parse(uri); 172 173 String xslStyleSheetURI 175 = extractXSLProcessingInstruction(inDoc); 176 177 if (xslStyleSheetURI == null) { 178 xslStyleSheetURI = uri; 180 } 181 182 ParsedURL parsedXSLStyleSheetURI 183 = new ParsedURL(uri, xslStyleSheetURI); 184 185 Transformer transformer 186 = tFactory.newTransformer 187 (new StreamSource (parsedXSLStyleSheetURI.toString())); 188 189 transformer.setURIResolver 191 (new DocumentURIResolver(parsedXSLStyleSheetURI.toString())); 192 193 StringWriter sw = new StringWriter (); 208 StreamResult result = new StreamResult (sw); 209 transformer.transform(new DOMSource (inDoc), 210 result); 211 sw.flush(); 212 sw.close(); 213 214 String parser = XMLResourceDescriptor.getXMLParserClassName(); 215 SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser); 216 SVGDocument outDoc = null; 217 218 try { 219 outDoc = f.createSVGDocument 220 (uri, new StringReader (sw.toString())); 221 } catch (Exception e) { 222 System.err.println("======================================"); 223 System.err.println(sw.toString()); 224 System.err.println("======================================"); 225 226 throw new IllegalArgumentException 227 (Resources.getString(ERROR_RESULT_GENERATED_EXCEPTION)); 228 } 229 230 233 svgViewerFrame.getJSVGCanvas().setSVGDocument(outDoc); 234 svgViewerFrame.setSVGDocument(outDoc, 235 uri, 236 outDoc.getTitle()); 237 } 238 239 246 protected void checkAndPatch(Document doc) { 247 Element root = doc.getDocumentElement(); 248 Node realRoot = root.getFirstChild(); 249 String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; 250 251 if (realRoot == null) { 252 throw new IllegalArgumentException 253 (Resources.getString(ERROR_TRANSFORM_PRODUCED_NO_CONTENT)); 254 } 255 256 if (realRoot.getNodeType() != Node.ELEMENT_NODE 257 || 258 !SVGConstants.SVG_SVG_TAG.equals(realRoot.getLocalName())) { 259 throw new IllegalArgumentException 260 (Resources.getString(ERROR_TRANSFORM_OUTPUT_NOT_SVG)); 261 } 262 263 if (!svgNS.equals(realRoot.getNamespaceURI())) { 264 throw new IllegalArgumentException 265 (Resources.getString(ERROR_TRANSFORM_OUTPUT_WRONG_NS)); 266 } 267 268 Node child = realRoot.getFirstChild(); 269 while ( child != null ) { 270 root.appendChild(child); 271 child = realRoot.getFirstChild(); 272 } 273 274 NamedNodeMap attrs = realRoot.getAttributes(); 275 int n = attrs.getLength(); 276 for (int i=0; i<n; i++) { 277 root.setAttributeNode((Attr )attrs.item(i)); 278 } 279 280 root.removeChild(realRoot); 281 } 282 283 287 protected String extractXSLProcessingInstruction(Document doc) { 288 Node child = doc.getFirstChild(); 289 while (child != null) { 290 if (child.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) { 291 ProcessingInstruction pi 292 = (ProcessingInstruction )child; 293 294 HashTable table = new HashTable(); 295 DOMUtilities.parseStyleSheetPIData(pi.getData(), 296 table); 297 298 Object type = table.get(PSEUDO_ATTRIBUTE_TYPE); 299 if (XSL_PROCESSING_INSTRUCTION_TYPE.equals(type)) { 300 Object href = table.get(PSEUDO_ATTRIBUTE_HREF); 301 if (href != null) { 302 return href.toString(); 303 } else { 304 return null; 305 } 306 } 307 } 308 child = child.getNextSibling(); 309 } 310 311 return null; 312 } 313 314 318 public class DocumentURIResolver implements URIResolver { 319 String documentURI; 320 321 public DocumentURIResolver(String documentURI) { 322 this.documentURI = documentURI; 323 } 324 325 public Source resolve(String href, String base) { 326 if (base == null || "".equals(base)) { 327 base = documentURI; 328 } 329 330 ParsedURL purl = new ParsedURL(base, href); 331 332 return new StreamSource (purl.toString()); 333 } 334 } 335 } 336 | Popular Tags |