001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.staticfile;
018
019import static org.apache.juneau.commons.utils.CollectionUtils.*;
020
021import java.nio.file.*;
022import java.util.*;
023
024import org.apache.http.*;
025import org.apache.juneau.*;
026import org.apache.juneau.commons.io.*;
027import org.apache.juneau.cp.*;
028import org.apache.juneau.http.resource.*;
029
030/**
031 * API for retrieving localized static files from either the classpath or file system.
032 *
033 * <h5 class='section'>See Also:</h5><ul>
034 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/StaticFiles">Static files</a>
035 * </ul>
036 */
037public interface StaticFiles extends FileFinder {
038   /**
039    * Builder class.
040    */
041   public static class Builder extends BeanBuilder<StaticFiles> {
042
043      List<Header> headers;
044      MimeTypeDetector mimeTypes;
045      FileFinder.Builder fileFinder;
046
047      /**
048       * Constructor.
049       *
050       * @param beanStore The bean store to use for creating beans.
051       */
052      protected Builder(BeanStore beanStore) {
053         super(BasicStaticFiles.class, beanStore);
054         headers = list();
055         fileFinder = FileFinder.create(beanStore);
056         mimeTypes = MimeTypeDetector.DEFAULT;
057      }
058
059      /**
060       * Prepend the MIME type values to the MIME types registry.
061       *
062       * @param mimeTypes A .mime.types formatted string of entries.  See {@link MimeTypeDetector.Builder#addTypes(String...)}.
063       * @return This object.
064       */
065      public Builder addMimeTypes(String mimeTypes) {
066         this.mimeTypes = MimeTypeDetector.builder().addTypes(mimeTypes).build();
067         return this;
068      }
069
070      /**
071       * Enables in-memory caching of files for quicker retrieval.
072       *
073       * @param cachingLimit The maximum file size in bytes.
074       * @return This object.
075       */
076      public Builder caching(long cachingLimit) {
077         fileFinder.caching(cachingLimit);
078         return this;
079      }
080
081      /**
082       * Adds a class subpackage to the lookup paths.
083       *
084       * @param c The class whose package will be added to the lookup paths.  Must not be <jk>null</jk>.
085       * @param path The absolute or relative subpath.
086       * @param recursive If <jk>true</jk>, also recursively adds all the paths of the parent classes as well.
087       * @return This object.
088       */
089      public Builder cp(Class<?> c, String path, boolean recursive) {
090         fileFinder.cp(c, path, recursive);
091         return this;
092      }
093
094      /**
095       * Adds a file system directory to the lookup paths.
096       *
097       * @param path The path relative to the working directory.  Must not be <jk>null</jk>
098       * @return This object.
099       */
100      public Builder dir(String path) {
101         fileFinder.dir(path);
102         return this;
103      }
104
105      /**
106       * Specifies the regular expression file name pattern to use to exclude files from being retrieved from the file source.
107       *
108       * @param patterns
109       *    The regular expression exclude patterns.
110       *    <br>If none are specified, no files will be excluded.
111       * @return This object.
112       */
113      public Builder exclude(String...patterns) {
114         fileFinder.exclude(patterns);
115         return this;
116      }
117
118      /**
119       * Appends headers to add to HTTP responses.
120       *
121       * <p>
122       * Can be called multiple times to add multiple headers.
123       *
124       * @param headers The headers to add.
125       * @return This object.
126       */
127      public Builder headers(Header...headers) {
128         addAll(this.headers, headers);
129         return this;
130      }
131
132      @Override /* Overridden from BeanBuilder */
133      public Builder impl(Object value) {
134         super.impl(value);
135         return this;
136      }
137
138      /**
139       * Specifies the regular expression file name patterns to use to include files being retrieved from the file source.
140       *
141       * @param patterns
142       *    The regular expression include patterns.
143       *    <br>The default is <js>".*"</js>.
144       * @return This object.
145       */
146      public Builder include(String...patterns) {
147         fileFinder.include(patterns);
148         return this;
149      }
150
151      /**
152       * Replaces the MIME types registry used for determining content types.
153       *
154       * @param value The new MIME types registry.
155       * @return This object.
156       */
157      public Builder mimeTypes(MimeTypeDetector value) {
158         mimeTypes = value;
159         return this;
160      }
161
162      /**
163       * Adds a file system directory to the lookup paths.
164       *
165       * @param value The directory path.
166       * @return This object.
167       */
168      public Builder path(Path value) {
169         fileFinder.path(value);
170         return this;
171      }
172
173      @Override /* Overridden from BeanBuilder */
174      public Builder type(Class<?> value) {
175         super.type(value);
176         return this;
177      }
178
179      @Override /* Overridden from BeanBuilder */
180      protected StaticFiles buildDefault() {
181         return new BasicStaticFiles(this);
182      }
183   }
184
185   /** Represents no static files */
186   public abstract class Void implements StaticFiles {}
187
188   /**
189    * Static creator.
190    *
191    * @param beanStore The bean store to use for creating beans.
192    * @return A new builder for this object.
193    */
194   static Builder create(BeanStore beanStore) {
195      return new Builder(beanStore);
196   }
197
198   /**
199    * Resolve the specified path.
200    *
201    * @param path The path to resolve to a static file.
202    * @param locale Optional locale.
203    * @return The resource, or <jk>null</jk> if not found.
204    */
205   Optional<HttpResource> resolve(String path, Locale locale);
206}