package com.aol.micro.server.module; import static com.aol.micro.server.utility.UsefulStaticMethods.concat; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; import java.util.function.Supplier; import javax.servlet.Filter; import javax.servlet.Servlet; import javax.servlet.ServletContextListener; import javax.servlet.ServletRequestListener; import com.aol.micro.server.auto.discovery.CommonRestResource; import com.aol.micro.server.servers.model.ServerData; import com.aol.micro.server.utility.HashMapBuilder; import cyclops.collections.immutable.PMapX; import cyclops.collections.immutable.PSetX; import cyclops.collections.immutable.PStackX; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.experimental.Wither; @Builder @AllArgsConstructor public class ConfigurableModule implements Module { @Wither private final Set<Object> jaxRsResourceObjects; @Wither private final Set<Class<?>> restResourceClasses; @Wither private final Set<Class<? extends Annotation>> restAnnotationClasses; @Wither private final List<Class<?>> defaultResources; @Wither private final List<ServletContextListener> listeners; @Wither private final List<ServletRequestListener> requestListeners; @Wither private final Map<String, Filter> filters; @Wither private final Map<String, Servlet> servlets; @Wither private final String jaxWsRsApplication; @Wither private final String providers; @Wither private final String context; @Wither private final Set<Class<?>> springConfigurationClasses; @Wither private final Map<String, String> propertyOverrides; @Wither private final List<String> defaultJaxRsPackages; private final Consumer<WebServerProvider<?>> serverConfigManager; private final Consumer<JaxRsProvider<?>> resourceConfigManager; @Wither private final Map<String, Object> serverProperties; @Wither final boolean resetAll; public <T> ConfigurableModule withResourceConfigManager(Consumer<JaxRsProvider<T>> resourceConfigManager) { return new ConfigurableModule(jaxRsResourceObjects, restResourceClasses, restAnnotationClasses, defaultResources, listeners, requestListeners, filters, servlets, jaxWsRsApplication, providers, context, springConfigurationClasses, propertyOverrides, defaultJaxRsPackages, serverConfigManager, (Consumer) resourceConfigManager, serverProperties, resetAll); } public <T> ConfigurableModule withServerConfigManager(Consumer<WebServerProvider<?>> serverConfigManager) { return new ConfigurableModule(jaxRsResourceObjects, restResourceClasses, restAnnotationClasses, defaultResources, listeners, requestListeners, filters, servlets, jaxWsRsApplication, providers, context, springConfigurationClasses, propertyOverrides, defaultJaxRsPackages, (Consumer) serverConfigManager, resourceConfigManager, serverProperties, resetAll); } @Override public Set<Object> getJaxRsResourceObjects() { if (this.jaxRsResourceObjects != null) return PSetX.fromCollection(concat(this.jaxRsResourceObjects, extract(() -> Module.super.getJaxRsResourceObjects()))); return Module.super.getJaxRsResourceObjects(); } @Override public <T> Consumer<WebServerProvider<T>> getServerConfigManager() { if (serverConfigManager != null) return (Consumer) serverConfigManager; return Module.super.getServerConfigManager(); } @Override public <T> Consumer<JaxRsProvider<T>> getResourceConfigManager() { if (resourceConfigManager != null) return (Consumer) resourceConfigManager; return Module.super.getResourceConfigManager(); } @Override public List<String> getDefaultJaxRsPackages() { if (defaultJaxRsPackages != null) return PStackX.fromCollection(concat(defaultJaxRsPackages, extract(() -> Module.super.getDefaultJaxRsPackages()))); return PStackX.fromCollection(Module.super.getDefaultJaxRsPackages()); } private <T> Collection<T> extract(Supplier<Collection<T>> s) { if (!resetAll) return s.get(); return Arrays.asList(); } private <K, V> Map<K, V> extractMap(Supplier<Map<K, V>> s) { if (!resetAll) return s.get(); return HashMapBuilder.of(); } @Override public Set<Class<?>> getRestResourceClasses() { if (restResourceClasses != null) return PSetX.fromCollection(concat(restResourceClasses, extract(() -> Collections.singletonList(CommonRestResource.class)))); return Module.super.getRestResourceClasses(); } @Override public Set<Class<? extends Annotation>> getRestAnnotationClasses() { if (restAnnotationClasses != null) return PSetX.fromCollection(concat(restAnnotationClasses, extract(() -> Module.super.getRestAnnotationClasses()))); return Module.super.getRestAnnotationClasses(); } @Override public List<Class<?>> getDefaultResources() { if (this.defaultResources != null) { return PStackX.fromCollection((concat(this.defaultResources, extract(() -> Module.super.getDefaultResources())))); } return Module.super.getDefaultResources(); } @Override public List<ServletContextListener> getListeners(ServerData data) { if (listeners != null) return PStackX.fromCollection((concat(this.listeners, extract(() -> Module.super.getListeners(data))))); return Module.super.getListeners(data); } @Override public List<ServletRequestListener> getRequestListeners(ServerData data) { if (requestListeners != null) return PStackX.fromCollection(concat(this.requestListeners, extract(() -> Module.super.getRequestListeners(data)))); return Module.super.getRequestListeners(data); } @Override public Map<String, Filter> getFilters(ServerData data) { if (filters != null) return PMapX.fromMap(filters).plusAll(extractMap(() -> Module.super.getFilters(data))); return Module.super.getFilters(data); } @Override public Map<String, Servlet> getServlets(ServerData data) { if (servlets != null) return PMapX.fromMap(servlets).plusAll(extractMap(() -> Module.super.getServlets(data))); return Module.super.getServlets(data); } @Override public String getJaxWsRsApplication() { if (this.jaxWsRsApplication != null) return jaxWsRsApplication; return Module.super.getJaxWsRsApplication(); } @Override public String getProviders() { if (providers != null) return providers; return Module.super.getProviders(); } @Override public String getContext() { return context; } @Override public Set<Class<?>> getSpringConfigurationClasses() { if (this.springConfigurationClasses != null) return PSetX.fromCollection(concat(this.springConfigurationClasses, extract(() -> Module.super.getSpringConfigurationClasses()))); return Module.super.getSpringConfigurationClasses(); } @Override public Map<String, Object> getServerProperties() { if (serverProperties != null) { return PMapX.fromMap(serverProperties).plusAll(extractMap(() -> Module.super.getServerProperties())); } else { return Module.super.getServerProperties(); } } }