001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.vfs2.provider.jar;
018
019import java.io.File;
020import java.io.IOException;
021import java.util.Collection;
022import java.util.jar.Attributes;
023import java.util.jar.Attributes.Name;
024import java.util.jar.JarFile;
025import java.util.jar.Manifest;
026import java.util.zip.ZipEntry;
027import java.util.zip.ZipFile;
028
029import org.apache.commons.vfs2.Capability;
030import org.apache.commons.vfs2.FileObject;
031import org.apache.commons.vfs2.FileSystemException;
032import org.apache.commons.vfs2.FileSystemOptions;
033import org.apache.commons.vfs2.provider.AbstractFileName;
034import org.apache.commons.vfs2.provider.zip.ZipFileObject;
035import org.apache.commons.vfs2.provider.zip.ZipFileSystem;
036
037/**
038 * A read-only file system for Jar files.
039 */
040public class JarFileSystem extends ZipFileSystem {
041    private Attributes attributes;
042
043    protected JarFileSystem(final AbstractFileName rootName, final FileObject file,
044            final FileSystemOptions fileSystemOptions) throws FileSystemException {
045        super(rootName, file, fileSystemOptions);
046    }
047
048    // @Override
049    // protected FileObject createFile(AbstractFileName name) throws FileSystemException
050    // {
051    // return new JarFileObject(name, null, this, false);
052    // }
053
054    @Override
055    protected ZipFile createZipFile(final File file) throws FileSystemException {
056        try {
057            return new JarFile(file);
058        } catch (final IOException ioe) {
059            throw new FileSystemException("vfs.provider.jar/open-jar-file.error", file, ioe);
060        }
061    }
062
063    @Override
064    protected ZipFileObject createZipFileObject(final AbstractFileName name, final ZipEntry entry)
065            throws FileSystemException {
066        return new JarFileObject(name, entry, this, true);
067    }
068
069    /**
070     * Returns the capabilities of this file system.
071     */
072    @Override
073    protected void addCapabilities(final Collection<Capability> caps) {
074        // super.addCapabilities(caps);
075        caps.addAll(JarFileProvider.capabilities);
076    }
077
078    Attributes getAttributes() throws IOException {
079        if (attributes == null) {
080            final Manifest man = ((JarFile) getZipFile()).getManifest();
081            if (man == null) {
082                attributes = new Attributes(1);
083            } else {
084                attributes = man.getMainAttributes();
085                if (attributes == null) {
086                    attributes = new Attributes(1);
087                }
088            }
089        }
090
091        return attributes;
092    }
093
094    Object getAttribute(final Name attrName) throws FileSystemException {
095        try {
096            final Attributes attr = getAttributes();
097            final String value = attr.getValue(attrName);
098            return value;
099        } catch (final IOException ioe) {
100            throw new FileSystemException(attrName.toString(), ioe);
101        }
102    }
103
104    Name lookupName(final String attrName) {
105        if (Name.CLASS_PATH.toString().equals(attrName)) {
106            return Name.CLASS_PATH;
107        } else if (Name.CONTENT_TYPE.toString().equals(attrName)) {
108            return Name.CONTENT_TYPE;
109        } else if (Name.EXTENSION_INSTALLATION.toString().equals(attrName)) {
110            return Name.EXTENSION_INSTALLATION;
111        } else if (Name.EXTENSION_LIST.toString().equals(attrName)) {
112            return Name.EXTENSION_LIST;
113        } else if (Name.EXTENSION_NAME.toString().equals(attrName)) {
114            return Name.EXTENSION_NAME;
115        } else if (Name.IMPLEMENTATION_TITLE.toString().equals(attrName)) {
116            return Name.IMPLEMENTATION_TITLE;
117        } else if (Name.IMPLEMENTATION_URL.toString().equals(attrName)) {
118            return Name.IMPLEMENTATION_URL;
119        } else if (Name.IMPLEMENTATION_VENDOR.toString().equals(attrName)) {
120            return Name.IMPLEMENTATION_VENDOR;
121        } else if (Name.IMPLEMENTATION_VENDOR_ID.toString().equals(attrName)) {
122            return Name.IMPLEMENTATION_VENDOR_ID;
123        } else if (Name.IMPLEMENTATION_VERSION.toString().equals(attrName)) {
124            return Name.IMPLEMENTATION_VENDOR;
125        } else if (Name.MAIN_CLASS.toString().equals(attrName)) {
126            return Name.MAIN_CLASS;
127        } else if (Name.MANIFEST_VERSION.toString().equals(attrName)) {
128            return Name.MANIFEST_VERSION;
129        } else if (Name.SEALED.toString().equals(attrName)) {
130            return Name.SEALED;
131        } else if (Name.SIGNATURE_VERSION.toString().equals(attrName)) {
132            return Name.SIGNATURE_VERSION;
133        } else if (Name.SPECIFICATION_TITLE.toString().equals(attrName)) {
134            return Name.SPECIFICATION_TITLE;
135        } else if (Name.SPECIFICATION_VENDOR.toString().equals(attrName)) {
136            return Name.SPECIFICATION_VENDOR;
137        } else if (Name.SPECIFICATION_VERSION.toString().equals(attrName)) {
138            return Name.SPECIFICATION_VERSION;
139        } else {
140            return new Name(attrName);
141        }
142    }
143
144    /**
145     * Retrives the attribute with the specified name. The default implementation simply throws an exception.
146     *
147     * @param attrName The attiribute's name.
148     * @return The value of the attribute.
149     * @throws FileSystemException if an error occurs.
150     */
151    @Override
152    public Object getAttribute(final String attrName) throws FileSystemException {
153        final Name name = lookupName(attrName);
154        return getAttribute(name);
155    }
156
157    @Override
158    protected ZipFile getZipFile() throws FileSystemException {
159        // make accessible
160        return super.getZipFile();
161    }
162
163}