1 package org.codehaus.plexus.classworlds.realm; 2 3 /* 4 * Copyright 2001-2006 Codehaus Foundation. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 /** 20 * Import description entry. 21 * 22 * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a> 23 */ 24 class Entry 25 implements Comparable<Entry> 26 { 27 28 final ClassLoader classLoader; 29 30 final String pkgName; 31 32 Entry( ClassLoader realm, String pkgName ) 33 { 34 this.classLoader = realm; 35 36 this.pkgName = pkgName; 37 } 38 39 // ------------------------------------------------------------ 40 // Instance methods 41 // ------------------------------------------------------------ 42 43 /** 44 * Retrieve the class loader. 45 * 46 * @return The class loader. 47 */ 48 ClassLoader getClassLoader() 49 { 50 return this.classLoader; 51 } 52 53 /** 54 * Retrieve the package name. 55 * 56 * @return The package name. 57 */ 58 String getPackageName() 59 { 60 return this.pkgName; 61 } 62 63 /** 64 * Determine if the class/resource name matches the package 65 * described by this entry. 66 * 67 * @param name The class or resource name to test, must not be <code>null</code>. 68 * @return <code>true</code> if this entry matches the 69 * classname, otherwise <code>false</code>. 70 */ 71 boolean matches( String name ) 72 { 73 String pkg = getPackageName(); 74 75 if ( pkg.endsWith( ".*" ) ) 76 { 77 String pkgName; 78 79 if ( name.indexOf( '/' ) < 0 ) 80 { 81 // a binary class name, e.g. java.lang.Object 82 83 int index = name.lastIndexOf( '.' ); 84 pkgName = ( index < 0 ) ? "" : name.substring( 0, index ); 85 } 86 else 87 { 88 // a resource name, e.g. java/lang/Object.class 89 90 int index = name.lastIndexOf( '/' ); 91 pkgName = ( index < 0 ) ? "" : name.substring( 0, index ).replace( '/', '.' ); 92 } 93 94 return pkgName.length() == pkg.length() - 2 && pkg.regionMatches( 0, pkgName, 0, pkgName.length() ); 95 } 96 else if ( pkg.length() > 0 ) 97 { 98 if ( name.indexOf( '/' ) < 0 ) 99 { 100 // a binary class name, e.g. java.lang.Object 101 102 if ( name.startsWith( pkg ) ) 103 { 104 if ( name.length() == pkg.length() ) 105 { 106 // exact match of class name 107 return true; 108 } 109 else if ( name.charAt( pkg.length() ) == '.' ) 110 { 111 // prefix match of package name 112 return true; 113 } 114 else if ( name.charAt( pkg.length() ) == '$' ) 115 { 116 // prefix match of enclosing type 117 return true; 118 } 119 } 120 } 121 else 122 { 123 // a resource name, e.g. java/lang/Object.class 124 125 if ( name.equals( pkg ) ) 126 { 127 // exact match of resource name 128 return true; 129 } 130 131 pkg = pkg.replace( '.', '/' ); 132 133 if ( name.startsWith( pkg ) && name.length() > pkg.length() ) 134 { 135 if ( name.charAt( pkg.length() ) == '/' ) 136 { 137 // prefix match of package directory 138 return true; 139 } 140 else if ( name.charAt( pkg.length() ) == '$' ) 141 { 142 // prefix match of nested class file 143 return true; 144 } 145 else if ( name.length() == pkg.length() + 6 && name.endsWith( ".class" ) ) 146 { 147 // exact match of class file 148 return true; 149 } 150 } 151 } 152 153 return false; 154 } 155 else 156 { 157 return true; 158 } 159 } 160 161 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 162 // java.lang.Comparable 163 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 164 165 /** 166 * Compare this entry to another for relative ordering. 167 * <p/> 168 * <p/> 169 * The natural ordering of Entry objects is reverse-alphabetical 170 * based upon package name. 171 * </p> 172 * 173 * @param thatObj The object to compare. 174 * @return -1 if this object sorts before that object, 0 175 * if they are equal, or 1 if this object sorts 176 * after that object. 177 */ 178 public int compareTo( Entry that ) 179 { 180 // We are reverse sorting this list, so that 181 // we get longer matches first: 182 // 183 // com.werken.foo.bar 184 // com.werken.foo 185 // com.werken 186 187 return - ( getPackageName().compareTo( that.getPackageName() ) ); 188 } 189 190 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 191 // java.lang.Object 192 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 193 194 /** 195 * Test this entry for equality to another. 196 * <p/> 197 * <p/> 198 * Consistent with {@link #compareTo}, this method tests 199 * for equality purely on the package name. 200 * </p> 201 * 202 * @param thatObj The object to compare 203 * @return <code>true</code> if the two objects are 204 * semantically equivalent, otherwise <code>false</code>. 205 */ 206 public boolean equals( Object thatObj ) 207 { 208 Entry that = (Entry) thatObj; 209 210 return getPackageName().equals( that.getPackageName() ); 211 } 212 213 /** 214 * <p/> 215 * Consistent with {@link #equals}, this method creates a hashCode 216 * based on the packagename. 217 * </p> 218 */ 219 public int hashCode() 220 { 221 return getPackageName().hashCode(); 222 } 223 224 public String toString() 225 { 226 return "Entry[import " + getPackageName() + " from realm " + getClassLoader() + "]"; 227 } 228 }