You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by vh...@apache.org on 2001/02/15 03:27:30 UTC
cvs commit: xml-batik/sources/org/apache/batik/util SoftReferenceCache.java
vhardy 01/02/14 18:27:30
Modified: sources/org/apache/batik/bridge CSSUtilities.java
SVGColorProfileElementBridge.java
SVGImageElementBridge.java
SVGPatternElementBridge.java
sources/org/apache/batik/ext/awt/color ICCColorSpaceExt.java
sources/org/apache/batik/ext/awt/image/renderable
RasterRable.java URLImageCache.java
sources/org/apache/batik/ext/awt/image/rendered
ProfileRed.java
sources/org/apache/batik/svggen
ImageHandlerBase64Encoder.java
Added: sources/org/apache/batik/ext/awt/color
NamedProfileCache.java
sources/org/apache/batik/util SoftReferenceCache.java
Log:
More work on color-profile:
a. Added caching for color-profile so that if the same color-profile is
referenced multiple times, it is only loaded once.
b. Added color-profile support on Base64 images.
c. Abstracted Thomas' URLImageCache into a SoftReferenceCache (in xx.util)
that URLImageCache and NamedProfileCache (new) extend by offering
strongly typed methods.
The modifications are validated by a new test: samples\tests\colorProfile.svg.
Revision Changes Path
1.15 +1 -11 xml-batik/sources/org/apache/batik/bridge/CSSUtilities.java
Index: CSSUtilities.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/CSSUtilities.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- CSSUtilities.java 2001/02/14 20:34:19 1.14
+++ CSSUtilities.java 2001/02/15 02:27:28 1.15
@@ -70,7 +70,7 @@
* A collection of utility methods involving CSS.
*
* @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
- * @version $Id: CSSUtilities.java,v 1.14 2001/02/14 20:34:19 vhardy Exp $
+ * @version $Id: CSSUtilities.java,v 1.15 2001/02/15 02:27:28 vhardy Exp $
*/
public class CSSUtilities implements SVGConstants {
@@ -643,18 +643,8 @@
return null;
}
- for(int i=0; i<colorValue.length; i++){
- System.out.println("colorValue[" + i + "] = " + colorValue[i]);
- // colorValue[i] /= 255f;
- }
-
- System.out.println("opacity : " + opacity);
-
// Convert values to RGB
float rgb[] = profileCS.intendedToRGB(colorValue);
- for(int i=0; i<colorValue.length; i++){
- System.out.println("rgb[" + i + "] = " + rgb[i]);
- }
return new Color(rgb[0], rgb[1], rgb[2], opacity);
}
1.2 +28 -3 xml-batik/sources/org/apache/batik/bridge/SVGColorProfileElementBridge.java
Index: SVGColorProfileElementBridge.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGColorProfileElementBridge.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SVGColorProfileElementBridge.java 2001/02/14 20:34:20 1.1
+++ SVGColorProfileElementBridge.java 2001/02/15 02:27:28 1.2
@@ -20,6 +20,7 @@
import org.apache.batik.bridge.resources.Messages;
import org.apache.batik.dom.svg.SVGOMDocument;
import org.apache.batik.ext.awt.color.ICCColorSpaceExt;
+import org.apache.batik.ext.awt.color.NamedProfileCache;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -31,10 +32,15 @@
* an <tt>ICC_ColorSpace</tt> object.
*
* @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
- * @version $Id: SVGColorProfileElementBridge.java,v 1.1 2001/02/14 20:34:20 vhardy Exp $
+ * @version $Id: SVGColorProfileElementBridge.java,v 1.2 2001/02/15 02:27:28 vhardy Exp $
*/
public class SVGColorProfileElementBridge implements Bridge, SVGConstants {
/**
+ * Profile cache
+ */
+ public NamedProfileCache cache = new NamedProfileCache();
+
+ /**
* Builds an ICC_ColorSpace for the given input color profile
* name, if the name can be resolved and successfully accessed
*
@@ -49,9 +55,17 @@
public ICCColorSpaceExt build(String iccProfileName,
BridgeContext ctx,
Element paintedElement){
- System.out.println("Invoking ColorProfileElementBridge : " + iccProfileName);
+ /*
+ * Check if there is one if the cache.
+ */
+ ICCColorSpaceExt cs = cache.request(iccProfileName);
+ if(cs != null){
+ return cs;
+ }
/**
+ * There was no cached copies for the profile. Load it
+ * now.
* Search for a color-profile element with specific name
*/
Document doc = paintedElement.getOwnerDocument();
@@ -106,8 +120,15 @@
*/
String intentStr = profile.getAttributeNS(null, SVG_RENDERING_INTENT_ATTRIBUTE);
int intent = convertIntent(intentStr);
+
+ cs = new ICCColorSpaceExt(p, intent);
- return new ICCColorSpaceExt(p, intent);
+ /**
+ * Add profile to cache
+ */
+ cache.put(iccProfileName, cs);
+
+ return cs;
}
private int convertIntent(String intentStr){
@@ -125,6 +146,10 @@
}
if(VALUE_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC_VALUE.equals(intentStr)){
return ICCColorSpaceExt.ABSOLUTE_COLORIMETRIC;
+ }
+
+ if(VALUE_RENDERING_INTENT_SATURATION_VALUE.equals(intentStr)){
+ return ICCColorSpaceExt.SATURATION;
}
throw new IllegalAttributeValueException
1.10 +1 -4 xml-batik/sources/org/apache/batik/bridge/SVGImageElementBridge.java
Index: SVGImageElementBridge.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGImageElementBridge.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- SVGImageElementBridge.java 2001/02/14 20:34:21 1.9
+++ SVGImageElementBridge.java 2001/02/15 02:27:28 1.10
@@ -66,7 +66,7 @@
*
* @author <a href="mailto:Thierry.Kormann@sophia.inria.fr">Thierry Kormann</a>
* @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
- * @version $Id: SVGImageElementBridge.java,v 1.9 2001/02/14 20:34:21 vhardy Exp $
+ * @version $Id: SVGImageElementBridge.java,v 1.10 2001/02/15 02:27:28 vhardy Exp $
*/
public class SVGImageElementBridge implements GraphicsNodeBridge,
SVGConstants {
@@ -200,8 +200,6 @@
String colorProfileProperty
= svgElement.getAttributeNS(null, CSS_COLOR_PROFILE_PROPERTY);
- System.out.println(CSS_COLOR_PROFILE_PROPERTY + " : " + colorProfileProperty);
-
/**
* The only cases that need special handling are
* 'sRGB' and 'name'
@@ -229,7 +227,6 @@
= profileBridge.build(colorProfileProperty,
ctx, svgElement);
- System.out.println("colorSpace : " + colorSpace);
}
}
1.12 +1 -2 xml-batik/sources/org/apache/batik/bridge/SVGPatternElementBridge.java
Index: SVGPatternElementBridge.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGPatternElementBridge.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- SVGPatternElementBridge.java 2001/02/14 20:34:22 1.11
+++ SVGPatternElementBridge.java 2001/02/15 02:27:28 1.12
@@ -47,7 +47,7 @@
* a <tt>PatternPaint</tt>
*
* @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
- * @version $Id: SVGPatternElementBridge.java,v 1.11 2001/02/14 20:34:22 vhardy Exp $
+ * @version $Id: SVGPatternElementBridge.java,v 1.12 2001/02/15 02:27:28 vhardy Exp $
*/
public class SVGPatternElementBridge implements PaintBridge, SVGConstants {
@@ -296,7 +296,6 @@
CSSPrimitiveValue v =
(CSSPrimitiveValue)paintedCssDecl.getPropertyCSSValue(paintOpacityProperty);
float opacity = CSSUtilities.convertOpacity(v);
- System.out.println("Pattern on " + paintOpacityProperty + " = " + opacity);
if(opacity != 1){
float[][] matrix = {{1, 0, 0, 0, 0},
{0, 1, 0, 0, 0},
1.2 +16 -8 xml-batik/sources/org/apache/batik/ext/awt/color/ICCColorSpaceExt.java
Index: ICCColorSpaceExt.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/color/ICCColorSpaceExt.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ICCColorSpaceExt.java 2001/02/14 20:34:26 1.1
+++ ICCColorSpaceExt.java 2001/02/15 02:27:28 1.2
@@ -19,7 +19,7 @@
* relative colorimetric.
*
* @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
- * @version $Id: ICCColorSpaceExt.java,v 1.1 2001/02/14 20:34:26 vhardy Exp $
+ * @version $Id: ICCColorSpaceExt.java,v 1.2 2001/02/15 02:27:28 vhardy Exp $
*/
public class ICCColorSpaceExt extends ICC_ColorSpace {
public static final int PERCEPTUAL = 0;
@@ -41,10 +41,18 @@
case ABSOLUTE_COLORIMETRIC:
case SATURATION:
case PERCEPTUAL:
- return;
+ break;
default:
throw new IllegalArgumentException();
}
+
+ /**
+ * Apply the requested intent into the profile
+ */
+ if(intent != AUTO){
+ byte[] hdr = p.getData(ICC_Profile.icSigHead);
+ hdr[ICC_Profile.icHdrRenderingIntent] = (byte)intent;
+ }
}
/**
@@ -73,7 +81,6 @@
* base class's toRGB method
*/
public float[] perceptualToRGB(float[] values){
- System.out.println("==> perceptual");
return toRGB(values);
}
@@ -82,22 +89,23 @@
* conversion
*/
public float[] relativeColorimetricToRGB(float[] values){
- System.out.println("==> relativeColorimetric");
float[] ciexyz = toCIEXYZ(values);
return sRGB.fromCIEXYZ(ciexyz);
}
/**
- * Absolute colorimetric. NOT IMPLEMENTED
+ * Absolute colorimetric. NOT IMPLEMENTED.
+ * Temporarily returns same as perceptual
*/
public float[] absoluteColorimetricToRGB(float[] values){
- throw new Error();
+ return perceptualToRGB(values);
}
/**
- * Saturation. NOT IMPLEMENTED
+ * Saturation. NOT IMPLEMENTED. Temporarily returns same
+ * as perceptual.
*/
public float[] saturationToRGB(float[] values){
- throw new Error();
+ return perceptualToRGB(values);
}
}
1.1 xml-batik/sources/org/apache/batik/ext/awt/color/NamedProfileCache.java
Index: NamedProfileCache.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.ext.awt.color;
import java.awt.image.RenderedImage;
import java.net.URL;
import java.util.Map;
import java.util.HashMap;
import java.lang.ref.SoftReference;
import org.apache.batik.util.SoftReferenceCache;
/**
* This class manages a cache of soft references to named profiles that
* we have already loaded.
*
* @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
* @version $Id: NamedProfileCache.java,v 1.1 2001/02/15 02:27:28 vhardy Exp $
*/
public class NamedProfileCache extends SoftReferenceCache{
static NamedProfileCache theCache = new NamedProfileCache();
public static NamedProfileCache getDefaultCache() { return theCache; }
/**
* Let people create there own caches.
*/
public NamedProfileCache() { }
/**
* Check if <tt>request(profileName)</tt> will return with a ICCColorSpaceExt
* (not putting you on the hook for it). Note that it is possible
* that this will return true but between this call and the call
* to request the soft-reference will be cleared. So it
* is still possible for request to return NULL, just much less
* likely (you can always call 'clear' in that case).
*/
public synchronized boolean isPresent(String profileName) {
return super.isPresentImpl(profileName);
}
/**
* Check if <tt>request(profileName)</tt> will return immediately with the
* ICCColorSpaceExt. Note that it is possible that this will return
* true but between this call and the call to request the
* soft-reference will be cleared.
*/
public synchronized boolean isDone(String profileName) {
return super.isDoneImpl(profileName);
}
/**
* If this returns null then you are now 'on the hook'.
* to put the ICCColorSpaceExt associated with String into the
* cache. */
public synchronized ICCColorSpaceExt request(String profileName) {
return (ICCColorSpaceExt)super.requestImpl(profileName);
}
/**
* Clear the entry for String.
* This is the easiest way to 'get off the hook'.
* if you didn't indend to get on it.
*/
public synchronized void clear(String profileName) {
super.clearImpl(profileName);
}
/**
* Associate bi with profileName. bi is only referenced through
* a soft reference so don't rely on the cache to keep it
* around. If the map no longer contains our profileName it was
* probably cleared or flushed since we were put on the hook
* for it, so in that case we will do nothing.
*/
public synchronized void put(String profileName, ICCColorSpaceExt bi) {
super.putImpl(profileName, bi);
}
}
1.5 +11 -4 xml-batik/sources/org/apache/batik/ext/awt/image/renderable/RasterRable.java
Index: RasterRable.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/renderable/RasterRable.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- RasterRable.java 2001/02/14 20:34:26 1.4
+++ RasterRable.java 2001/02/15 02:27:29 1.5
@@ -21,7 +21,6 @@
import java.awt.Graphics2D;
import java.awt.Label;
import java.awt.MediaTracker;
-import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
@@ -64,7 +63,7 @@
* RenderableImage world.
*
* @author <a href="mailto:Thomas.DeWeese@Kodak.com>Thomas DeWeese</a>
- * @version $Id: RasterRable.java,v 1.4 2001/02/14 20:34:26 vhardy Exp $
+ * @version $Id: RasterRable.java,v 1.5 2001/02/15 02:27:29 vhardy Exp $
*/
public class RasterRable
extends AbstractRable {
@@ -205,7 +204,6 @@
*/
public ImageLoader(ICCColorSpaceExt colorSpace) {
this.colorSpace = colorSpace;
- System.out.println("colorSpace : " + colorSpace);
}
/**
@@ -371,7 +369,6 @@
RenderedImage bi = cache.request(url);
if (bi == null){
- System.out.println("Loading " + url);
// Image is not loaded yet
bi = super.load();
@@ -451,5 +448,15 @@
return null;
}
}
+
+ public RenderedImage load() {
+ RenderedImage ri = super.load();
+ if(ri != null && colorSpace != null){
+ ri = applyColorProfile(ri);
+ }
+
+ return ri;
+ }
+
}
}
1.4 +8 -79 xml-batik/sources/org/apache/batik/ext/awt/image/renderable/URLImageCache.java
Index: URLImageCache.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/renderable/URLImageCache.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- URLImageCache.java 2001/02/14 20:34:27 1.3
+++ URLImageCache.java 2001/02/15 02:27:29 1.4
@@ -17,6 +17,8 @@
import java.lang.ref.SoftReference;
+import org.apache.batik.util.SoftReferenceCache;
+
/**
* This class manages a cache of soft references to Images that
* we have already loaded. Adding an image is two fold.
@@ -28,12 +30,10 @@
* been put they will be blocked until the put.
*/
-public class URLImageCache {
+public class URLImageCache extends SoftReferenceCache{
static URLImageCache theCache = new URLImageCache();
- HashMap map = new HashMap();
-
public static URLImageCache getDefaultCache() { return theCache; }
/**
@@ -41,18 +41,6 @@
*/
public URLImageCache() { }
-
- /**
- * Let people flush the cache (remove any cached data). Pending
- * requests will be treated as though clear() was called on the
- * URL, this should cause them to go and re-read the data.
- */
-
- public synchronized void flush() {
- map.clear();
- this.notifyAll();
- }
-
/**
* Check if <tt>request(url)</tt> will return with a RenderedImage
* (not putting you on the hook for it). Note that it is possible
@@ -62,24 +50,7 @@
* likely (you can always call 'clear' in that case).
*/
public synchronized boolean isPresent(URL url) {
- if (!map.containsKey(url))
- return false;
-
- Object o = map.get(url);
- if (o == null)
- // It's been requested but hasn't been 'put' yet.
- return true;
-
- // It's been put let's make sure the soft reference hasn't
- // been cleared.
- SoftReference sr = (SoftReference)o;
- o = sr.get();
- if (o != null)
- return true;
-
- // Soft reference was cleared, so remove our record of url.
- clear(url);
- return false;
+ return super.isPresentImpl(url);
}
/**
@@ -89,16 +60,7 @@
* soft-reference will be cleared.
*/
public synchronized boolean isDone(URL url) {
- Object o = map.get(url);
- if (o == null) return false;
- SoftReference sr = (SoftReference)o;
- o = sr.get();
- if (o != null)
- return true;
-
- // Soft reference was cleared
- clear(url);
- return false;
+ return super.isDoneImpl(url);
}
/**
@@ -106,35 +68,7 @@
* to put the RenderedImage associated with URL into the
* cache. */
public synchronized RenderedImage request(URL url) {
- if (map.containsKey(url)) {
-
- Object o = map.get(url);
- while(o == null) {
- try {
- // When something is cleared or put we will be notified.
- wait();
- }
- catch (InterruptedException ie) { }
-
- // check if url was cleared, if so it will most likely
- // never be 'put'.
- if (!map.containsKey(url))
- break;
-
- // Let's see if it was put...
- o = map.get(url);
- }
- if (o != null) {
- SoftReference sr = (SoftReference)o;
- o = sr.get();
- if (o != null)
- return (RenderedImage)o;
- }
- }
-
- // So now the caller get's the hot potato.
- map.put(url, null);
- return null;
+ return (RenderedImage)super.requestImpl(url);
}
/**
@@ -143,8 +77,7 @@
* if you didn't indend to get on it.
*/
public synchronized void clear(URL url) {
- map.remove(url);
- this.notifyAll();
+ super.clearImpl(url);
}
/**
@@ -155,10 +88,6 @@
* for it, so in that case we will do nothing.
*/
public synchronized void put(URL url, RenderedImage bi) {
- if (map.containsKey(url)) {
- SoftReference ref = new SoftReference(bi);
- map.put(url, ref);
- this.notifyAll();
- }
+ super.putImpl(url, bi);
}
}
1.2 +1 -2 xml-batik/sources/org/apache/batik/ext/awt/image/rendered/ProfileRed.java
Index: ProfileRed.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/ProfileRed.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ProfileRed.java 2001/02/14 20:34:28 1.1
+++ ProfileRed.java 2001/02/15 02:27:29 1.2
@@ -37,7 +37,7 @@
* on its source
*
* @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
- * @version $Id: ProfileRed.java,v 1.1 2001/02/14 20:34:28 vhardy Exp $
+ * @version $Id: ProfileRed.java,v 1.2 2001/02/15 02:27:29 vhardy Exp $
*/
public class ProfileRed extends AbstractRed {
private static final ColorSpace sRGBCS
@@ -102,7 +102,6 @@
* any bug as of JDK 1.3.
*/
public WritableRaster copyData(WritableRaster argbWR){
- System.err.println("Applying color profile .....");
try{
RenderedImage img = getSource();
1.7 +37 -8 xml-batik/sources/org/apache/batik/svggen/ImageHandlerBase64Encoder.java
Index: ImageHandlerBase64Encoder.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/svggen/ImageHandlerBase64Encoder.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ImageHandlerBase64Encoder.java 2001/02/06 12:33:38 1.6
+++ ImageHandlerBase64Encoder.java 2001/02/15 02:27:29 1.7
@@ -29,7 +29,7 @@
* the data protocol.
*
* @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
- * @version $Id: ImageHandlerBase64Encoder.java,v 1.6 2001/02/06 12:33:38 tkormann Exp $
+ * @version $Id: ImageHandlerBase64Encoder.java,v 1.7 2001/02/15 02:27:29 vhardy Exp $
* @see org.apache.batik.svggen.SVGGraphics2D
* @see org.apache.batik.svggen.ImageHandler
*/
@@ -151,13 +151,41 @@
/**
* Unit testing
*/
+ public static final String USAGE = "java org.apache.batik.svggen.ImageHandlerBase64Encoder [<imageFile>]";
+
public static void main(String args[]) {
- BufferedImage buf = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
- Graphics2D g = buf.createGraphics();
- g.setPaint(Color.red);
- g.fillRect(0, 0, 50, 50);
- g.fillRect(50, 50, 50, 50);
- g.dispose();
+ BufferedImage buf = null;
+
+ if(args.length == 0){
+ buf = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = buf.createGraphics();
+ g.setPaint(Color.red);
+ g.fillRect(0, 0, 50, 50);
+ g.fillRect(50, 50, 50, 50);
+ g.dispose();
+ }
+ else{
+ Component cmp = new Component(){};
+ MediaTracker mediaTracker = new MediaTracker(cmp);
+ Image img = Toolkit.getDefaultToolkit().createImage(args[0]);
+ mediaTracker.addImage(img, 0);
+ try{
+ mediaTracker.waitForAll();
+ }catch(InterruptedException e){
+ img = null;
+ }
+
+ if(img == null){
+ System.err.println("Could not load : " + args[0]);
+ }
+
+ buf = new BufferedImage(img.getWidth(null),
+ img.getHeight(null),
+ BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = buf.createGraphics();
+ g.drawImage(img, 0, 0, null);
+ g.dispose();
+ }
ImageHandler imageHandler = new ImageHandlerBase64Encoder();
Document domFactory = TestUtil.getDocumentPrototype();
@@ -171,7 +199,8 @@
System.out.println();
System.out.println("<svg width=\"450\" height=\"500\">");
System.out.println(" <rect width=\"100%\" height=\"100%\" fill=\"yellow\" />");
- System.out.println(" <image x=\"30\" y=\"30\" xlink:href=\"" + imageElement.getAttributeNS(null, SVGSyntax.ATTR_XLINK_HREF) + "\" width=\"100\" height=\"100\" />");
+ System.out.println(" <image width=\"" + buf.getWidth() + "\" height=\"" +
+ buf.getHeight() + "\" xlink:href=\"" + XLinkSupport.getXLinkHref(imageElement) + "\" />");
System.out.println("</svg>");
System.exit(0);
}
1.1 xml-batik/sources/org/apache/batik/util/SoftReferenceCache.java
Index: SoftReferenceCache.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.util;
import java.util.Map;
import java.util.HashMap;
import java.lang.ref.SoftReference;
/**
* This class manages a cache of soft references to objects that may
* take some time to load or create, such as images loaded from the
* network.
*
* Adding an object is two fold: <br />
* + First you add the key, this lets the cache know that someone is
* working on that key. <br />
* + Then when the completed object is ready you put it into the cache.<P>
*
* If someone requests a key after it has been added but before it has
* been put they will be blocked until the put.
*/
public class SoftReferenceCache {
HashMap map = new HashMap();
/**
* Let people create there own caches.
*/
protected SoftReferenceCache() { }
/**
* Let people flush the cache (remove any cached data). Pending
* requests will be treated as though clear() was called on the
* key, this should cause them to go and re-read the data.
*/
public synchronized void flush() {
map.clear();
this.notifyAll();
}
/**
* Check if <tt>request(key)</tt> will return with an Object
* (not putting you on the hook for it). Note that it is possible
* that this will return true but between this call and the call
* to request the soft-reference will be cleared. So it
* is still possible for request to return NULL, just much less
* likely (you can always call 'clear' in that case).
*/
protected final synchronized boolean isPresentImpl(Object key) {
if (!map.containsKey(key))
return false;
Object o = map.get(key);
if (o == null)
// It's been requested but hasn't been 'put' yet.
return true;
// It's been put let's make sure the soft reference hasn't
// been cleared.
SoftReference sr = (SoftReference)o;
o = sr.get();
if (o != null)
return true;
// Soft reference was cleared, so remove our record of key.
clearImpl(key);
return false;
}
/**
* Check if <tt>request(key)</tt> will return immediately with the
* Object. Note that it is possible that this will return
* true but between this call and the call to request the
* soft-reference will be cleared.
*/
protected final synchronized boolean isDoneImpl(Object key) {
Object o = map.get(key);
if (o == null) return false;
SoftReference sr = (SoftReference)o;
o = sr.get();
if (o != null)
return true;
// Soft reference was cleared
clearImpl(key);
return false;
}
/**
* If this returns null then you are now 'on the hook'.
* to put the Object associated with key into the
* cache. */
protected final synchronized Object requestImpl(Object key) {
if (map.containsKey(key)) {
Object o = map.get(key);
while(o == null) {
try {
// When something is cleared or put we will be notified.
wait();
}
catch (InterruptedException ie) { }
// check if key was cleared, if so it will most likely
// never be 'put'.
if (!map.containsKey(key))
break;
// Let's see if it was put...
o = map.get(key);
}
if (o != null) {
SoftReference sr = (SoftReference)o;
o = sr.get();
if (o != null)
return o;
}
}
// So now the caller get's the hot potato.
map.put(key, null);
return null;
}
/**
* Clear the entry for key.
* This is the easiest way to 'get off the hook'.
* if you didn't indend to get on it.
*/
protected final synchronized void clearImpl(Object key) {
map.remove(key);
this.notifyAll();
}
/**
* Associate object with key. 'object' is only referenced through
* a soft reference so don't rely on the cache to keep it
* around. If the map no longer contains our url it was
* probably cleared or flushed since we were put on the hook
* for it, so in that case we will do nothing.
*/
protected final synchronized void putImpl(Object key, Object object) {
if (map.containsKey(key)) {
SoftReference ref = new SoftReference(object);
map.put(key, ref);
this.notifyAll();
}
}
}