From: Jeremias Maerki Date: Fri, 21 Nov 2008 17:24:32 +0000 (+0000) Subject: Fixed possible ClassCastException that was caused by my earlier attempt to support... X-Git-Tag: fop-1_0~378 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=2f8e166bfd7e1e958b94a4fa590a51dc80915b86;p=xmlgraphics-fop.git Fixed possible ClassCastException that was caused by my earlier attempt to support SVG 1.2. Batik's SAXSVGDocumentFactory doesn't currently deal well with the case when namespaces are declared outside of its scope. Worked around that by doing the SVG version detection in FOP code. SVG12DOMImplementation is obtained by reflection in order to keep backwards compatilibility with earlier Batik versions that don't support SVG 1.2. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@719646 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/fop/fo/extensions/svg/SVGDOMContentHandlerFactory.java b/src/java/org/apache/fop/fo/extensions/svg/SVGDOMContentHandlerFactory.java index c5064da3f..6556c7251 100644 --- a/src/java/org/apache/fop/fo/extensions/svg/SVGDOMContentHandlerFactory.java +++ b/src/java/org/apache/fop/fo/extensions/svg/SVGDOMContentHandlerFactory.java @@ -19,25 +19,37 @@ package org.apache.fop.fo.extensions.svg; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; + +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; + +import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.apache.batik.dom.svg.SVGDOMImplementation; -import org.apache.batik.util.XMLResourceDescriptor; -import org.apache.fop.svg.FOPSAXSVGDocumentFactory; import org.apache.fop.util.ContentHandlerFactory; +import org.apache.fop.util.DelegatingContentHandler; /** - * ContentHandlerFactory which constructs ContentHandlers that build SVG DOM Documents. + * ContentHandlerFactory which constructs ContentHandlers that build SVG DOM + * Documents. */ public class SVGDOMContentHandlerFactory implements ContentHandlerFactory { + private static SAXTransformerFactory tFactory + = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + /** * Default Constructor. */ public SVGDOMContentHandlerFactory() { - //nop + // nop } /** {@inheritDoc} */ @@ -50,13 +62,18 @@ public class SVGDOMContentHandlerFactory implements ContentHandlerFactory { return new Handler(); } - private static class Handler extends FOPSAXSVGDocumentFactory - implements ContentHandlerFactory.ObjectSource { + private static class Handler extends DelegatingContentHandler implements + ContentHandlerFactory.ObjectSource { + private Document doc; private ObjectBuiltListener obListener; public Handler() throws SAXException { - super(XMLResourceDescriptor.getXMLParserClassName()); + super(); + } + + public Document getDocument() { + return this.doc; } /** {@inheritDoc} */ @@ -69,6 +86,58 @@ public class SVGDOMContentHandlerFactory implements ContentHandlerFactory { this.obListener = listener; } + /** {@inheritDoc} */ + public void startDocument() throws SAXException { + // Suppress startDocument() call if doc has not been set, yet. It + // will be done later. + if (doc != null) { + super.startDocument(); + } + } + + private DOMImplementation getDOMImplementation(String ver) { + //TODO It would be great if Batik provided this method as static helper method. + if (ver == null || ver.length() == 0 + || ver.equals("1.0") || ver.equals("1.1")) { + return SVGDOMImplementation.getDOMImplementation(); + } else if (ver.equals("1.2")) { + try { + Class clazz = Class.forName( + "org.apache.batik.dom.svg12.SVG12DOMImplementation"); + return (DOMImplementation)clazz.getMethod( + "getDOMImplementation", null).invoke(null, null); + } catch (Exception e) { + return SVGDOMImplementation.getDOMImplementation(); + } + } + throw new RuntimeException("Unsupport SVG version '" + ver + "'"); + } + + /** {@inheritDoc} */ + public void startElement(String uri, String localName, String qName, Attributes atts) + throws SAXException { + if (doc == null) { + TransformerHandler handler; + try { + handler = tFactory.newTransformerHandler(); + } catch (TransformerConfigurationException e) { + throw new SAXException("Error creating a new TransformerHandler", e); + } + String version = atts.getValue("version"); + DOMImplementation domImplementation = getDOMImplementation(version); + doc = domImplementation.createDocument(uri, qName, null); + // It's easier to work with an empty document, so remove the + // root element + doc.removeChild(doc.getDocumentElement()); + handler.setResult(new DOMResult(doc)); + setDelegateContentHandler(handler); + setDelegateLexicalHandler(handler); + setDelegateDTDHandler(handler); + handler.startDocument(); + } + super.startElement(uri, localName, qName, atts); + } + /** {@inheritDoc} */ public void endDocument() throws SAXException { super.endDocument(); diff --git a/src/java/org/apache/fop/fo/extensions/svg/SVGElement.java b/src/java/org/apache/fop/fo/extensions/svg/SVGElement.java index 917e8c0d8..72cf19bc7 100644 --- a/src/java/org/apache/fop/fo/extensions/svg/SVGElement.java +++ b/src/java/org/apache/fop/fo/extensions/svg/SVGElement.java @@ -26,7 +26,6 @@ import java.awt.geom.Rectangle2D; import java.net.URL; import org.w3c.dom.Element; -import org.w3c.dom.svg.SVGDocument; import org.apache.batik.bridge.UnitProcessor; import org.apache.batik.dom.svg.SVGContext; @@ -85,7 +84,6 @@ public class SVGElement extends SVGObj { log.error("Could not set base URL for svg", e); } - Element e = ((SVGDocument)doc).getRootElement(); final float ptmm = getUserAgent().getSourcePixelUnitToMillimeter(); // temporary svg context SVGContext dc = new SVGContext() { @@ -138,7 +136,8 @@ public class SVGElement extends SVGObj { public void deselectAll() { } }; - ((SVGOMElement)e).setSVGContext(dc); + SVGOMElement e = (SVGOMElement)svgRoot; + e.setSVGContext(dc); //if (!e.hasAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns")) { e.setAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns", @@ -146,7 +145,7 @@ public class SVGElement extends SVGObj { //} int fontSize = 12; Point2D p2d = getSize(fontSize, svgRoot, getUserAgent().getSourcePixelUnitToMillimeter()); - ((SVGOMElement)e).setSVGContext(null); + e.setSVGContext(null); return p2d; }