Clover coverage report - classworlds - 1.1-alpha-1
Coverage timestamp: Sun Sep 19 2004 14:08:44 EDT
file stats: LOC: 300   Methods: 10
NCLOC: 142   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
JarUrlConnection.java 79.2% 87.5% 90% 85.4%
coverage coverage
 1   
 package org.codehaus.classworlds.uberjar.protocol.jar;
 2   
 
 3   
 /*
 4   
  $Id: JarUrlConnection.java,v 1.1.1.1 2004/07/01 13:59:19 jvanzyl Exp $
 5   
 
 6   
  Copyright 2002 (C) The Werken Company. All Rights Reserved.
 7   
 
 8   
  Redistribution and use of this software and associated documentation
 9   
  ("Software"), with or without modification, are permitted provided
 10   
  that the following conditions are met:
 11   
 
 12   
  1. Redistributions of source code must retain copyright
 13   
     statements and notices.  Redistributions must also contain a
 14   
     copy of this document.
 15   
 
 16   
  2. Redistributions in binary form must reproduce the
 17   
     above copyright notice, this list of conditions and the
 18   
     following disclaimer in the documentation and/or other
 19   
     materials provided with the distribution.
 20   
 
 21   
  3. The name "classworlds" must not be used to endorse or promote
 22   
     products derived from this Software without prior written
 23   
     permission of The Werken Company.  For written permission,
 24   
     please contact bob@werken.com.
 25   
 
 26   
  4. Products derived from this Software may not be called "classworlds"
 27   
     nor may "classworlds" appear in their names without prior written
 28   
     permission of The Werken Company. "classworlds" is a registered
 29   
     trademark of The Werken Company.
 30   
 
 31   
  5. Due credit should be given to The Werken Company.
 32   
     (http://classworlds.werken.com/).
 33   
 
 34   
  THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS
 35   
  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 36   
  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 37   
  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 38   
  THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 39   
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 40   
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 41   
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 42   
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 43   
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 44   
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 45   
  OF THE POSSIBILITY OF SUCH DAMAGE.
 46   
 
 47   
  */
 48   
 
 49   
 import org.codehaus.classworlds.UrlUtils;
 50   
 
 51   
 import java.io.IOException;
 52   
 import java.io.InputStream;
 53   
 import java.net.JarURLConnection;
 54   
 import java.net.MalformedURLException;
 55   
 import java.net.URL;
 56   
 import java.net.URLDecoder;
 57   
 import java.util.ArrayList;
 58   
 import java.util.List;
 59   
 import java.util.StringTokenizer;
 60   
 import java.util.jar.JarEntry;
 61   
 import java.util.jar.JarFile;
 62   
 import java.util.jar.JarInputStream;
 63   
 
 64   
 /**
 65   
  * <code>URLConnection</code> capable of handling multiply-nested jars.
 66   
  *
 67   
  * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
 68   
  * @version $Id: JarUrlConnection.java,v 1.1.1.1 2004/07/01 13:59:19 jvanzyl Exp $
 69   
  */
 70   
 public class JarUrlConnection
 71   
     extends JarURLConnection
 72   
 {
 73   
     // ----------------------------------------------------------------------
 74   
     //     Instance members
 75   
     // ----------------------------------------------------------------------
 76   
 
 77   
     /**
 78   
      * Base resource.
 79   
      */
 80   
     private URL baseResource;
 81   
 
 82   
     /**
 83   
      * Additional nested segments.
 84   
      */
 85   
     private String[] segments;
 86   
 
 87   
     /**
 88   
      * Terminal input-stream.
 89   
      */
 90   
     private InputStream in;
 91   
 
 92   
     // ----------------------------------------------------------------------
 93   
     //     Constructors
 94   
     // ----------------------------------------------------------------------
 95   
 
 96   
     /**
 97   
      * Construct.
 98   
      *
 99   
      * @param url Target URL of the connections.
 100   
      * @throws java.io.IOException If an error occurs while attempting to initialize
 101   
      *                             the connection.
 102   
      */
 103  30
     JarUrlConnection( URL url )
 104   
         throws IOException
 105   
     {
 106  30
         super( url = normaliseURL( url ) );
 107   
 
 108  30
         String baseText = url.getPath();
 109   
 
 110  30
         int bangLoc = baseText.indexOf( "!" );
 111   
 
 112  30
         String baseResourceText = baseText.substring( 0, bangLoc );
 113   
 
 114  30
         String extraText = "";
 115   
 
 116  30
         if ( bangLoc <= ( baseText.length() - 2 )
 117   
             &&
 118   
             baseText.charAt( bangLoc + 1 ) == '/' )
 119   
         {
 120  28
             if ( bangLoc + 2 == baseText.length() )
 121   
             {
 122  14
                 extraText = "";
 123   
             }
 124   
             else
 125   
             {
 126  14
                 extraText = baseText.substring( bangLoc + 1 );
 127   
             }
 128   
         }
 129   
         else
 130   
         {
 131  2
             throw new MalformedURLException( "No !/ in url: " + url.toExternalForm() );
 132   
         }
 133   
 
 134   
 
 135  28
         List segments = new ArrayList();
 136   
 
 137  28
         StringTokenizer tokens = new StringTokenizer( extraText, "!" );
 138   
 
 139  28
         while ( tokens.hasMoreTokens() )
 140   
         {
 141  20
             segments.add( tokens.nextToken() );
 142   
         }
 143   
 
 144  28
         this.segments = (String[]) segments.toArray( new String[segments.size()] );
 145   
 
 146  28
         this.baseResource = new URL( baseResourceText );
 147   
     }
 148   
 
 149  36
     protected static URL normaliseURL( URL url ) throws MalformedURLException
 150   
     {
 151  36
         String text = UrlUtils.normalizeUrlPath( url.toString() );
 152   
 
 153  36
         if ( !text.startsWith( "jar:" ) )
 154   
         {
 155  4
             text = "jar:" + text;
 156   
         }
 157   
 
 158  36
         if ( text.indexOf( '!' ) < 0 )
 159   
         {
 160  12
             text = text + "!/";
 161   
         }
 162   
 
 163  36
         return new URL( text );
 164   
     }
 165   
 
 166   
     // ----------------------------------------------------------------------
 167   
     //     Instance methods
 168   
     // ----------------------------------------------------------------------
 169   
 
 170   
     /**
 171   
      * Retrieve the nesting path segments.
 172   
      *
 173   
      * @return The segments.
 174   
      */
 175  2
     protected String[] getSegments()
 176   
     {
 177  2
         return this.segments;
 178   
     }
 179   
 
 180   
     /**
 181   
      * Retrieve the base resource <code>URL</code>.
 182   
      *
 183   
      * @return The base resource url.
 184   
      */
 185  26
     protected URL getBaseResource()
 186   
     {
 187  26
         return this.baseResource;
 188   
     }
 189   
 
 190   
     /**
 191   
      * @see java.net.URLConnection
 192   
      */
 193  24
     public void connect()
 194   
         throws IOException
 195   
     {
 196  24
         if ( this.segments.length == 0 )
 197   
         {
 198  12
             setupBaseResourceInputStream();
 199   
         }
 200   
         else
 201   
         {
 202  12
             setupPathedInputStream();
 203   
         }
 204   
     }
 205   
 
 206   
     /**
 207   
      * Setup the <code>InputStream</code> purely from the base resource.
 208   
      *
 209   
      * @throws java.io.IOException If an I/O error occurs.
 210   
      */
 211  12
     protected void setupBaseResourceInputStream()
 212   
         throws IOException
 213   
     {
 214  12
         this.in = getBaseResource().openStream();
 215   
     }
 216   
 
 217   
     /**
 218   
      * Setup the <code>InputStream</code> for URL with nested segments.
 219   
      *
 220   
      * @throws java.io.IOException If an I/O error occurs.
 221   
      */
 222  12
     protected void setupPathedInputStream()
 223   
         throws IOException
 224   
     {
 225  12
         InputStream curIn = getBaseResource().openStream();
 226   
 
 227  12
         for ( int i = 0; i < this.segments.length; ++i )
 228   
         {
 229  16
             curIn = getSegmentInputStream( curIn,
 230   
                                            segments[i] );
 231   
         }
 232   
 
 233  12
         this.in = curIn;
 234   
     }
 235   
 
 236   
     /**
 237   
      * Retrieve the <code>InputStream</code> for the nesting
 238   
      * segment relative to a base <code>InputStream</code>.
 239   
      *
 240   
      * @param baseIn  The base input-stream.
 241   
      * @param segment The nesting segment path.
 242   
      * @return The input-stream to the segment.
 243   
      * @throws java.io.IOException If an I/O error occurs.
 244   
      */
 245  16
     protected InputStream getSegmentInputStream( InputStream baseIn,
 246   
                                                  String segment )
 247   
         throws IOException
 248   
     {
 249  16
         JarInputStream jarIn = new JarInputStream( baseIn );
 250  16
         JarEntry entry = null;
 251   
 
 252  44
         while ( jarIn.available() != 0 )
 253   
         {
 254  44
             entry = jarIn.getNextJarEntry();
 255   
 
 256  44
             if ( entry == null )
 257   
             {
 258  0
                 break;
 259   
             }
 260   
 
 261  44
             if ( ( "/" + entry.getName() ).equals( segment ) )
 262   
             {
 263  16
                 return jarIn;
 264   
             }
 265   
         }
 266   
 
 267  0
         throw new IOException( "unable to locate segment: " + segment );
 268   
     }
 269   
 
 270   
     /**
 271   
      * @see java.net.URLConnection
 272   
      */
 273  22
     public InputStream getInputStream()
 274   
         throws IOException
 275   
     {
 276  22
         if ( this.in == null )
 277   
         {
 278  22
             connect();
 279   
         }
 280  22
         return this.in;
 281   
     }
 282   
 
 283   
     /**
 284   
      * @return JarFile
 285   
      * @throws java.io.IOException
 286   
      * @see java.net.JarURLConnection#getJarFile()
 287   
      */
 288  0
     public JarFile getJarFile() throws IOException
 289   
     {
 290  0
         String url = baseResource.toExternalForm();
 291   
 
 292  0
         if ( url.startsWith( "file:/" ) )
 293   
         {
 294  0
             url = url.substring( 6 );
 295   
         }
 296   
 
 297  0
         return new JarFile( URLDecoder.decode( url, "UTF-8" ) );
 298   
     }
 299   
 }
 300