Clover coverage report - classworlds - 1.1-alpha-1
Coverage timestamp: Sun Sep 19 2004 14:08:44 EDT
file stats: LOC: 427   Methods: 19
NCLOC: 271   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
DefaultClassRealm.java 46% 53.5% 73.7% 53.5%
coverage coverage
 1   
 package org.codehaus.classworlds;
 2   
 
 3   
 /*
 4   
  $Id: DefaultClassRealm.java,v 1.8 2004/08/09 22:00:16 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   
 
 50   
 import java.io.File;
 51   
 import java.io.IOException;
 52   
 import java.io.InputStream;
 53   
 import java.net.URL;
 54   
 import java.util.Enumeration;
 55   
 import java.util.Iterator;
 56   
 import java.util.TreeSet;
 57   
 import java.util.Vector;
 58   
 
 59   
 
 60   
 /**
 61   
  * Implementation of <code>ClassRealm</code>.  The realm is the class loading gateway.
 62   
  * The search is proceded as follows:
 63   
  * <ol>
 64   
  * <li>Search the parent class loader (passed via the constructor) if there
 65   
  * is one.</li>
 66   
  * <li>Search the imports.</li>
 67   
  * <li>Search this realm's constituents.</li>
 68   
  * <li>Search the parent realm.</li>
 69   
  * </ol>
 70   
  *
 71   
  * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
 72   
  * @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
 73   
  * @version $Id: DefaultClassRealm.java,v 1.8 2004/08/09 22:00:16 jvanzyl Exp $
 74   
  * @todo allow inheritance to be turn on/off at runtime.
 75   
  * @todo allow direction of search
 76   
  */
 77   
 public class DefaultClassRealm
 78   
     implements ClassRealm
 79   
 {
 80   
     private ClassWorld world;
 81   
 
 82   
     private String id;
 83   
 
 84   
     private TreeSet imports;
 85   
 
 86   
     private ClassLoader foreignClassLoader;
 87   
 
 88   
     private RealmClassLoader classLoader;
 89   
 
 90   
     private ClassRealm parent;
 91   
 
 92  180
     public DefaultClassRealm( ClassWorld world, String id )
 93   
     {
 94  180
         this( world, id, null );
 95   
     }
 96   
 
 97  180
     public DefaultClassRealm( ClassWorld world, String id, ClassLoader foreignClassLoader )
 98   
     {
 99  180
         this.world = world;
 100   
 
 101  180
         this.id = id;
 102   
 
 103  180
         imports = new TreeSet();
 104   
 
 105  180
         if ( foreignClassLoader != null )
 106   
         {
 107  0
             this.foreignClassLoader = foreignClassLoader;
 108   
         }
 109   
 
 110  180
         if ( "true".equals( System.getProperty( "classworlds.bootstrapped" ) ) )
 111   
         {
 112  14
             classLoader = new UberJarRealmClassLoader( this );
 113   
         }
 114   
         else
 115   
         {
 116  166
             classLoader = new RealmClassLoader( this );
 117   
         }
 118   
     }
 119   
 
 120  0
     public URL[] getConstituents()
 121   
     {
 122  0
         return classLoader.getURLs();
 123   
     }
 124   
 
 125  84
     public ClassRealm getParent()
 126   
     {
 127  84
         return parent;
 128   
     }
 129   
 
 130  12
     public void setParent( ClassRealm parent )
 131   
     {
 132  12
         this.parent = parent;
 133   
     }
 134   
 
 135  4
     public String getId()
 136   
     {
 137  4
         return this.id;
 138   
     }
 139   
 
 140  290
     public ClassWorld getWorld()
 141   
     {
 142  290
         return this.world;
 143   
     }
 144   
 
 145  32
     public void importFrom( String realmId, String packageName )
 146   
         throws NoSuchRealmException
 147   
     {
 148  32
         imports.add( new Entry( getWorld().getRealm( realmId ), packageName ) );
 149  32
         imports.add( new Entry( getWorld().getRealm( realmId ), packageName.replace('.', '/') ) );
 150   
     }
 151   
 
 152  90
     public void addConstituent( URL constituent )
 153   
     {
 154  90
         classLoader.addConstituent( constituent );
 155   
     }
 156   
     
 157   
     /**
 158   
      *  Adds a byte[] class definition as a constituent for locating classes.
 159   
      *  Currently uses BytesURLStreamHandler to hold a reference of the byte[] in memory.
 160   
      *  This ensures we have a unifed URL resource model for all constituents.
 161   
      *  The code to cache to disk is commented out - maybe a property to choose which method?
 162   
      *
 163   
      *  @param constituent class name
 164   
      *  @param b the class definition as a byte[]
 165   
      */
 166  0
     public void addConstituent(String constituent,
 167   
                                byte[] b) throws ClassNotFoundException
 168   
     {
 169  0
         try
 170   
         {
 171  0
             File path, file;
 172  0
             if (constituent.lastIndexOf('.') != -1)
 173   
             {
 174  0
                 path = new File("byteclass/" + constituent.substring(0, constituent.lastIndexOf('.') + 1).replace('.', File.separatorChar));
 175   
 
 176  0
                 file = new File(path, constituent.substring(constituent.lastIndexOf('.') + 1) + ".class");
 177   
             }
 178   
             else
 179   
             {
 180  0
                 path = new File("byteclass/");
 181   
 
 182  0
                 file = new File(path, constituent + ".class");
 183   
             }
 184   
 
 185  0
             addConstituent( new URL( null,
 186   
                                      file.toURL().toExternalForm(),
 187   
                                      new BytesURLStreamHandler(b) ) );
 188   
         }
 189   
         catch (java.io.IOException e)
 190   
         {
 191  0
             throw new ClassNotFoundException( "Couldn't load byte stream.", e );
 192   
         }
 193   
     }
 194   
     
 195  308
     public ClassRealm locateSourceRealm( String classname )
 196   
     {
 197  308
         for ( Iterator iterator = imports.iterator(); iterator.hasNext(); )
 198   
         {
 199  250
             Entry entry = (Entry) iterator.next();
 200   
 
 201  250
             if ( entry.matches( classname ) )
 202   
             {
 203  50
                 return entry.getRealm();
 204   
             }
 205   
         }
 206   
 
 207  258
         return this;
 208   
     }
 209   
 
 210  64
     public ClassLoader getClassLoader()
 211   
     {
 212  64
         return classLoader;
 213   
     }
 214   
 
 215  8
     public ClassRealm createChildRealm( String id )
 216   
         throws DuplicateRealmException
 217   
     {
 218  8
         ClassRealm childRealm = getWorld().newRealm( id );
 219   
 
 220  8
         childRealm.setParent( this );
 221   
 
 222  8
         return childRealm;
 223   
     }
 224   
 
 225   
     // ----------------------------------------------------------------------
 226   
     // ClassLoader API
 227   
     // ----------------------------------------------------------------------
 228   
 
 229  428
     public Class loadClass( String name )
 230   
         throws ClassNotFoundException
 231   
     {
 232  428
         if ( name.startsWith( "org.codehaus.classworlds." ) )
 233   
         {
 234  216
             return getWorld().loadClass( name );
 235   
         }
 236   
 
 237  212
         try
 238   
         {
 239  212
             if ( foreignClassLoader != null )
 240   
             {
 241  0
                 try
 242   
                 {
 243  0
                     return foreignClassLoader.loadClass( name );
 244   
                 }
 245   
                 catch ( ClassNotFoundException e )
 246   
                 {
 247   
                     // Do nothing as we will now look in the realm.
 248   
                 }
 249   
             }
 250   
 
 251  212
             ClassRealm sourceRealm = locateSourceRealm( name );
 252   
             
 253  212
             if ( sourceRealm == this )
 254   
             {
 255  202
                 return classLoader.loadClassDirect( name );
 256   
             }
 257   
             else
 258   
             {
 259  10
                 try
 260   
                 {
 261  10
                     return sourceRealm.loadClass( name );
 262   
                 }
 263   
                 catch ( ClassNotFoundException cnfe )
 264   
                 {
 265   
                     // If we can't find it in an import, try loading directly.
 266  0
                     return classLoader.loadClassDirect( name );
 267   
                 }
 268   
             }
 269   
         }
 270   
         catch ( ClassNotFoundException e )
 271   
         {
 272  46
             if ( getParent() != null )
 273   
             {
 274  24
                 return getParent().loadClass( name );
 275   
             }
 276   
 
 277  22
             throw e;
 278   
         }
 279   
     }
 280   
 
 281  28
     public URL getResource( String name )
 282   
     {
 283  28
         URL resource = null;
 284  28
         name = UrlUtils.normalizeUrlPath( name );
 285   
         
 286  28
         if ( foreignClassLoader != null )
 287   
         {
 288  0
             resource = foreignClassLoader.getResource( name );
 289   
 
 290  0
             if ( resource != null )
 291   
             {
 292  0
                 return resource;
 293   
             }
 294   
         }
 295   
 
 296  28
         ClassRealm sourceRealm = locateSourceRealm( name );
 297   
         
 298  28
         if ( sourceRealm == this )
 299   
         {
 300  28
             resource = classLoader.getResourceDirect( name );
 301   
         }
 302   
         else
 303   
         {
 304  0
             resource = sourceRealm.getResource( name );
 305   
 
 306  0
             if ( resource == null )
 307   
             {
 308  0
                 resource = classLoader.getResourceDirect( name );
 309   
             }
 310   
         }
 311   
 
 312  28
         if ( resource == null && getParent() != null )
 313   
         {
 314  6
             resource = getParent().getResource( name );
 315   
         }
 316   
 
 317  28
         return resource;
 318   
     }
 319   
 
 320  0
     public InputStream getResourceAsStream( String name )
 321   
     {
 322  0
         URL url = getResource( name );
 323   
 
 324  0
         InputStream is = null;
 325   
 
 326  0
         if ( url != null )
 327   
         {
 328  0
             try
 329   
             {
 330  0
                 is = url.openStream();
 331   
             }
 332   
             catch ( IOException e )
 333   
             {
 334   
                 // do nothing
 335   
             }
 336   
         }
 337   
 
 338  0
         return is;
 339   
     }
 340   
     
 341  2
     public Enumeration findResources(String name)
 342   
         throws IOException
 343   
     {
 344  2
         name = UrlUtils.normalizeUrlPath(name);
 345   
 
 346  2
         Vector resources = new Vector();
 347   
 
 348   
         // Find resources from the parent class loader
 349  2
         if ( foreignClassLoader != null )
 350   
         {
 351  0
             for ( Enumeration res = foreignClassLoader.getResources(name); res.hasMoreElements(); )
 352   
             {
 353  0
                 resources.addElement(res.nextElement());
 354   
             }
 355   
         }
 356   
         
 357   
         // Load imports
 358  2
         ClassRealm sourceRealm = locateSourceRealm( name );
 359   
         
 360  2
         if ( sourceRealm != this )
 361   
         {
 362   
             // Attempt to load directly first, then go to the imported packages.
 363  0
             for ( Enumeration res = sourceRealm.findResources(name); res.hasMoreElements(); )
 364   
             {
 365  0
                 resources.addElement(res.nextElement());
 366   
             }
 367   
         }
 368   
 
 369   
         // Load from our classloader
 370  2
         for ( Enumeration direct = classLoader.findResourcesDirect(name); direct.hasMoreElements(); )
 371   
         {
 372  4
             resources.addElement(direct.nextElement());
 373   
         }
 374   
         
 375   
         // Find resources from the parent realm.
 376  2
         if (parent != null)
 377   
         {
 378  0
             for ( Enumeration parent = getParent().findResources(name); parent.hasMoreElements(); )
 379   
             {
 380  0
                 resources.addElement(parent.nextElement());
 381   
             }
 382   
         }
 383   
 
 384  2
         return resources.elements();
 385   
     }
 386   
 
 387  0
     public void display()
 388   
     {
 389  0
         ClassRealm cr = this;
 390   
 
 391  0
         System.out.println( "-----------------------------------------------------" );
 392   
 
 393   
 
 394  0
         showUrls( cr );
 395   
 
 396  0
         while( cr.getParent() != null )
 397   
         {
 398  0
             System.out.println( "\n" );
 399   
 
 400  0
             cr = cr.getParent();
 401   
 
 402  0
             showUrls( cr );
 403   
         }
 404   
 
 405  0
         System.out.println( "-----------------------------------------------------" );
 406   
     }
 407   
 
 408  0
     private void showUrls( ClassRealm classRealm )
 409   
     {
 410  0
         System.out.println( "this realm = " + classRealm.getId() );
 411   
 
 412  0
         URL[] urls = classRealm.getConstituents();
 413   
 
 414  0
         for ( int i = 0; i < urls.length; i++ )
 415   
         {
 416  0
             System.out.println( "urls[" + i + "] = " + urls[i] );
 417   
         }
 418   
 
 419  0
         System.out.println( "Number of imports: " + imports.size() );
 420   
 
 421  0
         for ( Iterator i = imports.iterator(); i.hasNext(); )
 422   
         {
 423  0
             System.out.println( "import: " + i.next() );
 424   
         }
 425   
     }
 426   
 }
 427