content: /*
   * Copyright (C) 2020 ActiveJ LLC.
   *
   * Licensed 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 io.activej.http.loader;
  
  import io.activej.bytebuf.ByteBuf;
  import io.activej.common.annotation.ComponentInterface;
  import io.activej.http.StaticServlet;
  import io.activej.promise.Promise;
  import io.activej.reactor.Reactor;
  
  import java.nio.file.Path;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.concurrent.Executor;
  import java.util.function.BiConsumer;
  import java.util.function.Function;
  import java.util.function.Predicate;
  import java.util.function.UnaryOperator;
  
  /**
   * Represents the 'predefined storage' for the {@link StaticServlet StaticServlet}.
   */
  @ComponentInterface
  public interface IStaticLoader {
  
  	Promise<ByteBuf> load(String path);
  
  	default IStaticLoader filter(Predicate<String> predicate) {
  		return path -> predicate.test(path) ?
  			load(path) :
  			Promise.ofException(new ResourceNotFoundException("Resource '" + path + "' has been filtered out"));
  	}
  
  	default IStaticLoader map(UnaryOperator<String> fn) {
  		return path -> this.load(fn.apply(path));
  	}
  
  	default IStaticLoader subdirectory(String subdirectory) {
  		String folder = subdirectory.endsWith("/") ? subdirectory : subdirectory + '/';
  		return map(name -> folder + name);
  	}
  
  	default IStaticLoader cached(Reactor reactor) {
  		return cacheOf(reactor, this);
  	}
  
  	default IStaticLoader cached(Reactor reactor, Map<String, byte[]> map) {
  		return cacheOf(reactor, this, map);
  	}
  
  	static IStaticLoader cacheOf(Reactor reactor, IStaticLoader loader) {
  		return cacheOf(reactor, loader, new HashMap<>());
  	}
  
  	static IStaticLoader cacheOf(Reactor reactor, IStaticLoader loader, Map<String, byte[]> map) {
  		return cacheOf(reactor, loader, map::get, map::put);
  	}
  
  	static IStaticLoader cacheOf(Reactor reactor, IStaticLoader loader, Function<String, byte[]> get, BiConsumer<String, byte[]> put) {
  		return new CacheStaticLoader(reactor, loader, get, put);
  	}
  
  	static IStaticLoader ofClassPath(Reactor reactor, Executor executor, String root) {
  		return ClassPathStaticLoader.create(reactor, executor, root);
  	}
  
  	static IStaticLoader ofClassPath(Reactor reactor, Executor executor, ClassLoader classLoader, String root) {
  		return ClassPathStaticLoader.create(reactor, executor, classLoader, root);
  	}
  
  	static IStaticLoader ofPath(Reactor reactor, Executor executor, Path dir) {
  		return new FileReaderStaticLoader(reactor, executor, dir);
  	}
  
  }
  