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