// // ======================================================================== // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // // The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php // // You may elect to redistribute this code under either of these licenses. // ======================================================================== // package org.eclipse.jetty.webapp; import java.util.Collection; import java.util.Collections; import java.util.ListIterator; import java.util.ServiceLoader; import org.eclipse.jetty.util.TopologicalSort; import org.eclipse.jetty.util.annotation.Name; /* ------------------------------------------------------------------------------- */ /** A pluggable Configuration for {@link WebAppContext}s. * <p> * A {@link WebAppContext} is configured by the application of one or more {@link Configuration} * instances. Typically each implemented Configuration is responsible for an aspect of the * servlet specification (eg {@link WebXmlConfiguration}, {@link FragmentConfiguration}, etc.) * or feature (eg {@link WebSocketConfiguration}, {@link JmxConfiguration} etc.) * </p> * <p>Configuration instances are discovered by the {@link Configurations} class using either the * {@link ServiceLoader} mechanism or by an explicit call to {@link Configurations#setKnown(String...)}. * By default, all Configurations that do not implement the {@link DisabledByDefault} interface * are applied to all {@link WebAppContext}s within the JVM. However a Server wide default {@link Configurations} * collection may also be defined with {@link Configurations#setServerDefault(org.eclipse.jetty.server.Server)}. * Furthermore, each individual Context may have its Configurations list explicitly set and/or amended with * {@link WebAppContext#setConfigurations(Configuration[])}, {@link WebAppContext#addConfiguration(Configuration...)} * or {@link WebAppContext#getWebAppConfigurations()}. * </p> * <p>Since Jetty-9.4, Configurations are self ordering using the {@link #getDependencies()} and * {@link #getDependents()} methods for a {@link TopologicalSort} initiated by {@link Configurations#sort()} * when a {@link WebAppContext} is started. This means that feature configurations * (eg {@link JndiConfiguration}, {@link JaasConfiguration}} etc.) can be added or removed without concern * for ordering. * </p> * <p>Also since Jetty-9.4, Configurations are responsible for providing {@link #getServerClasses()} and * {@link #getSystemClasses()} to configure the {@link WebAppClassLoader} for each context. * </p> * */ public interface Configuration { public final static String ATTR="org.eclipse.jetty.webapp.configuration"; /** Get a class that this class replaces/extends. * If this is added to {@link Configurations} collection that already contains a * configuration of the replaced class or that reports to replace the same class, then * it is replaced with this instance. * @return The class this Configuration replaces/extends or null if it replaces no other configuration */ public default Class<? extends Configuration> replaces() { return null; } /** Get known Configuration Dependencies. * @return The names of Configurations that {@link TopologicalSort} must order * before this configuration. */ public default Collection<String> getDependencies() { return Collections.emptyList(); } /** Get known Configuration Dependents. * @return The names of Configurations that {@link TopologicalSort} must order * after this configuration. */ public default Collection<String> getDependents(){ return Collections.emptyList(); } /** Get the system classes associated with this Configuration. * @return ClasspathPattern of system classes. */ public default ClasspathPattern getSystemClasses() { return new ClasspathPattern(); } /** Get the system classes associated with this Configuration. * @return ClasspathPattern of server classes. */ public default ClasspathPattern getServerClasses() { return new ClasspathPattern(); } /** Set up for configuration. * <p> * Typically this step discovers configuration resources. * Calls to preConfigure may alter the Configurations configured on the * WebAppContext, so long as configurations prior to this configuration * are not altered. * @param context The context to configure * @throws Exception if unable to pre configure */ public void preConfigure (WebAppContext context) throws Exception; /** Configure WebApp. * <p> * Typically this step applies the discovered configuration resources to * either the {@link WebAppContext} or the associated {@link MetaData}. * @param context The context to configure * @throws Exception if unable to configure */ public void configure (WebAppContext context) throws Exception; /** Clear down after configuration. * @param context The context to configure * @throws Exception if unable to post configure */ public void postConfigure (WebAppContext context) throws Exception; /** DeConfigure WebApp. * This method is called to undo all configuration done. This is * called to allow the context to work correctly over a stop/start cycle * @param context The context to configure * @throws Exception if unable to deconfigure */ public void deconfigure (WebAppContext context) throws Exception; /** Destroy WebApp. * This method is called to destroy a webappcontext. It is typically called when a context * is removed from a server handler hierarchy by the deployer. * @param context The context to configure * @throws Exception if unable to destroy */ public void destroy (WebAppContext context) throws Exception; /** * @return true if configuration is disabled by default */ public boolean isDisabledByDefault(); /** * @return true if configuration should be aborted */ public boolean abort(WebAppContext context); /** * @deprecated Use {@link Configurations} */ @Deprecated public class ClassList extends Configurations { @Deprecated public void addAfter(@Name("afterClass") String afterClass,@Name("configClass")String... configClass) { if (configClass!=null && afterClass!=null) { ListIterator<Configuration> iter = _configurations.listIterator(); while (iter.hasNext()) { Configuration c=iter.next(); if (afterClass.equals(c.getClass().getName()) || afterClass.equals(c.replaces().getName())) { for (String cc: configClass) iter.add(newConfiguration(cc)); return; } } } throw new IllegalArgumentException("afterClass '"+afterClass+"' not found in "+this); } @Deprecated public void addBefore(@Name("beforeClass") String beforeClass,@Name("configClass")String... configClass) { if (configClass!=null && beforeClass!=null) { ListIterator<Configuration> iter = _configurations.listIterator(); while (iter.hasNext()) { Configuration c=iter.next(); if (beforeClass.equals(c.getClass().getName()) || beforeClass.equals(c.replaces().getName())) { iter.previous(); for (String cc: configClass) iter.add(newConfiguration(cc)); return; } } } throw new IllegalArgumentException("beforeClass '"+beforeClass+"' not found in "+this); } } }