View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2.provider.jar;
18  
19  import java.io.IOException;
20  import java.security.cert.Certificate;
21  import java.util.HashMap;
22  import java.util.Map;
23  import java.util.jar.Attributes;
24  import java.util.jar.JarEntry;
25  import java.util.jar.JarFile;
26  import java.util.jar.Manifest;
27  import java.util.zip.ZipEntry;
28  
29  import org.apache.commons.vfs2.FileSystemException;
30  import org.apache.commons.vfs2.provider.AbstractFileName;
31  import org.apache.commons.vfs2.provider.zip.ZipFileObject;
32  
33  /**
34   * A file in a Jar file system.
35   */
36  public class JarFileObject extends ZipFileObject {
37  
38      private final JarFileSystem fs;
39  
40      private Attributes attributes;
41  
42      /**
43       * Constructs a new instance.
44       *
45       * @param fileName the file name.
46       * @param entry the zip entry.
47       * @param fileSystem the file system.
48       * @param zipExists Whether the zip file exists.
49       * @throws FileSystemException if a file system error occurs.
50       */
51      protected JarFileObject(final AbstractFileName fileName, final ZipEntry entry, final JarFileSystem fileSystem,
52          final boolean zipExists) throws FileSystemException {
53          super(fileName, entry, fileSystem, zipExists);
54          if (entry != null) {
55              // For Java 9 and up: Force the certificates to be read and cached now. This avoids an
56              // IllegalStateException in java.util.jar.JarFile.isMultiRelease() when it tries
57              // to read the certificates and the file is closed.
58              ((JarEntry) entry).getCertificates();
59          }
60          this.fs = fileSystem;
61  
62          try {
63              getAttributes(); // early get the attributes as the zip file might be closed
64          } catch (final IOException e) {
65              throw new FileSystemException(e);
66          }
67      }
68  
69      /**
70       * Adds the source attributes to the destination map.
71       */
72      private void addAll(final Attributes src, final Map<String, Object> dest) {
73          src.forEach((k, v) -> dest.put(String.valueOf(k), v));
74      }
75  
76      /**
77       * Returns the value of an attribute.
78       */
79      @Override
80      protected Map<String, Object> doGetAttributes() throws Exception {
81          final Map<String, Object> attrs = new HashMap<>();
82  
83          // Add the file system's attributes first
84          final JarFileSystem fs = (JarFileSystem) getFileSystem();
85          addAll(fs.getAttributes(), attrs);
86  
87          // Add this file's attributes
88          addAll(getAttributes(), attrs);
89  
90          return attrs;
91      }
92  
93      /**
94       * Gets the certificates of this JarEntry.
95       */
96      @Override
97      protected Certificate[] doGetCertificates() {
98          if (entry == null) {
99              return null;
100         }
101 
102         return ((JarEntry) entry).getCertificates();
103     }
104 
105     /**
106      * Returns the attributes of this file.
107      */
108     Attributes getAttributes() throws IOException {
109         if (attributes == null) {
110             if (entry == null) {
111                 attributes = new Attributes(1);
112             } else {
113                 attributes = ((JarEntry) entry).getAttributes();
114                 if (attributes == null) {
115                     attributes = new Attributes(1);
116                 }
117             }
118         }
119 
120         return attributes;
121     }
122 
123     /**
124      * Returns the Jar manifest.
125      */
126     Manifest getManifest() throws IOException {
127         if (fs.getZipFile() == null) {
128             return null;
129         }
130 
131         return ((JarFile) fs.getZipFile()).getManifest();
132     }
133 }