/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.catalina;

import java.io.InputStream;
import java.net.URL;
import java.util.Set;

/**
 * Represents the complete set of resources for a web application. The resources
 * for a web application comprise of multiple ResourceSets and when looking for
 * a Resource, the ResourceSets are processed in the following order:
 * <ol>
 * <li>Pre  - Resources defined by the &lt;PreResource&gt; element in the web
 *            application&apos;s context.xml. Resources will be searched in the
 *            order they were specified.</li>
 * <li>Main - The main resources for the web application - i.e. the WAR or the
 *            directory containing the expanded WAR</li>
 * <li>JARs - Resource JARs as defined by the Servlet specification. JARs will
 *            be searched in the order they were added to the ResourceRoot.</li>
 * <li>Post - Resources defined by the &lt;PostResource&gt; element in the web
 *            application&apos;s context.xml. Resources will be searched in the
 *            order they were specified.</li>
 * </ol>
 * The following conventions should be noted:
 * <ul>
 * <li>Write operations (including delete) will only be applied to the main
 *     ResourceSet. The write operation will fail if the presence of a Resource
 *     in one of the other ResourceSets effectively makes the operation on the
 *     main ResourceSet a NO-OP.</li>
 * <li>A file in a ResourceSet will hide a directory of the same name (and all
 *     the contents of that directory) in a ResourceSet that is later in the
 *     search order.</li>
 * <li>Only the main ResourceSet may define a META-INF/context.xml since that
 *     file defines the Pre- and Post-Resources.</li>
 * <li>As per the Servlet specification, any META-INF or WEB-INF directories in
 *     a resource JAR will be ignored.</li>
 * <li>Pre- and Post-Resources may define WEB-INF/lib and WEB-INF/classes in
 *     order to make additional libraries and/or classes available to the web
 *     application.
 * </ul>
 * This mechanism replaces and extends the following features that were present
 * in earlier versions:
 * <ul>
 * <li>Aliases               - Replaced by Post-Resources with the addition of
 *                             support for single files as well as directories
 *                             and JARs.</li>
 * <li>VirtualWebappLoader   - Replaced by Pre- and Post-Resources mapped to
 *                             WEB-INF/lib and WEB-INF/classes</li>
 * <li>VirtualDirContext     - Replaced by Pre- and Post-Resources</li>
 * <li>External repositories - Replaced by Pre- and Post-Resources mapped to
 *                             WEB-INF/lib and WEB-INF/classes</li>
 * <li>Resource JARs         - Same feature but implemented using the same
 *                             mechanism as all the other additional
 *                             resources.</li>
 * </ul>
 */
/*
 * A potential future enhancement is to allow writing to any ResourceSet,
 * not just the main ResourceSet although that adds all sorts complications
 * including:
 * - which ResourceSet to write to
 * - unexpected behaviour when deleting a resource from one ResourceSet since
 *   that may unmask a resource in a lower priority ResouceSet so what was a
 *   delete looks like a replace with the user having no idea where the 'new'
 *   resource came from
 * - how to handle PUT when the target is read-only but it could be written to
 *   a higher priority ResourceSet that is read-write
 */
public interface WebResourceRoot extends Lifecycle {
    /**
     * Obtain the object that represents the resource at the given path. Note
     * that the resource at that path may not exist. If the path does not
     * exist, the WebResource returned will be associated with the main
     * WebResourceSet.
     *
     * @param path  The path for the resource of interest relative to the root
     *              of the web application. It must start with '/'.
     *
     * @return  The object that represents the resource at the given path
     */
    WebResource getResource(String path);

    /**
     * Obtain the object(s) that represent the resource at the given path. Note
     * that the resource at that path may not exist. If the path does not
     * exist, the WebResource returned will be associated with the main
     * WebResourceSet. This will include all matches even if the resource would
     * not normally be accessible (e.g. because it was overridden by another
     * resource)
     *
     * @param path  The path for the resource of interest relative to the root
     *              of the web application. It must start with '/'.
     *
     * @return  The object that represents the resource at the given path
     */
    WebResource[] getResources(String path);

    /**
     * Obtain the list of the names of all of the files and directories located
     * in the specified directory.
     *
     * @param path  The path for the resource of interest relative to the root
     *              of the web application. It must start with '/'.
     *
     * @return  The list of resources. If path does not refer to a directory
     *          then a zero length array will be returned.
     */
    String[] list(String path);

    /**
     * Obtain the Set of the web applications pathnames of all of the files and
     * directories located in the specified directory. Paths representing
     * directories will end with a '/' character.
     *
     * @param path  The path for the resource of interest relative to the root
     *              of the web application. It must start with '/'.
     *
     * @return  The Set of resources. If path does not refer to a directory
     *          then null will be returned.
     */
    Set<String> listWebAppPaths(String path);

    /**
     * Obtain the list of all of the WebResources in the specified directory.
     *
     * @param path  The path for the resource of interest relative to the root
     *              of the web application. It must start with '/'.
     *
     * @return  The list of resources. If path does not refer to a directory
     *          then a zero length array will be returned.
     */
    WebResource[] listResources(String path);

    /**
     * Create a new directory at the given path.
     *
     * @param path  The path for the new resource to create relative to the root
     *              of the web application. It must start with '/'.
     *
     * @return  <code>true</code> if the directory was created, otherwise
     *          <code>false</code>
     */
    boolean mkdir(String path);

    /**
     * Create a new resource at the requested path using the provided
     * InputStream.
     *
     * @param path      The path to be used for the new Resource. It is relative
     *                  to the root of the web application and must start with
     *                  '/'.
     * @param is        The InputStream that will provide the content for the
     *                  new Resource.
     * @param overwrite If <code>true</code> and the resource already exists it
     *                  will be overwritten. If <code>false</code> and the
     *                  resource already exists the write will fail.
     *
     * @return  <code>true</code> if and only if the new Resource is written
     */
    boolean write(String path, InputStream is, boolean overwrite);

    /**
     * Creates a new {@link WebResourceSet} for this {@link WebResourceRoot}
     * based on the provided parameters.
     *
     * @param type          The type of {@link WebResourceSet} to create
     * @param webAppMount   The path within the web application that the
     *                          resources should be published at. It must start
     *                          with '/'.
     * @param url           The URL of the resource (must locate a JAR, file or
     *                          directory)
     * @param internalPath  The path within the resource where the content is to
     *                          be found. It must start with '/'.
     */
    void createWebResourceSet(ResourceSetType type, String webAppMount, URL url,
            String internalPath);

    /**
     * Creates a new {@link WebResourceSet} for this {@link WebResourceRoot}
     * based on the provided parameters.
     *
     * @param type          The type of {@link WebResourceSet} to create
     * @param webAppMount   The path within the web application that the
     *                          resources should be published at. It must start
     *                          with '/'.
     * @param base          The location of the resources
     * @param archivePath   The path within the resource to the archive where
     *                          the content is to be found. If there is no
     *                          archive then this should be <code>null</code>.
     * @param internalPath  The path within the archive (or the resource if the
     *                          archivePath is <code>null</code> where the
     *                          content is to be found. It must start with '/'.
     */
    void createWebResourceSet(ResourceSetType type, String webAppMount,
            String base, String archivePath, String internalPath);


    /**
     * Adds the provided WebResourceSet to this web application as a 'Pre'
     * resource.
     */
    void addPreResources(WebResourceSet webResourceSet);

    /**
     * Get the list of WebResourceSet configured to this web application
     * as a 'Pre' resource.
     */
    WebResourceSet[] getPreResources();

    /**
     * Adds the provided WebResourceSet to this web application as a 'Jar'
     * resource.
     */
    void addJarResources(WebResourceSet webResourceSet);

    /**
     * Get the list of WebResourceSet configured to this web application
     * as a 'Jar' resource.
     */
    WebResourceSet[] getJarResources();

    /**
     * Adds the provided WebResourceSet to this web application as a 'Post'
     * resource.
     */
    void addPostResources(WebResourceSet webResourceSet);

    /**
     * Get the list of WebResourceSet configured to this web application
     * as a 'Post' resource.
     */
    WebResourceSet[] getPostResources();

    /**
     * Obtain the web application this WebResourceRoot is associated with.
     */
    Context getContext();

    /**
     * Set the web application this WebResourceRoot is associated with.
     */
    void setContext(Context context);

    /**
     * Configure if this resources allow the use of symbolic links.
     *
     * @param allowLinking  <code>true</code> if symbolic links are allowed.
     */
    void setAllowLinking(boolean allowLinking);

    /**
     * Determine if this resources allow the use of symbolic links.
     *
     * @return  <code>true</code> if symbolic links are allowed
     */
    boolean getAllowLinking();

    /**
     * Set whether or not caching is permitted for this web application.
     *
     * @param cachingAllowed    <code>true</code> to enable caching, else
     *                          <code>false</code>
     */
    void setCachingAllowed(boolean cachingAllowed);

    /**
     * Get whether or not caching is permitted for this web application.
     */
    boolean isCachingAllowed();

    /**
     * Set the Time-To-Live (TTL) for cache entries.
     *
     * @param ttl   TTL in milliseconds
     */
    void setCacheTtl(long ttl);

    /**
     * Get the Time-To-Live (TTL) for cache entries.
     *
     * @return  TTL in milliseconds
     */
    long getCacheTtl();

    /**
     * Set the maximum permitted size for the cache.
     *
     * @param cacheMaxSize  Maximum cache size in kilobytes
     */
    void setCacheMaxSize(long cacheMaxSize);

    /**
     * Get the maximum permitted size for the cache.
     *
     * @return  Maximum cache size in kilobytes
     */
    long getCacheMaxSize();

    /**
     * Set the maximum permitted size for a single object in the cache.
     *
     * @param cacheMaxObjectSize    Maximum size for a single cached object in
     *                              kilobytes
     */
    void setCacheMaxObjectSize(long cacheMaxObjectSize);

    /**
     * Get the maximum permitted size for a single object in the cache.
     *
     * @return  Maximum size for a single cached object in kilobytes
     */
    long getCacheMaxObjectSize();

    /**
     * This method will be invoked by the context on a periodic basis and allows
     * the implementation a method that executes periodic tasks, such as purging
     * expired cache entries.
     */
    public void backgroundProcess();

    public static enum ResourceSetType {
        PRE,
        RESOURCE_JAR,
        POST
    }
}
