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 de...@apache.org on 2005/07/16 12:27:59 UTC

svn commit: r219312 - in /xmlgraphics/batik/branches/svg11: resources/org/apache/batik/bridge/ resources/org/apache/batik/bridge/resources/ resources/org/apache/batik/ext/awt/image/spi/resources/ resources/org/apache/batik/swing/svg/ resources/org/apac...

Author: deweese
Date: Sat Jul 16 03:27:56 2005
New Revision: 219312

URL: http://svn.apache.org/viewcvs?rev=219312&view=rev
Log:
1) Handling of broken links is now forwarded to the bridge UserAgent Interface.
   This will cause problems if you don't derive off the UserAgentAdapter.
2) The default UserAgentAdapter now throws a BridgeException.  As a
   result the Transcoders now throw an error when an image can't be
   read rather than substituting the broken link document.
3) The JSVGCanvas now provides the BrokenLinkDocument - which should
   make it easier for people to customize the behaviour.
4) The JSVGCanvas now has an improved tooltip handling mechanism
   (although it still doesn't quite work as desired for the image element).

Added:
    xmlgraphics/batik/branches/svg11/resources/org/apache/batik/swing/svg/BrokenLink.svg
      - copied unchanged from r209122, xmlgraphics/batik/trunk/resources/org/apache/batik/bridge/BrokenLink.svg
    xmlgraphics/batik/branches/svg11/test-resources/org/apache/batik/dom/svg/bug30580_image.png   (with props)
Removed:
    xmlgraphics/batik/branches/svg11/resources/org/apache/batik/bridge/BrokenLink.svg
Modified:
    xmlgraphics/batik/branches/svg11/resources/org/apache/batik/bridge/resources/Messages.properties
    xmlgraphics/batik/branches/svg11/resources/org/apache/batik/ext/awt/image/spi/resources/Messages.properties
    xmlgraphics/batik/branches/svg11/resources/org/apache/batik/swing/svg/resources/Messages.properties
    xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/ErrorConstants.java
    xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGBrokenLinkProvider.java
    xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGImageElementBridge.java
    xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgent.java
    xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgentAdapter.java
    xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/spi/ImageTagRegistry.java
    xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/event/AWTEventDispatcher.java
    xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/JSVGCanvas.java
    xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/svg/JSVGComponent.java
    xmlgraphics/batik/branches/svg11/test-resources/org/apache/batik/swing/unitTesting.xml

Modified: xmlgraphics/batik/branches/svg11/resources/org/apache/batik/bridge/resources/Messages.properties
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/resources/org/apache/batik/bridge/resources/Messages.properties?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/resources/org/apache/batik/bridge/resources/Messages.properties (original)
+++ xmlgraphics/batik/branches/svg11/resources/org/apache/batik/bridge/resources/Messages.properties Sat Jul 16 03:27:56 2005
@@ -49,8 +49,7 @@
 {0}:{1}\n\
 Cannot find the referenced element:\n\
 "{3}"\n\
-specified on the element <{2}> - may be a problem of 'id'
-
+specified on the element <{2}> - may be a problem of ''id''
 
 uri.io = \
 {0}:{1}\n\
@@ -76,8 +75,15 @@
 The URI "{3}"\n\
 specified on the element <{2}> is invalid
 
-broken.link.title = \
-Broken Link:
+uri.image.broken = \
+{0}:{1}\n\
+The URI "{3}"\n\
+on element <{2}> can''t be opened because:\n\
+{4}
+
+uri.image.error = \
+The URI can''t be opened:\n\
+{0}
 
 ##########################################################################
 # Messages for DefaultScriptSecurity

Modified: xmlgraphics/batik/branches/svg11/resources/org/apache/batik/ext/awt/image/spi/resources/Messages.properties
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/resources/org/apache/batik/ext/awt/image/spi/resources/Messages.properties?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/resources/org/apache/batik/ext/awt/image/spi/resources/Messages.properties (original)
+++ xmlgraphics/batik/branches/svg11/resources/org/apache/batik/ext/awt/image/spi/resources/Messages.properties Sat Jul 16 03:27:56 2005
@@ -21,13 +21,10 @@
 {0} stream is corrupt or unsupported variant
 
 url.unreachable = \
-Unable to access URL: \n\
-{0}
+Unable to access URL
 
 url.uninterpretable = \
-URL data in unsupported format or corrupt: \n\
-{0}
+URL data in unsupported format or corrupt
 
 url.format.unreadable =\
-{0} URL is corrupt or unsupported variant: \n\
-{1}
+{0} URL is corrupt or unsupported variant

Modified: xmlgraphics/batik/branches/svg11/resources/org/apache/batik/swing/svg/resources/Messages.properties
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/resources/org/apache/batik/swing/svg/resources/Messages.properties?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/resources/org/apache/batik/swing/svg/resources/Messages.properties (original)
+++ xmlgraphics/batik/branches/svg11/resources/org/apache/batik/swing/svg/resources/Messages.properties Sat Jul 16 03:27:56 2005
@@ -22,3 +22,6 @@
 
 script.prompt = \
 Script prompt:\n{0}
+
+broken.link.title = \
+Image reference unavailable:

Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/ErrorConstants.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/ErrorConstants.java?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/ErrorConstants.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/ErrorConstants.java Sat Jul 16 03:27:56 2005
@@ -133,12 +133,25 @@
      * {0} = the uri
      * </pre>
      */
-    public static final String ERR_URI_IMAGE_INVALID
-        = "uri.image.invalid";
+    public static final String ERR_URI_IMAGE_INVALID = "uri.image.invalid";
 
     /**
-     * The resource that contains the title for the Broken Link message
+     * The error code when the bridge tries to read an image and the image
+     * url can't be opened or the contents aren't usable.
+     * <pre>
+     * {0} = the uri
+     * {1} = the reason it can't be opened.
+     * </pre>
      */
-    public static final String MSG_BROKEN_LINK_TITLE
-        = "broken.link.title";
+    public static final String ERR_URI_IMAGE_BROKEN = "uri.image.broken";
+
+    /**
+     * The error code when the bridge tries to read an image and the image
+     * url can't be opened:
+     * <pre>
+     * {0} = the reason it can't be opened.
+     * </pre>
+     */
+    public static final String URI_IMAGE_ERROR = "uri.image.error";
+
 }

Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGBrokenLinkProvider.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGBrokenLinkProvider.java?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGBrokenLinkProvider.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGBrokenLinkProvider.java Sat Jul 16 03:27:56 2005
@@ -17,19 +17,14 @@
  */
 package org.apache.batik.bridge;
 
-import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.batik.dom.util.DOMUtilities;
 import org.apache.batik.ext.awt.image.renderable.Filter;
 import org.apache.batik.ext.awt.image.spi.DefaultBrokenLinkProvider;
-import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.CompositeGraphicsNode;
 import org.apache.batik.gvt.filter.GraphicsNodeRable8Bit;
-import org.apache.batik.util.SVGConstants;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.svg.SVGDocument;
+
 /**
  * This interface is to be used to provide alternate ways of 
  * generating a placeholder image when the ImageTagRegistry
@@ -39,31 +34,7 @@
     extends    DefaultBrokenLinkProvider 
     implements ErrorConstants {
 
-    public final static String SVG_BROKEN_LINK_DOCUMENT_PROPERTY = 
-        "org.apache.batik.bridge.BrokenLinkDocument";
-
-    UserAgent      userAgent;
-    DocumentLoader loader;
-    BridgeContext  ctx;
-    GraphicsNode   gvtRoot = null;
-    SVGDocument       svgDoc;
-    
     public SVGBrokenLinkProvider() {
-        userAgent = new UserAgentAdapter();
-        loader    = new DocumentLoader(userAgent);
-        ctx       = new BridgeContext(userAgent, loader);
-
-        Class cls = SVGBrokenLinkProvider.class;
-        URL blURL = cls.getResource("BrokenLink.svg");
-        if (blURL == null) return;
-
-        GVTBuilder builder = new GVTBuilder();
-        try {
-            svgDoc  = (SVGDocument)loader.loadDocument(blURL.toString());
-            gvtRoot = builder.build(ctx, svgDoc);
-        } catch (Exception ex) {
-            // t.printStackTrace();
-        }
     }
 
     /**
@@ -81,38 +52,11 @@
      *        the circumstances of the failure.  */
     public Filter getBrokenLinkImage(Object base, String code, 
                                      Object[] params) {
-        if (gvtRoot == null) 
-            return null;
-
         String message = formatMessage(base, code, params);
-        Document doc = getBrokenLinkDocument(message);
         Map props = new HashMap();
         props.put(BROKEN_LINK_PROPERTY, message);
-        props.put(SVG_BROKEN_LINK_DOCUMENT_PROPERTY, doc);
-        
-        return new GraphicsNodeRable8Bit(gvtRoot, props);
-    }
-
-    public SVGDocument getBrokenLinkDocument(Object base, 
-                                          String code, Object [] params) {
-        String message = formatMessage(base, code, params);
-        return getBrokenLinkDocument(message);
-    }
 
-    public SVGDocument getBrokenLinkDocument(String message) {
-        SVGDocument doc = (SVGDocument)DOMUtilities.deepCloneDocument
-            (svgDoc, svgDoc.getImplementation());
-        Element infoE = doc.getElementById("__More_About");
-        Element title = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
-                                            SVGConstants.SVG_TITLE_TAG);
-        title.appendChild(doc.createTextNode
-                          (Messages.formatMessage
-                           (MSG_BROKEN_LINK_TITLE, null)));
-        Element desc = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
-                                           SVGConstants.SVG_DESC_TAG);
-        desc.appendChild(doc.createTextNode(message));
-        infoE.insertBefore(desc, infoE.getFirstChild());
-        infoE.insertBefore(title, desc);
-        return doc;
+        CompositeGraphicsNode cgn = new CompositeGraphicsNode();
+        return new GraphicsNodeRable8Bit(cgn, props);
     }
 }

Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGImageElementBridge.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGImageElementBridge.java?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGImageElementBridge.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/SVGImageElementBridge.java Sat Jul 16 03:27:56 2005
@@ -38,6 +38,7 @@
 import org.apache.batik.ext.awt.color.ICCColorSpaceExt;
 import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit;
 import org.apache.batik.ext.awt.image.renderable.Filter;
+import org.apache.batik.ext.awt.image.spi.BrokenLinkProvider;
 import org.apache.batik.ext.awt.image.spi.ImageTagRegistry;
 import org.apache.batik.gvt.CanvasGraphicsNode;
 import org.apache.batik.gvt.CompositeGraphicsNode;
@@ -212,7 +213,7 @@
             /* Check the ImageTagRegistry Cache */
             Filter img = reg.checkCache(purl, colorspace);
             if (img != null) {
-                return createRasterImageNode(ctx, e, img);
+                return createRasterImageNode(ctx, e, img, purl);
             }
         }
 
@@ -230,7 +231,8 @@
             throw new BridgeException(e, ERR_URI_UNSECURE,
                                       new Object[] {purl});
         } catch (IOException ioe) {
-            return createBrokenImageNode(ctx, e, purl.toString());
+            return createBrokenImageNode(ctx, e, purl.toString(),
+                                         ioe.getLocalizedMessage());
         }
 
         {
@@ -244,7 +246,7 @@
                                      false, false);
             if (img != null) {
                 // It's a bouncing baby Raster...
-                return createRasterImageNode(ctx, e, img);
+                return createRasterImageNode(ctx, e, img, purl);
             }
         }
 
@@ -257,7 +259,8 @@
                 reference = openStream(e, purl);
             } catch (IOException ioe2) {
                 // Since we already opened the stream this is unlikely.
-                return createBrokenImageNode(ctx, e, purl.toString());
+                return createBrokenImageNode(ctx, e, purl.toString(),
+                                             ioe2.getLocalizedMessage());
             }
         }
 
@@ -285,7 +288,8 @@
                 // Couldn't reset stream so reopen it.
                 reference = openStream(e, purl);
             } catch (IOException ioe2) {
-                return createBrokenImageNode(ctx, e, purl.toString());
+                return createBrokenImageNode(ctx, e, purl.toString(),
+                                             ioe2.getLocalizedMessage());
             }
         }
 
@@ -297,7 +301,7 @@
                                      true, true);
             if (img != null) {
                 // It's a bouncing baby Raster...
-                return createRasterImageNode(ctx, e, img);
+                return createRasterImageNode(ctx, e, img, purl);
             }
         } finally {
             reference.release();
@@ -539,18 +543,22 @@
      */
     protected GraphicsNode createRasterImageNode(BridgeContext ctx,
                                                  Element       e,
-                                                 Filter        img) {
+                                                 Filter        img,
+                                                 ParsedURL     purl) {
         Rectangle2D bounds = getImageBounds(ctx, e);
         if ((bounds.getWidth() == 0) || (bounds.getHeight() == 0)) {
             ShapeNode sn = new ShapeNode();
             sn.setShape(bounds);
             return sn;
         }
-        Object           obj = img.getProperty
-            (SVGBrokenLinkProvider.SVG_BROKEN_LINK_DOCUMENT_PROPERTY);
-        if ((obj != null) && (obj instanceof SVGDocument)) {
-            // Ok so we are dealing with a broken link.
-            SVGOMDocument doc = (SVGOMDocument)obj;
+
+        Object obj = img.getProperty(BrokenLinkProvider.BROKEN_LINK_PROPERTY);
+        if (obj != null) {
+            String msg = "unknown";
+            if (obj instanceof String)
+                msg = (String)obj;
+            SVGDocument doc = ctx.getUserAgent().getBrokenLinkDocument
+                (e, purl.toString(), msg);
             return createSVGImageNode(ctx, e, doc);
         }
 
@@ -889,28 +897,11 @@
     }
 
     GraphicsNode createBrokenImageNode
-        (BridgeContext ctx, Element e, String uri) {
-        
-        String lname = "<Unknown Element>";
-        SVGDocument doc = null;
-        if (e != null) {
-            doc = (SVGDocument)e.getOwnerDocument();
-            lname = e.getLocalName();
-        }
-        String docUri;
-        if (doc == null)  docUri = "<Unknown Document>";
-        else              docUri = doc.getURL();
-        int line = ctx.getDocumentLoader().getLineNumber(e);
-        Object [] fullparams = new Object[4];
-        fullparams[0] = docUri;
-        fullparams[1] = new Integer(line);
-        fullparams[2] = lname;
-        fullparams[3] = uri;
-
-        SVGDocument blDoc = brokenLinkProvider.getBrokenLinkDocument
-            (this, ERR_URI_IO, fullparams);
-        hitCheckChildren = true;
-        return createSVGImageNode(ctx, e, blDoc);
+        (BridgeContext ctx, Element e, String uri, String message) {
+        SVGDocument doc = ctx.getUserAgent().getBrokenLinkDocument
+            (e, uri, Messages.formatMessage(URI_IMAGE_ERROR, 
+                                           new Object[] { message } ));
+        return createSVGImageNode(ctx, e, doc);
     }
 
 

Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgent.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgent.java?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgent.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgent.java Sat Jul 16 03:27:56 2005
@@ -27,6 +27,7 @@
 import org.apache.batik.util.ParsedURL;
 import org.w3c.dom.Element;
 import org.w3c.dom.svg.SVGAElement;
+import org.w3c.dom.svg.SVGDocument;
 
 /**
  * An interface that provides access to the User Agent informations
@@ -285,4 +286,16 @@
     void checkLoadExternalResource(ParsedURL resourceURL,
                                    ParsedURL docURL) throws SecurityException;
 
+
+    /**
+     * This method should return an image to be displayed when an image
+     * can't be loaded.  If it returns 'null' then a BridgeException will
+     * be thrown.
+     *
+     * @param e   The <image> element that can't be loaded.
+     * @param url The resolved url that can't be loaded.
+     * @param message As best as can be determined the reason it can't be
+     *                loaded (not available, corrupt, unknown format,...).
+     */
+    SVGDocument getBrokenLinkDocument(Element e, String url, String message);
 }

Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgentAdapter.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgentAdapter.java?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgentAdapter.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/bridge/UserAgentAdapter.java Sat Jul 16 03:27:56 2005
@@ -33,6 +33,7 @@
 import org.apache.batik.util.XMLResourceDescriptor;
 import org.w3c.dom.Element;
 import org.w3c.dom.svg.SVGAElement;
+import org.w3c.dom.svg.SVGDocument;
 
 /**
  * An abstract user agent adaptor implementation.  It exists to simply
@@ -422,5 +423,19 @@
         }
     }
 
+    /**
+     * This Implementation simply throws a BridgeException.
+     *
+     * @param e   The <image> element that can't be loaded.
+     * @param url The resolved url that can't be loaded.
+     * @param message As best as can be determined the reason it can't be
+     *                loaded (not available, corrupt, unknown format,...).
+     */
+    public SVGDocument getBrokenLinkDocument(Element e, 
+                                             String url, 
+                                             String message) {
+        throw new BridgeException(e, ErrorConstants.ERR_URI_IMAGE_BROKEN,
+                                  new Object[] {url, message });
+    }
 }
 

Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/spi/ImageTagRegistry.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/spi/ImageTagRegistry.java?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/spi/ImageTagRegistry.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/spi/ImageTagRegistry.java Sat Jul 16 03:27:56 2005
@@ -196,13 +196,11 @@
                 // Technially it's possible that it's an unknown
                 // 'protocol that caused the open to fail but probably
                 // it's a bad URL...
-                return getBrokenLinkImage(this, ERR_URL_UNREACHABLE,
-                                          new Object[] { purl });
+                return getBrokenLinkImage(this, ERR_URL_UNREACHABLE, null);
 
             // We were able to get to the data we just couldn't
             // make sense of it...
-            return getBrokenLinkImage(this, ERR_URL_UNINTERPRETABLE, 
-                                      new Object[] { purl } );
+            return getBrokenLinkImage(this, ERR_URL_UNINTERPRETABLE, null);
         }
 
         if (ret.getProperty(BrokenLinkProvider.BROKEN_LINK_PROPERTY) != null) {

Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/event/AWTEventDispatcher.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/event/AWTEventDispatcher.java?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/event/AWTEventDispatcher.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/event/AWTEventDispatcher.java Sat Jul 16 03:27:56 2005
@@ -411,7 +411,7 @@
         }
 
         if (lastHit != node) {
-            // post an MOUSE_EXITED
+            // post a MOUSE_EXITED event
             if (lastHit != null) {
                 gvtevt = new GraphicsNodeMouseEvent(lastHit,
                                                     MouseEvent.
@@ -429,7 +429,7 @@
                 processMouseEvent(gvtevt);
                 // lastHit.processMouseEvent(gvtevt);
             }
-            // post an MOUSE_ENTERED
+            // post a MOUSE_ENTERED event
             if (node != null) {
                 gvtevt = new GraphicsNodeMouseEvent(node,
                                                     MouseEvent.

Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/JSVGCanvas.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/JSVGCanvas.java?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/JSVGCanvas.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/JSVGCanvas.java Sat Jul 16 03:27:56 2005
@@ -28,9 +28,12 @@
 import java.awt.geom.AffineTransform;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
+import java.lang.ref.WeakReference;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.WeakHashMap;
 
 import javax.swing.AbstractAction;
@@ -186,6 +189,8 @@
     protected Map toolTipMap = null;
     protected EventListener toolTipListener = new ToolTipModifier();
     protected EventTarget   lastTarget = null;;
+    protected Set toolTipDocs = null;
+
     /**
      * The time of the last tool tip event.
      */
@@ -546,31 +551,29 @@
     }
 
     protected void installSVGDocument(SVGDocument doc) {
-        if (svgDocument != null) {
-            EventTarget root;
-            root = (EventTarget)svgDocument.getRootElement();
-            root.removeEventListener(SVGConstants.SVG_EVENT_MOUSEOVER,
-                                     toolTipListener, false);
-            root.removeEventListener(SVGConstants.SVG_EVENT_MOUSEOUT,
-                                     toolTipListener, false);
-            lastTarget = null;
+        if (toolTipDocs != null) {
+            Iterator i = toolTipDocs.iterator();
+            while (i.hasNext()) {
+                SVGDocument ttdoc;
+                ttdoc = (SVGDocument)((WeakReference)i.next()).get();
+                if (ttdoc == null) continue;
+
+                EventTarget root;
+                root = (EventTarget)ttdoc.getRootElement();
+                if (root == null) continue;
+                root.removeEventListener(SVGConstants.SVG_EVENT_MOUSEOVER,
+                                         toolTipListener, false);
+                root.removeEventListener(SVGConstants.SVG_EVENT_MOUSEOUT,
+                                         toolTipListener, false);
+            }
+            toolTipDocs = null;
         }
+        lastTarget = null;
 
         if (toolTipMap != null) {
             toolTipMap.clear();
         }
 
-        if (doc != null) {
-            EventTarget root;
-            root = (EventTarget)doc.getRootElement();
-            // On mouseover, it sets the tooltip to the given value
-            root.addEventListener(SVGConstants.SVG_EVENT_MOUSEOVER,
-                                  toolTipListener, false);
-            // On mouseout, it removes the tooltip
-            root.addEventListener(SVGConstants.SVG_EVENT_MOUSEOUT,
-                                  toolTipListener, false);
-        }
-
         super.installSVGDocument(doc);
     }
 
@@ -1002,6 +1005,21 @@
         public void setToolTip(Element elt, String toolTip){
             if (toolTipMap == null) {
                 toolTipMap = new WeakHashMap();
+            }
+            if (toolTipDocs == null) {
+                toolTipDocs = new HashSet();
+            }
+            SVGDocument doc = (SVGDocument)elt.getOwnerDocument();
+            WeakReference wr = new WeakReference(doc);
+            if (toolTipDocs.add(wr)) {
+                EventTarget root;
+                root = (EventTarget)doc.getRootElement();
+                // On mouseover, it sets the tooltip to the given value
+                root.addEventListener(SVGConstants.SVG_EVENT_MOUSEOVER,
+                                      toolTipListener, false);
+                // On mouseout, it removes the tooltip
+                root.addEventListener(SVGConstants.SVG_EVENT_MOUSEOUT,
+                                      toolTipListener, false);
             }
 
             toolTipMap.put(elt, toolTip);

Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/svg/JSVGComponent.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/svg/JSVGComponent.java?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/svg/JSVGComponent.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/swing/svg/JSVGComponent.java Sat Jul 16 03:27:56 2005
@@ -39,6 +39,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.net.URL;
 
 import javax.swing.JOptionPane;
 
@@ -47,7 +48,9 @@
 import org.apache.batik.bridge.BridgeExtension;
 import org.apache.batik.bridge.DefaultScriptSecurity;
 import org.apache.batik.bridge.DocumentLoader;
+import org.apache.batik.bridge.ErrorConstants;
 import org.apache.batik.bridge.ExternalResourceSecurity;
+import org.apache.batik.bridge.GVTBuilder;
 import org.apache.batik.bridge.RelaxedExternalResourceSecurity;
 import org.apache.batik.bridge.ScriptSecurity;
 import org.apache.batik.bridge.UpdateManager;
@@ -230,6 +233,31 @@
     public final static int ALWAYS_INTERACTIVE = 3;
 
     /**
+     * String constant for the resource with the text for a script alert
+     * dialog. Must have a substitution for one string.
+     */
+    public final static String SCRIPT_ALERT = "script.alert";
+
+    /**
+     * String constant for the resource with the text for a script
+     * prompt dialog. Must have a substitution for one string.
+     */
+    public final static String SCRIPT_PROMPT = "script.prompt";
+
+    /**
+     * String constant for the resource with the text for a script
+     * confim dialog. Must have a substitution for one string.
+     */
+    public final static String SCRIPT_CONFIRM = "script.confirm";
+
+    /**
+     * String constant for the resource with the text for the title
+     * of the info tooltip for brokin link images.
+     * No string substitution.
+     */
+    public final static String BROKEN_LINK_TITLE = "broken.link.title";
+
+    /**
      * The document loader.
      */
     protected SVGDocumentLoader documentLoader;
@@ -1147,7 +1175,7 @@
      */
     public void showAlert(String message) {
         JOptionPane.showMessageDialog
-            (this, Messages.formatMessage("script.alert",
+            (this, Messages.formatMessage(SCRIPT_ALERT,
                                           new Object[] { message }));
     }
 
@@ -1156,7 +1184,7 @@
      */
     public String showPrompt(String message) {
         return JOptionPane.showInputDialog
-            (this, Messages.formatMessage("script.prompt",
+            (this, Messages.formatMessage(SCRIPT_PROMPT,
                                           new Object[] { message }));
     }
 
@@ -1166,7 +1194,7 @@
     public String showPrompt(String message, String defaultValue) {
         return (String)JOptionPane.showInputDialog
             (this,
-             Messages.formatMessage("script.prompt",
+             Messages.formatMessage(SCRIPT_PROMPT,
                                     new Object[] { message }),
              null,
              JOptionPane.PLAIN_MESSAGE,
@@ -1178,7 +1206,7 @@
      */
     public boolean showConfirm(String message) {
         return JOptionPane.showConfirmDialog
-            (this, Messages.formatMessage("script.confirm",
+            (this, Messages.formatMessage(SCRIPT_CONFIRM,
                                           new Object[] { message }),
              "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
     }
@@ -2872,6 +2900,37 @@
             }
         }
         
+
+        /**
+         * This Implementation simply forwards the request to the AWT thread.
+         *
+         * @param e   The <image> element that can't be loaded.
+         * @param url The resolved url that can't be loaded.
+         * @param message As best as can be determined the reason it can't be
+         *                loaded (not available, corrupt, unknown format,...).
+         */
+        public SVGDocument getBrokenLinkDocument(final Element e, 
+                                                 final String url, 
+                                                 final String msg) {
+            if (EventQueue.isDispatchThread()) 
+                return userAgent.getBrokenLinkDocument(e, url, msg);
+
+            class Query implements Runnable {
+                SVGDocument doc;
+                RuntimeException rex = null;
+                public void run() {
+                    try {
+                        doc = userAgent.getBrokenLinkDocument(e, url, msg);
+                    } catch (RuntimeException re) { rex = re; }
+                }
+            }
+            Query q = new Query();
+            invokeAndWait(q);
+            if (q.rex != null) throw q.rex;
+            return q.doc;
+        }
+
+  
         /**
          * Invokes the given runnable from the event thread, and wait
          * for the run method to terminate.
@@ -3420,7 +3479,62 @@
             }
         }
         
+        /**
+         * This implementation provides a true SVG Document that it
+         * annotates with some information about why the real document
+         * can't be loaded (unfortunately right now tool tips are broken
+         * for content referenced by images so you can't actually see
+         * the info).
+         *
+         * @param e   The <image> element that can't be loaded.
+         * @param url The resolved url that can't be loaded.
+         * @param message As best as can be determined the reason it can't be
+         *                loaded (not available, corrupt, unknown format,...).
+         */
+        public SVGDocument getBrokenLinkDocument(Element e, 
+                                                 String url, 
+                                                 String message) {
+            Class cls = JSVGComponent.class;
+            URL blURL = cls.getResource("BrokenLink.svg");
+            if (blURL == null) 
+                throw new BridgeException
+                    (e, ErrorConstants.ERR_URI_IMAGE_BROKEN,
+                     new Object[] {url, message });
 
+            DocumentLoader loader  = bridgeContext.getDocumentLoader();
+            SVGDocument    doc = null;
+
+            try {
+                doc  = (SVGDocument)loader.loadDocument(blURL.toString());
+                if (doc == null) return doc;
+
+                DOMImplementation impl;
+                impl = SVGDOMImplementation.getDOMImplementation();
+                doc  = (SVGDocument)DOMUtilities.deepCloneDocument(doc, impl);
+
+                String title;
+                Element infoE, titleE, descE;
+                infoE = doc.getElementById("__More_About");
+                if (infoE == null) return doc;
+
+                titleE = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
+                                            SVGConstants.SVG_TITLE_TAG);
+                title = Messages.formatMessage(BROKEN_LINK_TITLE, null);
+                titleE.appendChild(doc.createTextNode(title));
+
+                descE = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
+                                           SVGConstants.SVG_DESC_TAG);
+                descE.appendChild(doc.createTextNode(message));
+
+                infoE.insertBefore(descE, infoE.getFirstChild());
+                infoE.insertBefore(titleE, descE);
+            } catch (Exception ex) {
+                throw new BridgeException
+                    (e, ErrorConstants.ERR_URI_IMAGE_BROKEN,
+                     new Object[] {url, message });
+            }
+            return doc;
+        }
     }
 
     protected final static Set FEATURES = new HashSet();

Added: xmlgraphics/batik/branches/svg11/test-resources/org/apache/batik/dom/svg/bug30580_image.png
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/test-resources/org/apache/batik/dom/svg/bug30580_image.png?rev=219312&view=auto
==============================================================================
Binary file - no diff available.

Propchange: xmlgraphics/batik/branches/svg11/test-resources/org/apache/batik/dom/svg/bug30580_image.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: xmlgraphics/batik/branches/svg11/test-resources/org/apache/batik/swing/unitTesting.xml
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/test-resources/org/apache/batik/swing/unitTesting.xml?rev=219312&r1=219311&r2=219312&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/test-resources/org/apache/batik/swing/unitTesting.xml (original)
+++ xmlgraphics/batik/branches/svg11/test-resources/org/apache/batik/swing/unitTesting.xml Sat Jul 16 03:27:56 2005
@@ -26,9 +26,10 @@
     <test id="samples/tests/spec/scripting/memoryLeak1.svg"/>
   </testGroup>
 
+<!--
   <test id="NullURITest" 
         class="org.apache.batik.swing.NullURITest" />
-
+-->
   <test id="NullSetSVGDocumentTest" 
         class="org.apache.batik.swing.NullSetSVGDocumentTest" />