JarFileFactory.java revision 49965c1dc9da104344f4893a05e45795a5740d20
1b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org/* 2b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. 3b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 5b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * This code is free software; you can redistribute it and/or modify it 6b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * under the terms of the GNU General Public License version 2 only, as 7b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * published by the Free Software Foundation. Oracle designates this 8b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * particular file as subject to the "Classpath" exception as provided 9b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * by Oracle in the LICENSE file that accompanied this code. 10b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 11b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * This code is distributed in the hope that it will be useful, but WITHOUT 12b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * version 2 for more details (a copy is included in the LICENSE file that 15b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * accompanied this code). 16b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 17b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * You should have received a copy of the GNU General Public License version 18b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 2 along with this work; if not, write to the Free Software Foundation, 19b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 21b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * or visit www.oracle.com if you need additional information or have any 23b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * questions. 24b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org */ 25b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 26b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgpackage sun.net.www.protocol.jar; 27b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 28b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgimport java.io.IOException; 29b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgimport java.io.FileNotFoundException; 30b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgimport java.net.URL; 31c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgimport java.net.URLConnection; 323c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgimport java.util.HashMap; 33b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgimport java.util.jar.JarFile; 34b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgimport java.security.Permission; 35b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgimport sun.net.util.URLUtil; 36b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 37df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org/* A factory for cached JAR file. This class is used to both retrieve 38a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org * and cache Jar files. 39b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 4081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström * @author Benjamin Renaud 41b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * @since JDK1.2 42b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org */ 43a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.orgclass JarFileFactory implements URLJarFile.URLJarFileCloseController { 44a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org 45a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org /* the url to file cache */ 46b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org private static final HashMap<String, JarFile> fileCache = new HashMap<>(); 4781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 4881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström /* the file to url cache */ 4950fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org private static final HashMap<JarFile, URL> urlCache = new HashMap<>(); 50776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 51ab990ae43a2b84b103cb3c50bc38502375c13e68pbos@webrtc.org private static final JarFileFactory instance = new JarFileFactory(); 52b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 53b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org private JarFileFactory() { } 54b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 55d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg public static JarFileFactory getInstance() { 56b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return instance; 57b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström URLConnection getConnection(JarFile jarFile) throws IOException { 6081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström URL u; 6181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström synchronized (instance) { 6281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström u = urlCache.get(jarFile); 6381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 6481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (u != null) 6581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return u.openConnection(); 6681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 6781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return null; 6881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 6981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström public JarFile get(URL url) throws IOException { 7181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return get(url, true); 7281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 7381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström JarFile get(URL url, boolean useCaches) throws IOException { 7581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström JarFile result; 7781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström JarFile local_result; 7881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (useCaches) { 8081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström synchronized (instance) { 8181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström result = getCachedJarFile(url); 8281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 8381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (result == null) { 8481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström local_result = URLJarFile.getJarFile(url, this); 8581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström synchronized (instance) { 8681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström result = getCachedJarFile(url); 8781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (result == null) { 8881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström fileCache.put(URLUtil.urlNoFragString(url), local_result); 8981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström urlCache.put(local_result, url); 9081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström result = local_result; 9181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } else { 9281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (local_result != null) { 9381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström local_result.close(); 9481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 9581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 9681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 9781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 9881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } else { 9981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström result = URLJarFile.getJarFile(url, this); 10081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (result == null) 10281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström throw new FileNotFoundException(url.toString()); 10381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 10481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return result; 10581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 10781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström /** 108d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg * Callback method of the URLJarFileCloseController to 10981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström * indicate that the JarFile is close. This way we can 11081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström * remove the JarFile from the cache 11181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström */ 11281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström public void close(JarFile jarFile) { 11381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström synchronized (instance) { 11481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström URL urlRemoved = urlCache.remove(jarFile); 11581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (urlRemoved != null) 11681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); 11781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 11881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 11981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 12081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström private JarFile getCachedJarFile(URL url) { 12181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström assert Thread.holdsLock(instance); 12281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); 12381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 12481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström /* if the JAR file is cached, the permission will always be there */ 12581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (result != null) { 12681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström Permission perm = getPermission(result); 12781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (perm != null) { 12881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström SecurityManager sm = System.getSecurityManager(); 12981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (sm != null) { 13081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström try { 13181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström sm.checkPermission(perm); 13281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } catch (SecurityException se) { 13381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // fallback to checkRead/checkConnect for pre 1.2 13481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // security managers 13581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if ((perm instanceof java.io.FilePermission) && 13681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström perm.getActions().indexOf("read") != -1) { 13781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström sm.checkRead(perm.getName()); 13881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } else if ((perm instanceof 13981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström java.net.SocketPermission) && 14081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström perm.getActions().indexOf("connect") != -1) { 14181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström sm.checkConnect(url.getHost(), url.getPort()); 14281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } else { 14381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström throw se; 14481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 14581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 14681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 14781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 14881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 14981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return result; 15081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 15181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 15281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström private Permission getPermission(JarFile jarFile) { 15381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström try { 15481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström URLConnection uc = getConnection(jarFile); 15581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (uc != null) 15681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return uc.getPermission(); 15781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } catch (IOException ioe) { 15881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // gulp 15981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 16081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 16181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return null; 16281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 16381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 16481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström