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 de...@apache.org on 2001/04/19 19:31:42 UTC

cvs commit: xml-batik/sources/org/apache/batik/util ParsedURL.java

deweese     01/04/19 10:31:41

  Modified:    .        build.xml
               sources/org/apache/batik/ext/awt/image/codec PNGRed.java
               sources/org/apache/batik/ext/awt/image/renderable
                        DeferRable.java DisplacementMapRable8Bit.java
                        RedRable.java
               sources/org/apache/batik/ext/awt/image/rendered
                        AbstractTiledRed.java AffineRed.java TileGrid.java
                        TileLRUMember.java TileMap.java
               sources/org/apache/batik/ext/awt/image/spi
                        ImageTagRegistry.java URLRegistryEntry.java
  Added:       sources/org/apache/batik/util ParsedURL.java
  Log:
  1) Added ParsedURL which will attempt to parse a URL and make the
     components available.
  
  2) Switched from using URL to ParsedURL in ImageTagRegistry.
  
  3) Switched from TileGrid to TileMap in AbstractTiledRed.
  
  4) Improved TileMap so it cleans stuff out of the Map as the Soft
     references are cleared.
  
  Revision  Changes    Path
  1.56      +10 -5     xml-batik/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/xml-batik/build.xml,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -r1.55 -r1.56
  --- build.xml	2001/04/18 23:54:01	1.55
  +++ build.xml	2001/04/19 17:30:57	1.56
  @@ -45,7 +45,7 @@
     [win32] .\build.bat help
   
    
  - $Id: build.xml,v 1.55 2001/04/18 23:54:01 vhardy Exp $
  + $Id: build.xml,v 1.56 2001/04/19 17:30:57 deweese Exp $
   
   -->
   
  @@ -576,9 +576,9 @@
       </java>
     </target>
   
  -  <target name="regard"
  -          depends="compiletest"
  -          description="Runs test suite whose file or uri is passed as an input">
  +  <target name="testdirs"
  +          description="Created directories needed for test suite">
  +
       <mkdir dir="${test-reports}"/>
       <mkdir dir="${test-references}/samples/accepted-variation"/>
       <mkdir dir="${test-references}/samples/candidate-variation"/>
  @@ -586,6 +586,11 @@
       <mkdir dir="${test-references}/samples/tests/candidate-variation"/>
       <mkdir dir="${test-references}/svgbe/accepted-variation"/>
       <mkdir dir="${test-references}/svgbe/candidate-variation"/>
  +  </target>
  +
  +  <target name="regard"
  +          depends="compiletest, testdirs"
  +          description="Runs test suite whose file or uri is passed as an input">
       <java fork="yes"
             classname="${class-prefix}.test.xml.XMLTestSuiteRunner"
             jvmargs="-DproxyHost=webcache.eng.sun.com -DproxyPort=8080">
  @@ -601,7 +606,7 @@
     </target>
   
     <target name="runtestsuite"
  -          depends="compiletest"
  +          depends="compiletest, testdirs"
             description="Runs test suite whose file or uri is passed as an input">
       <mkdir dir="${test-reports}"/>
       <java fork="yes"
  
  
  
  1.2       +3 -2      xml-batik/sources/org/apache/batik/ext/awt/image/codec/PNGRed.java
  
  Index: PNGRed.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/codec/PNGRed.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- PNGRed.java	2001/04/10 14:48:47	1.1
  +++ PNGRed.java	2001/04/19 17:31:01	1.2
  @@ -40,6 +40,7 @@
   
   import org.apache.batik.ext.awt.image.rendered.AbstractRed;
   import org.apache.batik.ext.awt.image.rendered.CachableRed;
  +import org.apache.batik.ext.awt.image.GraphicsUtil;
   
   public class PNGRed extends AbstractRed {
   
  @@ -1836,8 +1837,8 @@
       }
   
       public WritableRaster copyData(WritableRaster wr) {
  -	wr.setRect(theTile);
  -	return wr;
  +        GraphicsUtil.copyData(theTile, wr);
  +        return wr;
       }
   
       // RenderedImage stuff
  
  
  
  1.2       +1 -1      xml-batik/sources/org/apache/batik/ext/awt/image/renderable/DeferRable.java
  
  Index: DeferRable.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/renderable/DeferRable.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DeferRable.java	2001/04/10 14:48:48	1.1
  +++ DeferRable.java	2001/04/19 17:31:05	1.2
  @@ -62,7 +62,7 @@
        */
       public synchronized void setSource(Filter src) {
           // Only let them set Source once.
  -        if (src != null) return;
  +        if (this.src != null) return;
   
           this.src = src;
           notifyAll();
  
  
  
  1.4       +18 -15    xml-batik/sources/org/apache/batik/ext/awt/image/renderable/DisplacementMapRable8Bit.java
  
  Index: DisplacementMapRable8Bit.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/renderable/DisplacementMapRable8Bit.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DisplacementMapRable8Bit.java	2001/03/26 21:27:32	1.3
  +++ DisplacementMapRable8Bit.java	2001/04/19 17:31:07	1.4
  @@ -36,7 +36,7 @@
    * another image to spatially displace the input image
    *
    * @author <a href="mailto:sheng.pei@eng.sun.com>Sheng Pei</a>
  - * @version $Id: DisplacementMapRable8Bit.java,v 1.3 2001/03/26 21:27:32 deweese Exp $
  + * @version $Id: DisplacementMapRable8Bit.java,v 1.4 2001/04/19 17:31:07 deweese Exp $
    */
   public class DisplacementMapRable8Bit 
       extends AbstractRable
  @@ -140,6 +140,11 @@
       }
   
       public RenderedImage createRendering(RenderContext rc) {
  +        // The source image to be displaced.
  +        Filter displaced = (Filter)getSources().elementAt(0);
  +        // The map giving the displacement.
  +        Filter map = (Filter)getSources().elementAt(1);
  +
           RenderingHints rh = rc.getRenderingHints();
           if (rh == null) rh = new RenderingHints(null);
   
  @@ -161,6 +166,17 @@
           double atScaleX = Math.sqrt(sx*sx + shy*shy);
           double atScaleY = Math.sqrt(sy*sy + shx*shx);
   
  +        // Now, apply the filter
  +        //
  +        int scaleX = (int)(scale*atScaleX);
  +        int scaleY = (int)(scale*atScaleY);
  +
  +        // If both scale factors are zero then we don't
  +        // affect the source image so just return it...
  +        if ((scaleX == 0) && (scaleY == 0))
  +            return displaced.createRendering(rc);
  +
  +        
           AffineTransform srcAt
               = AffineTransform.getScaleInstance(atScaleX, atScaleY);
   
  @@ -169,10 +185,8 @@
               origAOI = getBounds2D();
   
           Rectangle2D aoiR = origAOI.getBounds2D();
  -        //
  +
           // Get a rendering from the displacement map
  -        //
  -        Filter map = (Filter)getSources().elementAt(1);
           PadRable mapPad = new PadRable8Bit(map, aoiR, PadMode.ZERO_PAD);
   
           RenderContext srcRc = new RenderContext(srcAt, aoiR, rh);
  @@ -189,11 +203,6 @@
                                         aoiR.getWidth()  + scale,
                                         aoiR.getHeight() + scale);
   
  -        //
  -        // Now, get a rendering from the image source
  -        //
  -        Filter displaced = (Filter)getSources().elementAt(0);
  -
           Rectangle2D displacedRect = displaced.getBounds2D();
           if (aoiR.intersects(displacedRect) == false)
               return null;
  @@ -215,12 +224,6 @@
   
           // Get Raster for mapRed
           Raster mapRas       = mapRed.getData();
  -        
  -        //
  -        // Now, apply the filter
  -        //
  -        int scaleX = (int)(scale*atScaleX);
  -        int scaleY = (int)(scale*atScaleY);
           
           DisplacementMapOp op 
               = new DisplacementMapOp(xChannelSelector,
  
  
  
  1.2       +18 -10    xml-batik/sources/org/apache/batik/ext/awt/image/renderable/RedRable.java
  
  Index: RedRable.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/renderable/RedRable.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- RedRable.java	2001/04/10 14:48:48	1.1
  +++ RedRable.java	2001/04/19 17:31:10	1.2
  @@ -9,6 +9,7 @@
   package org.apache.batik.ext.awt.image.renderable;
   
   import java.awt.Shape;
  +import java.awt.Rectangle;
   import java.awt.RenderingHints;
   import java.awt.geom.AffineTransform;
   import java.awt.geom.Rectangle2D;
  @@ -25,7 +26,7 @@
    * RenderableImage world.
    *
    * @author <a href="mailto:Thomas.DeWeese@Kodak.com>Thomas DeWeese</a>
  - * @version $Id: RedRable.java,v 1.1 2001/04/10 14:48:48 deweese Exp $
  + * @version $Id: RedRable.java,v 1.2 2001/04/19 17:31:10 deweese Exp $
    */
   public class RedRable
       extends    AbstractRable {
  @@ -36,7 +37,7 @@
           this.src = src;
       }
   
  -    public synchronized CachableRed getSource() {
  +    public CachableRed getSource() {
           return src;
       }
   
  @@ -55,21 +56,28 @@
           if (rh == null) rh = new RenderingHints(null);
   
           Shape aoi = rc.getAreaOfInterest();
  -        if(aoi == null) aoi = getBounds2D();
  +        Rectangle aoiR;
  +        if (aoi != null) 
  +            aoiR = aoi.getBounds();
  +        else
  +            aoiR = getBounds2D().getBounds();
   
           // get the current affine transform
           AffineTransform at = rc.getTransform();
   
  -        // Get the device bounds, we will crop the affine to those
  -        // bounds.
  -        Shape devAOI = at.createTransformedShape(aoi);
  -
           // For high quality output we should really apply a Gaussian
           // Blur when we are scaling the image down significantly this
           // helps to prevent aliasing in the result image.
  -        CachableRed cr = new AffineRed(getSource(), at, rh);
  -        cr = new PadRed(cr, devAOI.getBounds(), PadMode.ZERO_PAD, rh);
  +        CachableRed cr = getSource();
  +
  +        if (aoiR.intersects(cr.getBounds()) == false)
  +            return null;
  +        aoiR = aoiR.intersection(cr.getBounds());
  +
  +        // Get the device bounds, we will crop the affine to those
  +        // bounds.
  +        Rectangle devAOI = at.createTransformedShape(aoiR).getBounds();
   
  -        return cr;
  +        return new AffineRed(cr, at, rh);
       }
   }
  
  
  
  1.8       +2 -2      xml-batik/sources/org/apache/batik/ext/awt/image/rendered/AbstractTiledRed.java
  
  Index: AbstractTiledRed.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/AbstractTiledRed.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- AbstractTiledRed.java	2001/03/26 13:57:24	1.7
  +++ AbstractTiledRed.java	2001/04/19 17:31:17	1.8
  @@ -28,7 +28,7 @@
    * the subclass implementation.
    *
    * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
  - * @version $Id: AbstractTiledRed.java,v 1.7 2001/03/26 13:57:24 deweese Exp $
  + * @version $Id: AbstractTiledRed.java,v 1.8 2001/04/19 17:31:17 deweese Exp $
    */
   public abstract class AbstractTiledRed 
       extends    AbstractRed
  @@ -245,7 +245,7 @@
       }
   
       protected TileStore createTileStore() {
  -        return TileCache.getTileGrid(this, this);
  +        return TileCache.getTileMap(this);
       }
   
       public WritableRaster copyData(WritableRaster wr) {
  
  
  
  1.7       +5 -5      xml-batik/sources/org/apache/batik/ext/awt/image/rendered/AffineRed.java
  
  Index: AffineRed.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/AffineRed.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AffineRed.java	2001/03/26 21:27:35	1.6
  +++ AffineRed.java	2001/04/19 17:31:19	1.7
  @@ -35,15 +35,13 @@
    * to do the work.  Eventually this may move to be more tiled in nature.
    *
    * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
  - * @version $Id: AffineRed.java,v 1.6 2001/03/26 21:27:35 deweese Exp $ */
  + * @version $Id: AffineRed.java,v 1.7 2001/04/19 17:31:19 deweese Exp $ */
   public class AffineRed extends AbstractRed {
   
       RenderingHints  hints;
       AffineTransform src2me;
       AffineTransform me2src;
   
  -    TileGrid tiles;
  -
       public AffineTransform getTransform() {
           return (AffineTransform)src2me.clone();
       }
  @@ -67,9 +65,11 @@
           }
   
           // Calculate my bounds by applying the affine transform to
  -        // my input data..
  +        // my input data..codec/
  +        Rectangle srcBounds = src.getBounds();
  +        // srcBounds.grow(-1,-1);
           Rectangle myBounds;
  -        myBounds = src2me.createTransformedShape(src.getBounds()).getBounds();
  +        myBounds = src2me.createTransformedShape(srcBounds).getBounds();
   
           // If the output buffer is not premultiplied in certain cases it
           // fails to properly divide out the Alpha (it always does
  
  
  
  1.5       +1 -2      xml-batik/sources/org/apache/batik/ext/awt/image/rendered/TileGrid.java
  
  Index: TileGrid.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/TileGrid.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TileGrid.java	2001/02/23 14:59:59	1.4
  +++ TileGrid.java	2001/04/19 17:31:21	1.5
  @@ -62,8 +62,7 @@
           } 
           item.setRaster(ras);
   		
  -        if (item.lruGet() != null) cache.touch(item);
  -        else                       cache.add(item);
  +        cache.add(item);
   
           if (DEBUG) System.out.println("Setting: (" + (x+minTileX) + ", " + 
                                         (y+minTileY) + ")");
  
  
  
  1.3       +6 -5      xml-batik/sources/org/apache/batik/ext/awt/image/rendered/TileLRUMember.java
  
  Index: TileLRUMember.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/TileLRUMember.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TileLRUMember.java	2001/02/07 18:30:00	1.2
  +++ TileLRUMember.java	2001/04/19 17:31:22	1.3
  @@ -9,7 +9,8 @@
   package org.apache.batik.ext.awt.image.rendered;
   
   import  java.awt.image.Raster;
  -import  java.lang.ref.WeakReference;
  +import  java.lang.ref.Reference;
  +import  java.lang.ref.SoftReference;
   
   /**
    * This is a useful class that wraps a Raster for patricipation in
  @@ -21,9 +22,9 @@
   public class TileLRUMember implements LRUCache.LRUObj {
       private static final boolean DEBUG = false;
   			
  -	private LRUCache.LRUNode myNode  = null;
  -	private WeakReference    wRaster = null;
  -	private Raster           hRaster = null;
  +	protected LRUCache.LRUNode myNode  = null;
  +	protected Reference        wRaster = null;
  +	protected Raster           hRaster = null;
   
   	public TileLRUMember() { }
   
  @@ -33,7 +34,7 @@
   
   	public void setRaster(Raster ras) {
   	    hRaster = ras;
  -	    wRaster = new WeakReference(ras);
  +	    wRaster = new SoftReference(ras);
   	}
   
   	public boolean checkRaster() {
  
  
  
  1.5       +74 -15    xml-batik/sources/org/apache/batik/ext/awt/image/rendered/TileMap.java
  
  Index: TileMap.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/TileMap.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TileMap.java	2001/03/26 13:57:24	1.4
  +++ TileMap.java	2001/04/19 17:31:23	1.5
  @@ -11,13 +11,39 @@
   import java.awt.Point;
   import java.awt.image.Raster;
   import java.util.HashMap;
  +import java.lang.ref.Reference;
  +import java.lang.ref.ReferenceQueue;
  +import java.lang.ref.SoftReference;
   
  -
   public class TileMap implements TileStore {
       private static final boolean DEBUG = false;
       private static final boolean COUNT = false;		
   
  +    private static ReferenceQueue queue = new ReferenceQueue();
  +
  +    private static HashMap items  =new HashMap();
       private HashMap rasters=new HashMap();
  +
  +    static class TileMapLRUMember extends TileLRUMember {
  +        public Point   pt;
  +        public TileMap parent;
  +        TileMapLRUMember(TileMap parent, Point pt, Raster ras) {
  +            super(ras);
  +            this.parent = parent;
  +            this.pt     = pt;
  +        }
  +
  +        public void setRaster(Raster ras) {
  +            hRaster = ras;
  +            synchronized (items) {
  +                if (wRaster != null)
  +                    items.remove(wRaster);
  +                wRaster = new SoftReference(ras, queue);
  +                items.put(wRaster, this);
  +            }
  +        }
  +    }
  +
       private TileGenerator source = null;
       private LRUCache      cache = null;
   
  @@ -30,16 +56,16 @@
       public void setTile(int x, int y, Raster ras) {
           Point pt = new Point(x, y);
           Object o = rasters.get(pt);
  -        TileLRUMember item;
  +        TileMapLRUMember item;
           if (o == null) {
  -            item = new TileLRUMember(ras);
  +            item = new TileMapLRUMember(this, pt, ras);
  +            rasters.put(pt, item);
           } else {
  -            item = (TileLRUMember)o;
  +            item = (TileMapLRUMember)o;
               item.setRaster(ras);
           }
   		
  -        if (item.lruGet() != null) cache.touch(item);
  -        else                       cache.add(item);
  +        cache.add(item);
           if (DEBUG) System.out.println("Setting: (" + x + ", " + y + ")");
       }
   
  @@ -51,8 +77,11 @@
           if (o == null) 
               return null;
   
  -        TileLRUMember item = (TileLRUMember)o;
  -        return item.retrieveRaster();
  +        TileMapLRUMember item = (TileMapLRUMember)o;
  +        Raster ret = item.retrieveRaster();
  +        if (ret != null)
  +            cache.add(item);
  +        return ret;
       }
   
       public Raster getTile(int x, int y) {
  @@ -63,12 +92,9 @@
           Raster       ras  = null;
           Point pt = new Point(x, y);
           Object o = rasters.get(pt);
  -        TileLRUMember item;
  -        if (o == null) {
  -            item = new TileLRUMember();
  -            rasters.put(pt, item);
  -        } else {
  -            item = (TileLRUMember)o;
  +        TileMapLRUMember item = null;
  +        if (o != null) {
  +            item = (TileMapLRUMember)o;
               ras = item.retrieveRaster();
           }
   		
  @@ -84,7 +110,12 @@
               if (Thread.currentThread().isInterrupted())
                   return ras;
   
  -            item.setRaster(ras);
  +            if (item != null)
  +                item.setRaster(ras);
  +            else  {
  +                item = new TileMapLRUMember(this, pt, ras);
  +                rasters.put(pt, item);
  +            }
           }
   
           // Update the item's position in the cache..
  @@ -95,4 +126,32 @@
   
       static int requests;
       static int misses;
  +
  +    static Thread cleanup;
  +
  +    static {
  +        cleanup = new Thread() {
  +                public void run() {
  +                    while(true) {
  +                        Reference ref;
  +
  +                        try {
  +                            ref = queue.remove();
  +                        } catch (InterruptedException ie) {
  +                            continue;
  +                        }
  +                        synchronized (items) {
  +                            Object o = items.remove(ref);
  +                            if (DEBUG) System.out.println("Cleaning: " + o);
  +                            if (o == null) continue;
  +                        
  +                            TileMapLRUMember item = (TileMapLRUMember)o;
  +                            item.parent.rasters.remove(item.pt);
  +                        }
  +                    }
  +                }
  +            };
  +        cleanup.start();
  +    }
  +
   }
  
  
  
  1.2       +13 -14    xml-batik/sources/org/apache/batik/ext/awt/image/spi/ImageTagRegistry.java
  
  Index: ImageTagRegistry.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/spi/ImageTagRegistry.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ImageTagRegistry.java	2001/04/10 14:48:48	1.1
  +++ ImageTagRegistry.java	2001/04/19 17:31:32	1.2
  @@ -17,9 +17,8 @@
   import java.io.IOException;
   import java.io.StreamCorruptedException;
   
  -import java.net.URL;
  -
   import org.apache.batik.ext.awt.image.renderable.Filter;
  +import org.apache.batik.util.ParsedURL;
   
   public class ImageTagRegistry {
       List entries = new LinkedList();
  @@ -27,7 +26,7 @@
       public ImageTagRegistry() {
       }
   
  -    Filter readURL(URL url) {
  +    public Filter readURL(ParsedURL purl) {
           Iterator i;
           i = entries.iterator();
           while (i.hasNext()) {
  @@ -35,8 +34,8 @@
               if (! (re instanceof URLRegistryEntry))
                   continue;
               URLRegistryEntry ure = (URLRegistryEntry)re;
  -            if (ure.isCompatibleURL(url)) {
  -                return ure.handleURL(url);
  +            if (ure.isCompatibleURL(purl)) {
  +                return ure.handleURL(purl);
               }
           }
   	
  @@ -51,7 +50,7 @@
               try {
                   if (is == null) {
                       try {
  -                        is = url.openStream();
  +                        is = purl.openStream();
                       } catch(IOException ioe) {
                           // Couldn't open the stream...
                           return null;
  @@ -63,8 +62,9 @@
                           is = new BufferedInputStream(is);
                   }
   
  -                if (sre.isCompatibleStream(is))
  +                if (sre.isCompatibleStream(is)) {
                       return sre.handleStream(is);
  +                }
               } catch (StreamCorruptedException sce) {
                   // Stream is messed up so setup to reopen it..
                   is = null;
  @@ -73,7 +73,7 @@
           return null;
       }
       
  -    Filter readStream(InputStream is) {
  +    public Filter readStream(InputStream is) {
           if (!is.markSupported())
               // Doesn't support mark so wrap with BufferedInputStream that does.
               is = new BufferedInputStream(is);
  @@ -100,15 +100,14 @@
           entries.add(re);
       }
   
  -    static ImageTagRegistry registry = null;
  +    static ImageTagRegistry registry = new ImageTagRegistry();
       
  -    public synchronized static ImageTagRegistry getRegistry() { 
  -        if (registry != null) 
  -            return registry;
  -
  -        registry = new ImageTagRegistry();
  +    static {
           registry.register(new PNGRegistryEntry());
           registry.register(new JPEGRegistryEntry());
  +    }
  +
  +    public static ImageTagRegistry getRegistry() { 
           return registry;
       }
   }
  
  
  
  1.2       +3 -4      xml-batik/sources/org/apache/batik/ext/awt/image/spi/URLRegistryEntry.java
  
  Index: URLRegistryEntry.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/spi/URLRegistryEntry.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- URLRegistryEntry.java	2001/04/10 14:48:48	1.1
  +++ URLRegistryEntry.java	2001/04/19 17:31:34	1.2
  @@ -8,8 +8,7 @@
   
   package org.apache.batik.ext.awt.image.spi;
   
  -import java.net.URL;
  -
  +import org.apache.batik.util.ParsedURL;
   import org.apache.batik.ext.awt.image.renderable.Filter;
   
   /**
  @@ -33,11 +32,11 @@
        * StreamRegistryEntry, so the URL "connection" will be made
        * only once.  
        */
  -    public boolean isCompatibleURL(URL url);
  +    public boolean isCompatibleURL(ParsedURL url);
   
       /**
        * Decode the URL into a RenderableImage, here you should feel
        * free to open the URL yourself.
        */
  -    public Filter handleURL(URL url);
  +    public Filter handleURL(ParsedURL url);
   }
  
  
  
  1.1                  xml-batik/sources/org/apache/batik/util/ParsedURL.java
  
  Index: ParsedURL.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.io.ByteArrayInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  
  import java.net.URL;
  import java.net.MalformedURLException;
  
  public class ParsedURL {
  
      static class URLData {
          public String protocol = null;
          public String host     = null;
          public int    port     = -1;
          public String path     = null;
          public String ref      = null;
  
          protected URL buildURL() throws MalformedURLException {
              String file = "";
              if (path != null) 
                  file = path;
              if (ref != null)
                  file += "#" + ref;
  
              if (port == -1)
                  return new URL(protocol, host, file);
  
              return new URL(protocol, host, port, file);
          }
          
          public boolean complete() {
              try {
                  URL url = buildURL();
              } catch (MalformedURLException mue) {
                  return false;
              }
              return true;
          }
  
          public InputStream openStream() throws IOException {
              URL url = null;
              try {
                  url = buildURL();
              } catch (MalformedURLException mue) {
                  throw new IOException
                      ("Unable to make sense of URL for connection");
              }
  
              if (url != null)
                  return url.openStream();
  
              return null;
          }
  
          public String getPortStr() {
              String portStr ="";
              if (protocol != null)
                  portStr += protocol + ":";
  
              if ((host != null) || (port != -1)) {
                  portStr += "//";
                  if (host != null) portStr += host;
                  if (port != -1)   portStr += ":" + port;
              }
  
              return portStr;
          }
  
          public String toString() {
              String ret = getPortStr();
              if (path != null)
                  ret += path;
  
              if (ref != null) 
                  ret += "#" + ref;
  
              return ret;
          }
      };
  
      URLData data;
  
      static Map            parsers       = new HashMap();
      static ProtocolParser defaultParser = new DefaultProtocolParser();
  
      static void registerParser(ProtocolParser pp) {
          if (pp.getProtocolHandled() == null) {
              defaultParser = pp;
              return;
          }
  
          parsers.put(pp.getProtocolHandled(), pp);
      }
  
      static {
          registerParser(new DataProtocolParser());
      }
  
      public ParsedURL(String urlStr) {
          data = parseURL(urlStr);
      }
  
      public ParsedURL(String baseStr, String urlStr) {
          if (baseStr != null)
              data = parseURL(baseStr, urlStr);
          else
              data = parseURL(urlStr);
      }
  
      public ParsedURL(ParsedURL baseURL, String urlStr) {
          if (baseURL != null)
              data = parseURL(baseURL, urlStr);
          else
              data = parseURL(urlStr);
      }
  
      public boolean complete() {
          return data.complete();
      }
  
      public String getProtocol() { 
          if (data.protocol == null) return null;
          return new String(data.protocol); 
      }
      public String getHost()     { 
          if (data.host == null) return null;
          return new String(data.host); 
      }
      public String getPath()     { 
          if (data.path == null) return null;
          return new String(data.path); 
      }
      public String getRef()      { 
          if (data.ref == null) return null;
          return new String(data.ref); 
      }
      public int    getPort()     { return data.port; }
  
  
      public String getPortStr() {
          return data.getPortStr();
      }
  
      public String toString() {
          return data.toString();
      }
  
      public InputStream openStream() throws IOException {
          return data.openStream();
      }
  
      protected static String getProtocol(String urlStr) {
          int idx = urlStr.indexOf(':');
          if (idx == -1) 
              return null;
  
          // May have a protocol spec...
          String protocol = urlStr.substring(0, idx);
          if (protocol.indexOf('/') != -1)
              // Got a slash in protocol probably means 
              // no protocol given.
              return null;
  
          return protocol;
      }
  
  
      public static URLData parseURL(String urlStr) {
          String protocol = getProtocol(urlStr);
          if (protocol == null)
              // no protocol given, use default parser.
              return defaultParser.parseURL(urlStr);
  
          Object o = parsers.get(protocol);
          if (o==null)
              return defaultParser.parseURL(urlStr);
  
          return ((ProtocolParser)o).parseURL(urlStr);
      }
  
      public static URLData parseURL(String baseStr, String urlStr) {
          String protocol = getProtocol(urlStr);
          if (protocol != null)
              // Protocol given, ignore base...
              return parseURL(urlStr);
  
          ParsedURL purl = new ParsedURL(baseStr);
          return parseURL(purl, urlStr);
      }
  
      public static URLData parseURL(ParsedURL baseURL, String urlStr) {
          String protocol = getProtocol(urlStr);
          if (protocol != null)
              // Protocol given, ignore base...
              return parseURL(urlStr);
  
          Object o = parsers.get(protocol);
          if (o==null)
              return defaultParser.parseURL(baseURL, urlStr);
  
          return ((ProtocolParser)o).parseURL(baseURL, urlStr);        
      }
  
  
  
      static public abstract class ProtocolParser {
          String protocol;
          public ProtocolParser(String protocol) {
              this.protocol = protocol;
          }
  
          public String getProtocolHandled() {
              return protocol;
          }
  
          abstract public URLData parseURL(String urlStr);
          abstract public URLData parseURL(ParsedURL basepurl, String urlStr);
      }
  
      static public class DefaultProtocolParser extends ProtocolParser {
  
          public DefaultProtocolParser() {
              super(null);
          }
  
          public URLData parseURL(String urlStr) {
              URLData ret = new URLData();
  
              try {
                  URL url = new URL(urlStr);
                  ret.protocol = url.getProtocol();
                  if ((ret.protocol != null) && (ret.protocol.length() == 0)) 
                      ret.protocol = null;
  
                  ret.host = url.getHost();
                  if ((ret.host != null) && (ret.host.length() == 0)) 
                      ret.host = null;
  
                  ret.port     = url.getPort();
  
                  ret.path     = url.getPath();
                  if ((ret.path != null) && (ret.path.length() == 0)) 
                      ret.path = null;
  
                  ret.ref      = url.getRef();
                  if ((ret.ref != null) && (ret.ref.length() == 0))  
                      ret.ref = null;
              
                  return ret;
              } catch (MalformedURLException mue) {
                  // Built in URL wouldn't take it...
              }
  
              int pidx=0, idx;
              int len = urlStr.length();
  
              idx = urlStr.indexOf(':');
              if (idx != -1) {
                  // May have a protocol spec...
                  ret.protocol = urlStr.substring(pidx, idx);
                  if (ret.protocol.indexOf('/') == -1)
                      pidx = idx+1;
                  else {
                      // Got a slash in protocol probably means 
                      // no protocol given, (host and port?)
                      ret.protocol = null;
                      pidx = 0;
                  }
              }
  
              // See if we have host/port spec.
              idx = urlStr.indexOf('/');
              if ((idx == -1) || ((pidx+2<len)                   &&
                                  (urlStr.charAt(pidx)   == '/') &&
                                  (urlStr.charAt(pidx+1) == '/'))) {
                  // No slashes (apache.org) or a double slash 
                  // (//apache.org/....) so
                  // we should have host[:port] before next slash.
  
                  if (idx != -1) 
                      pidx+=2;  // Skip double slash...
  
                  idx = urlStr.indexOf('/', pidx);  // find end of host:Port spec
                  String hostPort;
                  if (idx == -1) 
                      // Just host and port nothing following...
                      hostPort = urlStr.substring(pidx);
                  else
                      // Path spec follows...
                      hostPort = urlStr.substring(pidx, idx);
  
                  pidx = idx;  // Remember location of '/'
  
                  // pull apart host and port number...
                  idx = hostPort.indexOf(':');
                  ret.port = -1;
                  if (idx == -1) {
                      // Just Host...
                      if (hostPort.length() == 0)
                          ret.host = null;
                      else
                          ret.host = hostPort;
                  } else {
                      // Host and port
                      if (idx == 0) 
                          ret.host = null;
                      else
                          ret.host = hostPort.substring(0,idx);
  
                      if (idx+1 < hostPort.length()) {
                          String portStr = hostPort.substring(idx+1);
                          try {
                              ret.port = Integer.parseInt(portStr);
                          } catch (NumberFormatException nfe) { 
                              // bad port leave as '-1'
                          }
                      }
                  }
              }
  
              if ((pidx == -1) || (pidx >= len)) return ret; // Nothing follows
  
              String pathRef = urlStr.substring(pidx);
              idx = pathRef.indexOf('#');
              ret.ref = null;
              if (idx == -1) {
                  // No ref (fragment) in URL
                  ret.path = pathRef;
              } else {
                  ret.path = pathRef.substring(0,idx);
                  if (idx+1 < pathRef.length())
                      ret.ref = pathRef.substring(idx+1);
              }
              return ret;
          }
  
          public URLData parseURL(ParsedURL baseURL, String urlStr) {
              int idx = urlStr.indexOf(':');
              if (idx != -1)
                  // Absolute URL ignore base...
                  return parseURL(urlStr);
  
              if (urlStr.startsWith("/"))
                  // Absolute path.
                  return parseURL(baseURL.getPortStr() + urlStr);
  
              if (urlStr.startsWith("#"))
                  return parseURL(baseURL.getPortStr() + 
                                  baseURL.getPath() + urlStr);
  
              String path = baseURL.getPath();
              if (path == null) path = "/";
              idx = path.lastIndexOf('/');
              if (idx == -1) 
                  path = "/";
              else
                  path = path.substring(0,idx+1);
          
              return parseURL(baseURL.getPortStr() + path + urlStr);
          }
      }
  
      static public class DataProtocolParser extends ProtocolParser {
  
          public DataProtocolParser() {
              super("data");
          }
  
          static class DataURLData extends URLData {
  
              public boolean complete() {
                  return (path != null);
              }
  
              public String getPortStr() {
                  String portStr ="data:";
                  if (host != null) portStr += host;
                  portStr += ",";
                  return portStr;
              }
                  
              public String toString() {
                  String ret = getPortStr();
                  if (path != null) ret += path;
                  return ret;
              }
  
              public InputStream openStream() throws IOException {
                  byte [] data = path.getBytes();
                  InputStream is = new ByteArrayInputStream(data);
                  return new Base64DecodeStream(is);
              }
          }
  
          public URLData parseURL(String urlStr) {
              URLData ret = new DataURLData();
  
              int pidx=0, idx;
              int len = urlStr.length();
  
              idx = urlStr.indexOf(':');
              if (idx != -1) {
                  // May have a protocol spec...
                  ret.protocol = urlStr.substring(pidx, idx);
                  if (ret.protocol.indexOf('/') == -1)
                      pidx = idx+1;
                  else {
                      // Got a slash in protocol probably means 
                      // no protocol given, (host and port?)
                      ret.protocol = null;
                      pidx = 0;
                  }
              }
  
              idx = urlStr.indexOf(',',pidx);
              if (idx != -1) {
                  ret.host = urlStr.substring(pidx, idx);
                  pidx = idx+1;
              }
              if (pidx != urlStr.length()) 
                  ret.path = urlStr.substring(pidx);
  
              return ret;
          }
  
          public URLData parseURL(ParsedURL baseURL, String urlStr) {
              // No relative form...
              return parseURL(urlStr);
          }
      }    
  
      static public void main1(String []args) {
          for (int i=0; i<args.length; i++) {
              ParsedURL purl = new ParsedURL(args[i]);
  
              System.out.println("URL:        \"" + args[i] + "\"");
              System.out.println("  Str:      \"" + purl + "\"");
              System.out.println("  Protocol: \"" + purl.getProtocol()+"\"");
              System.out.println("  Host:     \"" + purl.getHost()    +"\"");
              System.out.println("  Port:     \"" + purl.getPort()    +"\"");
              System.out.println("  Path:     \"" + purl.getPath()    +"\"");
              System.out.println("  Ref:      \"" + purl.getRef()     +"\"");
          }
      }
  
      // This is a little test harness that takes the arguments and uses
      // them to construct 'relative' URLS (so it always uses the
      // previous url to construct the next url).
      //
      // Example input:
      // "xml.apache.org ~deweese 
      // file:///home/deweese/.cshrc 
      // http://xml.apache.org:8080/~deweese/index.html#1234asdb 
      // file:/home/deweese/tools/src/foo.cc 
      // fooz:/home/deweese/tools/src/foo.cc 
      // fooz:///home/deweese/tools/src/foo.cc 
      // fooz://www.www.www:1234/home/deweese/src/foo.cc#abcd 
      //      xzy.html#lalsjdf 
      // /xyz.svg#alskd
  
      static public void main(String []args) {
          ParsedURL purl = null;
          for (int i=0; i<args.length; i++) {
              purl = new ParsedURL(purl, args[i]);
  
              System.out.println("URL:        \"" + args[i] + "\"");
              System.out.println("  Str:      \"" + purl + "\"");
              System.out.println("  Protocol: \"" + purl.getProtocol()+"\"");
              System.out.println("  Host:     \"" + purl.getHost()    +"\"");
              System.out.println("  Port:     \"" + purl.getPort()    +"\"");
              System.out.println("  Path:     \"" + purl.getPath()    +"\"");
              System.out.println("  Ref:      \"" + purl.getRef()     +"\"");
          }
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org