001: /*
002: ******************************************************************************
003: * Copyright (C) 2005, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: ******************************************************************************
006: */
007:
008: package com.ibm.icu.impl;
009:
010: import java.io.BufferedReader;
011: import java.io.File;
012: import java.io.InputStream;
013: import java.io.InputStreamReader;
014: import java.lang.reflect.InvocationTargetException;
015: import java.lang.reflect.Method;
016: import java.net.JarURLConnection;
017: import java.net.URL;
018: import java.util.Enumeration;
019: import java.util.HashMap;
020: import java.util.Map;
021: import java.util.jar.JarEntry;
022: import java.util.jar.JarFile;
023:
024: public abstract class URLHandler {
025: public static final String PROPNAME = "urlhandler.props";
026:
027: private static final Map handlers;
028:
029: private static final boolean DEBUG = ICUDebug.enabled("URLHandler");
030:
031: static {
032: Map h = null;
033:
034: try {
035: InputStream is = URLHandler.class
036: .getResourceAsStream(PROPNAME);
037:
038: if (is == null) {
039: is = ClassLoader.getSystemClassLoader()
040: .getResourceAsStream(PROPNAME);
041: }
042:
043: if (is != null) {
044: Class[] params = { URL.class };
045: BufferedReader br = new BufferedReader(
046: new InputStreamReader(is));
047:
048: for (String line = br.readLine(); line != null; line = br
049: .readLine()) {
050: line = line.trim();
051:
052: if (line.length() == 0 || line.charAt(0) == '#') {
053: continue;
054: }
055:
056: int ix = line.indexOf('=');
057:
058: if (ix == -1) {
059: if (DEBUG)
060: System.err.println("bad urlhandler line: '"
061: + line + "'");
062: break;
063: }
064:
065: String key = line.substring(0, ix).trim();
066: String value = line.substring(ix + 1).trim();
067:
068: try {
069: Class cl = Class.forName(value);
070: Method m = cl.getDeclaredMethod("get", params);
071:
072: if (h == null) {
073: h = new HashMap();
074: }
075:
076: h.put(key, m);
077: } catch (ClassNotFoundException e) {
078: if (DEBUG)
079: System.err.println(e);
080: } catch (NoSuchMethodException e) {
081: if (DEBUG)
082: System.err.println(e);
083: } catch (SecurityException e) {
084: if (DEBUG)
085: System.err.println(e);
086: }
087: }
088: }
089: } catch (Throwable t) {
090: if (DEBUG)
091: System.err.println(t);
092: }
093:
094: handlers = h;
095: }
096:
097: public static URLHandler get(URL url) {
098: if (url == null) {
099: return null;
100: }
101:
102: String protocol = url.getProtocol();
103:
104: if (handlers != null) {
105: Method m = (Method) handlers.get(protocol);
106:
107: if (m != null) {
108: try {
109: URLHandler handler = (URLHandler) m.invoke(null,
110: new Object[] { url });
111:
112: if (handler != null) {
113: return handler;
114: }
115: } catch (IllegalAccessException e) {
116: if (DEBUG)
117: System.err.println(e);
118: } catch (IllegalArgumentException e) {
119: if (DEBUG)
120: System.err.println(e);
121: } catch (InvocationTargetException e) {
122: if (DEBUG)
123: System.err.println(e);
124: }
125: }
126: }
127:
128: return getDefault(url);
129: }
130:
131: protected static URLHandler getDefault(URL url) {
132: String protocol = url.getProtocol();
133:
134: if (protocol.equals("file")) {
135: return new FileURLHandler(url);
136: } else if (protocol.equals("jar")) {
137: return new JarURLHandler(url);
138: } else {
139: return null;
140: }
141: }
142:
143: private static class FileURLHandler extends URLHandler {
144: File file;
145: String root;
146:
147: FileURLHandler(URL url) {
148: root = url.getPath();
149: file = new File(root);
150:
151: if (!file.exists()) {
152: if (DEBUG)
153: System.err.println("file does not exist");
154: throw new IllegalArgumentException();
155: }
156: }
157:
158: public void guide(URLVisitor v, boolean recurse, boolean strip) {
159: if (file.isDirectory()) {
160: process(v, recurse, strip, "/", file.listFiles());
161: } else {
162: v.visit(file.getName());
163: }
164: }
165:
166: private void process(URLVisitor v, boolean recurse,
167: boolean strip, String path, File[] files) {
168: for (int i = 0; i < files.length; i++) {
169: File f = files[i];
170:
171: if (f.isDirectory()) {
172: if (recurse) {
173: process(v, recurse, strip, path + f.getName()
174: + '/', f.listFiles());
175: }
176: } else {
177: v.visit(strip ? f.getName() : path + f.getName());
178: }
179: }
180: }
181: }
182:
183: private static class JarURLHandler extends URLHandler {
184: JarFile jarFile;
185: String prefix;
186:
187: JarURLHandler(URL url) {
188: try {
189: prefix = url.getPath();
190:
191: int ix = prefix.indexOf("!/");
192:
193: if (ix >= 0) {
194: prefix = prefix.substring(ix + 2); // truncate after "!/"
195: }
196:
197: JarURLConnection conn = (JarURLConnection) url
198: .openConnection();
199:
200: jarFile = conn.getJarFile();
201: } catch (Exception e) {
202: if (DEBUG)
203: System.err.println("icurb jar error: " + e);
204: throw new IllegalArgumentException("jar error: "
205: + e.getMessage());
206: }
207: }
208:
209: public void guide(URLVisitor v, boolean recurse, boolean strip) {
210: try {
211: Enumeration entries = jarFile.entries();
212:
213: while (entries.hasMoreElements()) {
214: JarEntry entry = (JarEntry) entries.nextElement();
215:
216: if (!entry.isDirectory()) { // skip just directory paths
217: String name = entry.getName();
218:
219: if (name.startsWith(prefix)) {
220: name = name.substring(prefix.length());
221:
222: int ix = name.lastIndexOf('/');
223:
224: if (ix != -1) {
225: if (!recurse) {
226: continue;
227: }
228:
229: if (strip) {
230: name = name.substring(ix + 1);
231: }
232: }
233:
234: v.visit(name);
235: }
236: }
237: }
238: } catch (Exception e) {
239: if (DEBUG)
240: System.err.println("icurb jar error: " + e);
241: }
242: }
243: }
244:
245: public void guide(URLVisitor visitor, boolean recurse) {
246: guide(visitor, recurse, true);
247: }
248:
249: public abstract void guide(URLVisitor visitor, boolean recurse,
250: boolean strip);
251:
252: public interface URLVisitor {
253: void visit(String str);
254: }
255: }
|