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.File;
022import java.io.IOException;
023import java.net.URL;
024import java.net.URLClassLoader;
025import java.util.jar.JarFile;
026
027import org.apache.commons.logging.LogFactory;
028import org.nuxeo.runtime.api.Framework;
029import org.nuxeo.runtime.api.SharedResourceLoader;
030
031/**
032 * Given a location, close the corresponding jar files opened by URL class loaders and in jar file cache
033 *
034 * @since 5.6
035 * @author matic
036 */
037public class URLJarFileCloser implements JarFileCloser {
038
039    protected final URLClassLoaderCloser applicationCloser;
040
041    protected final URLJarFileIntrospector introspector;
042
043    public URLJarFileCloser(URLJarFileIntrospector anIntrospector, ClassLoader appCL)
044            throws URLJarFileIntrospectionError {
045        introspector = anIntrospector;
046        applicationCloser = appCL instanceof URLClassLoader ? introspector.newURLClassLoaderCloser((URLClassLoader) appCL)
047                : null;
048    }
049
050    @Override
051    public void close(JarFile file) throws IOException {
052        file.close();
053        URL location = new File(file.getName()).toURI().toURL();
054        boolean closed = false;
055        try {
056            final SharedResourceLoader loader = Framework.getResourceLoader();
057            if (loader != null) {
058                closed = introspector.newURLClassLoaderCloser(loader).close(location);
059            }
060        } catch (URLJarFileIntrospectionError cause) {
061            LogFactory.getLog(URLJarFileCloser.class).error("Cannot introspect shared resource loader", cause);
062
063        }
064        if (closed == false) {
065            if (applicationCloser != null) {
066                closed = applicationCloser.close(location);
067            }
068        }
069        introspector.close(location);
070    }
071}