View Javadoc

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