View Javadoc

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