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 }