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 implements Comparable<Entry> { 25 26 final ClassLoader classLoader; 27 28 final String pkgName; 29 30 Entry(ClassLoader realm, String pkgName) { 31 this.classLoader = realm; 32 33 this.pkgName = pkgName; 34 } 35 36 // ------------------------------------------------------------ 37 // Instance methods 38 // ------------------------------------------------------------ 39 40 /** 41 * Retrieve the class loader. 42 * 43 * @return The class loader. 44 */ 45 ClassLoader getClassLoader() { 46 return this.classLoader; 47 } 48 49 /** 50 * Retrieve the package name. 51 * 52 * @return The package name. 53 */ 54 String getPackageName() { 55 return this.pkgName; 56 } 57 58 /** 59 * Determine if the class/resource name matches the package 60 * described by this entry. 61 * 62 * @param name The class or resource name to test, must not be <code>null</code>. 63 * @return <code>true</code> if this entry matches the 64 * classname, otherwise <code>false</code>. 65 */ 66 boolean matches(String name) { 67 String pkg = getPackageName(); 68 69 if (pkg.endsWith(".*")) { 70 String pkgName; 71 72 if (name.indexOf('/') < 0) { 73 // a binary class name, e.g. java.lang.Object 74 75 int index = name.lastIndexOf('.'); 76 pkgName = (index < 0) ? "" : name.substring(0, index); 77 } else { 78 // a resource name, e.g. java/lang/Object.class 79 80 int index = name.lastIndexOf('/'); 81 pkgName = (index < 0) ? "" : name.substring(0, index).replace('/', '.'); 82 } 83 84 return pkgName.length() == pkg.length() - 2 && pkg.regionMatches(0, pkgName, 0, pkgName.length()); 85 } else if (pkg.length() > 0) { 86 if (name.indexOf('/') < 0) { 87 // a binary class name, e.g. java.lang.Object 88 89 if (name.startsWith(pkg)) { 90 if (name.length() == pkg.length()) { 91 // exact match of class name 92 return true; 93 } else if (name.charAt(pkg.length()) == '.') { 94 // prefix match of package name 95 return true; 96 } else if (name.charAt(pkg.length()) == '$') { 97 // prefix match of enclosing type 98 return true; 99 } 100 } 101 } else { 102 // a resource name, e.g. java/lang/Object.class 103 104 if (name.equals(pkg)) { 105 // exact match of resource name 106 return true; 107 } 108 109 pkg = pkg.replace('.', '/'); 110 111 if (name.startsWith(pkg) && name.length() > pkg.length()) { 112 if (name.charAt(pkg.length()) == '/') { 113 // prefix match of package directory 114 return true; 115 } else if (name.charAt(pkg.length()) == '$') { 116 // prefix match of nested class file 117 return true; 118 } else if (name.length() == pkg.length() + 6 && name.endsWith(".class")) { 119 // exact match of class file 120 return true; 121 } 122 } 123 } 124 125 return false; 126 } else { 127 return true; 128 } 129 } 130 131 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 132 // java.lang.Comparable 133 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 134 135 /** 136 * Compare this entry to another for relative ordering. 137 * <p/> 138 * <p/> 139 * The natural ordering of Entry objects is reverse-alphabetical 140 * based upon package name. 141 * </p> 142 * 143 * @param that The object to compare. 144 * @return -1 if this object sorts before that object, 0 145 * if they are equal, or 1 if this object sorts 146 * after that object. 147 */ 148 public int compareTo(Entry that) { 149 // We are reverse sorting this list, so that 150 // we get longer matches first: 151 // 152 // com.werken.foo.bar 153 // com.werken.foo 154 // com.werken 155 156 return -(getPackageName().compareTo(that.getPackageName())); 157 } 158 159 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 160 // java.lang.Object 161 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 162 163 /** 164 * Test this entry for equality to another. 165 * <p/> 166 * <p/> 167 * Consistent with {@link #compareTo}, this method tests 168 * for equality purely on the package name. 169 * </p> 170 * 171 * @param thatObj The object to compare 172 * @return <code>true</code> if the two objects are 173 * semantically equivalent, otherwise <code>false</code>. 174 */ 175 public boolean equals(Object thatObj) { 176 Entry that = (Entry) thatObj; 177 178 return getPackageName().equals(that.getPackageName()); 179 } 180 181 /** 182 * <p/> 183 * Consistent with {@link #equals}, this method creates a hashCode 184 * based on the packagename. 185 * </p> 186 */ 187 public int hashCode() { 188 return getPackageName().hashCode(); 189 } 190 191 public String toString() { 192 return "Entry[import " + getPackageName() + " from realm " + getClassLoader() + "]"; 193 } 194 }