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.Map.Entry;
24  import java.util.jar.Attributes;
25  import java.util.jar.JarEntry;
26  import java.util.jar.JarFile;
27  import java.util.jar.Manifest;
28  import java.util.zip.ZipEntry;
29  
30  import org.apache.commons.vfs2.FileSystemException;
31  import org.apache.commons.vfs2.provider.AbstractFileName;
32  import org.apache.commons.vfs2.provider.zip.ZipFileObject;
33  
34  /**
35   * A file in a Jar file system.
36   */
37  public class JarFileObject extends ZipFileObject {
38  
39      private final JarFileSystem fs;
40  
41      private Attributes attributes;
42  
43      protected JarFileObject(final AbstractFileName name, final ZipEntry entry, final JarFileSystem fs,
44              final boolean zipExists) throws FileSystemException {
45          super(name, entry, fs, zipExists);
46          if (entry != null) {
47  			// For Java 9 and up: Force the certificates to be read and cached now. This avoids an
48  			// IllegalStateException in java.util.jar.JarFile.isMultiRelease() when it tries
49  			// to read the certificates and the file is closed.
50          	((JarEntry) entry).getCertificates();
51          }
52          this.fs = fs;
53  
54          try {
55              getAttributes(); // early get the attributes as the zip file might be closed
56          } catch (final IOException e) {
57              throw new FileSystemException(e);
58          }
59      }
60  
61      /**
62       * Returns the Jar manifest.
63       */
64      Manifest getManifest() throws IOException {
65          if (fs.getZipFile() == null) {
66              return null;
67          }
68  
69          return ((JarFile) fs.getZipFile()).getManifest();
70      }
71  
72      /**
73       * Returns the attributes of this file.
74       */
75      Attributes getAttributes() throws IOException {
76          if (attributes == null) {
77              if (entry == null) {
78                  attributes = new Attributes(1);
79              } else {
80                  attributes = ((JarEntry) entry).getAttributes();
81                  if (attributes == null) {
82                      attributes = new Attributes(1);
83                  }
84              }
85          }
86  
87          return attributes;
88      }
89  
90      /**
91       * Returns the value of an attribute.
92       */
93      @Override
94      protected Map<String, Object> doGetAttributes() throws Exception {
95          final Map<String, Object> attrs = new HashMap<>();
96  
97          // Add the file system's attributes first
98          final JarFileSystem../../../../../org/apache/commons/vfs2/provider/jar/JarFileSystem.html#JarFileSystem">JarFileSystem fs = (JarFileSystem) getFileSystem();
99          addAll(fs.getAttributes(), attrs);
100 
101         // Add this file's attributes
102         addAll(getAttributes(), attrs);
103 
104         return attrs;
105     }
106 
107     /**
108      * Adds the source attributes to the destination map.
109      */
110     private void addAll(final Attributes src, final Map<String, Object> dest) {
111         for (final Entry<Object, Object> entry : src.entrySet()) {
112             // final String name = entry.getKey().toString().toLowerCase();
113             final String name = entry.getKey().toString();
114             dest.put(name, entry.getValue());
115         }
116     }
117 
118     /**
119      * Return the certificates of this JarEntry.
120      */
121     @Override
122     protected Certificate[] doGetCertificates() {
123         if (entry == null) {
124             return null;
125         }
126 
127         return ((JarEntry) entry).getCertificates();
128     }
129 }