40 |
|
|
41 |
import java.io.*; |
import java.io.*; |
42 |
import java.util.*; |
import java.util.*; |
43 |
|
import java.net.*; |
44 |
|
import gnu.java.io.PlatformHelper; |
45 |
|
|
46 |
|
/** |
47 |
|
* Currently getSystemResourceAsFile is only used in java/lang/Character.<clinit>. |
48 |
|
* Personally I think it's not wise for java/lang/Character to have data stored in |
49 |
|
* character.uni / block.uni / titlecase.uni files. It'll be more efficient and |
50 |
|
* convenient to have these data inlined in Character.java. |
51 |
|
* And what's more specific here, if we inlined those data, we don't need |
52 |
|
* ClassLoaderHelper.getSystemResourceAsFile any more. It's a procedure which could bring |
53 |
|
* trouble. |
54 |
|
* Consider when we add jar support to ClassLoaderHelper.getSystemResourceAsFile, we will |
55 |
|
* encounter the following call chain: |
56 |
|
* |
57 |
|
* Character.<clinit> -> ClassLoaderHelper.getSystemResourceAsFile() -> ... ->Character.toLowerCase(). |
58 |
|
* |
59 |
|
* It's another recursive call when initialization of Character is still on the way, |
60 |
|
* call to Character happens. |
61 |
|
* Currently I have to use a call of Character.toLowerCase() to verify if initialization |
62 |
|
* of Character has been finished, if exceptions are throwed, it indicates that the construction |
63 |
|
* of Character is ongoing, so I abandon further investigation of the jar package. |
64 |
|
* It's somewhat ugly, and what's important is that it'll degrade performance. |
65 |
|
* Maybe we need to check why we have so many heavyweight <clinit>/<init> which will lead to |
66 |
|
* call methods/access fields of itself. |
67 |
|
* |
68 |
|
* "fileResourceCache" is used to save File instances mapping to specific absolute paths and jar urls. |
69 |
|
* -- Gansha |
70 |
|
*/ |
71 |
|
|
72 |
/** |
/** |
73 |
** ClassLoaderHelper has various methods that ought to have been |
** ClassLoaderHelper has various methods that ought to have been |
78 |
**/ |
**/ |
79 |
public class ClassLoaderHelper |
public class ClassLoaderHelper |
80 |
{ |
{ |
81 |
|
private static Hashtable fileResourceCache = new Hashtable(); |
82 |
|
private static final int READBUFSIZE = 1024; |
83 |
|
|
84 |
/** |
/** |
85 |
* Searches the CLASSPATH for a resource and returns it as a File. |
* Searches the CLASSPATH for a resource and returns it as a File. |
|
* Currently ignores ZIP and JAR archives. |
|
86 |
* |
* |
87 |
* @param name name of resource to locate |
* @param name name of resource to locate |
88 |
* |
* |
92 |
public static final File getSystemResourceAsFile(String name) { |
public static final File getSystemResourceAsFile(String name) { |
93 |
if (name.startsWith("/")) |
if (name.startsWith("/")) |
94 |
name = name.substring(1); |
name = name.substring(1); |
95 |
|
|
96 |
String path = System.getProperty("java.class.path", "."); |
String path = System.getProperty("java.class.path", "."); |
97 |
StringTokenizer st = new StringTokenizer(path, |
StringTokenizer st = new StringTokenizer(path, |
98 |
System.getProperty("path.separator", ":")); |
System.getProperty("path.separator", ":")); |
99 |
while (st.hasMoreElements()) { |
while (st.hasMoreElements()) { |
100 |
String token = st.nextToken(); |
String token = st.nextToken(); |
101 |
File file; |
File file; |
102 |
if (token.endsWith(File.separator)) |
if (token.endsWith(".zip") || |
103 |
file = new File(token, name); |
token.endsWith(".jar") ){ |
104 |
else |
// The following tests whether java/lang/Character |
105 |
file = new File(token + File.separator + name); |
// has been initialized, if no, abort loading this archive to |
106 |
if (file.isFile()) |
// avoid infinite recursive call |
107 |
return file; |
try{ |
108 |
|
token = token.toLowerCase(); |
109 |
|
}catch(Exception e){ |
110 |
|
continue; |
111 |
|
} |
112 |
|
|
113 |
|
file = new File(token); |
114 |
|
if(!file.exists())continue; |
115 |
|
|
116 |
|
path = file.getAbsolutePath(); |
117 |
|
try { |
118 |
|
if(path.startsWith("/")) |
119 |
|
path = "jar:file:/"+ path + "!/" + name; |
120 |
|
else |
121 |
|
path = "jar:file://"+ path + "!/" + name; |
122 |
|
file = (File)fileResourceCache.get(path); |
123 |
|
if(file == null){ |
124 |
|
//load jar/zip entry from the url |
125 |
|
URL url = new URL(path); |
126 |
|
URLConnection urlconn = url.openConnection(); |
127 |
|
InputStream is = urlconn.getInputStream(); |
128 |
|
byte[] buf = new byte[READBUFSIZE]; |
129 |
|
file = File.createTempFile("tmp", "", new File(".")); |
130 |
|
FileOutputStream fos = new FileOutputStream(file); |
131 |
|
int len = 0; |
132 |
|
while((len = is.read(buf)) != -1){ |
133 |
|
fos.write(buf); |
134 |
|
} |
135 |
|
fos.close(); |
136 |
|
} |
137 |
|
} catch(Exception e) { |
138 |
|
continue; |
139 |
|
} |
140 |
|
}else{ |
141 |
|
if (PlatformHelper.endWithSeparator(token)) |
142 |
|
path = token + name; |
143 |
|
else |
144 |
|
path = token + File.separator + name; |
145 |
|
file = (File)fileResourceCache.get(path); |
146 |
|
if(file == null) |
147 |
|
file = new File(path); |
148 |
|
} |
149 |
|
|
150 |
|
if (file != null && file.isFile()){ |
151 |
|
fileResourceCache.put(path, file); |
152 |
|
return file; |
153 |
|
} |
154 |
} |
} |
155 |
return null; |
return null; |
156 |
} |
} |