View Javadoc

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 }