View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.servlet;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.Collection;
25  import java.util.EnumSet;
26  import java.util.List;
27  
28  import javax.servlet.DispatcherType;
29  import javax.servlet.Filter;
30  import javax.servlet.FilterConfig;
31  import javax.servlet.FilterRegistration;
32  import javax.servlet.ServletContext;
33  import javax.servlet.ServletException;
34  
35  import org.eclipse.jetty.util.TypeUtil;
36  import org.eclipse.jetty.util.component.Dumpable;
37  import org.eclipse.jetty.util.log.Log;
38  import org.eclipse.jetty.util.log.Logger;
39  
40  /* --------------------------------------------------------------------- */
41  /**
42   *
43   */
44  public class FilterHolder extends Holder<Filter>
45  {
46      private static final Logger LOG = Log.getLogger(FilterHolder.class);
47  
48      /* ------------------------------------------------------------ */
49      private transient Filter _filter;
50      private transient Config _config;
51      private transient FilterRegistration.Dynamic _registration;
52  
53      /* ---------------------------------------------------------------- */
54      /** Constructor
55       */
56      public FilterHolder()
57      {
58          this(Source.EMBEDDED);
59      }
60  
61  
62      /* ---------------------------------------------------------------- */
63      /** Constructor
64       */
65      public FilterHolder(Holder.Source source)
66      {
67          super(source);
68      }
69  
70      /* ---------------------------------------------------------------- */
71      /** Constructor
72       */
73      public FilterHolder(Class<? extends Filter> filter)
74      {
75          this(Source.EMBEDDED);
76          setHeldClass(filter);
77      }
78  
79      /* ---------------------------------------------------------------- */
80      /** Constructor for existing filter.
81       */
82      public FilterHolder(Filter filter)
83      {
84          this(Source.EMBEDDED);
85          setFilter(filter);
86      }
87  
88      /* ------------------------------------------------------------ */
89      @Override
90      public void doStart()
91          throws Exception
92      {
93          super.doStart();
94  
95          if (!javax.servlet.Filter.class
96              .isAssignableFrom(_class))
97          {
98              String msg = _class+" is not a javax.servlet.Filter";
99              super.stop();
100             throw new IllegalStateException(msg);
101         }
102     }
103     
104     
105     
106 
107 
108 
109     /* ------------------------------------------------------------ */
110     @Override
111     public void initialize() throws Exception
112     {
113         super.initialize();
114         
115         if (_filter==null)
116         {
117             try
118             {
119                 ServletContext context=_servletHandler.getServletContext();
120                 _filter=(context instanceof ServletContextHandler.Context)
121                     ?((ServletContextHandler.Context)context).createFilter(getHeldClass())
122                     :getHeldClass().newInstance();
123             }
124             catch (ServletException se)
125             {
126                 Throwable cause = se.getRootCause();
127                 if (cause instanceof InstantiationException)
128                     throw (InstantiationException)cause;
129                 if (cause instanceof IllegalAccessException)
130                     throw (IllegalAccessException)cause;
131                 throw se;
132             }
133         }
134 
135         _config=new Config();
136         if (LOG.isDebugEnabled())
137             LOG.debug("Filter.init {}",_filter);
138         _filter.init(_config);
139     }
140 
141 
142     /* ------------------------------------------------------------ */
143     @Override
144     public void doStop()
145         throws Exception
146     {
147         if (_filter!=null)
148         {
149             try
150             {
151                 destroyInstance(_filter);
152             }
153             catch (Exception e)
154             {
155                 LOG.warn(e);
156             }
157         }
158         if (!_extInstance)
159             _filter=null;
160 
161         _config=null;
162         super.doStop();
163     }
164 
165     /* ------------------------------------------------------------ */
166     @Override
167     public void destroyInstance (Object o)
168         throws Exception
169     {
170         if (o==null)
171             return;
172         Filter f = (Filter)o;
173         f.destroy();
174         getServletHandler().destroyFilter(f);
175     }
176 
177     /* ------------------------------------------------------------ */
178     public synchronized void setFilter(Filter filter)
179     {
180         _filter=filter;
181         _extInstance=true;
182         setHeldClass(filter.getClass());
183         if (getName()==null)
184             setName(filter.getClass().getName());
185     }
186 
187     /* ------------------------------------------------------------ */
188     public Filter getFilter()
189     {
190         return _filter;
191     }
192 
193     /* ------------------------------------------------------------ */
194     @Override
195     public String toString()
196     {
197         return getName();
198     }
199     
200     /* ------------------------------------------------------------ */
201     @Override
202     public void dump(Appendable out, String indent) throws IOException
203     {
204         super.dump(out, indent);
205         if(_filter instanceof Dumpable) {
206             ((Dumpable) _filter).dump(out, indent);
207         }
208     }
209 
210     /* ------------------------------------------------------------ */
211     public FilterRegistration.Dynamic getRegistration()
212     {
213         if (_registration == null)
214             _registration = new Registration();
215         return _registration;
216     }
217 
218     /* ------------------------------------------------------------ */
219     /* ------------------------------------------------------------ */
220     /* ------------------------------------------------------------ */
221     protected class Registration extends HolderRegistration implements FilterRegistration.Dynamic
222     {
223         public void addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... servletNames)
224         {
225             illegalStateIfContextStarted();
226             FilterMapping mapping = new FilterMapping();
227             mapping.setFilterHolder(FilterHolder.this);
228             mapping.setServletNames(servletNames);
229             mapping.setDispatcherTypes(dispatcherTypes);
230             if (isMatchAfter)
231                 _servletHandler.addFilterMapping(mapping);
232             else
233                 _servletHandler.prependFilterMapping(mapping);
234         }
235 
236         public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... urlPatterns)
237         {
238             illegalStateIfContextStarted();
239             FilterMapping mapping = new FilterMapping();
240             mapping.setFilterHolder(FilterHolder.this);
241             mapping.setPathSpecs(urlPatterns);
242             mapping.setDispatcherTypes(dispatcherTypes);
243             if (isMatchAfter)
244                 _servletHandler.addFilterMapping(mapping);
245             else
246                 _servletHandler.prependFilterMapping(mapping);
247         }
248 
249         public Collection<String> getServletNameMappings()
250         {
251             FilterMapping[] mappings =_servletHandler.getFilterMappings();
252             List<String> names=new ArrayList<String>();
253             for (FilterMapping mapping : mappings)
254             {
255                 if (mapping.getFilterHolder()!=FilterHolder.this)
256                     continue;
257                 String[] servlets=mapping.getServletNames();
258                 if (servlets!=null && servlets.length>0)
259                     names.addAll(Arrays.asList(servlets));
260             }
261             return names;
262         }
263 
264         public Collection<String> getUrlPatternMappings()
265         {
266             FilterMapping[] mappings =_servletHandler.getFilterMappings();
267             List<String> patterns=new ArrayList<String>();
268             for (FilterMapping mapping : mappings)
269             {
270                 if (mapping.getFilterHolder()!=FilterHolder.this)
271                     continue;
272                 String[] specs=mapping.getPathSpecs();
273                 patterns.addAll(TypeUtil.asList(specs));
274             }
275             return patterns;
276         }
277     }
278 
279     /* ------------------------------------------------------------ */
280     /* ------------------------------------------------------------ */
281     /* ------------------------------------------------------------ */
282     class Config extends HolderConfig implements FilterConfig
283     {
284         /* ------------------------------------------------------------ */
285         public String getFilterName()
286         {
287             return _name;
288         }
289     }
290 }