41 * @since JDK1.2 |
41 * @since JDK1.2 |
42 */ |
42 */ |
43 class JarFileFactory implements URLJarFile.URLJarFileCloseController { |
43 class JarFileFactory implements URLJarFile.URLJarFileCloseController { |
44 |
44 |
45 /* the url to file cache */ |
45 /* the url to file cache */ |
46 private static HashMap<String, JarFile> fileCache = new HashMap<String, JarFile>(); |
46 private static final HashMap<String, JarFile> fileCache = new HashMap<>(); |
47 |
47 |
48 /* the file to url cache */ |
48 /* the file to url cache */ |
49 private static HashMap<JarFile, URL> urlCache = new HashMap<JarFile, URL>(); |
49 private static final HashMap<JarFile, URL> urlCache = new HashMap<>(); |
|
50 |
|
51 private static final JarFileFactory instance = new JarFileFactory(); |
|
52 |
|
53 private JarFileFactory() { } |
|
54 |
|
55 public static JarFileFactory getInstance() { |
|
56 return instance; |
|
57 } |
50 |
58 |
51 URLConnection getConnection(JarFile jarFile) throws IOException { |
59 URLConnection getConnection(JarFile jarFile) throws IOException { |
52 URL u = urlCache.get(jarFile); |
60 URL u; |
|
61 synchronized (instance) { |
|
62 u = urlCache.get(jarFile); |
|
63 } |
53 if (u != null) |
64 if (u != null) |
54 return u.openConnection(); |
65 return u.openConnection(); |
55 |
66 |
56 return null; |
67 return null; |
57 } |
68 } |
70 |
81 |
71 url = new URL("file", "", "//" + host + url.getPath()); |
82 url = new URL("file", "", "//" + host + url.getPath()); |
72 } |
83 } |
73 } |
84 } |
74 |
85 |
75 JarFile result = null; |
86 JarFile result; |
76 JarFile local_result = null; |
87 JarFile local_result; |
77 |
88 |
78 if (useCaches) { |
89 if (useCaches) { |
79 synchronized (this) { |
90 synchronized (instance) { |
80 result = getCachedJarFile(url); |
91 result = getCachedJarFile(url); |
81 } |
92 } |
82 if (result == null) { |
93 if (result == null) { |
83 local_result = URLJarFile.getJarFile(url, this); |
94 local_result = URLJarFile.getJarFile(url, this); |
84 synchronized (this) { |
95 synchronized (instance) { |
85 result = getCachedJarFile(url); |
96 result = getCachedJarFile(url); |
86 if (result == null) { |
97 if (result == null) { |
87 fileCache.put(URLUtil.urlNoFragString(url), local_result); |
98 fileCache.put(URLUtil.urlNoFragString(url), local_result); |
88 urlCache.put(local_result, url); |
99 urlCache.put(local_result, url); |
89 result = local_result; |
100 result = local_result; |
107 * Callback method of the URLJarFileCloseController to |
118 * Callback method of the URLJarFileCloseController to |
108 * indicate that the JarFile is close. This way we can |
119 * indicate that the JarFile is close. This way we can |
109 * remove the JarFile from the cache |
120 * remove the JarFile from the cache |
110 */ |
121 */ |
111 public void close(JarFile jarFile) { |
122 public void close(JarFile jarFile) { |
112 URL urlRemoved = urlCache.remove(jarFile); |
123 synchronized (instance) { |
113 if( urlRemoved != null) { |
124 URL urlRemoved = urlCache.remove(jarFile); |
|
125 if (urlRemoved != null) |
114 fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); |
126 fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); |
115 } |
127 } |
116 } |
128 } |
117 |
129 |
118 private JarFile getCachedJarFile(URL url) { |
130 private JarFile getCachedJarFile(URL url) { |
|
131 assert Thread.holdsLock(instance); |
119 JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); |
132 JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); |
120 |
133 |
121 /* if the JAR file is cached, the permission will always be there */ |
134 /* if the JAR file is cached, the permission will always be there */ |
122 if (result != null) { |
135 if (result != null) { |
123 Permission perm = getPermission(result); |
136 Permission perm = getPermission(result); |