You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by ca...@apache.org on 2007/09/30 07:10:21 UTC

svn commit: r580678 - in /xmlgraphics/batik/trunk/sources/org/apache/batik: bridge/BridgeContext.java bridge/DocumentBridge.java bridge/GVTBuilder.java bridge/SVGDocumentBridge.java bridge/SVGUseElementBridge.java dom/svg/SVGOMDocument.java

Author: cam
Date: Sat Sep 29 22:10:20 2007
New Revision: 580678

URL: http://svn.apache.org/viewvc?rev=580678&view=rev
Log:
Allow a document's document element to be replaced.  Fixes bug 42543.

Added:
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/DocumentBridge.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGDocumentBridge.java
Modified:
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BridgeContext.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/GVTBuilder.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMDocument.java

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BridgeContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BridgeContext.java?rev=580678&r1=580677&r2=580678&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BridgeContext.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BridgeContext.java Sat Sep 29 22:10:20 2007
@@ -865,49 +865,49 @@
     // Bindings //////////////////////////////////////////////////////////////
 
     /**
-     * Binds the specified GraphicsNode to the specified Element. This method
+     * Binds the specified GraphicsNode to the specified Node. This method
      * automatically bind the graphics node to the element and the element to
      * the graphics node.
      *
-     * @param element the element to bind to the specified graphics node
-     * @param node the graphics node to bind to the specified element
+     * @param node the DOM Node to bind to the specified graphics node
+     * @param gn the graphics node to bind to the specified element
      */
-    public void bind(Element element, GraphicsNode node) {
+    public void bind(Node node, GraphicsNode gn) {
         if (elementNodeMap == null) {
             elementNodeMap = new WeakHashMap();
             nodeElementMap = new WeakHashMap();
         }
-        elementNodeMap.put(element, new SoftReference(node));
-        nodeElementMap.put(node, new SoftReference(element));
+        elementNodeMap.put(node, new SoftReference(gn));
+        nodeElementMap.put(gn, new SoftReference(node));
     }
 
     /**
-     * Removes the binding of the specified Element.
+     * Removes the binding of the specified Node.
      *
-     * @param element the element to unbind
+     * @param node the DOM Node to unbind
      */
-    public void unbind(Element element) {
+    public void unbind(Node node) {
         if (elementNodeMap == null) {
             return;
         }
-        GraphicsNode node = null;
-        SoftReference sr = (SoftReference)elementNodeMap.get(element);
+        GraphicsNode gn = null;
+        SoftReference sr = (SoftReference)elementNodeMap.get(node);
         if (sr != null)
-            node = (GraphicsNode)sr.get();
-        elementNodeMap.remove(element);
-        if (node != null)
-            nodeElementMap.remove(node);
+            gn = (GraphicsNode)sr.get();
+        elementNodeMap.remove(node);
+        if (gn != null)
+            nodeElementMap.remove(gn);
     }
 
     /**
-     * Returns the GraphicsNode associated to the specified Element or
+     * Returns the GraphicsNode associated to the specified Node or
      * null if any.
      *
-     * @param element the element associated to the graphics node to return
+     * @param node the DOM Node associated to the graphics node to return
      */
-    public GraphicsNode getGraphicsNode(Element element) {
+    public GraphicsNode getGraphicsNode(Node node) {
         if (elementNodeMap != null) {
-            SoftReference sr = (SoftReference)elementNodeMap.get(element);
+            SoftReference sr = (SoftReference)elementNodeMap.get(node);
             if (sr != null)
                 return (GraphicsNode)sr.get();
         }
@@ -915,16 +915,20 @@
     }
 
     /**
-     * Returns the Element associated to the specified GraphicsNode or
+     * Returns the Node associated to the specified GraphicsNode or
      * null if any.
      *
-     * @param node the graphics node associated to the element to return
+     * @param gn the graphics node associated to the element to return
      */
-    public Element getElement(GraphicsNode node) {
+    public Element getElement(GraphicsNode gn) {
         if (nodeElementMap != null) {
-            SoftReference sr = (SoftReference)nodeElementMap.get(node);
-            if (sr != null)
-                return (Element)sr.get();
+            SoftReference sr = (SoftReference)nodeElementMap.get(gn);
+            if (sr != null) {
+                Node n = (Node) sr.get();
+                if (n.getNodeType() == Node.ELEMENT_NODE) {
+                    return (Element) n;
+                }
+            }
         }
         return null;
     }
@@ -952,6 +956,13 @@
     }
 
     /**
+     * Returns the bridge for the document node.
+     */
+    public DocumentBridge getDocumentBridge() {
+        return new SVGDocumentBridge();
+    }
+
+    /**
      * Returns the bridge associated with the specified element.
      *
      * @param element the element
@@ -1449,13 +1460,13 @@
         if (focusManager != null) {
             focusManager.dispose();
         }
-        if ( elementDataMap != null ){
+        if (elementDataMap != null) {
             elementDataMap.clear();
         }
-        if ( nodeElementMap != null ){
+        if (nodeElementMap != null) {
             nodeElementMap.clear();
         }
-        if ( elementNodeMap != null ){
+        if (elementNodeMap != null) {
             elementNodeMap.clear();
         }        
     }
@@ -1466,7 +1477,9 @@
      */
     protected static SVGContext getSVGContext(Node node) {
         if (node instanceof SVGOMElement) {
-            return ((SVGOMElement)node).getSVGContext();
+            return ((SVGOMElement) node).getSVGContext();
+        } else if (node instanceof SVGOMDocument) {
+            return ((SVGOMDocument) node).getSVGContext();
         } else {
             return null;
         }

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/DocumentBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/DocumentBridge.java?rev=580678&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/DocumentBridge.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/DocumentBridge.java Sat Sep 29 22:10:20 2007
@@ -0,0 +1,50 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge;
+
+import org.apache.batik.gvt.RootGraphicsNode;
+
+import org.w3c.dom.Document;
+
+public interface DocumentBridge extends Bridge {
+
+    /**
+     * Creates a <tt>GraphicsNode</tt> according to the specified parameters.
+     * This is called before children have been added to the
+     * returned GraphicsNode (obviously since you construct and return it).
+     *
+     * @param ctx the bridge context to use
+     * @param doc the document node that describes the graphics node to build
+     * @return a graphics node that represents the specified document node
+     */
+    RootGraphicsNode createGraphicsNode(BridgeContext ctx, Document doc);
+
+    /**
+     * Builds using the specified BridgeContext and element, the
+     * specified graphics node.  This is called after all the children
+     * of the node have been constructed and added, so it is safe to
+     * do work that depends on being able to see your children nodes
+     * in this method.
+     *
+     * @param ctx the bridge context to use
+     * @param doc the document node that describes the graphics node to build
+     * @param node the graphics node to build
+     */
+    void buildGraphicsNode(BridgeContext ctx, Document doc, RootGraphicsNode node);
+}

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/GVTBuilder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/GVTBuilder.java?rev=580678&r1=580677&r2=580678&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/GVTBuilder.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/GVTBuilder.java Sat Sep 29 22:10:20 2007
@@ -58,10 +58,14 @@
         ctx.setGVTBuilder(this);
 
         // build the GVT tree
-        RootGraphicsNode rootNode = new RootGraphicsNode();
-        Element svgElement = document.getDocumentElement();
-        GraphicsNode topNode = null;
+        DocumentBridge dBridge = ctx.getDocumentBridge();
+        RootGraphicsNode rootNode = null;
         try {
+            // create the root node
+            rootNode = dBridge.createGraphicsNode(ctx, document);
+            Element svgElement = document.getDocumentElement();
+            GraphicsNode topNode = null;
+
             // get the appropriate bridge according to the specified element
             Bridge bridge = ctx.getBridge(svgElement);
             if (bridge == null || !(bridge instanceof GraphicsNodeBridge)) {
@@ -77,6 +81,9 @@
 
             buildComposite(ctx, svgElement, (CompositeGraphicsNode)topNode);
             gnBridge.buildGraphicsNode(ctx, svgElement, topNode);
+
+            // finally, build the root node
+            dBridge.buildGraphicsNode(ctx, document, rootNode);
         } catch (BridgeException ex) {
             // update the exception with the missing parameters
             ex.setGraphicsNode(rootNode);

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGDocumentBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGDocumentBridge.java?rev=580678&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGDocumentBridge.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGDocumentBridge.java Sat Sep 29 22:10:20 2007
@@ -0,0 +1,227 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.batik.css.engine.CSSEngineEvent;
+import org.apache.batik.dom.svg.AnimatedLiveAttributeValue;
+import org.apache.batik.dom.svg.SVGContext;
+import org.apache.batik.dom.svg.SVGOMDocument;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.RootGraphicsNode;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.events.MutationEvent;
+
+/**
+ * Bridge class for an SVGDocument node.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public class SVGDocumentBridge implements DocumentBridge, BridgeUpdateHandler,
+                                          SVGContext {
+
+    /**
+     * The document node this bridge is associated with.
+     */
+    protected Document document;
+
+    /**
+     * The graphics node constructed by this bridge.
+     */
+    protected RootGraphicsNode node;
+
+    /**
+     * The bridge context.
+     */
+    protected BridgeContext ctx;
+
+    /**
+     * Constructs a new bridge the SVG document.
+     */
+    public SVGDocumentBridge() {
+    }
+
+    // Bridge ////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns the namespace URI of the element this <tt>Bridge</tt> is
+     * dedicated to.  Returns <code>null</code>, as a Document node has no
+     * namespace URI.
+     */
+    public String getNamespaceURI() {
+        return null;
+    }
+
+    /**
+     * Returns the local name of the element this <tt>Bridge</tt> is dedicated
+     * to.  Returns <code>null</code>, as a Document node has no local name.
+     */
+    public String getLocalName() {
+        return null;
+    }
+
+    /**
+     * Returns a new instance of this bridge.
+     */
+    public Bridge getInstance() {
+        return new SVGDocumentBridge();
+    }
+
+    // DocumentBridge ////////////////////////////////////////////////////////
+
+    /**
+     * Creates a <tt>GraphicsNode</tt> according to the specified parameters.
+     * This is called before children have been added to the
+     * returned GraphicsNode (obviously since you construct and return it).
+     *
+     * @param ctx the bridge context to use
+     * @param doc the document node that describes the graphics node to build
+     * @return a graphics node that represents the specified document node
+     */
+    public RootGraphicsNode createGraphicsNode(BridgeContext ctx,
+                                               Document doc) {
+        RootGraphicsNode gn = new RootGraphicsNode();
+        this.document = doc;
+        this.node = gn;
+        this.ctx = ctx;
+        ((SVGOMDocument) doc).setSVGContext(this);
+        return gn;
+    }
+
+    /**
+     * Builds using the specified BridgeContext and element, the
+     * specified graphics node.  This is called after all the children
+     * of the node have been constructed and added, so it is safe to
+     * do work that depends on being able to see your children nodes
+     * in this method.
+     *
+     * @param ctx the bridge context to use
+     * @param doc the document node that describes the graphics node to build
+     * @param node the graphics node to build
+     */
+    public void buildGraphicsNode(BridgeContext ctx,
+                                  Document doc,
+                                  RootGraphicsNode node) {
+        if (ctx.isDynamic()) {
+            ctx.bind(doc, node);
+        }
+    }
+
+    // BridgeUpdateHandler ///////////////////////////////////////////////////
+
+    /**
+     * Invoked when an MutationEvent of type 'DOMAttrModified' is fired.
+     */
+    public void handleDOMAttrModifiedEvent(MutationEvent evt) {
+    }
+
+    /**
+     * Invoked when an MutationEvent of type 'DOMNodeInserted' is fired.
+     */
+    public void handleDOMNodeInsertedEvent(MutationEvent evt) {
+        if (evt.getTarget() instanceof Element) {
+            Element childElt = (Element) evt.getTarget();
+
+            GVTBuilder builder = ctx.getGVTBuilder();
+            GraphicsNode childNode = builder.build(ctx, childElt);
+            if (childNode == null) {
+                return;
+            }
+
+            // There can only be one document element.
+            node.add(childNode);
+        }
+    }
+
+    /**
+     * Invoked when an MutationEvent of type 'DOMNodeRemoved' is fired.
+     */
+    public void handleDOMNodeRemovedEvent(MutationEvent evt) {
+    }
+
+    /**
+     * Invoked when an MutationEvent of type 'DOMCharacterDataModified' 
+     * is fired.
+     */
+    public void handleDOMCharacterDataModified(MutationEvent evt) {
+    }
+
+    /**
+     * Invoked when an CSSEngineEvent is fired.
+     */
+    public void handleCSSEngineEvent(CSSEngineEvent evt) {
+    }
+
+    /**
+     * Invoked when the animated value of an animated attribute has changed.
+     */
+    public void handleAnimatedAttributeChanged(AnimatedLiveAttributeValue alav) {
+    }
+
+    /**
+     * Invoked when an 'other' animation value has changed.
+     */
+    public void handleOtherAnimationChanged(String type) {
+    }
+
+    /**
+     * Disposes this BridgeUpdateHandler and releases all resources.
+     */
+    public void dispose() {
+        ((SVGOMDocument) document).setSVGContext(null);
+        ctx.unbind(document);
+    }
+
+    // SVGContext //////////////////////////////////////////////////////////
+
+    /**
+     * Returns the size of a px CSS unit in millimeters.
+     */
+    public float getPixelUnitToMillimeter() {
+        return ctx.getUserAgent().getPixelUnitToMillimeter();
+    }
+
+    /**
+     * Returns the size of a px CSS unit in millimeters.
+     * This will be removed after next release.
+     * @see #getPixelUnitToMillimeter()
+     */
+    public float getPixelToMM() {
+        return getPixelUnitToMillimeter();
+    }
+
+    public Rectangle2D getBBox() { return null; }
+    public AffineTransform getScreenTransform() {
+        return ctx.getUserAgent().getTransform();
+    }
+    public void setScreenTransform(AffineTransform at) {
+        ctx.getUserAgent().setTransform(at);
+    }
+    public AffineTransform getCTM() { return null; }
+    public AffineTransform getGlobalTransform() { return null; }
+    public float getViewportWidth() { return 0f; }
+    public float getViewportHeight() { return 0f; }
+    public float getFontSize() { return 0; }
+}

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java?rev=580678&r1=580677&r2=580678&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUseElementBridge.java Sat Sep 29 22:10:20 2007
@@ -358,7 +358,7 @@
      * implementation.
      */
     protected GraphicsNode instantiateGraphicsNode() {
-        return null; // nothing to do, createGraphicsNode is fully overriden
+        return null; // nothing to do, createGraphicsNode is fully overridden
     }
 
     /**

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMDocument.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMDocument.java?rev=580678&r1=580677&r2=580678&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMDocument.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMDocument.java Sat Sep 29 22:10:20 2007
@@ -136,6 +136,11 @@
     protected LinkedList animatedAttributeListeners = new LinkedList();
 
     /**
+     * The SVG context.
+     */
+    protected transient SVGContext svgContext;
+
+    /**
      * Creates a new uninitialized document.
      */
     protected SVGOMDocument() {
@@ -390,6 +395,22 @@
             return SVG_ID_ATTRIBUTE.equals(node.getNodeName());
         }
         return node.getNodeName().equals(XML_ID_QNAME);
+    }
+
+    /**
+     * Sets the SVG context to use to get SVG specific informations.
+     *
+     * @param ctx the SVG context
+     */
+    public void setSVGContext(SVGContext ctx) {
+        svgContext = ctx;
+    }
+
+    /**
+     * Returns the SVG context used to get SVG specific informations.
+     */
+    public SVGContext getSVGContext() {
+        return svgContext;
     }
 
     // CSSNavigableDocument ///////////////////////////////////////////