deweese 2003/07/07 17:16:58
Modified: . build.bat build.xml
samples/tests/spec/scripting memoryLeak1.svg
sources/org/apache/batik/bridge
BaseScriptingEnvironment.java BridgeContext.java
FocusManager.java
sources/org/apache/batik/dom AbstractDocument.java
sources/org/apache/batik/dom/svg SVGOMStyleElement.java
sources/org/apache/batik/dom/util DocumentDescriptor.java
sources/org/apache/batik/gvt AbstractGraphicsNode.java
sources/org/apache/batik/script/rhino RhinoInterpreter.java
sources/org/apache/batik/swing JSVGCanvas.java
sources/org/apache/batik/swing/gvt JGVTComponent.java
sources/org/apache/batik/swing/svg JSVGComponent.java
sources/org/apache/batik/util RunnableQueue.java
test-resources/org/apache/batik/swing unitTesting.xml
test-resources/org/apache/batik/swing/resources
TestMessages.properties
test-resources/org/apache/batik/test/svg/resources
Messages.properties
test-sources/org/apache/batik/swing JSVGCanvasHandler.java
JSVGMemoryLeakTest.java NullURITest.java
test-sources/org/apache/batik/test MemoryLeakTest.java
test-sources/org/apache/batik/test/svg
JSVGRenderingAccuracyTest.java
Added: test-references/test-resources/org/apache/batik/test/svg
SetSVGDocumentTest.png
test-sources/org/apache/batik/swing
NullSetSVGDocumentTest.java SetSVGDocumentTest.java
Log:
1) setSVGDocument with a Document that has been previously viewed in
the Canvas now works (actually using setSVGDocument after viewing
any dynamic document used to have problems).
2) setSVGDocument with a non-Batik Document (SVGOMDocument) now works.
3) setSVGDocument with 'null' now releases all heavy resources and
makes the Canvas display only Background.
4) Fixed a Memory leak that prevent any DOM node created from a stream
from going to GC (DocumentDescriptor kept a hard reference to
Elements to track line numbers).
5) 'style' and 'script' elements no longer include the contents of
XML Comments (unless using a CDATA block).
6) RunnableQueue now catches all exceptions.
7) Various affine actions are now public classes (Zoom, Pan, Rotate).
8) New MemoryLeak tests
PR: 21125, 21352, 18640
Revision Changes Path
1.11 +2 -3 xml-batik/build.bat
Index: build.bat
===================================================================
RCS file: /home/cvs/xml-batik/build.bat,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- build.bat 2 Jul 2003 08:18:07 -0000 1.10
+++ build.bat 8 Jul 2003 00:16:56 -0000 1.11
@@ -13,17 +13,16 @@
:gotJavaHome
if not "%ANT_HOME%" == "" goto gotAntHome
-set ANT_HOME=.
:: ----- Set Up The Runtime Classpath -----------------------------------------
-set
CP=%JAVA_HOME%\lib\tools.jar;%ANT_HOME%\lib\build\ant_1_4_1.jar;.\lib\build\crimson-ant.jar;.\lib\build\jaxp.jar
+set
CP=%JAVA_HOME%\lib\tools.jar;lib\build\ant_1_4_1.jar;.\lib\build\crimson-ant.jar;.\lib\build\jaxp.jar
:: ----- Execute The Requested Build ------------------------------------------
-%JAVA_HOME%\bin\java.exe %ANT_OPTS% -classpath %CP% org.apache.tools.ant.Main
-emacs -Dant.home=%ANT_HOME% %1 -Dargs="%2 %3 %4 %5 %6 %7 %8 %9"
+%JAVA_HOME%\bin\java.exe %ANT_OPTS% -classpath %CP% org.apache.tools.ant.Main
-emacs -Dant.home=. %1 -Dargs="%2 %3 %4 %5 %6 %7 %8 %9"
:: ----- Cleanup the environment ----------------------------------------------
1.132 +2 -1 xml-batik/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/xml-batik/build.xml,v
retrieving revision 1.131
retrieving revision 1.132
diff -u -r1.131 -r1.132
--- build.xml 5 Jul 2003 00:15:07 -0000 1.131
+++ build.xml 8 Jul 2003 00:16:56 -0000 1.132
@@ -1075,6 +1075,7 @@
<java fork="yes"
classname="${class-prefix}.test.xml.XMLTestSuiteRunner">
<!-- <jvmarg value="-Xrunhprof:format=b" /> -->
+<!-- <jvmarg value="-Xrunhprof:net=localhost:7001,format=b" /> -->
<classpath>
<pathelement location="${dest}" />
<path refid="libs-classpath"/>
1.2 +49 -15 xml-batik/samples/tests/spec/scripting/memoryLeak1.svg
Index: memoryLeak1.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec/scripting/memoryLeak1.svg,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- memoryLeak1.svg 5 Jul 2003 00:15:07 -0000 1.1
+++ memoryLeak1.svg 8 Jul 2003 00:16:56 -0000 1.2
@@ -17,28 +17,62 @@
<!-- @version $Id$ -->
<!-- ====================================================================== -->
-<?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?>
-
<svg id="body" width="450" height="500" viewBox="0 0 450 500">
- <title><text> children 'onload'</title>
-
- <text x="50%" y="45" class="title"><text> children in 'onload'</text>
-
<script type="text/ecmascript"><![CDATA[
var inRegard=false;
+ var elems = new Array
+ ("t1", "t2", "r1", "r2", "c1", "c2", "ts1", "ts2", "xxx");
+
function regardStart() {
- inRegard=true;
- var elem = document.getElementById("t1");
- regardTestInstance.registerObjectDesc(elem, "T1");
- elem.parentNode.removeChild(elem);
- regardTestInstance.scriptDone();
+ inRegard=true;
+
+ var elem;
+ for(var i=0; i<elems.length; i++) {
+ var elem = document.getElementById(elems[i]);
+ regardTestInstance.registerElement(elem, elems[i]);
+ elem.parentNode.removeChild(elem);
+ }
+
+ setTimeout("checkElem()", 10);
+ }
+
+ function checkElem() {
+ regardTestInstance.checkObjects(elems);
+ // setTimeout("regardTestInstance.scriptDone()", 30000);
+ regardTestInstance.scriptDone();
}
]]></script>
+ <defs>
+ <rect id="xxx" x="10" y="150" width="100" height="50" fill="purple"/>
+ </defs>
+
<g id="test-content">
- <g style="font-size:40" >
- <text id="t1_bg" x="70" y="135" style="fill:gold">The good the bad</text>
- <text id="t1" x="70" y="135" style="fill:crimson">The good the bad</text>
+ <g style="font-size:20" >
+ <text id="t1_bg" x="5" y="135" fill="purple" >Simple Text</text>
+ <text id="t2" x="155" y="135" fill="gold" >Simple Text</text>
+ <text id="t1" x="305" y="135" fill="crimson">Simple Text</text>
+ </g>
+
+ <g>
+ <rect id="r_bg" x="10" y="150" width="100" height="50" fill="purple"/>
+ <rect id="r1" x="160" y="150" width="100" height="50" fill="crimson"/>
+ <rect id="r2" x="310" y="150" width="100" height="50" fill="gold"/>
+ </g>
+
+ <g>
+ <circle id="c_bg" cx="60" cy="235" r="25" fill="purple"/>
+ <circle id="c1" cx="210" cy="235" r="25" fill="crimson"/>
+ <circle id="c2" cx="360" cy="235" r="25" fill="gold"/>
+ </g>
+
+ <g style="font-size:15" >
+ <text x="5" y="290" fill="purple">Some
+ <tspan id="ts_bg" font-weight="bold">Complex</tspan> Text</text>
+ <text x="155" y="290" fill="crimson">Some
+ <tspan id="ts1" font-weight="bold">Complex</tspan> Text</text>
+ <text x="305" y="290" fill="gold">Some
+ <tspan id="ts2" font-weight="bold">Complex</tspan> Text</text>
</g>
</g>
</svg>
1.22 +4 -2
xml-batik/sources/org/apache/batik/bridge/BaseScriptingEnvironment.java
Index: BaseScriptingEnvironment.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/bridge/BaseScriptingEnvironment.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- BaseScriptingEnvironment.java 3 Jul 2003 02:00:00 -0000 1.21
+++ BaseScriptingEnvironment.java 8 Jul 2003 00:16:56 -0000 1.22
@@ -365,7 +365,9 @@
if (n != null) {
StringBuffer sb = new StringBuffer();
while (n != null) {
- sb.append(n.getNodeValue());
+ if (n.getNodeType() == n.CDATA_SECTION_NODE
+ || n.getNodeType() == n.TEXT_NODE)
+ sb.append(n.getNodeValue());
n = n.getNextSibling();
}
reader = new StringReader(sb.toString());
1.65 +2 -1 xml-batik/sources/org/apache/batik/bridge/BridgeContext.java
Index: BridgeContext.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/BridgeContext.java,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -r1.64 -r1.65
--- BridgeContext.java 1 Jul 2003 09:34:17 -0000 1.64
+++ BridgeContext.java 8 Jul 2003 00:16:56 -0000 1.65
@@ -988,6 +988,7 @@
if (cssEngine != null) {
cssEngine.removeCSSEngineListener(cssPropertiesChangedListener);
cssEngine.dispose();
+ svgDocument.setCSSEngine(null);
}
if (focusManager != null) {
focusManager.dispose();
1.5 +2 -1 xml-batik/sources/org/apache/batik/bridge/FocusManager.java
Index: FocusManager.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/FocusManager.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- FocusManager.java 11 Apr 2003 13:54:43 -0000 1.4
+++ FocusManager.java 8 Jul 2003 00:16:57 -0000 1.5
@@ -96,6 +96,7 @@
* Removes all listeners attached to the document and that manage focus.
*/
public void dispose() {
+ if (document == null) return;
EventTarget target = (EventTarget)document;
target.removeEventListener("click", mouseclickListener, true);
target.removeEventListener("mouseover", mouseoverListener, true);
1.18 +67 -62 xml-batik/sources/org/apache/batik/dom/AbstractDocument.java
Index: AbstractDocument.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/dom/AbstractDocument.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- AbstractDocument.java 11 Apr 2003 13:56:01 -0000 1.17
+++ AbstractDocument.java 8 Jul 2003 00:16:57 -0000 1.18
@@ -206,77 +206,82 @@
*/
public Node importNode(Node importedNode, boolean deep)
throws DOMException {
+ /* TED: This is bad because it usually does not create the
+ * the proper subclass of Element for the document it is
+ * being imported into based on namespace/tag name.
+ */
+ /**
if (importedNode instanceof AbstractNode) {
AbstractNode an = (AbstractNode)importedNode;
return (deep)
? an.deepExport(an.cloneNode(false), this)
: an.export(an.cloneNode(false), this);
- } else {
- Node result;
- switch (importedNode.getNodeType()) {
- case ELEMENT_NODE:
- Element e = createElementNS(importedNode.getNamespaceURI(),
- importedNode.getNodeName());
- result = e;
- if (importedNode.hasAttributes()) {
- NamedNodeMap attr = importedNode.getAttributes();
- int len = attr.getLength();
- for (int i = 0; i < len; i++) {
- Attr a = (Attr)attr.item(i);
- if (a.getSpecified()) {
- e.setAttributeNodeNS((Attr)importNode(a, true));
- }
+ }
+ */
+
+ Node result;
+ switch (importedNode.getNodeType()) {
+ case ELEMENT_NODE:
+ Element e = createElementNS(importedNode.getNamespaceURI(),
+ importedNode.getNodeName());
+ result = e;
+ if (importedNode.hasAttributes()) {
+ NamedNodeMap attr = importedNode.getAttributes();
+ int len = attr.getLength();
+ for (int i = 0; i < len; i++) {
+ Attr a = (Attr)attr.item(i);
+ if (a.getSpecified()) {
+ e.setAttributeNodeNS((Attr)importNode(a, true));
}
}
- break;
-
- case ATTRIBUTE_NODE:
- result = createAttributeNS(importedNode.getNamespaceURI(),
- importedNode.getNodeName());
- break;
-
- case TEXT_NODE:
- result = createTextNode(importedNode.getNodeValue());
- deep = false;
- break;
-
- case CDATA_SECTION_NODE:
- result = createCDATASection(importedNode.getNodeValue());
- deep = false;
- break;
-
- case ENTITY_REFERENCE_NODE:
- result = createEntityReference(importedNode.getNodeName());
- break;
-
- case PROCESSING_INSTRUCTION_NODE:
- result = createProcessingInstruction
- (importedNode.getNodeName(),
- importedNode.getNodeValue());
- deep = false;
- break;
-
- case COMMENT_NODE:
- result = createComment(importedNode.getNodeValue());
- deep = false;
- break;
-
- default:
- throw createDOMException(DOMException.NOT_SUPPORTED_ERR,
- "import.node",
- new Object[] {});
}
-
- if (deep) {
- for (Node n = importedNode.getFirstChild();
- n != null;
- n = n.getNextSibling()) {
- result.appendChild(importNode(n, true));
- }
+ break;
+
+ case ATTRIBUTE_NODE:
+ result = createAttributeNS(importedNode.getNamespaceURI(),
+ importedNode.getNodeName());
+ break;
+
+ case TEXT_NODE:
+ result = createTextNode(importedNode.getNodeValue());
+ deep = false;
+ break;
+
+ case CDATA_SECTION_NODE:
+ result = createCDATASection(importedNode.getNodeValue());
+ deep = false;
+ break;
+
+ case ENTITY_REFERENCE_NODE:
+ result = createEntityReference(importedNode.getNodeName());
+ break;
+
+ case PROCESSING_INSTRUCTION_NODE:
+ result = createProcessingInstruction
+ (importedNode.getNodeName(),
+ importedNode.getNodeValue());
+ deep = false;
+ break;
+
+ case COMMENT_NODE:
+ result = createComment(importedNode.getNodeValue());
+ deep = false;
+ break;
+
+ default:
+ throw createDOMException(DOMException.NOT_SUPPORTED_ERR,
+ "import.node",
+ new Object[] {});
+ }
+
+ if (deep) {
+ for (Node n = importedNode.getFirstChild();
+ n != null;
+ n = n.getNextSibling()) {
+ result.appendChild(importNode(n, true));
}
-
- return result;
}
+ return result;
}
/**
1.14 +4 -2
xml-batik/sources/org/apache/batik/dom/svg/SVGOMStyleElement.java
Index: SVGOMStyleElement.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/dom/svg/SVGOMStyleElement.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- SVGOMStyleElement.java 11 Apr 2003 13:56:16 -0000 1.13
+++ SVGOMStyleElement.java 8 Jul 2003 00:16:57 -0000 1.14
@@ -98,7 +98,9 @@
if (n != null) {
StringBuffer sb = new StringBuffer();
while (n != null) {
- sb.append(n.getNodeValue());
+ if (n.getNodeType() == n.CDATA_SECTION_NODE
+ || n.getNodeType() == n.TEXT_NODE)
+ sb.append(n.getNodeValue());
n = n.getNextSibling();
}
text = sb.toString();
1.2 +67 -35
xml-batik/sources/org/apache/batik/dom/util/DocumentDescriptor.java
Index: DocumentDescriptor.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/dom/util/DocumentDescriptor.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DocumentDescriptor.java 13 Feb 2001 19:45:15 -0000 1.1
+++ DocumentDescriptor.java 8 Jul 2003 00:16:57 -0000 1.2
@@ -10,6 +10,8 @@
import org.w3c.dom.Element;
+import org.apache.batik.util.CleanerThread;
+
/**
* This class contains informations about a document.
*
@@ -44,7 +46,9 @@
* Returns the number of elements in the document.
*/
public int getNumberOfElements() {
- return count;
+ synchronized (this) {
+ return count;
+ }
}
/**
@@ -52,14 +56,18 @@
* @return zero if the information is unknown.
*/
public int getLocationLine(Element elt) {
- int hash = elt.hashCode() & 0x7FFFFFFF;
- int index = hash % table.length;
-
- for (Entry e = table[index]; e != null; e = e.next) {
- if ((e.hash == hash) && e.element.equals(elt)) {
- return e.locationLine;
- }
- }
+ synchronized (this) {
+ int hash = elt.hashCode() & 0x7FFFFFFF;
+ int index = hash % table.length;
+
+ for (Entry e = table[index]; e != null; e = e.next) {
+ if (e.hash != hash)
+ continue;
+ Object o = e.get();
+ if (o == elt)
+ return e.locationLine;
+ }
+ }
return 0;
}
@@ -67,24 +75,28 @@
* Sets the location in the source file of the end element.
*/
public void setLocationLine(Element elt, int line) {
- int hash = elt.hashCode() & 0x7FFFFFFF;
- int index = hash % table.length;
-
- for (Entry e = table[index]; e != null; e = e.next) {
- if ((e.hash == hash) && e.element.equals(elt)) {
- e.locationLine = line;
- }
- }
-
- // The key is not in the hash table
- int len = table.length;
- if (count++ >= (len * 3) >>> 2) {
- rehash();
- index = hash % table.length;
- }
-
- Entry e = new Entry(hash, elt, line, table[index]);
- table[index] = e;
+ synchronized (this) {
+ int hash = elt.hashCode() & 0x7FFFFFFF;
+ int index = hash % table.length;
+
+ for (Entry e = table[index]; e != null; e = e.next) {
+ if (e.hash != hash)
+ continue;
+ Object o = e.get();
+ if (o == elt)
+ e.locationLine = line;
+ }
+
+ // The key is not in the hash table
+ int len = table.length;
+ if (count++ >= (len * 3) >>> 2) {
+ rehash();
+ index = hash % table.length;
+ }
+
+ Entry e = new Entry(hash, elt, line, table[index]);
+ table[index] = e;
+ }
}
/**
@@ -107,21 +119,37 @@
}
}
+ protected void removeEntry(Entry e) {
+ synchronized (this) {
+ int hash = e.hash;
+ int index = hash % table.length;
+ Entry curr = table[index];
+ Entry prev = null;
+ while (curr != e) {
+ prev = curr;
+ curr = curr.next;
+ }
+ if (curr == null) return; // already remove???
+
+ if (prev == null)
+ // First entry.
+ table[index] = curr.next;
+ else
+ prev.next = curr.next;
+ count--;
+ }
+ }
+
/**
* To manage collisions
*/
- protected static class Entry {
+ protected class Entry extends CleanerThread.WeakReferenceCleared {
/**
* The hash code
*/
public int hash;
/**
- * The element
- */
- public Element element;
-
- /**
* The line number.
*/
public int locationLine;
@@ -135,10 +163,14 @@
* Creates a new entry
*/
public Entry(int hash, Element element, int locationLine, Entry next) {
+ super(element);
this.hash = hash;
- this.element = element;
this.locationLine = locationLine;
this.next = next;
}
+
+ public void cleared() {
+ removeEntry(this);
+ }
}
}
1.49 +2 -1 xml-batik/sources/org/apache/batik/gvt/AbstractGraphicsNode.java
Index: AbstractGraphicsNode.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/gvt/AbstractGraphicsNode.java,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- AbstractGraphicsNode.java 30 May 2003 01:07:15 -0000 1.48
+++ AbstractGraphicsNode.java 8 Jul 2003 00:16:57 -0000 1.49
@@ -602,6 +602,7 @@
(this, GraphicsNodeChangeEvent.CHANGE_STARTED);
changeStartedEvent.setChangeSrc(changeSrc);
fireGraphicsNodeChangeStarted(changeStartedEvent);
+ changeStartedEvent.setChangeSrc(null);
}
//
1.27 +3 -1
xml-batik/sources/org/apache/batik/script/rhino/RhinoInterpreter.java
Index: RhinoInterpreter.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/script/rhino/RhinoInterpreter.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- RhinoInterpreter.java 5 Jul 2003 00:15:07 -0000 1.26
+++ RhinoInterpreter.java 8 Jul 2003 00:16:57 -0000 1.27
@@ -174,6 +174,8 @@
if (!contexts.contains(ctx)) {
ctx.setWrapFactory(wrapFactory);
ctx.setSecurityController(securityController);
+ // This prevents a serious memory leak where
+ // all the SVG document state is preserved.
ctx.setCachingEnabled(false);
contexts.add(ctx);
1.40 +12 -12 xml-batik/sources/org/apache/batik/swing/JSVGCanvas.java
Index: JSVGCanvas.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/swing/JSVGCanvas.java,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- JSVGCanvas.java 17 Jun 2003 01:37:57 -0000 1.39
+++ JSVGCanvas.java 8 Jul 2003 00:16:57 -0000 1.40
@@ -503,7 +503,7 @@
/**
* A swing action to reset the rendering transform of the canvas.
*/
- protected class ResetTransformAction extends AbstractAction {
+ public class ResetTransformAction extends AbstractAction {
public void actionPerformed(ActionEvent evt) {
fragmentIdentifier = null;
resetRenderingTransform();
@@ -517,7 +517,7 @@
* 0,0 so scale and rotate occur around the middle of
* the display.
*/
- protected class AffineAction extends AbstractAction {
+ public class AffineAction extends AbstractAction {
AffineTransform at;
public AffineAction(AffineTransform at) {
this.at = at;
@@ -545,7 +545,7 @@
* A swing action to apply a zoom factor to the canvas.
* This can be used to zoom in (scale > 1) and out (scale <1).
*/
- protected class ZoomAction extends AffineAction {
+ public class ZoomAction extends AffineAction {
public ZoomAction(double scale) {
super(AffineTransform.getScaleInstance(scale, scale));
}
@@ -557,21 +557,21 @@
/**
* A swing action to zoom in the canvas.
*/
- protected class ZoomInAction extends ZoomAction {
+ public class ZoomInAction extends ZoomAction {
ZoomInAction() { super(2); }
}
/**
* A swing action to zoom out the canvas.
*/
- protected class ZoomOutAction extends ZoomAction {
+ public class ZoomOutAction extends ZoomAction {
ZoomOutAction() { super(.5); }
}
/**
* A swing action to Rotate the canvas.
*/
- protected class RotateAction extends AffineAction {
+ public class RotateAction extends AffineAction {
public RotateAction(double theta) {
super(AffineTransform.getRotateInstance(theta));
}
@@ -580,7 +580,7 @@
/**
* A swing action to Pan/scroll the canvas.
*/
- protected class ScrollAction extends AffineAction {
+ public class ScrollAction extends AffineAction {
public ScrollAction(double tx, double ty) {
super(AffineTransform.getTranslateInstance(tx, ty));
}
@@ -590,7 +590,7 @@
* A swing action to scroll the canvas to the right,
* by a fixed amount
*/
- protected class ScrollRightAction extends ScrollAction {
+ public class ScrollRightAction extends ScrollAction {
public ScrollRightAction(int inc) {
super(-inc, 0);
}
@@ -600,7 +600,7 @@
* A swing action to scroll the canvas to the left,
* by a fixed amount
*/
- protected class ScrollLeftAction extends ScrollAction {
+ public class ScrollLeftAction extends ScrollAction {
public ScrollLeftAction(int inc) {
super(inc, 0);
}
@@ -610,7 +610,7 @@
* A swing action to scroll the canvas up,
* by a fixed amount
*/
- protected class ScrollUpAction extends ScrollAction {
+ public class ScrollUpAction extends ScrollAction {
public ScrollUpAction(int inc) {
super(0, inc);
}
@@ -620,7 +620,7 @@
* A swing action to scroll the canvas down,
* by a fixed amount
*/
- protected class ScrollDownAction extends ScrollAction {
+ public class ScrollDownAction extends ScrollAction {
public ScrollDownAction(int inc) {
super(0, -inc);
}
1.34 +6 -1 xml-batik/sources/org/apache/batik/swing/gvt/JGVTComponent.java
Index: JGVTComponent.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/swing/gvt/JGVTComponent.java,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- JGVTComponent.java 11 Apr 2003 13:59:20 -0000 1.33
+++ JGVTComponent.java 8 Jul 2003 00:16:57 -0000 1.34
@@ -675,6 +675,7 @@
textSelectionManager = null;
}
renderer = null;
+ image = null;
gvtRoot = null;
}
@@ -822,6 +823,10 @@
needRender = false;
} else {
immediateRepaint();
+ }
+
+ if (eventDispatcher != null) {
+ eventDispatcher.setRootNode(gvtRoot);
}
}
1.72 +94 -13 xml-batik/sources/org/apache/batik/swing/svg/JSVGComponent.java
Index: JSVGComponent.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/swing/svg/JSVGComponent.java,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -r1.71 -r1.72
--- JSVGComponent.java 19 Jun 2003 00:32:11 -0000 1.71
+++ JSVGComponent.java 8 Jul 2003 00:16:57 -0000 1.72
@@ -49,6 +49,7 @@
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.ViewBox;
import org.apache.batik.dom.svg.SVGDOMImplementation;
+import org.apache.batik.dom.util.DOMUtilities;
import org.apache.batik.dom.util.XLinkSupport;
import org.apache.batik.ext.awt.image.spi.ImageTagRegistry;
import org.apache.batik.gvt.CanvasGraphicsNode;
@@ -63,6 +64,8 @@
import org.apache.batik.util.RunnableQueue;
import org.apache.batik.util.SVGConstants;
import org.apache.batik.util.XMLResourceDescriptor;
+import org.w3c.dom.Document;
+import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGAElement;
import org.w3c.dom.svg.SVGDocument;
@@ -463,14 +466,99 @@
}
/**
- * Sets the SVG document to display.
+ * Sets the Document to display. If the document does not use
+ * Batik's SVG DOM Implemenation it will be cloned into that
+ * implementation. In this case you should use 'getSVGDocument()'
+ * to get the actual DOM that is attached to the rendering interface.
+ */
+ public void setDocument(Document doc) {
+ if ((doc != null) &&
+ !(doc.getImplementation() instanceof SVGDOMImplementation)) {
+ DOMImplementation impl;
+ impl = SVGDOMImplementation.getDOMImplementation();
+ Document d = DOMUtilities.deepCloneDocument(doc, impl);
+ doc = d;
+ }
+ setSVGDocument((SVGDocument)doc);
+ }
+
+ /**
+ * Sets the SVGDocument to display. If the document does not use
+ * Batik's SVG DOM Implemenation it will be cloned into that
+ * implementation. In this case you should use 'getSVGDocument()'
+ * to get the actual DOM that is attached to the rendering
+ * interface.
*/
public void setSVGDocument(SVGDocument doc) {
stopProcessing();
- if (!(doc.getImplementation() instanceof SVGDOMImplementation)) {
- throw new IllegalArgumentException("Invalid DOM implementation.");
+
+ if ((doc != null) &&
+ !(doc.getImplementation() instanceof SVGDOMImplementation)) {
+ DOMImplementation impl;
+ impl = SVGDOMImplementation.getDOMImplementation();
+ Document d = DOMUtilities.deepCloneDocument(doc, impl);
+ doc = (SVGDocument)d;
+ }
+
+ if (updateManager == null) {
+ // No update manager just install new document.
+ installSVGDocument(doc);
+ } else {
+ // We have to wait for the update manager to stop
+ // before we install the new document otherwise bad
+ // things can happen with the update manager.
+ final SVGDocument svgdoc = doc;
+ updateManager.addUpdateManagerListener
+ (new UpdateManagerListener () {
+ UpdateManager um = updateManager;
+ public void managerStopped(UpdateManagerEvent e) {
+ // Remove ourselves from the old update manger,
+ // and install the new document.
+ um.removeUpdateManagerListener(this);
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ installSVGDocument(svgdoc);
+ }
+ });
+ }
+ // There really should be an updateManagerAdapter.
+ public void managerStarted(UpdateManagerEvent e) { }
+ public void managerSuspended(UpdateManagerEvent e) { }
+ public void managerResumed(UpdateManagerEvent e) { }
+ public void updateStarted(UpdateManagerEvent e) { }
+ public void updateCompleted(UpdateManagerEvent e) { }
+ public void updateFailed(UpdateManagerEvent e) { }
+ });
+ }
+
+ }
+
+ /**
+ * This does the real work of installing the SVG Document after
+ * the update manager from the previous document (if any) has been
+ * properly 'shut down'.
+ */
+ protected void installSVGDocument(SVGDocument doc) {
+ svgDocument = doc;
+
+ if (bridgeContext != null) {
+ bridgeContext.dispose();
+ bridgeContext = null;
}
+ releaseRenderingReferences();
+
+ if (doc == null) {
+ isDynamicDocument = false;
+ isInteractiveDocument = false;
+ disableInteractions = true;
+ initialTransform = new AffineTransform();
+ setRenderingTransform(initialTransform, false);
+ Dimension d = getSize();
+ repaint(0, 0, d.width, d.height);
+ return;
+ }
+
switch (documentState) {
case ALWAYS_STATIC:
isDynamicDocument = false;
@@ -489,21 +577,15 @@
if (isDynamicDocument)
isInteractiveDocument = true;
else
- isInteractiveDocument = BridgeContext.isInteractiveDocument(doc);
+ isInteractiveDocument =
+ BridgeContext.isInteractiveDocument(doc);
}
- // System.err.println("Dynamic: " + isDynamicDocument);
- // System.err.println("Interactive: " + isInteractiveDocument);
-
- svgDocument = doc;
Element root = doc.getDocumentElement();
String znp = root.getAttributeNS
(null, SVGConstants.SVG_ZOOM_AND_PAN_ATTRIBUTE);
disableInteractions = !znp.equals(SVGConstants.SVG_MAGNIFY_VALUE);
- if (bridgeContext != null) {
- bridgeContext.dispose();
- }
bridgeContext = createBridgeContext();
nextGVTTreeBuilder = new GVTTreeBuilder(doc, bridgeContext);
nextGVTTreeBuilder.setPriority(Thread.MIN_PRIORITY);
@@ -514,7 +596,6 @@
((GVTTreeBuilderListener)it.next());
}
- releaseRenderingReferences();
initializeEventHandling();
if (gvtTreeBuilder == null &&
1.12 +8 -2 xml-batik/sources/org/apache/batik/util/RunnableQueue.java
Index: RunnableQueue.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/util/RunnableQueue.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- RunnableQueue.java 11 Apr 2003 13:59:29 -0000 1.11
+++ RunnableQueue.java 8 Jul 2003 00:16:57 -0000 1.12
@@ -158,7 +158,13 @@
rable = l.runnable;
}
- rable.run();
+ try {
+ rable.run();
+ } catch (Throwable t) {
+ // Might be nice to notify someone directly.
+ // But this is more or less what Swing does.
+ t.printStackTrace();
+ }
l.unlock();
runnableInvoked(rable);
}
1.1
xml-batik/test-references/test-resources/org/apache/batik/test/svg/SetSVGDocumentTest.png
<<Binary file>>
1.4 +7 -1 xml-batik/test-resources/org/apache/batik/swing/unitTesting.xml
Index: unitTesting.xml
===================================================================
RCS file: /home/cvs/xml-batik/test-resources/org/apache/batik/swing/unitTesting.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- unitTesting.xml 5 Jul 2003 00:15:08 -0000 1.3
+++ unitTesting.xml 8 Jul 2003 00:16:58 -0000 1.4
@@ -20,4 +20,10 @@
<test id="NullURITest"
class="org.apache.batik.swing.NullURITest" />
+
+ <test id="SetSVGDocumentTest"
+ class="org.apache.batik.swing.SetSVGDocumentTest" />
+
+ <test id="NullSetSVGDocumentTest"
+ class="org.apache.batik.swing.NullSetSVGDocumentTest" />
</testSuite>
1.2 +8 -3
xml-batik/test-resources/org/apache/batik/swing/resources/TestMessages.properties
Index: TestMessages.properties
===================================================================
RCS file:
/home/cvs/xml-batik/test-resources/org/apache/batik/swing/resources/TestMessages.properties,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestMessages.properties 5 Jul 2003 00:15:08 -0000 1.1
+++ TestMessages.properties 8 Jul 2003 00:16:58 -0000 1.2
@@ -13,12 +13,17 @@
Error Description
JSVGCanvasHandler.message.error.could.not.load.svg = \
-Could not load SVG file: '{0}'
+Could not load SVG file: {0}
JSVGCanvasHandler.message.error.svg.render.failed = \
-Failed to render SVG file: '{0}'
+Failed to render SVG file: {0}
JSVGCanvasHandler.message.error.svg.update.failed = \
-Failed to handle SVG update: '{0}'
+Failed to handle SVG update: {0}
+NullSetSVGDocumentTest.message.error.image.not.cleared = \
+setSVGDocument(null) failed, display Image was not cleared from component.
+
+NullSetSVGDocumentTest.message.error.on.set = \
+setSVGDocument(null) failed with error: {0}
1.7 +0 -3
xml-batik/test-resources/org/apache/batik/test/svg/resources/Messages.properties
Index: Messages.properties
===================================================================
RCS file:
/home/cvs/xml-batik/test-resources/org/apache/batik/test/svg/resources/Messages.properties,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Messages.properties 5 Jul 2003 00:15:08 -0000 1.6
+++ Messages.properties 8 Jul 2003 00:16:58 -0000 1.7
@@ -9,9 +9,6 @@
#
# Keys in the generated TestReport Entries
#
-JSVGCanvasHandler.entry.key.error.description = \
-Error Description
-
SVGRenderingAccuracyTest.entry.key.error.description = \
Error description
1.2 +146 -106
xml-batik/test-sources/org/apache/batik/swing/JSVGCanvasHandler.java
Index: JSVGCanvasHandler.java
===================================================================
RCS file:
/home/cvs/xml-batik/test-sources/org/apache/batik/swing/JSVGCanvasHandler.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JSVGCanvasHandler.java 5 Jul 2003 00:15:08 -0000 1.1
+++ JSVGCanvasHandler.java 8 Jul 2003 00:16:58 -0000 1.2
@@ -9,6 +9,7 @@
package org.apache.batik.swing;
import java.awt.Dimension;
+import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
@@ -19,12 +20,14 @@
import org.apache.batik.test.Test;
import org.apache.batik.test.TestReport;
+
import org.apache.batik.bridge.ScriptingEnvironment;
import org.apache.batik.bridge.UpdateManager;
import org.apache.batik.bridge.UpdateManagerEvent;
import org.apache.batik.bridge.UpdateManagerListener;
import org.apache.batik.script.Interpreter;
import org.apache.batik.script.InterpreterException;
+import org.apache.batik.util.RunnableQueue;
import org.apache.batik.swing.gvt.GVTTreeRendererAdapter;
import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
@@ -44,7 +47,9 @@
public interface Delegate {
public String getName();
- public void canvasInit(JSVGCanvas canvas);
+ // Returns true if a load event was triggered. In this case
+ // the handler will wait for the load event to complete/fail.
+ public boolean canvasInit(JSVGCanvas canvas);
public void canvasLoaded(JSVGCanvas canvas);
public void canvasRendered(JSVGCanvas canvas);
public boolean canvasUpdated(JSVGCanvas canvas);
@@ -95,14 +100,15 @@
LoadListener ll = null;
UpdateRenderListener url = null;
- boolean renderFailed;
- boolean loadFailed;
- boolean abort;
+ boolean failed;
+ boolean abort = false;
+ boolean done = false;
Object loadMonitor = new Object();
Object renderMonitor = new Object();
Delegate delegate;
Test host;
+ String desc;
public JSVGCanvasHandler(Test host, Delegate delegate) {
this.host = host;
@@ -113,119 +119,97 @@
public JSVGCanvas getCanvas() { return canvas; }
public void runCanvas(String desc) {
- DefaultTestReport report = new DefaultTestReport(host);
- loadFailed = true;
- renderFailed = true;
-
- frame = new JFrame(delegate.getName());
- canvas = new JSVGCanvas();
- frame.getContentPane().add(canvas);
- frame.setSize(new Dimension(450, 500));
- frame.setVisible(true);
- wl = new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- synchronized (loadMonitor) {
- abort = true;
- loadMonitor.notifyAll();
- }
- synchronized (renderMonitor) {
- abort = true;
- renderMonitor.notifyAll();
- }
- }
- };
- frame.addWindowListener(wl);
+ this.desc = desc;
+ try {
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ frame = new JFrame(delegate.getName());
+ canvas = new JSVGCanvas();
+ frame.getContentPane().add(canvas);
+ frame.setSize(new Dimension(450, 500));
+ wl = new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ synchronized (loadMonitor) {
+ abort = true;
+ loadMonitor.notifyAll();
+ }
+ synchronized (renderMonitor) {
+ abort = true;
+ renderMonitor.notifyAll();
+ }
+ }
+ };
+ frame.addWindowListener(wl);
+ frame.setVisible(true);
+
+ irl = new InitialRenderListener();
+ canvas.addGVTTreeRendererListener(irl);
+ ll = new LoadListener();
+ canvas.addSVGDocumentLoaderListener(ll);
+ }});
+ } catch (Throwable t) { }
+
+ if ( abort) return;
- irl = new InitialRenderListener();
- canvas.addGVTTreeRendererListener(irl);
- ll = new LoadListener();
- canvas.addSVGDocumentLoaderListener(ll);
try {
-
- delegate.canvasInit(canvas);
-
synchronized (renderMonitor) {
synchronized (loadMonitor) {
- try { loadMonitor.wait(); }
- catch(InterruptedException ie) { /* nothing */ }
- if (abort || loadFailed) {
- report.setErrorCode(ERROR_CANNOT_LOAD_SVG);
- report.setDescription(new TestReport.Entry[] {
- new TestReport.Entry
- (fmt(ENTRY_KEY_ERROR_DESCRIPTION, null),
- fmt(ERROR_CANNOT_LOAD_SVG,
- new Object[]{desc}))
- });
- report.setPassed(false);
- delegate.failure(report);
- return;
+ if (delegate.canvasInit(canvas)) {
+ checkLoad();
}
- delegate.canvasLoaded(canvas);
}
- try { renderMonitor.wait(); }
- catch(InterruptedException ie) { /* nothing */ }
- if (abort || renderFailed) {
- report.setErrorCode(ERROR_SVG_RENDER_FAILED);
- report.setDescription(new TestReport.Entry[] {
- new TestReport.Entry
- (fmt(ENTRY_KEY_ERROR_DESCRIPTION, null),
- fmt(ERROR_SVG_RENDER_FAILED,
- new Object[]{desc}))
- });
- report.setPassed(false);
- delegate.failure(report);
+ if ( abort) return;
+
+ checkRender();
+ if ( abort) return;
+
+ try {
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ updateManager = canvas.getUpdateManager();
+ if (updateManager == null)
+ return;
+ url = new UpdateRenderListener();
+ updateManager.addUpdateManagerListener(url);
+ }});
+ } catch (Throwable t) { t.printStackTrace(); }
+ if ( abort) return;
+
+ if (updateManager == null)
return;
- }
- delegate.canvasRendered(canvas);
- updateManager = canvas.getUpdateManager();
- if (updateManager != null) {
- url = new UpdateRenderListener();
- updateManager.addUpdateManagerListener(url);
- updateManager.getUpdateRunnableQueue().invokeLater
- (new Runnable() {
- UpdateManager um = updateManager;
- public void run() {
- ScriptingEnvironment scriptEnv;
- scriptEnv = um.getScriptingEnvironment();
- Interpreter interp;
- interp = scriptEnv.getInterpreter();
- interp.bindObject(REGARD_TEST_INSTANCE,
- host);
- try {
- interp.evaluate(REGARD_START_SCRIPT);
- } catch (InterpreterException ie) {
- // Could not wait if no start script.
- }
- }
- });
+ bindHost();
- boolean done = false;
- while (!done) {
- try { renderMonitor.wait(); }
- catch (InterruptedException ie) { /* nothing */ }
- if (abort || renderFailed) {
- report.setErrorCode(ERROR_SVG_UPDATE_FAILED);
- report.setDescription(new TestReport.Entry[] {
- new TestReport.Entry
- (fmt(ENTRY_KEY_ERROR_DESCRIPTION, null),
- fmt(ERROR_SVG_UPDATE_FAILED,
- new Object[]{desc}))
- });
- report.setPassed(false);
- delegate.failure(report);
- return;
- }
- done = delegate.canvasUpdated(canvas);
- }
+ if ( abort) return;
+
+ while (!done) {
+ checkUpdate();
+ if ( abort) return;
}
}
+ } catch (Throwable t) {
+ t.printStackTrace();
} finally {
delegate.canvasDone(canvas);
dispose();
}
}
+
+ public void scriptDone() {
+ if (updateManager == null) return;
+
+ updateManager.getUpdateRunnableQueue().invokeLater
+ (new Runnable() {
+ public void run() {
+ synchronized(renderMonitor) {
+ done = true;
+ failed = false;
+ renderMonitor.notifyAll();
+ }
+ }
+ });
+ }
public void dispose() {
if (frame != null) {
@@ -242,17 +226,73 @@
canvas = null;
frame = null;
}
-
+
+ public void checkSomething(Object monitor, String errorCode) {
+ synchronized (monitor) {
+ failed = true;
+ try { monitor.wait(); }
+ catch(InterruptedException ie) { /* nothing */ }
+ if (abort || failed) {
+ DefaultTestReport report = new DefaultTestReport(host);
+ report.setErrorCode(errorCode);
+ report.setDescription(new TestReport.Entry[] {
+ new TestReport.Entry
+ (fmt(ENTRY_KEY_ERROR_DESCRIPTION, null),
+ fmt(errorCode, new Object[]{desc}))
+ });
+ report.setPassed(false);
+ delegate.failure(report);
+ done = true;
+ return;
+ }
+ }
+ }
+
+ public void checkLoad() {
+ checkSomething(loadMonitor, ERROR_CANNOT_LOAD_SVG);
+ delegate.canvasLoaded(canvas);
+ }
+
+ public void checkRender() {
+ checkSomething(renderMonitor, ERROR_SVG_RENDER_FAILED);
+ delegate.canvasRendered(canvas);
+ }
+
+ public void checkUpdate() {
+ checkSomething(renderMonitor, ERROR_SVG_UPDATE_FAILED);
+ if (!done)
+ done = delegate.canvasUpdated(canvas);
+ }
+
+ public void bindHost() {
+ RunnableQueue rq;
+ rq = updateManager.getUpdateRunnableQueue();
+ rq.invokeLater(new Runnable() {
+ UpdateManager um = updateManager;
+ public void run() {
+ ScriptingEnvironment scriptEnv;
+ scriptEnv = um.getScriptingEnvironment();
+ Interpreter interp;
+ interp = scriptEnv.getInterpreter();
+ interp.bindObject(REGARD_TEST_INSTANCE,
+ host);
+ try {
+ interp.evaluate(REGARD_START_SCRIPT);
+ } catch (InterpreterException ie) {
+ // Could not wait if no start script.
+ }
+ }
+ });
+ }
class UpdateRenderListener implements UpdateManagerListener {
public void updateCompleted(UpdateManagerEvent e) {
synchronized(renderMonitor){
- renderFailed = false;
+ failed = false;
renderMonitor.notifyAll();
}
}
public void updateFailed(UpdateManagerEvent e) {
synchronized(renderMonitor){
- renderFailed = true;
renderMonitor.notifyAll();
}
}
@@ -266,7 +306,7 @@
class InitialRenderListener extends GVTTreeRendererAdapter {
public void gvtRenderingCompleted(GVTTreeRendererEvent e) {
synchronized(renderMonitor){
- renderFailed = false;
+ failed = false;
renderMonitor.notifyAll();
}
}
@@ -288,7 +328,7 @@
class LoadListener extends SVGDocumentLoaderAdapter {
public void documentLoadingCompleted(SVGDocumentLoaderEvent e) {
synchronized(loadMonitor){
- loadFailed = false;
+ failed = false;
loadMonitor.notifyAll();
}
}
1.2 +37 -9
xml-batik/test-sources/org/apache/batik/swing/JSVGMemoryLeakTest.java
Index: JSVGMemoryLeakTest.java
===================================================================
RCS file:
/home/cvs/xml-batik/test-sources/org/apache/batik/swing/JSVGMemoryLeakTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JSVGMemoryLeakTest.java 5 Jul 2003 00:15:08 -0000 1.1
+++ JSVGMemoryLeakTest.java 8 Jul 2003 00:16:58 -0000 1.2
@@ -8,14 +8,22 @@
package org.apache.batik.swing;
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.UpdateManager;
+import org.apache.batik.dom.svg.SVGOMElement;
+import org.apache.batik.dom.svg.SVGContext;
+import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.test.DefaultTestReport;
import org.apache.batik.test.TestReport;
import org.apache.batik.test.MemoryLeakTest;
-import javax.swing.SwingUtilities;
-import javax.swing.JFrame;
import java.io.File;
import java.net.MalformedURLException;
+import javax.swing.SwingUtilities;
+import javax.swing.JFrame;
+
+import org.w3c.dom.Element;
+
/**
* One line Class Desc
@@ -38,6 +46,10 @@
JFrame theFrame;
JSVGCanvas theCanvas;
+ public static String fmt(String key, Object []args) {
+ return TestMessages.formatMessage(key, args);
+ }
+
public TestReport doSomething() throws Exception {
handler = new JSVGCanvasHandler(this, this);
registerObjectDesc(handler, "Handler");
@@ -77,13 +89,27 @@
public void scriptDone() {
synchronized (this) {
done = true;
- // The canvasUpdate will notify the handler that the
- // canvas can be shut down.
+ handler.scriptDone();
+ }
+ }
+
+ public void registerElement(Element e, String desc) {
+ registerObjectDesc(e, desc);
+ UpdateManager um = theCanvas.getUpdateManager();
+ BridgeContext bc = um.getBridgeContext();
+ GraphicsNode gn = bc.getGraphicsNode(e);
+ if (gn != null)
+ registerObjectDesc(gn, desc+"_GN");
+ if (e instanceof SVGOMElement) {
+ SVGOMElement svge = (SVGOMElement)e;
+ SVGContext svgctx = svge.getSVGContext();
+ if (svgctx != null)
+ registerObjectDesc(svgctx, desc+"_CTX");
}
}
/* JSVGCanvasHandler.Delegate Interface */
- public void canvasInit(JSVGCanvas canvas) {
+ public boolean canvasInit(JSVGCanvas canvas) {
// System.err.println("In Init");
theCanvas = canvas;
theFrame = handler.getFrame();
@@ -95,17 +121,19 @@
}
registerObjectDesc(canvas, "JSVGCanvas");
registerObjectDesc(handler.getFrame(), "JFrame");
+
+ return true;
}
public void canvasLoaded(JSVGCanvas canvas) {
// System.err.println("Loaded");
- registerObjectDesc(canvas.getSVGDocument(), "SVG Document");
+ registerObjectDesc(canvas.getSVGDocument(), "SVGDoc");
}
public void canvasRendered(JSVGCanvas canvas) {
// System.err.println("Rendered");
- registerObjectDesc(canvas.getGraphicsNode(), "Graphics Node Tree");
- registerObjectDesc(canvas.getUpdateManager(), "Update Manager");
+ registerObjectDesc(canvas.getGraphicsNode(), "GVT");
+ registerObjectDesc(canvas.getUpdateManager(), "updateManager");
}
public boolean canvasUpdated(JSVGCanvas canvas) {
1.3 +1 -3 xml-batik/test-sources/org/apache/batik/swing/NullURITest.java
Index: NullURITest.java
===================================================================
RCS file: /home/cvs/xml-batik/test-sources/org/apache/batik/swing/NullURITest.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- NullURITest.java 10 Jun 2002 12:07:05 -0000 1.2
+++ NullURITest.java 8 Jul 2003 00:16:58 -0000 1.3
@@ -33,8 +33,6 @@
public static final String ERROR_COULD_NOT_RENDER_NULL_URI
= "error.could.not.render.null.uri";
- public String testURI = "samples/anne.svg";
-
public TestReport runImpl() throws Exception {
final JFrame f = new JFrame();
final JSVGCanvas canvas = new JSVGCanvas();
1.1
xml-batik/test-sources/org/apache/batik/swing/NullSetSVGDocumentTest.java
Index: NullSetSVGDocumentTest.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.batik.swing;
import java.awt.EventQueue;
import java.io.StringWriter;
import java.io.PrintWriter;
import org.apache.batik.dom.GenericDOMImplementation;
import org.apache.batik.test.DefaultTestReport;
import org.apache.batik.test.TestReport;
import org.apache.batik.test.svg.JSVGRenderingAccuracyTest;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Element;
/**
* Test setDocument on JSVGComponent with non-Batik SVGOMDocument.
*
* This test constructs a generic Document with SVG content then it
* ensures that when this is passed to JSVGComponet.setDocument it is
* properly imported to an SVGOMDocument and rendered from there.
*
* @author <a href="mailto:[EMAIL PROTECTED]>l449433</a>
* @version $Id: NullSetSVGDocumentTest.java,v 1.1 2003/07/08 00:16:58 deweese Exp $
*/
public class NullSetSVGDocumentTest extends JSVGMemoryLeakTest {
public NullSetSVGDocumentTest() {
}
public static final String TEST_NON_NULL_URI
= "file:samples/anne.svg";
/**
* Entry describing the error
*/
public static final String ENTRY_KEY_ERROR_DESCRIPTION
= "JSVGCanvasHandler.entry.key.error.description";
/**
* Entry describing the error
*/
public static final String ERROR_IMAGE_NOT_CLEARED
= "NullSetSVGDocumentTest.message.error.image.not.cleared";
public static final String ERROR_ON_SET
= "NullSetSVGDocumentTest.message.error.on.set";
/* JSVGCanvasHandler.Delegate Interface */
public boolean canvasInit(JSVGCanvas canvas) {
theCanvas = canvas;
theFrame = handler.getFrame();
canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
canvas.setURI(TEST_NON_NULL_URI);
registerObjectDesc(canvas, "JSVGCanvas");
registerObjectDesc(handler.getFrame(), "JFrame");
return true; // We did trigger a load event.
}
public void canvasRendered(JSVGCanvas canvas) {
super.canvasRendered(canvas);
final JSVGCanvas c = canvas;
try {
EventQueue.invokeAndWait(new Runnable () {
public void run() {
c.setSVGDocument(null);
}});
} catch (Throwable t) {
StringWriter trace = new StringWriter();
t.printStackTrace(new PrintWriter(trace));
DefaultTestReport report = new DefaultTestReport(this);
report.setErrorCode(ERROR_ON_SET);
report.setDescription(new TestReport.Entry[] {
new TestReport.Entry
(fmt(ENTRY_KEY_ERROR_DESCRIPTION, null),
fmt(ERROR_ON_SET, new Object[]{ trace.toString()}))
});
report.setPassed(false);
failReport = report;
}
// Check that the original SVG Document and GVT tree are cleared.
checkObjects(new String[] { "SVGDoc", "GVT", "updateManager" });
}
public boolean canvasUpdated(JSVGCanvas canvas) {
return true;
}
public void canvasDone(JSVGCanvas canvas) {
synchronized (this) {
if (canvas.getOffScreen() == null)
return;
DefaultTestReport report = new DefaultTestReport(this);
report.setErrorCode(ERROR_IMAGE_NOT_CLEARED);
// It would be great to provide the image here
// but it's a lot of work and this isn't _really_
// what we are testing. More testing that
// everything works (no exceptions thrown).
report.setDescription(new TestReport.Entry[] {
new TestReport.Entry
(fmt(ENTRY_KEY_ERROR_DESCRIPTION, null),
fmt(ERROR_IMAGE_NOT_CLEARED, null))});
report.setPassed(false);
failReport = report;
return;
}
}
};
1.1
xml-batik/test-sources/org/apache/batik/swing/SetSVGDocumentTest.java
Index: SetSVGDocumentTest.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.batik.swing;
import org.apache.batik.test.svg.JSVGRenderingAccuracyTest;
import org.apache.batik.util.SVGConstants;
import org.apache.batik.dom.GenericDOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Element;
/**
* Test setDocument on JSVGComponent with non-Batik SVGOMDocument.
*
* This test constructs a generic Document with SVG content then it
* ensures that when this is passed to JSVGComponet.setDocument it is
* properly imported to an SVGOMDocument and rendered from there.
*
* @author <a href="mailto:[EMAIL PROTECTED]>l449433</a>
* @version $Id: SetSVGDocumentTest.java,v 1.1 2003/07/08 00:16:58 deweese Exp $
*/
public class SetSVGDocumentTest extends JSVGRenderingAccuracyTest {
public SetSVGDocumentTest() {
}
protected String[] breakSVGFile(String svgFile){
if(svgFile == null) {
throw new IllegalArgumentException(svgFile);
}
String [] ret = new String[3];
ret[0] = "test-resources/org/apache/batik/test/svg/";
ret[1] = "SetSVGDocumentTest";
ret[2] = ".svg";
return ret;
}
/* JSVGCanvasHandler.Delegate Interface */
public boolean canvasInit(JSVGCanvas canvas) {
DOMImplementation impl =
GenericDOMImplementation.getDOMImplementation();
Document doc = impl.createDocument(SVGConstants.SVG_NAMESPACE_URI,
SVGConstants.SVG_SVG_TAG, null);
Element e = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
SVGConstants.SVG_RECT_TAG);
e.setAttribute("x", "10");
e.setAttribute("y", "10");
e.setAttribute("width", "100");
e.setAttribute("height", "50");
e.setAttribute("fill", "crimson");
doc.getDocumentElement().appendChild(e);
e = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
SVGConstants.SVG_CIRCLE_TAG);
e.setAttribute("cx", "55");
e.setAttribute("cy", "35");
e.setAttribute("r", "30");
e.setAttribute("fill", "gold");
doc.getDocumentElement().appendChild(e);
canvas.setDocument(doc);
return false; // We didn't trigger a load event.
}
public boolean canvasUpdated(JSVGCanvas canvas) {
return true;
}
};
1.3 +117 -34 xml-batik/test-sources/org/apache/batik/test/MemoryLeakTest.java
Index: MemoryLeakTest.java
===================================================================
RCS file:
/home/cvs/xml-batik/test-sources/org/apache/batik/test/MemoryLeakTest.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- MemoryLeakTest.java 5 Jul 2003 00:15:08 -0000 1.2
+++ MemoryLeakTest.java 8 Jul 2003 00:16:58 -0000 1.3
@@ -8,8 +8,10 @@
package org.apache.batik.test;
-import java.util.Set;
-import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
import java.util.Iterator;
import org.apache.batik.test.AbstractTest;
@@ -28,11 +30,14 @@
*/
public abstract class MemoryLeakTest extends AbstractTest {
- // I know that 60 seems _really_ high but it turns out
- // That the GraphicsNodeTree was not being cleared when I
- // tested with as high as 36. So I would leave it at 60
- // (why so large I don't know).
- final static int NUM_GC=60;
+ // I know that 120 seems _really_ high but it turns out
+ // That the "GraphicsNodeTree" was not being cleared when I
+ // tested with as high as 60. So I would leave it at 120
+ // (why so large I don't know) - it will bail if the all
+ // the objects of interest are collected sooner so the runtime
+ // is really only a concern for failures.
+ final static int NUM_GC=120;
+
final static String ERROR_OBJS_NOT_CLEARED =
"MemoryLeakTest.message.error.objs.not.cleared";
@@ -46,61 +51,139 @@
public MemoryLeakTest() {
}
- Set objs = new HashSet();
+ Map objs = new HashMap();
+ List entries = new ArrayList();
public void registerObject(Object o) {
synchronized (objs) {
- objs.add(new WeakRef(o));
+ String desc = o.toString();
+ objs.put(desc, new WeakRef(o, desc));
}
}
public void registerObjectDesc(Object o, String desc) {
synchronized (objs) {
- objs.add(new WeakRef(o, desc));
+ objs.put(desc, new WeakRef(o, desc));
}
}
+ public boolean checkObject(String desc) {
+ String [] strs = new String[1];
+ strs[0] = desc;
+ return checkObjects(strs);
+ }
- public TestReport runImpl() throws Exception {
- TestReport ret = doSomething();
- if ((ret != null) && !ret.hasPassed())
- return ret;
-
+ public boolean checkObjects(String [] descs) {
for (int i=0; i<NUM_GC; i++) {
System.gc();
+ boolean passed = true;
+ for (int j=0; j< descs.length; j++) {
+ String desc = descs[j];
+ WeakRef wr = (WeakRef)objs.get(desc);
+ if ((wr != null) && (wr.get() != null)) {
+ passed = false;
+ break;
+ }
+ }
+ if (passed) return true;
}
StringBuffer sb = new StringBuffer();
- int count = 0;
synchronized (objs) {
- Iterator i = objs.iterator();
- while (i.hasNext()) {
- WeakRef wr = (WeakRef)i.next();
+ boolean passed = true;
+ for (int j=0; j< descs.length; j++) {
+ String desc = descs[j];
+ WeakRef wr = (WeakRef)objs.get(desc);
+ if ((wr == null) || (wr.get() == null)) continue;
+ if (!passed)
+ sb.append(","); // Already put one obj out
+ passed = false;
+ sb.append("'");
+ sb.append(wr.getDesc());
+ sb.append("'");
+ }
+ }
+
+ String objStr = sb.toString();
+ TestReport.Entry entry = new TestReport.Entry
+ (fmt(ERROR_DESCRIPTION, null),
+ fmt(ERROR_OBJS_NOT_CLEARED, new Object[]{objStr}));
+ entries.add(entry);
+
+ if (objStr.length() > 40)
+ objStr = objStr.substring(0,40) + "..." ;
+ System.err.print(">>>>> Objects not cleared: " + objStr + "\n");
+ return false;
+ }
+
+ public boolean checkObjectsList(List descs) {
+ String [] strs = new String[descs.size()];
+ descs.toArray(strs);
+ return checkObjects(strs);
+ }
+
+ public boolean checkAllObjects() {
+ for (int i=0; i<NUM_GC; i++) {
+ System.gc();
+ synchronized (objs) {
+ boolean passed = true;
+ Iterator iter = objs.values().iterator();
+ while (iter.hasNext()) {
+ WeakRef wr = (WeakRef)iter.next();
+ Object o = wr.get();
+ if (o != null) {
+ passed = false;
+ break;
+ }
+ }
+ if (passed) return true;
+ }
+ }
+
+ StringBuffer sb = new StringBuffer();
+ synchronized (objs) {
+ boolean passed = true;
+ Iterator iter = objs.values().iterator();
+ while (iter.hasNext()) {
+ WeakRef wr = (WeakRef)iter.next();
Object o = wr.get();
if (o == null) continue;
- if (count != 0)
+ if (!passed)
sb.append(",");
-
+ passed = false;
sb.append(wr.getDesc());
- count++;
}
+ if (passed) return true;
}
- DefaultTestReport report = new DefaultTestReport(this);
- if (count == 0) {
- report.setPassed(true);
- return report;
- }
String objStr = sb.toString();
- report.setErrorCode(ERROR_OBJS_NOT_CLEARED);
- report.setDescription(new TestReport.Entry[] {
- new TestReport.Entry
+ TestReport.Entry entry = new TestReport.Entry
(fmt(ERROR_DESCRIPTION, null),
- fmt(ERROR_OBJS_NOT_CLEARED, new Object[]{objStr}))
- });
+ fmt(ERROR_OBJS_NOT_CLEARED, new Object[]{objStr}));
+ entries.add(entry);
+
if (objStr.length() > 40)
objStr = objStr.substring(0,40) + "..." ;
System.err.print(">>>>> Objects not cleared: " + objStr + "\n");
+ return false;
+ }
+
+ public TestReport runImpl() throws Exception {
+ TestReport ret = doSomething();
+ if ((ret != null) && !ret.hasPassed())
+ return ret;
+
+ checkAllObjects();
+
+ DefaultTestReport report = new DefaultTestReport(this);
+ if (entries.size() == 0) {
+ report.setPassed(true);
+ return report;
+ }
+ report.setErrorCode(ERROR_OBJS_NOT_CLEARED);
+ report.setDescription
+ ((TestReport.Entry[])entries.toArray
+ (new TestReport.Entry[entries.size()]));
report.setPassed(false);
return report;
}
@@ -122,7 +205,7 @@
public void cleared() {
synchronized (objs) {
- objs.remove(this);
+ objs.remove(desc);
}
}
1.3 +9 -6
xml-batik/test-sources/org/apache/batik/test/svg/JSVGRenderingAccuracyTest.java
Index: JSVGRenderingAccuracyTest.java
===================================================================
RCS file:
/home/cvs/xml-batik/test-sources/org/apache/batik/test/svg/JSVGRenderingAccuracyTest.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- JSVGRenderingAccuracyTest.java 5 Jul 2003 00:15:08 -0000 1.2
+++ JSVGRenderingAccuracyTest.java 8 Jul 2003 00:16:58 -0000 1.3
@@ -55,15 +55,18 @@
FileOutputStream fos;
TestReport failReport = null;
boolean done;
+ JSVGCanvasHandler handler = null;
public TestReport encode(URL srcURL, FileOutputStream fos) {
this.srcURL = srcURL;
this.fos = fos;
- JSVGCanvasHandler handler = new JSVGCanvasHandler(this, this);
+ handler = new JSVGCanvasHandler(this, this);
done = false;
handler.runCanvas(srcURL.toString());
-
+
+ handler = null;
+
if (failReport != null) return failReport;
DefaultTestReport report = new DefaultTestReport(this);
@@ -74,14 +77,14 @@
public void scriptDone() {
synchronized (this) {
done = true;
- // The canvasUpdate will notify the handler that the
- // canvas can be shut down.
+ handler.scriptDone();
}
}
/* JSVGCanvasHandler.Delegate Interface */
- public void canvasInit(JSVGCanvas canvas) {
+ public boolean canvasInit(JSVGCanvas canvas) {
canvas.setURI(srcURL.toString());
+ return true;
}
public void canvasLoaded(JSVGCanvas canvas) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]