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.catalina.webresources;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.jar.JarEntry;
22 import java.util.jar.JarFile;
23 import java.util.jar.JarInputStream;
24
25 import org.apache.juli.logging.Log;
26 import org.apache.juli.logging.LogFactory;
27 import org.apache.tomcat.util.buf.UriUtil;
28
29 /**
30  * Represents a single resource (file or directory) that is located within a
31  * JAR that in turn is located in a WAR file.
32  */

33 public class JarWarResource extends AbstractArchiveResource {
34
35     private static final Log log = LogFactory.getLog(JarWarResource.class);
36
37     private final String archivePath;
38
39     public JarWarResource(AbstractArchiveResourceSet archiveResourceSet, String webAppPath,
40             String baseUrl, JarEntry jarEntry, String archivePath) {
41
42         super(archiveResourceSet, webAppPath,
43                 "jar:war:" + baseUrl + UriUtil.getWarSeparator() + archivePath + "!/",
44                 jarEntry, "war:" + baseUrl + UriUtil.getWarSeparator() + archivePath);
45         this.archivePath = archivePath;
46     }
47
48     @Override
49     protected JarInputStreamWrapper getJarInputStreamWrapper() {
50         JarFile warFile = null;
51         JarInputStream jarIs = null;
52         JarEntry entry = null;
53         try {
54             warFile = getArchiveResourceSet().openJarFile();
55             JarEntry jarFileInWar = warFile.getJarEntry(archivePath);
56             InputStream isInWar = warFile.getInputStream(jarFileInWar);
57
58             jarIs = new JarInputStream(isInWar);
59             entry = jarIs.getNextJarEntry();
60             while (entry != null &&
61                     !entry.getName().equals(getResource().getName())) {
62                 entry = jarIs.getNextJarEntry();
63             }
64
65             if (entry == null) {
66                 return null;
67             }
68
69             return new JarInputStreamWrapper(entry, jarIs);
70         } catch (IOException e) {
71             if (log.isDebugEnabled()) {
72                 log.debug(sm.getString("jarResource.getInputStreamFail",
73                         getResource().getName(), getBaseUrl()), e);
74             }
75             // Ensure jarIs is closed if there is an exception
76             entry = null;
77             return null;
78         } finally {
79             if (entry == null) {
80                 if (jarIs != null) {
81                     try {
82                         jarIs.close();
83                     } catch (IOException ioe) {
84                         // Ignore
85                     }
86                 }
87                 if (warFile != null) {
88                     getArchiveResourceSet().closeJarFile();
89                 }
90             }
91         }
92     }
93
94     @Override
95     protected Log getLog() {
96         return log;
97     }
98 }
99