+ private static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ static {
+ dbf.setValidating(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) {
+ // Nothing to do
+ }
+ }
+
+ // Notice: Remember to change both implementations of applyAssigments when modifying the functionality.
+ protected static String applyAssigments(String svg, List<SVGNodeAssignment> assignments) {
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document doc = db.parse(new InputSource(new StringReader(svg)));
+
+ NodeList entries = doc.getElementsByTagName("*");
+ for (int i=0; i<entries.getLength(); i++) {
+ Element element = (Element) entries.item(i);
+ if (element.hasAttribute("id")) {
+ element.setIdAttribute("id", true);
+ }
+ }
+ for (SVGNodeAssignment ass : assignments) {
+ Element e = doc.getElementById(ass.elementId);
+ if (e != null) {
+ if ("$text".equals(ass.attributeNameOrId)) {
+ if (e.getTagName().equals("tspan")) {
+ if (ass.value.trim().isEmpty()) {
+ e.setTextContent("-");
+ } else {
+ e.setTextContent(ass.value);
+ }
+ }
+ } else if (ass.attributeNameOrId.startsWith("#")) {
+ e.setAttribute(ass.attributeNameOrId.substring(1), ass.value);
+ } else {
+ e.setAttribute(ass.attributeNameOrId, ass.value);
+ }
+ } else {
+ LOGGER.warn("Element with id='" + ass.elementId + " was not found.");
+ }
+ }
+
+ DOMSource domSource = new DOMSource(doc);
+ StringWriter writer = new StringWriter();
+ StreamResult result = new StreamResult(writer);
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer transformer = tf.newTransformer();
+ transformer.transform(domSource, result);
+ return writer.toString();
+
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ // Notice: Remember to change both implementations of applyAssigments when modifying the functionality.
+ protected boolean applyAssignments(SVGDiagram diagram, List<SVGNodeAssignment> assignments) throws SVGException {
+ if (assignments.isEmpty())
+ return false;
+
+ boolean changed = false;
+
+ // Without this elements are sometimes not found by id!
+ diagram.updateTime(0);
+
+ for (SVGNodeAssignment ass : assignments) {
+ SVGElement e = diagram.getElement(ass.elementId);
+ if (e != null) {
+ if ("$text".equals(ass.attributeNameOrId)) {
+ if (e instanceof Tspan) {
+ Tspan t = (Tspan) e;
+ if (ass.value.trim().isEmpty()) {
+ t.setText("-");
+ } else {
+ t.setText(ass.value);
+ }
+ SVGElement parent = t.getParent();
+ if (parent instanceof Text)
+ ((Text) parent).rebuild();
+ changed = true;
+ }
+ } else if (ass.attributeNameOrId.startsWith("#")) {
+ e.setAttribute(ass.attributeNameOrId.substring(1), AnimationElement.AT_CSS, ass.value);
+ changed = true;
+ } else {
+ e.setAttribute(ass.attributeNameOrId, AnimationElement.AT_AUTO, ass.value);
+ changed = true;
+ }
+ }
+ }
+
+ // Without this the attribute values are not correctly reflected in rendering
+ diagram.updateTime(0);
+
+ return changed;
+ }
+