// // ======================================================================== // 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.servlet; import java.io.IOException; import java.util.EnumSet; import javax.servlet.DispatcherType; import org.eclipse.jetty.http.PathMap; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; @ManagedObject("Filter Mappings") public class FilterMapping implements Dumpable { /** Dispatch types */ public static final int DEFAULT=0; public static final int REQUEST=1; public static final int FORWARD=2; public static final int INCLUDE=4; public static final int ERROR=8; public static final int ASYNC=16; public static final int ALL=31; /* ------------------------------------------------------------ */ /** Dispatch type from name * @param type the type name * @return the dispatcher type */ public static DispatcherType dispatch(String type) { if ("request".equalsIgnoreCase(type)) return DispatcherType.REQUEST; if ("forward".equalsIgnoreCase(type)) return DispatcherType.FORWARD; if ("include".equalsIgnoreCase(type)) return DispatcherType.INCLUDE; if ("error".equalsIgnoreCase(type)) return DispatcherType.ERROR; if ("async".equalsIgnoreCase(type)) return DispatcherType.ASYNC; throw new IllegalArgumentException(type); } /* ------------------------------------------------------------ */ /** Dispatch type from name * @param type the dispatcher type * @return the type constant ({@link #REQUEST}, {@link #ASYNC}, {@link #FORWARD}, {@link #INCLUDE}, or {@link #ERROR}) */ public static int dispatch(DispatcherType type) { switch(type) { case REQUEST: return REQUEST; case ASYNC: return ASYNC; case FORWARD: return FORWARD; case INCLUDE: return INCLUDE; case ERROR: return ERROR; } throw new IllegalArgumentException(type.toString()); } /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ private int _dispatches=DEFAULT; private String _filterName; private transient FilterHolder _holder; private String[] _pathSpecs; private String[] _servletNames; /* ------------------------------------------------------------ */ public FilterMapping() {} /* ------------------------------------------------------------ */ /** Check if this filter applies to a path. * @param path The path to check or null to just check type * @param type The type of request: __REQUEST,__FORWARD,__INCLUDE, __ASYNC or __ERROR. * @return True if this filter applies */ boolean appliesTo(String path, int type) { if (appliesTo(type)) { for (int i=0;i<_pathSpecs.length;i++) if (_pathSpecs[i]!=null && PathMap.match(_pathSpecs[i], path,true)) return true; } return false; } /* ------------------------------------------------------------ */ /** Check if this filter applies to a particular dispatch type. * @param type The type of request: * {@link Handler#REQUEST}, {@link Handler#FORWARD}, {@link Handler#INCLUDE} or {@link Handler#ERROR}. * @return <code>true</code> if this filter applies */ boolean appliesTo(int type) { if (_dispatches==0) return type==REQUEST || type==ASYNC && _holder.isAsyncSupported(); return (_dispatches&type)!=0; } /* ------------------------------------------------------------ */ public boolean appliesTo(DispatcherType t) { return appliesTo(dispatch(t)); } /* ------------------------------------------------------------ */ public boolean isDefaultDispatches() { return _dispatches==0; } /* ------------------------------------------------------------ */ /** * @return Returns the filterName. */ @ManagedAttribute(value="filter name", readonly=true) public String getFilterName() { return _filterName; } /* ------------------------------------------------------------ */ /** * @return Returns the holder. */ FilterHolder getFilterHolder() { return _holder; } /* ------------------------------------------------------------ */ /** * @return Returns the pathSpec. */ @ManagedAttribute(value="url patterns", readonly=true) public String[] getPathSpecs() { return _pathSpecs; } /* ------------------------------------------------------------ */ public void setDispatcherTypes(EnumSet<DispatcherType> dispatcherTypes) { _dispatches=DEFAULT; if (dispatcherTypes!=null) { if (dispatcherTypes.contains(DispatcherType.ERROR)) _dispatches|=ERROR; if (dispatcherTypes.contains(DispatcherType.FORWARD)) _dispatches|=FORWARD; if (dispatcherTypes.contains(DispatcherType.INCLUDE)) _dispatches|=INCLUDE; if (dispatcherTypes.contains(DispatcherType.REQUEST)) _dispatches|=REQUEST; if (dispatcherTypes.contains(DispatcherType.ASYNC)) _dispatches|=ASYNC; } } /* ------------------------------------------------------------ */ public EnumSet<DispatcherType> getDispatcherTypes() { EnumSet<DispatcherType> dispatcherTypes = EnumSet.noneOf(DispatcherType.class); if ((_dispatches & ERROR) == ERROR) dispatcherTypes.add(DispatcherType.ERROR); if ((_dispatches & FORWARD) == FORWARD) dispatcherTypes.add(DispatcherType.FORWARD); if ((_dispatches & INCLUDE) == INCLUDE) dispatcherTypes.add(DispatcherType.INCLUDE); if ((_dispatches & REQUEST) == REQUEST) dispatcherTypes.add(DispatcherType.REQUEST); if ((_dispatches & ASYNC) == ASYNC) dispatcherTypes.add(DispatcherType.ASYNC); return dispatcherTypes; } /* ------------------------------------------------------------ */ /** * @param dispatches The dispatches to set. * @see #DEFAULT * @see #REQUEST * @see #ERROR * @see #FORWARD * @see #INCLUDE */ public void setDispatches(int dispatches) { _dispatches = dispatches; } /* ------------------------------------------------------------ */ /** * @param filterName The filterName to set. */ public void setFilterName(String filterName) { _filterName = filterName; } /* ------------------------------------------------------------ */ /** * @param holder The holder to set. */ void setFilterHolder(FilterHolder holder) { _holder = holder; setFilterName(holder.getName()); } /* ------------------------------------------------------------ */ /** * @param pathSpecs The Path specifications to which this filter should be mapped. */ public void setPathSpecs(String[] pathSpecs) { _pathSpecs = pathSpecs; } /* ------------------------------------------------------------ */ /** * @param pathSpec The pathSpec to set. */ public void setPathSpec(String pathSpec) { _pathSpecs = new String[]{pathSpec}; } /* ------------------------------------------------------------ */ /** * @return Returns the servletName. */ @ManagedAttribute(value="servlet names", readonly=true) public String[] getServletNames() { return _servletNames; } /* ------------------------------------------------------------ */ /** * @param servletNames Maps the {@link #setFilterName(String) named filter} to multiple servlets * @see #setServletName */ public void setServletNames(String[] servletNames) { _servletNames = servletNames; } /* ------------------------------------------------------------ */ /** * @param servletName Maps the {@link #setFilterName(String) named filter} to a single servlet * @see #setServletNames */ public void setServletName(String servletName) { _servletNames = new String[]{servletName}; } /* ------------------------------------------------------------ */ public String toString() { return TypeUtil.asList(_pathSpecs)+"/"+ TypeUtil.asList(_servletNames)+"=="+ _dispatches+"=>"+ _filterName; } /* ------------------------------------------------------------ */ public void dump(Appendable out, String indent) throws IOException { out.append(String.valueOf(this)).append("\n"); } /* ------------------------------------------------------------ */ public String dump() { return ContainerLifeCycle.dump(this); } }