1
17 package org.apache.catalina.webresources;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.nio.file.Files;
24 import java.nio.file.StandardCopyOption;
25 import java.util.Set;
26 import java.util.jar.Manifest;
27
28 import org.apache.catalina.LifecycleException;
29 import org.apache.catalina.WebResource;
30 import org.apache.catalina.WebResourceRoot;
31 import org.apache.catalina.WebResourceRoot.ResourceSetType;
32 import org.apache.catalina.util.ResourceSet;
33 import org.apache.juli.logging.Log;
34 import org.apache.juli.logging.LogFactory;
35
36
39 public class DirResourceSet extends AbstractFileResourceSet {
40
41 private static final Log log = LogFactory.getLog(DirResourceSet.class);
42
43
46 public DirResourceSet() {
47 super("/");
48 }
49
50
68 public DirResourceSet(WebResourceRoot root, String webAppMount, String base,
69 String internalPath) {
70 super(internalPath);
71 setRoot(root);
72 setWebAppMount(webAppMount);
73 setBase(base);
74
75 if (root.getContext().getAddWebinfClassesResources()) {
76 File f = new File(base, internalPath);
77 f = new File(f, "/WEB-INF/classes/META-INF/resources");
78
79 if (f.isDirectory()) {
80 root.createWebResourceSet(ResourceSetType.RESOURCE_JAR, "/",
81 f.getAbsolutePath(), null, "/");
82 }
83 }
84
85 if (getRoot().getState().isAvailable()) {
86 try {
87 start();
88 } catch (LifecycleException e) {
89 throw new IllegalStateException(e);
90 }
91 }
92 }
93
94
95 @Override
96 public WebResource getResource(String path) {
97 checkPath(path);
98 String webAppMount = getWebAppMount();
99 WebResourceRoot root = getRoot();
100 if (path.startsWith(webAppMount)) {
101 File f = file(path.substring(webAppMount.length()), false);
102 if (f == null) {
103 return new EmptyResource(root, path);
104 }
105 if (!f.exists()) {
106 return new EmptyResource(root, path, f);
107 }
108 if (f.isDirectory() && path.charAt(path.length() - 1) != '/') {
109 path = path + '/';
110 }
111 return new FileResource(root, path, f, isReadOnly(), getManifest());
112 } else {
113 return new EmptyResource(root, path);
114 }
115 }
116
117 @Override
118 public String[] list(String path) {
119 checkPath(path);
120 String webAppMount = getWebAppMount();
121 if (path.startsWith(webAppMount)) {
122 File f = file(path.substring(webAppMount.length()), true);
123 if (f == null) {
124 return EMPTY_STRING_ARRAY;
125 }
126 String[] result = f.list();
127 if (result == null) {
128 return EMPTY_STRING_ARRAY;
129 } else {
130 return result;
131 }
132 } else {
133 if (!path.endsWith("/")) {
134 path = path + "/";
135 }
136 if (webAppMount.startsWith(path)) {
137 int i = webAppMount.indexOf('/', path.length());
138 if (i == -1) {
139 return new String[] {webAppMount.substring(path.length())};
140 } else {
141 return new String[] {
142 webAppMount.substring(path.length(), i)};
143 }
144 }
145 return EMPTY_STRING_ARRAY;
146 }
147 }
148
149 @Override
150 public Set<String> listWebAppPaths(String path) {
151 checkPath(path);
152 String webAppMount = getWebAppMount();
153 ResourceSet<String> result = new ResourceSet<>();
154 if (path.startsWith(webAppMount)) {
155 File f = file(path.substring(webAppMount.length()), true);
156 if (f != null) {
157 File[] list = f.listFiles();
158 if (list != null) {
159 for (File entry : list) {
160 StringBuilder sb = new StringBuilder(path);
161 if (path.charAt(path.length() - 1) != '/') {
162 sb.append('/');
163 }
164 sb.append(entry.getName());
165 if (entry.isDirectory()) {
166 sb.append('/');
167 }
168 result.add(sb.toString());
169 }
170 }
171 }
172 } else {
173 if (!path.endsWith("/")) {
174 path = path + "/";
175 }
176 if (webAppMount.startsWith(path)) {
177 int i = webAppMount.indexOf('/', path.length());
178 if (i == -1) {
179 result.add(webAppMount + "/");
180 } else {
181 result.add(webAppMount.substring(0, i + 1));
182 }
183 }
184 }
185 result.setLocked(true);
186 return result;
187 }
188
189 @Override
190 public boolean mkdir(String path) {
191 checkPath(path);
192 if (isReadOnly()) {
193 return false;
194 }
195 String webAppMount = getWebAppMount();
196 if (path.startsWith(webAppMount)) {
197 File f = file(path.substring(webAppMount.length()), false);
198 if (f == null) {
199 return false;
200 }
201 return f.mkdir();
202 } else {
203 return false;
204 }
205 }
206
207 @Override
208 public boolean write(String path, InputStream is, boolean overwrite) {
209 checkPath(path);
210
211 if (is == null) {
212 throw new NullPointerException(
213 sm.getString("dirResourceSet.writeNpe"));
214 }
215
216 if (isReadOnly()) {
217 return false;
218 }
219
220
221
222 if (path.endsWith("/")) {
223 return false;
224 }
225
226 File dest = null;
227 String webAppMount = getWebAppMount();
228 if (path.startsWith(webAppMount)) {
229 dest = file(path.substring(webAppMount.length()), false);
230 if (dest == null) {
231 return false;
232 }
233 } else {
234 return false;
235 }
236
237 if (dest.exists() && !overwrite) {
238 return false;
239 }
240
241 try {
242 if (overwrite) {
243 Files.copy(is, dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
244 } else {
245 Files.copy(is, dest.toPath());
246 }
247 } catch (IOException ioe) {
248 return false;
249 }
250
251 return true;
252 }
253
254 @Override
255 protected void checkType(File file) {
256 if (file.isDirectory() == false) {
257 throw new IllegalArgumentException(sm.getString("dirResourceSet.notDirectory",
258 getBase(), File.separator, getInternalPath()));
259 }
260 }
261
262
263 @Override
264 protected void initInternal() throws LifecycleException {
265 super.initInternal();
266
267 if (getWebAppMount().equals("")) {
268
269 File mf = file("META-INF/MANIFEST.MF", true);
270 if (mf != null && mf.isFile()) {
271 try (FileInputStream fis = new FileInputStream(mf)) {
272 setManifest(new Manifest(fis));
273 } catch (IOException e) {
274 log.warn(sm.getString("dirResourceSet.manifestFail", mf.getAbsolutePath()), e);
275 }
276 }
277 }
278 }
279 }
280