001/* 002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * matic 016 */ 017package org.nuxeo.osgi.util.jar; 018 019import java.io.IOException; 020import java.net.URL; 021import java.util.List; 022import java.util.Map; 023import java.util.jar.JarFile; 024 025/** 026 * @author matic 027 */ 028public class URLClassLoaderCloser { 029 030 protected List<?> loaders; 031 032 protected final URLJarFileIntrospector introspector; 033 034 protected final Map<?, ?> index; 035 036 public URLClassLoaderCloser(URLJarFileIntrospector anIntrospector, Map<?, ?> anIndex, List<?> someLoaders) { 037 introspector = anIntrospector; 038 index = anIndex; 039 loaders = someLoaders; 040 } 041 042 protected static String serializeURL(URL location) { 043 StringBuilder localStringBuilder = new StringBuilder(128); 044 String str1 = location.getProtocol(); 045 if (str1 != null) { 046 str1 = str1.toLowerCase(); 047 localStringBuilder.append(str1); 048 localStringBuilder.append("://"); 049 } 050 String str2 = location.getHost(); 051 if (str2 != null) { 052 str2 = str2.toLowerCase(); 053 localStringBuilder.append(str2); 054 int i = location.getPort(); 055 if (i == -1) { 056 i = location.getDefaultPort(); 057 } 058 if (i != -1) { 059 localStringBuilder.append(":").append(i); 060 } 061 } 062 String str3 = location.getFile(); 063 if (str3 != null) { 064 localStringBuilder.append(str3); 065 } 066 return localStringBuilder.toString(); 067 } 068 069 public boolean close(URL location) throws IOException { 070 if (index.isEmpty()) { 071 return false; 072 } 073 Object firstKey = index.keySet().iterator().next(); 074 Object loader = firstKey instanceof URL ? index.remove(location) : index.remove(serializeURL(location)); 075 if (loader == null) { 076 return false; 077 } 078 loaders.remove(loader); 079 JarFile jar = null; 080 try { 081 jar = (JarFile) introspector.jarField.get(loader); 082 introspector.jarField.set(loader, null); 083 } catch (IllegalArgumentException e) { 084 throw new RuntimeException("Cannot use reflection on url class path", e); 085 } catch (IllegalAccessException e) { 086 throw new RuntimeException("Cannot use reflection on url class path", e); 087 } 088 jar.close(); 089 return true; 090 } 091 092}