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;
18
19 import java.io.InputStream;
20 import java.net.URL;
21 import java.util.List;
22 import java.util.Set;
23
24 /**
25  * Represents the complete set of resources for a web application. The resources
26  * for a web application comprise of multiple ResourceSets and when looking for
27  * a Resource, the ResourceSets are processed in the following order:
28  * <ol>
29  * <li>Pre  - Resources defined by the &lt;PreResource&gt; element in the web
30  *            application's context.xml. Resources will be searched in the order
31  *            they were specified.</li>
32  * <li>Main - The main resources for the web application - i.e. the WAR or the
33  *            directory containing the expanded WAR</li>
34  * <li>JARs - Resource JARs as defined by the Servlet specification. JARs will
35  *            be searched in the order they were added to the ResourceRoot.</li>
36  * <li>Post - Resources defined by the &lt;PostResource&gt; element in the web
37  *            application's context.xml. Resources will be searched in the order
38  *            they were specified.</li>
39  * </ol>
40  * The following conventions should be noted:
41  * <ul>
42  * <li>Write operations (including delete) will only be applied to the main
43  *     ResourceSet. The write operation will fail if the presence of a Resource
44  *     in one of the other ResourceSets effectively makes the operation on the
45  *     main ResourceSet a NO-OP.</li>
46  * <li>A file in a ResourceSet will hide a directory of the same name (and all
47  *     the contents of that directory) in a ResourceSet that is later in the
48  *     search order.</li>
49  * <li>Only the main ResourceSet may define a META-INF/context.xml since that
50  *     file defines the Pre- and Post-Resources.</li>
51  * <li>As per the Servlet specification, any META-INF or WEB-INF directories in
52  *     a resource JAR will be ignored.</li>
53  * <li>Pre- and Post-Resources may define WEB-INF/lib and WEB-INF/classes in
54  *     order to make additional libraries and/or classes available to the web
55  *     application.
56  * </ul>
57  * This mechanism replaces and extends the following features that were present
58  * in earlier versions:
59  * <ul>
60  * <li>Aliases               - Replaced by Post-Resources with the addition of
61  *                             support for single files as well as directories
62  *                             and JARs.</li>
63  * <li>VirtualWebappLoader   - Replaced by Pre- and Post-Resources mapped to
64  *                             WEB-INF/lib and WEB-INF/classes</li>
65  * <li>VirtualDirContext     - Replaced by Pre- and Post-Resources</li>
66  * <li>External repositories - Replaced by Pre- and Post-Resources mapped to
67  *                             WEB-INF/lib and WEB-INF/classes</li>
68  * <li>Resource JARs         - Same feature but implemented using the same
69  *                             mechanism as all the other additional
70  *                             resources.</li>
71  * </ul>
72  */

73 /*
74  * A potential future enhancement is to allow writing to any ResourceSet,
75  * not just the main ResourceSet although that adds all sorts complications
76  * including:
77  * - which ResourceSet to write to
78  * - unexpected behaviour when deleting a resource from one ResourceSet since
79  *   that may unmask a resource in a lower priority ResourceSet so what was a
80  *   delete looks like a replace with the user having no idea where the 'new'
81  *   resource came from
82  * - how to handle PUT when the target is read-only but it could be written to
83  *   a higher priority ResourceSet that is read-write
84  */

85 public interface WebResourceRoot extends Lifecycle {
86     /**
87      * Obtain the object that represents the resource at the given path. Note
88      * that the resource at that path may not exist. If the path does not
89      * exist, the WebResource returned will be associated with the main
90      * WebResourceSet.
91      *
92      * @param path  The path for the resource of interest relative to the root
93      *              of the web application. It must start with '/'.
94      *
95      * @return  The object that represents the resource at the given path
96      */

97     WebResource getResource(String path);
98
99     /**
100      * Obtain the objects that represent the resource at the given path. Note
101      * that the resource at that path may not exist. If the path does not
102      * exist, the WebResource returned will be associated with the main
103      * WebResourceSet. This will include all matches even if the resource would
104      * not normally be accessible (e.g. because it was overridden by another
105      * resource)
106      *
107      * @param path  The path for the resource of interest relative to the root
108      *              of the web application. It must start with '/'.
109      *
110      * @return  The objects that represents the resource at the given path
111      */

112     WebResource[] getResources(String path);
113
114     /**
115      * Obtain the object that represents the class loader resource at the given
116      * path. WEB-INF/classes is always searched prior to searching JAR files in
117      * WEB-INF/lib. The search order for JAR files will be consistent across
118      * subsequent calls to this method until the web application is reloaded. No
119      * guarantee is made as to what the search order for JAR files may be.
120      *
121      * @param path  The path of the class loader resource of interest relative
122      *              to the the root of class loader resources for this web
123      *              application.
124      *
125      * @return  The object that represents the class loader resource at the
126      *          given path
127      */

128     WebResource getClassLoaderResource(String path);
129
130     /**
131      * Obtain the objects that represent the class loader resource at the given
132      * path. Note that the resource at that path may not exist. If the path does
133      * not exist, the WebResource returned will be associated with the main
134      * WebResourceSet. This will include all matches even if the resource would
135      * not normally be accessible (e.g. because it was overridden by another
136      * resource)
137      *
138      * @param path  The path for the class loader resource of interest relative
139      *              to the root of the class loader resources for the web
140      *              application. It must start with '/'.
141      *
142      * @return  The objects that represents the class loader resources at the
143      *          given path. There will always be at least one element although
144      *          that element may represent a resource that is not present.
145      */

146     WebResource[] getClassLoaderResources(String path);
147
148     /**
149      * Obtain the list of the names of all of the files and directories located
150      * in the specified directory.
151      *
152      * @param path  The path for the resource of interest relative to the root
153      *              of the web application. It must start with '/'.
154      *
155      * @return  The list of resources. If path does not refer to a directory
156      *          then a zero length array will be returned.
157      */

158     String[] list(String path);
159
160     /**
161      * Obtain the Set of the web applications pathnames of all of the files and
162      * directories located in the specified directory. Paths representing
163      * directories will end with a '/' character.
164      *
165      * @param path  The path for the resource of interest relative to the root
166      *              of the web application. It must start with '/'.
167      *
168      * @return  The Set of resources. If path does not refer to a directory
169      *          then null will be returned.
170      */

171     Set<String> listWebAppPaths(String path);
172
173     /**
174      * Obtain the list of all of the WebResources in the specified directory.
175      *
176      * @param path  The path for the resource of interest relative to the root
177      *              of the web application. It must start with '/'.
178      *
179      * @return  The list of resources. If path does not refer to a directory
180      *          then a zero length array will be returned.
181      */

182     WebResource[] listResources(String path);
183
184     /**
185      * Create a new directory at the given path.
186      *
187      * @param path  The path for the new resource to create relative to the root
188      *              of the web application. It must start with '/'.
189      *
190      * @return  <code>true</code> if the directory was created, otherwise
191      *          <code>false</code>
192      */

193     boolean mkdir(String path);
194
195     /**
196      * Create a new resource at the requested path using the provided
197      * InputStream.
198      *
199      * @param path      The path to be used for the new Resource. It is relative
200      *                  to the root of the web application and must start with
201      *                  '/'.
202      * @param is        The InputStream that will provide the content for the
203      *                  new Resource.
204      * @param overwrite If <code>true</code> and the resource already exists it
205      *                  will be overwritten. If <code>false</code> and the
206      *                  resource already exists the write will fail.
207      *
208      * @return  <code>true</code> if and only if the new Resource is written
209      */

210     boolean write(String path, InputStream is, boolean overwrite);
211
212     /**
213      * Creates a new {@link WebResourceSet} for this {@link WebResourceRoot}
214      * based on the provided parameters.
215      *
216      * @param type          The type of {@link WebResourceSet} to create
217      * @param webAppMount   The path within the web application that the
218      *                          resources should be published at. It must start
219      *                          with '/'.
220      * @param url           The URL of the resource (must locate a JAR, file or
221      *                          directory)
222      * @param internalPath  The path within the resource where the content is to
223      *                          be found. It must start with '/'.
224      */

225     void createWebResourceSet(ResourceSetType type, String webAppMount, URL url,
226             String internalPath);
227
228     /**
229      * Creates a new {@link WebResourceSet} for this {@link WebResourceRoot}
230      * based on the provided parameters.
231      *
232      * @param type          The type of {@link WebResourceSet} to create
233      * @param webAppMount   The path within the web application that the
234      *                          resources should be published at. It must start
235      *                          with '/'.
236      * @param base          The location of the resources
237      * @param archivePath   The path within the resource to the archive where
238      *                          the content is to be found. If there is no
239      *                          archive then this should be <code>null</code>.
240      * @param internalPath  The path within the archive (or the resource if the
241      *                          archivePath is <code>null</code> where the
242      *                          content is to be found. It must start with '/'.
243      */

244     void createWebResourceSet(ResourceSetType type, String webAppMount,
245             String base, String archivePath, String internalPath);
246
247
248     /**
249      * Adds the provided WebResourceSet to this web application as a 'Pre'
250      * resource.
251      *
252      * @param webResourceSet the resource set to use
253      */

254     void addPreResources(WebResourceSet webResourceSet);
255
256     /**
257      * @return the list of WebResourceSet configured to this web application
258      * as a 'Pre' resource.
259      */

260     WebResourceSet[] getPreResources();
261
262     /**
263      * Adds the provided WebResourceSet to this web application as a 'Jar'
264      * resource.
265      *
266      * @param webResourceSet the resource set to use
267      */

268     void addJarResources(WebResourceSet webResourceSet);
269
270     /**
271      * @return the list of WebResourceSet configured to this web application
272      * as a 'Jar' resource.
273      */

274     WebResourceSet[] getJarResources();
275
276     /**
277      * Adds the provided WebResourceSet to this web application as a 'Post'
278      * resource.
279      *
280      * @param webResourceSet the resource set to use
281      */

282     void addPostResources(WebResourceSet webResourceSet);
283
284     /**
285      * @return the list of WebResourceSet configured to this web application
286      * as a 'Post' resource.
287      */

288     WebResourceSet[] getPostResources();
289
290     /**
291      * @return the web application this WebResourceRoot is associated with.
292      */

293     Context getContext();
294
295     /**
296      * Set the web application this WebResourceRoot is associated with.
297      *
298      * @param context the associated context
299      */

300     void setContext(Context context);
301
302     /**
303      * Configure if this resources allow the use of symbolic links.
304      *
305      * @param allowLinking  <code>true</code> if symbolic links are allowed.
306      */

307     void setAllowLinking(boolean allowLinking);
308
309     /**
310      * Determine if this resources allow the use of symbolic links.
311      *
312      * @return  <code>true</code> if symbolic links are allowed
313      */

314     boolean getAllowLinking();
315
316     /**
317      * Set whether or not caching is permitted for this web application.
318      *
319      * @param cachingAllowed    <code>true</code> to enable caching, else
320      *                          <code>false</code>
321      */

322     void setCachingAllowed(boolean cachingAllowed);
323
324     /**
325      * @return <code>true</code> if caching is permitted for this web application.
326      */

327     boolean isCachingAllowed();
328
329     /**
330      * Set the Time-To-Live (TTL) for cache entries.
331      *
332      * @param ttl   TTL in milliseconds
333      */

334     void setCacheTtl(long ttl);
335
336     /**
337      * Get the Time-To-Live (TTL) for cache entries.
338      *
339      * @return  TTL in milliseconds
340      */

341     long getCacheTtl();
342
343     /**
344      * Set the maximum permitted size for the cache.
345      *
346      * @param cacheMaxSize  Maximum cache size in kilobytes
347      */

348     void setCacheMaxSize(long cacheMaxSize);
349
350     /**
351      * Get the maximum permitted size for the cache.
352      *
353      * @return  Maximum cache size in kilobytes
354      */

355     long getCacheMaxSize();
356
357     /**
358      * Set the maximum permitted size for a single object in the cache. Note
359      * that the maximum size in bytes may not exceed {@link Integer#MAX_VALUE}.
360      *
361      * @param cacheObjectMaxSize    Maximum size for a single cached object in
362      *                              kilobytes
363      */

364     void setCacheObjectMaxSize(int cacheObjectMaxSize);
365
366     /**
367      * Get the maximum permitted size for a single object in the cache. Note
368      * that the maximum size in bytes may not exceed {@link Integer#MAX_VALUE}.
369      *
370      * @return  Maximum size for a single cached object in kilobytes
371      */

372     int getCacheObjectMaxSize();
373
374     /**
375      * Controls whether the track locked files feature is enabled. If enabled,
376      * all calls to methods that return objects that lock a file and need to be
377      * closed to release that lock (e.g. {@link WebResource#getInputStream()}
378      * will perform a number of additional tasks.
379      * <ul>
380      *   <li>The stack trace at the point where the method was called will be
381      *       recorded and associated with the returned object.</li>
382      *   <li>The returned object will be wrapped so that the point where close()
383      *       (or equivalent) is called to release the resources can be detected.
384      *       Tracking of the object will cease once the resources have been
385      *       released.</li>
386      *   <li>All remaining locked resources on web application shutdown will be
387      *       logged and then closed.</li>
388      * </ul>
389      *
390      * @param trackLockedFiles {@code true} to enable it, {@code false} to
391      *                         disable it
392      */

393     void setTrackLockedFiles(boolean trackLockedFiles);
394
395     /**
396      * Has the track locked files feature been enabled?
397      *
398      * @return {@code trueif it has been enabled, otherwise {@code false}
399      */

400     boolean getTrackLockedFiles();
401
402     /**
403      * This method will be invoked by the context on a periodic basis and allows
404      * the implementation a method that executes periodic tasks, such as purging
405      * expired cache entries.
406      */

407     void backgroundProcess();
408
409     /**
410      * Add a specified resource to track to be able to later release
411      * resources on stop.
412      * @param trackedResource the resource that will be tracked
413      */

414     void registerTrackedResource(TrackedWebResource trackedResource);
415
416     /**
417      * Stop tracking specified resource, once it no longer needs to free resources.
418      * @param trackedResource the resource that was tracked
419      */

420     void deregisterTrackedResource(TrackedWebResource trackedResource);
421
422     /**
423      * @return the set of {@link WebResourceSet#getBaseUrl()} for all
424      * {@link WebResourceSet}s used by this root.
425      */

426     List<URL> getBaseUrls();
427
428     /**
429      * Implementations may cache some information to improve performance. This
430      * method triggers the clean-up of those resources.
431      */

432     void gc();
433
434     enum ResourceSetType {
435         PRE,
436         RESOURCE_JAR,
437         POST,
438         CLASSES_JAR
439     }
440 }
441