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{
042    private Attributes attributes;
043
044    protected JarFileSystem(final AbstractFileName rootName,
045                            final FileObject file,
046                            final FileSystemOptions fileSystemOptions) throws FileSystemException
047    {
048        super(rootName, file, fileSystemOptions);
049    }
050
051//    @Override
052//    protected FileObject createFile(AbstractFileName name) throws FileSystemException
053//    {
054//        return new JarFileObject(name, null, this, false);
055//    }
056
057    @Override
058    protected ZipFile createZipFile(final File file) throws FileSystemException
059    {
060        try
061        {
062            return new JarFile(file);
063        }
064        catch (final IOException ioe)
065        {
066            throw new FileSystemException("vfs.provider.jar/open-jar-file.error", file, ioe);
067        }
068    }
069
070    @Override
071    protected ZipFileObject createZipFileObject(final AbstractFileName name,
072                                                final ZipEntry entry) throws FileSystemException
073    {
074        return new JarFileObject(name, entry, this, true);
075    }
076
077    /**
078     * Returns the capabilities of this file system.
079     */
080    @Override
081    protected void addCapabilities(final Collection<Capability> caps)
082    {
083        // super.addCapabilities(caps);
084        caps.addAll(JarFileProvider.capabilities);
085    }
086
087    Attributes getAttributes() throws IOException
088    {
089        if (attributes == null)
090        {
091            final Manifest man = ((JarFile) getZipFile()).getManifest();
092            if (man == null)
093            {
094                attributes = new Attributes(1);
095            }
096            else
097            {
098                attributes = man.getMainAttributes();
099                if (attributes == null)
100                {
101                    attributes = new Attributes(1);
102                }
103            }
104        }
105
106        return attributes;
107    }
108
109    Object getAttribute(final Name attrName)
110        throws FileSystemException
111    {
112        try
113        {
114            final Attributes attr = getAttributes();
115            final String value = attr.getValue(attrName);
116            return value;
117        }
118        catch (final IOException ioe)
119        {
120            throw new FileSystemException(attrName.toString(), ioe);
121        }
122    }
123
124    Name lookupName(final String attrName)
125    {
126        if (Name.CLASS_PATH.toString().equals(attrName))
127        {
128            return Name.CLASS_PATH;
129        }
130        else if (Name.CONTENT_TYPE.toString().equals(attrName))
131        {
132            return Name.CONTENT_TYPE;
133        }
134        else if (Name.EXTENSION_INSTALLATION.toString().equals(attrName))
135        {
136            return Name.EXTENSION_INSTALLATION;
137        }
138        else if (Name.EXTENSION_LIST.toString().equals(attrName))
139        {
140            return Name.EXTENSION_LIST;
141        }
142        else if (Name.EXTENSION_NAME.toString().equals(attrName))
143        {
144            return Name.EXTENSION_NAME;
145        }
146        else if (Name.IMPLEMENTATION_TITLE.toString().equals(attrName))
147        {
148            return Name.IMPLEMENTATION_TITLE;
149        }
150        else if (Name.IMPLEMENTATION_URL.toString().equals(attrName))
151        {
152            return Name.IMPLEMENTATION_URL;
153        }
154        else if (Name.IMPLEMENTATION_VENDOR.toString().equals(attrName))
155        {
156            return Name.IMPLEMENTATION_VENDOR;
157        }
158        else if (Name.IMPLEMENTATION_VENDOR_ID.toString().equals(attrName))
159        {
160            return Name.IMPLEMENTATION_VENDOR_ID;
161        }
162        else if (Name.IMPLEMENTATION_VERSION.toString().equals(attrName))
163        {
164            return Name.IMPLEMENTATION_VENDOR;
165        }
166        else if (Name.MAIN_CLASS.toString().equals(attrName))
167        {
168            return Name.MAIN_CLASS;
169        }
170        else if (Name.MANIFEST_VERSION.toString().equals(attrName))
171        {
172            return Name.MANIFEST_VERSION;
173        }
174        else if (Name.SEALED.toString().equals(attrName))
175        {
176            return Name.SEALED;
177        }
178        else if (Name.SIGNATURE_VERSION.toString().equals(attrName))
179        {
180            return Name.SIGNATURE_VERSION;
181        }
182        else if (Name.SPECIFICATION_TITLE.toString().equals(attrName))
183        {
184            return Name.SPECIFICATION_TITLE;
185        }
186        else if (Name.SPECIFICATION_VENDOR.toString().equals(attrName))
187        {
188            return Name.SPECIFICATION_VENDOR;
189        }
190        else if (Name.SPECIFICATION_VERSION.toString().equals(attrName))
191        {
192            return Name.SPECIFICATION_VERSION;
193        }
194        else
195        {
196            return new Name(attrName);
197        }
198    }
199
200    /**
201     * Retrives the attribute with the specified name. The default
202     * implementation simply throws an exception.
203     * @param attrName The attiribute's name.
204     * @return The value of the attribute.
205     * @throws FileSystemException if an error occurs.
206     */
207    @Override
208    public Object getAttribute(final String attrName) throws FileSystemException
209    {
210        final Name name = lookupName(attrName);
211        return getAttribute(name);
212    }
213
214
215    @Override
216    protected ZipFile getZipFile() throws FileSystemException
217    {
218        return super.getZipFile();
219    }
220
221}