001/*
002 * Copyright (C) 2014 Jörg Prante
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 */
016package org.xbib.elasticsearch.plugin.jdbc.classloader.jar;
017
018import java.io.File;
019import java.io.IOException;
020import java.io.InputStream;
021import java.net.JarURLConnection;
022import java.net.MalformedURLException;
023import java.net.URL;
024import java.net.URLConnection;
025import java.net.URLStreamHandler;
026import java.security.Permission;
027import java.security.cert.Certificate;
028import java.util.jar.Attributes;
029import java.util.jar.JarEntry;
030import java.util.jar.JarFile;
031import java.util.jar.Manifest;
032
033public class JarFileUrlConnection extends JarURLConnection {
034
035    public static final URL DUMMY_JAR_URL;
036
037    static {
038        try {
039            DUMMY_JAR_URL = new URL("jar", "", -1, "file:dummy!/", new URLStreamHandler() {
040                protected URLConnection openConnection(URL u) {
041                    throw new UnsupportedOperationException();
042                }
043            });
044        } catch (Exception e) {
045            throw new ExceptionInInitializerError(e);
046        }
047    }
048
049    private final URL url;
050
051    private final JarFile jarFile;
052
053    private final JarEntry jarEntry;
054
055    private final URL jarFileUrl;
056
057    public JarFileUrlConnection(URL url, JarFile jarFile, JarEntry jarEntry) throws MalformedURLException {
058        super(DUMMY_JAR_URL);
059        if (url == null) {
060            throw new NullPointerException("url is null");
061        }
062        if (jarFile == null) {
063            throw new NullPointerException("jarFile is null");
064        }
065        if (jarEntry == null) {
066            throw new NullPointerException("jarEntry is null");
067        }
068        this.url = url;
069        this.jarFile = jarFile;
070        this.jarEntry = jarEntry;
071        jarFileUrl = new File(jarFile.getName()).toURI().toURL();
072    }
073
074    @Override
075    public JarFile getJarFile() throws IOException {
076        if (getUseCaches()) {
077            return jarFile;
078        } else {
079            return new JarFile(jarFile.getName());
080        }
081    }
082
083    @Override
084    public synchronized void connect() {
085    }
086
087    @Override
088    public URL getJarFileURL() {
089        return jarFileUrl;
090    }
091
092    @Override
093    public String getEntryName() {
094        return getJarEntry().getName();
095    }
096
097    @Override
098    public Manifest getManifest() throws IOException {
099        return jarFile.getManifest();
100    }
101
102    @Override
103    public JarEntry getJarEntry() {
104        if (getUseCaches()) {
105            return jarEntry;
106        } else {
107            //return (JarEntry) jarEntry.clone();
108            // There is a clone method, but the below way might be safer.
109            return jarFile.getJarEntry(jarEntry.getName());
110        }
111    }
112
113    @Override
114    public Attributes getAttributes() throws IOException {
115        return getJarEntry().getAttributes();
116    }
117
118    @Override
119    public Attributes getMainAttributes() throws IOException {
120        return getManifest().getMainAttributes();
121    }
122
123    @Override
124    public Certificate[] getCertificates() throws IOException {
125        return getJarEntry().getCertificates();
126    }
127
128    @Override
129    public URL getURL() {
130        return url;
131    }
132
133    @Override
134    public int getContentLength() {
135        long size = getJarEntry().getSize();
136        if (size > Integer.MAX_VALUE) {
137            return -1;
138        }
139        return (int) size;
140    }
141
142    @Override
143    public long getLastModified() {
144        return getJarEntry().getTime();
145    }
146
147    @Override
148    public synchronized InputStream getInputStream() throws IOException {
149        return jarFile.getInputStream(jarEntry);
150    }
151
152    @Override
153    public Permission getPermission() throws IOException {
154        URL jarFileUrl = new File(jarFile.getName()).toURI().toURL();
155        return jarFileUrl.openConnection().getPermission();
156    }
157
158    @Override
159    public String toString() {
160        return JarFileUrlConnection.class.getName() + ":" + url;
161    }
162}