X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.diagram.svg%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fsvg%2Fexport%2FSVGShapeWithPassthruSupport.java;fp=bundles%2Forg.simantics.diagram.svg%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fsvg%2Fexport%2FSVGShapeWithPassthruSupport.java;h=584bcf54123fb8fee87a72ec944502924845f0de;hb=e75a2a68817ab088db4f84419c2e988ec83fbd39;hp=0000000000000000000000000000000000000000;hpb=2318f67fbf458ee97fd438678be1bc5a636c9fa7;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.diagram.svg/src/org/simantics/diagram/svg/export/SVGShapeWithPassthruSupport.java b/bundles/org.simantics.diagram.svg/src/org/simantics/diagram/svg/export/SVGShapeWithPassthruSupport.java new file mode 100644 index 000000000..584bcf541 --- /dev/null +++ b/bundles/org.simantics.diagram.svg/src/org/simantics/diagram/svg/export/SVGShapeWithPassthruSupport.java @@ -0,0 +1,101 @@ +package org.simantics.diagram.svg.export; + +import java.awt.Shape; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.batik.svggen.SVGGeneratorContext; +import org.apache.batik.svggen.SVGShape; +import org.simantics.db.common.utils.Logger; +import org.simantics.scenegraph.utils.SVGPassthruShape; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +public class SVGShapeWithPassthruSupport extends SVGShape { + private DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + public SVGShapeWithPassthruSupport(SVGGeneratorContext generatorCtx) { + super(generatorCtx); + dbf.setValidating(false); + dbf.setExpandEntityReferences(false); + try { + dbf.setFeature("http://xml.org/sax/features/namespaces", false); + dbf.setFeature("http://xml.org/sax/features/validation", false); + dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); + dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + } catch (ParserConfigurationException e) { + Logger.defaultLogError(e); + } + } + + public Element toSVG(Shape shape) { + if (shape instanceof SVGPassthruShape) { + String source = ((SVGPassthruShape) shape).getSource(); + + try { + + Document owner = generatorContext.getDOMFactory(); + + @SuppressWarnings("unchecked") + Map defsMap = (Map)owner.getUserData("defs-map"); + if (defsMap == null) { + defsMap = new HashMap(); + owner.setUserData("defs-map", defsMap, null); + } + + synchronized (defsMap) { + String symbolId = defsMap.get(source); + if (symbolId == null) { + symbolId = "S" + defsMap.size(); + defsMap.put(source, symbolId); + + DocumentBuilder db = dbf.newDocumentBuilder(); + + Document doc = db.parse(new ByteArrayInputStream(source.getBytes("UTF-8"))); + Node node = doc.getDocumentElement(); + Node localNode = owner.importNode(node, true); + + if (localNode instanceof Element) { + Element g = generatorContext.getDOMFactory().createElementNS(SVG_NAMESPACE_URI, SVG_G_TAG); + Element e = (Element)localNode; + e.setAttribute("id", symbolId); + g.appendChild(localNode); + return g; + } else { + return null; + } + } else { + Element element = owner.createElement("use"); + element.setAttribute("xlink:href", "#" + symbolId); + return element; + } + } + } catch (UnsupportedEncodingException e) { + Logger.defaultLogError(e); + return null; + } catch (IOException e) { + Logger.defaultLogError(e); + return null; + } catch (ParserConfigurationException e) { + Logger.defaultLogError(e); + return null; + } catch (SAXException e) { + Logger.defaultLogError(e); + return null; + } + } else { + return super.toSVG(shape); + } + + } + +}