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