2 ******************************************************************************
\r
3 * Copyright (C) 2005-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 ******************************************************************************
\r
8 package com.ibm.icu.impl;
\r
10 import java.io.BufferedReader;
\r
11 import java.io.File;
\r
12 import java.io.InputStream;
\r
13 import java.io.InputStreamReader;
\r
14 import java.lang.reflect.InvocationTargetException;
\r
15 import java.lang.reflect.Method;
\r
16 import java.net.JarURLConnection;
\r
17 import java.net.URISyntaxException;
\r
18 import java.net.URL;
\r
19 import java.util.Enumeration;
\r
20 import java.util.HashMap;
\r
21 import java.util.Map;
\r
22 import java.util.jar.JarEntry;
\r
23 import java.util.jar.JarFile;
\r
25 public abstract class URLHandler {
\r
26 public static final String PROPNAME = "urlhandler.props";
\r
28 private static final Map<String, Method> handlers;
\r
30 private static final boolean DEBUG = ICUDebug.enabled("URLHandler");
\r
33 Map<String, Method> h = null;
\r
36 InputStream is = URLHandler.class.getResourceAsStream(PROPNAME);
\r
38 ClassLoader loader = Utility.getFallbackClassLoader();
\r
39 is = loader.getResourceAsStream(PROPNAME);
\r
43 Class<?>[] params = { URL.class };
\r
44 BufferedReader br = new BufferedReader(new InputStreamReader(is));
\r
46 for (String line = br.readLine(); line != null; line = br.readLine()) {
\r
49 if (line.length() == 0 || line.charAt(0) == '#') {
\r
53 int ix = line.indexOf('=');
\r
56 if (DEBUG) System.err.println("bad urlhandler line: '" + line + "'");
\r
60 String key = line.substring(0, ix).trim();
\r
61 String value = line.substring(ix+1).trim();
\r
64 Class<?> cl = Class.forName(value);
\r
65 Method m = cl.getDeclaredMethod("get", params);
\r
68 h = new HashMap<String, Method>();
\r
73 catch (ClassNotFoundException e) {
\r
74 if (DEBUG) System.err.println(e);
\r
76 catch(NoSuchMethodException e) {
\r
77 if (DEBUG) System.err.println(e);
\r
79 catch(SecurityException e) {
\r
80 if (DEBUG) System.err.println(e);
\r
84 } catch (Throwable t) {
\r
85 if (DEBUG) System.err.println(t);
\r
91 public static URLHandler get(URL url) {
\r
96 String protocol = url.getProtocol();
\r
98 if (handlers != null) {
\r
99 Method m = handlers.get(protocol);
\r
103 URLHandler handler = (URLHandler)m.invoke(null, new Object[] { url });
\r
105 if (handler != null) {
\r
109 catch(IllegalAccessException e) {
\r
110 if (DEBUG) System.err.println(e);
\r
112 catch(IllegalArgumentException e) {
\r
113 if (DEBUG) System.err.println(e);
\r
115 catch(InvocationTargetException e) {
\r
116 if (DEBUG) System.err.println(e);
\r
121 return getDefault(url);
\r
124 protected static URLHandler getDefault(URL url) {
\r
125 URLHandler handler = null;
\r
127 String protocol = url.getProtocol();
\r
129 if (protocol.equals("file")) {
\r
130 handler = new FileURLHandler(url);
\r
131 } else if (protocol.equals("jar") || protocol.equals("wsjar")) {
\r
132 handler = new JarURLHandler(url);
\r
134 } catch (Exception e) {
\r
135 // ignore - just return null
\r
140 private static class FileURLHandler extends URLHandler {
\r
143 FileURLHandler(URL url) {
\r
145 file = new File(url.toURI());
\r
146 } catch (URISyntaxException use) {
\r
149 if (file == null || !file.exists()) {
\r
150 if (DEBUG) System.err.println("file does not exist - " + url.toString());
\r
151 throw new IllegalArgumentException();
\r
155 public void guide(URLVisitor v, boolean recurse, boolean strip) {
\r
156 if (file.isDirectory()) {
\r
157 process(v, recurse, strip, "/", file.listFiles());
\r
159 v.visit(file.getName());
\r
163 private void process(URLVisitor v, boolean recurse, boolean strip, String path, File[] files) {
\r
164 for (int i = 0; i < files.length; i++) {
\r
167 if (f.isDirectory()) {
\r
169 process(v, recurse, strip, path + f.getName()+ '/', f.listFiles());
\r
172 v.visit(strip? f.getName() : path + f.getName());
\r
178 private static class JarURLHandler extends URLHandler {
\r
182 JarURLHandler(URL url) {
\r
184 prefix = url.getPath();
\r
186 int ix = prefix.indexOf("!/");
\r
189 prefix = prefix.substring(ix + 2); // truncate after "!/"
\r
192 String protocol = url.getProtocol();
\r
193 if (!protocol.equals("jar")) {
\r
194 // change the protocol to "jar"
\r
195 // Note: is this really OK?
\r
196 String urlStr = url.toString();
\r
197 int idx = urlStr.indexOf(":");
\r
199 url = new URL("jar" + urlStr.substring(idx));
\r
203 JarURLConnection conn = (JarURLConnection)url.openConnection();
\r
204 jarFile = conn.getJarFile();
\r
206 catch (Exception e) {
\r
207 if (DEBUG) System.err.println("icurb jar error: " + e);
\r
208 throw new IllegalArgumentException("jar error: " + e.getMessage());
\r
212 public void guide(URLVisitor v, boolean recurse, boolean strip) {
\r
214 Enumeration<JarEntry> entries = jarFile.entries();
\r
216 while (entries.hasMoreElements()) {
\r
217 JarEntry entry = entries.nextElement();
\r
219 if (!entry.isDirectory()) { // skip just directory paths
\r
220 String name = entry.getName();
\r
222 if (name.startsWith(prefix)) {
\r
223 name = name.substring(prefix.length());
\r
225 int ix = name.lastIndexOf('/');
\r
233 name = name.substring(ix+1);
\r
242 catch (Exception e) {
\r
243 if (DEBUG) System.err.println("icurb jar error: " + e);
\r
248 public void guide(URLVisitor visitor, boolean recurse)
\r
250 guide(visitor, recurse, true);
\r
253 public abstract void guide(URLVisitor visitor, boolean recurse, boolean strip);
\r
255 public interface URLVisitor {
\r
256 void visit(String str);
\r