001/*
002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     matic
018 */
019package org.nuxeo.osgi.util.jar;
020
021import java.io.IOException;
022import java.net.URL;
023import java.util.List;
024import java.util.Map;
025import java.util.jar.JarFile;
026
027/**
028 * @author matic
029 */
030public class URLClassLoaderCloser {
031
032    protected List<?> loaders;
033
034    protected final URLJarFileIntrospector introspector;
035
036    protected final Map<?, ?> index;
037
038    public URLClassLoaderCloser(URLJarFileIntrospector anIntrospector, Map<?, ?> anIndex, List<?> someLoaders) {
039        introspector = anIntrospector;
040        index = anIndex;
041        loaders = someLoaders;
042    }
043
044    protected static String serializeURL(URL location) {
045        StringBuilder localStringBuilder = new StringBuilder(128);
046        String str1 = location.getProtocol();
047        if (str1 != null) {
048            str1 = str1.toLowerCase();
049            localStringBuilder.append(str1);
050            localStringBuilder.append("://");
051        }
052        String str2 = location.getHost();
053        if (str2 != null) {
054            str2 = str2.toLowerCase();
055            localStringBuilder.append(str2);
056            int i = location.getPort();
057            if (i == -1) {
058                i = location.getDefaultPort();
059            }
060            if (i != -1) {
061                localStringBuilder.append(":").append(i);
062            }
063        }
064        String str3 = location.getFile();
065        if (str3 != null) {
066            localStringBuilder.append(str3);
067        }
068        return localStringBuilder.toString();
069    }
070
071    public boolean close(URL location) throws IOException {
072        if (index.isEmpty()) {
073            return false;
074        }
075        Object firstKey = index.keySet().iterator().next();
076        Object loader = firstKey instanceof URL ? index.remove(location) : index.remove(serializeURL(location));
077        if (loader == null) {
078            return false;
079        }
080        loaders.remove(loader);
081        JarFile jar = null;
082        try {
083            jar = (JarFile) introspector.jarField.get(loader);
084            introspector.jarField.set(loader, null);
085        } catch (IllegalArgumentException e) {
086            throw new RuntimeException("Cannot use reflection on url class path", e);
087        } catch (IllegalAccessException e) {
088            throw new RuntimeException("Cannot use reflection on url class path", e);
089        }
090        jar.close();
091        return true;
092    }
093
094}