View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.shared_impl.webapp.webxml;
20  
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.logging.Level;
27  import java.util.logging.Logger;
28  
29  import javax.faces.context.ExternalContext;
30  import javax.faces.webapp.FacesServlet;
31  
32  import org.apache.myfaces.shared.config.MyfacesConfig;
33  import org.apache.myfaces.shared.util.ClassUtils;
34  
35  /**
36   * @author Manfred Geiler (latest modification by $Author$)
37   * @version $Revision$ $Date$
38   */
39  public class WebXml
40  {
41      private static final Logger log = Logger.getLogger(WebXml.class.getName());
42  
43  
44      private static long refreshPeriod;
45      private long parsingTime;
46  
47      private Map _servlets = new HashMap();
48      private Map _servletMappings = new HashMap();
49      private Map _filters = new HashMap();
50      private Map _filterMappings = new HashMap();
51  
52      private volatile List _facesServletMappings = null;
53      private volatile List _facesExtensionsFilterMappings = null;
54      
55      private String _delegateFacesServlet = null;
56      private boolean errorPagePresent = false;
57  
58      void addServlet(String servletName, String servletClass)
59      {
60          if (_servlets.get(servletName) != null)
61          {
62              log.warning("Servlet " + servletName + " defined more than once, first definition will be used.");
63          }
64          else
65          {
66              _servlets.put(servletName, servletClass);
67          }
68      }
69  
70      void addFilter(String filterName, String filterClass)
71      {
72          if (_filters.get(filterName) != null)
73          {
74              log.warning("Filter " + filterName + " defined more than once, first definition will be used.");
75          }
76          else
77          {
78              _filters.put(filterName, filterClass);
79          }
80      }
81  
82      boolean containsServlet(String servletName)
83      {
84          return _servlets.containsKey(servletName);
85      }
86  
87      boolean containsFilter(String filterName)
88      {
89          return _filters.containsKey(filterName);
90      }
91  
92      void addServletMapping(String servletName, String urlPattern)
93      {
94          List mappings = (List)_servletMappings.get(servletName);
95          if (mappings == null)
96          {
97              mappings = new ArrayList();
98              _servletMappings.put(servletName, mappings);
99          }
100         mappings.add(urlPattern);
101     }
102 
103     void addFilterMapping(String filterName, String urlPattern)
104     {
105         List mappings = (List)_filterMappings.get(filterName);
106         if (mappings == null)
107         {
108             mappings = new ArrayList();
109             _filterMappings.put(filterName, mappings);
110         }
111         mappings.add(urlPattern);
112     }
113 
114     public List getFacesServletMappings()
115     {
116         if (_facesServletMappings != null)
117         {
118             return _facesServletMappings;
119         }
120 
121         List tempFacesServletMappings = new ArrayList();
122         for (Iterator it = _servlets.entrySet().iterator(); it.hasNext(); )
123         {
124             Map.Entry entry = (Map.Entry)it.next();
125             String servletName = (String)entry.getKey();
126             if (null == entry.getValue())
127             {
128                 // the value is null in the case of jsp files listed as servlets
129                 // in cactus
130                 // <servlet>
131                 //   <servlet-name>JspRedirector</servlet-name>
132                 //   <jsp-file>/jspRedirector.jsp</jsp-file>
133                 // </servlet>
134                 continue;
135             }
136 
137             Class servletClass = ClassUtils.simpleClassForName((String) entry.getValue(), false);
138             if (servletClass == null)
139             {
140                 if (log.isLoggable(Level.FINEST))
141                 {
142                     log.finest("ignoring servlet " + servletName + " because its class could not be loaded");
143                 }
144                 continue;
145             }
146 
147             if (FacesServlet.class.isAssignableFrom(servletClass) ||
148                     DelegatedFacesServlet.class.isAssignableFrom(servletClass) ||
149                     servletClass.getName().equals(_delegateFacesServlet))
150             {
151                 List urlPatterns = (List)_servletMappings.get(servletName);
152                 if( urlPatterns != null )
153                 {
154                     for (Iterator it2 = urlPatterns.iterator(); it2.hasNext(); )
155                     {
156                         String urlpattern = (String)it2.next();
157                         tempFacesServletMappings.add(new ServletMapping(servletName, servletClass, urlpattern));
158                         if (log.isLoggable(Level.FINEST))
159                         {
160                             log.finest("adding mapping for servlet + " + servletName + " urlpattern = " + urlpattern);
161                         }
162                     }
163                 }
164             }
165             else
166             {
167                 if (log.isLoggable(Level.FINEST))
168                 {
169                     log.finest("ignoring servlet + " + servletName + " " + servletClass + " (no FacesServlet)");
170                 }
171             }
172         }
173         
174         //Expose to all threads
175         _facesServletMappings = tempFacesServletMappings;
176         
177         return _facesServletMappings;
178     }
179 
180     /**
181      * returns a list of org.apache.myfaces.shared_impl.webapp.webxml.FilterMapping representing a
182      * extensions filter entry
183      */
184     public List getFacesExtensionsFilterMappings()
185     {
186         if (_facesExtensionsFilterMappings != null)
187         {
188             return _facesExtensionsFilterMappings;
189         }
190 
191         List tempExtensionsFilterMappings = new ArrayList();
192         for (Iterator it = _filters.entrySet().iterator(); it.hasNext(); )
193         {
194             Map.Entry entry = (Map.Entry)it.next();
195             String filterName = (String)entry.getKey();
196             String filterClassName = (String)entry.getValue();
197             
198             if (!"org.apache.myfaces.component.html.util.ExtensionsFilter".equals(filterClassName) &&
199                 !"org.apache.myfaces.webapp.filter.ExtensionsFilter".equals(filterClassName))
200             {
201                 // not an extensions filter
202                 continue;
203             }
204             
205             Class filterClass = org.apache.myfaces.shared.util.ClassUtils.simpleClassForName(filterClassName);
206             List urlPatterns = (List)_filterMappings.get(filterName);
207             if( urlPatterns != null )
208             {
209                 for (Iterator it2 = urlPatterns.iterator(); it2.hasNext(); )
210                 {
211                     String urlpattern = (String)it2.next();
212                     tempExtensionsFilterMappings.add(new org.apache.myfaces.shared_impl.webapp.webxml.FilterMapping(
213                         filterName, filterClass, urlpattern));
214                     if (log.isLoggable(Level.FINEST))
215                     {
216                         log.finest("adding mapping for filter + " + filterName + " urlpattern = " + urlpattern);
217                     }
218                 }
219             }
220         }
221         
222         //Expose to all threads
223         _facesExtensionsFilterMappings = tempExtensionsFilterMappings;
224         
225         return _facesExtensionsFilterMappings;
226     }
227 
228     protected void setParsingTime(long parsingTime)
229     {
230         this.parsingTime = parsingTime;
231     }
232     
233     private void setDelegateFacesServlet(String delegateFacesServlet)
234     {
235         this._delegateFacesServlet = delegateFacesServlet;
236     }
237     
238     /**
239      * Sets if, the web.xml contains an error-page entry
240      * @param errorPagePresent
241      */
242     public void setErrorPagePresent(boolean errorPagePresent)
243     {
244         this.errorPagePresent = errorPagePresent;
245     }
246     
247     /**
248      * Determines, if the web.xml contains an error-page entry
249      * @return
250      */
251     public boolean isErrorPagePresent()
252     {
253         return errorPagePresent;
254     }
255 
256     protected boolean isOld(ExternalContext context)
257     {
258         if (refreshPeriod > 0)
259         {
260             long ttl = this.parsingTime + refreshPeriod;
261             if (System.currentTimeMillis() > ttl)
262             {
263                 long lastModified = WebXmlParser.getWebXmlLastModified(context);
264                 return lastModified == 0 || lastModified > ttl;
265             }
266         }
267         return false;
268     }
269 
270     private static final String WEB_XML_ATTR = WebXml.class.getName();
271     public static WebXml getWebXml(ExternalContext context)
272     {
273         WebXml webXml = (WebXml)context.getApplicationMap().get(WEB_XML_ATTR);
274         if (webXml == null)
275         {
276             init(context);
277             webXml = (WebXml)context.getApplicationMap().get(WEB_XML_ATTR);
278         }
279         return webXml;
280     }
281 
282     /**
283      * should be called when initialising Servlet
284      * @param context
285      */
286     public static void init(ExternalContext context)
287     {
288         WebXmlParser parser = new WebXmlParser(context);
289         WebXml webXml = parser.parse();
290         context.getApplicationMap().put(WEB_XML_ATTR, webXml);
291         MyfacesConfig mfconfig = MyfacesConfig.getCurrentInstance(context);
292         long configRefreshPeriod = mfconfig.getConfigRefreshPeriod();
293         webXml.setParsingTime(System.currentTimeMillis());
294         webXml.setDelegateFacesServlet(mfconfig.getDelegateFacesServlet());
295         refreshPeriod = (configRefreshPeriod * 1000);
296     }
297 
298     public static void update(ExternalContext context)
299     {
300         if (getWebXml(context).isOld(context))
301         {
302             WebXml.init(context);
303         }
304     }
305 
306 }