View Javadoc
1 package org.codehaus.classworlds; 2 3 /* 4 $Id: DefaultClassRealm.java,v 1.1 2003/09/23 14:09:46 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 java.net.URL; 50 import java.util.TreeSet; 51 import java.util.Set; 52 import java.util.Iterator; 53 54 /*** Implementation of <code>ClassRealm</code>. 55 * 56 * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a> 57 * @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a> 58 * 59 * @version $Id: DefaultClassRealm.java,v 1.1 2003/09/23 14:09:46 jvanzyl Exp $ 60 * 61 * @todo allow inheritance to be turn on/off at runtime. 62 * @todo allow direction of search 63 */ 64 class DefaultClassRealm implements ClassRealm 65 { 66 // ------------------------------------------------------------ 67 // Instance members 68 // ------------------------------------------------------------ 69 70 /*** The world of which this realm is a member. */ 71 private ClassWorld world; 72 73 /*** The id of this realm. */ 74 private String id; 75 76 /*** Import spec entries. */ 77 private Set imports; 78 79 /*** The classloader. */ 80 private RealmClassLoader classLoader; 81 82 /*** Parent ClassRealm */ 83 private ClassRealm parent; 84 85 // ------------------------------------------------------------ 86 // Constructors 87 // ------------------------------------------------------------ 88 89 /*** Construct. 90 * 91 * @param world The world of which this realm is a member. 92 * @param id This realm's id. 93 */ 94 DefaultClassRealm( ClassWorld world, 95 String id ) 96 { 97 this.world = world; 98 this.id = id; 99 100 this.imports = new TreeSet(); 101 102 // We need to detect whether we are running in an UberJar 103 // or not. 104 if ( "true".equals( System.getProperty( "classworlds.bootstrapped" ) ) ) 105 { 106 this.classLoader = new UberJarRealmClassLoader( this ); 107 } 108 else 109 { 110 this.classLoader = new RealmClassLoader( this ); 111 } 112 } 113 114 // ------------------------------------------------------------ 115 // Instance methods 116 // ------------------------------------------------------------ 117 118 /*** 119 * 120 * @return 121 */ 122 public ClassRealm getParent() 123 { 124 return parent; 125 } 126 127 /*** 128 * 129 * @param parent 130 */ 131 public void setParent( ClassRealm parent ) 132 { 133 this.parent = parent; 134 } 135 136 /*** Retrieve the id. 137 * 138 * @return The id. 139 */ 140 public String getId() 141 { 142 return this.id; 143 } 144 145 /*** Retrieve the <code>ClassWorld</code>. 146 * 147 * @return The world. 148 */ 149 public ClassWorld getWorld() 150 { 151 return this.world; 152 } 153 154 /*** Import packages from another <code>ClassRealm</code>. 155 * 156 * <p> 157 * Specific packages can be imported from another realm 158 * instead of attempting to load them locally from this 159 * one. When importing a package a realm defers <b>completely</b> 160 * to the foreign realm to satisfy the package dependencies. 161 * </p> 162 * 163 * @param realmId The realm id from which to import. 164 * @param pkgName The package name to import. 165 * 166 * @throws NoSuchRealmException If the id of the realm from which 167 * to import does not correspond to a foreign realm within 168 * this realm's world. 169 */ 170 public void importFrom( String realmId, 171 String pkgName ) throws NoSuchRealmException 172 { 173 this.imports.add( new Entry( getWorld().getRealmImpl( realmId ), 174 pkgName ) ); 175 } 176 177 /*** Add a constituent to this realm for locating classes. 178 * 179 * @param constituent URL to contituent jar or directory. 180 */ 181 public void addConstituent( URL constituent ) 182 { 183 this.classLoader.addConstituent( constituent ); 184 } 185 186 /*** Locate the <code>ClassRealm</code> that should 187 * satisfy loading of a class. 188 * 189 * @param classname The name of the class to load. 190 * 191 * @return The appropriate realm. 192 */ 193 DefaultClassRealm locateSourceRealm( String classname ) 194 { 195 Iterator entryIter = this.imports.iterator(); 196 197 while ( entryIter.hasNext() ) 198 { 199 Entry eachEntry = (Entry) entryIter.next(); 200 201 if ( eachEntry.matches( classname ) ) 202 { 203 return eachEntry.getRealm(); 204 } 205 } 206 207 return this; 208 } 209 210 /*** Retrieve the <code>ClassLoader</code> view of 211 * this realm. 212 * 213 * @return The class-loader view of this realm. 214 */ 215 public ClassLoader getClassLoader() 216 { 217 return this.classLoader; 218 } 219 220 /*** Load a class. 221 * 222 * @param name The name of the class to load. 223 * 224 * @return The loaded class. 225 * 226 * @throws ClassNotFoundException If the class cannot be found. 227 */ 228 public Class loadClass( String name ) throws ClassNotFoundException 229 { 230 if ( name.startsWith( "org.codehaus.classworlds." ) ) 231 { 232 return getWorld().loadClass( name ); 233 } 234 235 DefaultClassRealm sourceRealm = locateSourceRealm( name ); 236 237 if ( sourceRealm == this ) 238 { 239 return loadClassDirect( name ); 240 } 241 242 return sourceRealm.loadClass( name ); 243 } 244 245 /*** Load a class. 246 * 247 * @param name The name of the class to load. 248 * 249 * @return The loaded class. 250 * 251 * @throws ClassNotFoundException If the class cannot be found. 252 */ 253 Class loadClassDirect( String name ) throws ClassNotFoundException 254 { 255 // 1. Try this realm's ClassLoader. 256 // 2. If the realm has a parent try the parent's ClassLoader. 257 258 Class clazz = null; 259 260 try 261 { 262 clazz = this.classLoader.loadClassDirect( name ); 263 } 264 catch ( ClassNotFoundException cnfe1 ) 265 { 266 if ( getParent() != null ) 267 { 268 clazz = getParent().getClassLoader().loadClass( name ); 269 } 270 else 271 { 272 throw cnfe1; 273 } 274 } 275 276 return clazz; 277 } 278 279 /*** Retrieve a resource. 280 * 281 * @param name The resource name. 282 * 283 * @return The URL to the located resource or <code>null</code> 284 * if none could be located. 285 */ 286 public URL getResource( String name ) 287 { 288 name = UrlUtils.normalizeUrlPath( name ); 289 290 DefaultClassRealm sourceRealm = locateSourceRealm( name ); 291 292 if ( sourceRealm == this ) 293 { 294 return loadResourceDirect( name ); 295 } 296 297 return sourceRealm.getResource( name ); 298 } 299 300 301 URL loadResourceDirect( String name ) 302 { 303 // 1. Try this realm's ClassLoader. 304 // 2. If the realm has a parent try the parent's ClassLoader. 305 306 URL resource = this.classLoader.findResource( name ); 307 308 if ( resource == null 309 && 310 getParent() != null ) 311 { 312 resource = getParent().getResource( name ); 313 } 314 315 return resource; 316 } 317 318 /*** 319 * @see ClassRealm#createChildRealm 320 */ 321 public ClassRealm createChildRealm( String id ) 322 { 323 ClassRealm childRealm = new DefaultClassRealm( getWorld(), id ); 324 childRealm.setParent( this ); 325 326 return childRealm; 327 } 328 }

This page was automatically generated by Maven