1 package org.naftulin.classpathexplorer.resourceinfo.impl; 2 3 import java.io.File; 4 import java.io.Serializable; 5 import java.io.UnsupportedEncodingException; 6 import java.net.URL; 7 import java.net.URLDecoder; 8 9 import org.naftulin.logwrapper.LogAdapter; 10 import org.naftulin.logwrapper.LogLevelAdaptor; 11 import org.naftulin.timespan.TimeSpan; 12 13 14 15 /*** 16 * Given a class or an object computes which archive it was loaded from. 17 * @author henry naftulin 18 * @version 1.0 19 */ 20 public class ResourceInfo implements Serializable { 21 private static final long serialVersionUID = 1L; 22 private static LogAdapter log = LogAdapter.getLogger(ResourceInfo.class); 23 public static final ResourceInfo NOT_FOUND_RESOURCE_INFO = new ResourceInfo((File)null); 24 private final File classArchiveSource; 25 26 /*** 27 * Given a class computes which archive it was loaded from and 28 * provides it's package information. 29 * @param clazz class 30 */ 31 private ResourceInfo(Class clazz) { 32 if (clazz == null) { 33 throw new IllegalArgumentException("Argument to constructor cannot be null"); 34 } 35 TimeSpan timeSpan = new TimeSpan("Getting resource information"); 36 timeSpan.start(); 37 38 String fileName = null; 39 40 String className = clazz.getName().replace('.','/') + ".class"; 41 ClassLoader cl = this.getClass().getClassLoader(); 42 URL url = cl.getResource(className); 43 fileName = url.getFile(); 44 if (fileName != null && fileName.indexOf(className) > 0) { 45 fileName = fileName.substring(0,fileName.indexOf(className)); 46 try { 47 fileName = URLDecoder.decode(fileName,"UTF-8"); 48 } catch (UnsupportedEncodingException e) { 49 log.log(LogLevelAdaptor.WARN,"could not decode file name " + fileName, e); 50 fileName = null; 51 } 52 } else { 53 fileName = null; 54 } 55 classArchiveSource = fileName != null ? new File(fileName) : null; 56 if (classArchiveSource == null) { 57 log.log(LogLevelAdaptor.ERROR,"Could not find class " + clazz.getName() + " in the class path. Was looking for resource named " + className); 58 } 59 timeSpan.stop(); 60 timeSpan.log(log, LogLevelAdaptor.DEBUG); 61 } 62 63 /*** 64 * Given an object cimputes which archive it was loaded from and 65 * provides it's package information. 66 * @param object 67 */ 68 private ResourceInfo(Object object) { 69 this(object.getClass()); 70 } 71 72 /*** 73 * Needed to represent not found resource. 74 * @param file 75 * @param pack 76 */ 77 private ResourceInfo(final File file) { 78 this.classArchiveSource = file; 79 } 80 81 /*** 82 * Returns the archive the resource was read from. 83 * @return the archive the resource was read from. 84 */ 85 public File getClassArchiveSource() { 86 return classArchiveSource; 87 } 88 89 /*** 90 * Given a class computes which archive it was loaded from and 91 * provides it's package information. 92 * @param clazz class 93 */ 94 public static ResourceInfo getResourceInfo(Class clazz) { 95 return new ResourceInfo(clazz); 96 } 97 98 /*** 99 * Given an object cimputes which archive it was loaded from and 100 * provides it's package information. 101 * @param object 102 */ 103 public static ResourceInfo getResourceInfoForObject(Object obj) { 104 return new ResourceInfo(obj); 105 } 106 107 public boolean equals(Object o) { 108 if (o == null) { return false; } 109 if (o == this) { return true; } 110 if (!(o instanceof ResourceInfo)) { return false; } 111 112 ResourceInfo r = (ResourceInfo) o; 113 boolean equals = (r.classArchiveSource == null && this.classArchiveSource == null) 114 || (this.classArchiveSource != null && this.classArchiveSource.equals(r.classArchiveSource)); 115 116 return equals; 117 } 118 119 public int hashCode() { 120 int hashCode = 37; 121 if (this.classArchiveSource != null){ 122 hashCode += 17 * this.classArchiveSource.hashCode(); 123 } 124 return hashCode; 125 } 126 127 }