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 Log log = LogFactory.getLog(WebXml.class);
42      private static final Logger log = Logger.getLogger(WebXml.class.getName());
43  
44  
45      private static long refreshPeriod;
46      private long parsingTime;
47  
48      private Map _servlets = new HashMap();
49      private Map _servletMappings = new HashMap();
50      private Map _filters = new HashMap();
51      private Map _filterMappings = new HashMap();
52  
53      private volatile List _facesServletMappings = null;
54      private volatile List _facesExtensionsFilterMappings = null;
55      
56      private String _delegateFacesServlet = null;
57      private boolean errorPagePresent = false;
58  
59      void addServlet(String servletName, String servletClass)
60      {
61          if (_servlets.get(servletName) != null)
62          {
63              log.warning("Servlet " + servletName + " defined more than once, first definition will be used.");
64          }
65          else
66          {
67              _servlets.put(servletName, servletClass);
68          }
69      }
70  
71      void addFilter(String filterName, String filterClass)
72      {
73          if (_filters.get(filterName) != null)
74          {
75              log.warning("Filter " + filterName + " defined more than once, first definition will be used.");
76          }
77          else
78          {
79              _filters.put(filterName, filterClass);
80          }
81      }
82  
83      boolean containsServlet(String servletName)
84      {
85          return _servlets.containsKey(servletName);
86      }
87  
88      boolean containsFilter(String filterName)
89      {
90          return _filters.containsKey(filterName);
91      }
92  
93      void addServletMapping(String servletName, String urlPattern)
94      {
95          List mappings = (List)_servletMappings.get(servletName);
96          if (mappings == null)
97          {
98              mappings = new ArrayList();
99              _servletMappings.put(servletName, mappings);
100         }
101         mappings.add(urlPattern);
102     }
103 
104     void addFilterMapping(String filterName, String urlPattern)
105     {
106         List mappings = (List)_filterMappings.get(filterName);
107         if (mappings == null)
108         {
109             mappings = new ArrayList();
110             _filterMappings.put(filterName, mappings);
111         }
112         mappings.add(urlPattern);
113     }
114 
115     public List getFacesServletMappings()
116     {
117         if (_facesServletMappings != null)
118         {
119             return _facesServletMappings;
120         }
121 
122         List tempFacesServletMappings = new ArrayList();
123         for (Iterator it = _servlets.entrySet().iterator(); it.hasNext(); )
124         {
125             Map.Entry entry = (Map.Entry)it.next();
126             String servletName = (String)entry.getKey();
127             if (null == entry.getValue())
128             {
129                 // the value is null in the case of jsp files listed as servlets
130                 // in cactus
131                 // <servlet>
132                 //   <servlet-name>JspRedirector</servlet-name>
133                 //   <jsp-file>/jspRedirector.jsp</jsp-file>
134                 // </servlet>
135                 continue;
136             }
137 
138             Class servletClass = ClassUtils.simpleClassForName((String) entry.getValue(), false);
139             if (servletClass == null)
140             {
141                 if (log.isLoggable(Level.FINEST))
142                 {
143                     log.finest("ignoring servlet " + servletName + " because its class could not be loaded");
144                 }
145                 continue;
146             }
147 
148             if (FacesServlet.class.isAssignableFrom(servletClass) ||
149                     DelegatedFacesServlet.class.isAssignableFrom(servletClass) ||
150                     servletClass.getName().equals(_delegateFacesServlet))
151             {
152                 List urlPatterns = (List)_servletMappings.get(servletName);
153                 if( urlPatterns != null )
154                 {
155                     for (Iterator it2 = urlPatterns.iterator(); it2.hasNext(); )
156                     {
157                         String urlpattern = (String)it2.next();
158                         tempFacesServletMappings.add(new ServletMapping(servletName, servletClass, urlpattern));
159                         if (log.isLoggable(Level.FINEST))
160                         {
161                             log.finest("adding mapping for servlet + " + servletName + " urlpattern = " + urlpattern);
162                         }
163                     }
164                 }
165             }
166             else
167             {
168                 if (log.isLoggable(Level.FINEST))
169                 {
170                     log.finest("ignoring servlet + " + servletName + " " + servletClass + " (no FacesServlet)");
171                 }
172             }
173         }
174         
175         //Expose to all threads
176         _facesServletMappings = tempFacesServletMappings;
177         
178         return _facesServletMappings;
179     }
180 
181     /**
182      * returns a list of {@see #org.apache.myfaces.shared_impl.webapp.webxml.FilterMapping}s representing a
183      * extensions filter entry
184      */
185     public List getFacesExtensionsFilterMappings()
186     {
187         if (_facesExtensionsFilterMappings != null)
188         {
189             return _facesExtensionsFilterMappings;
190         }
191 
192         List tempExtensionsFilterMappings = new ArrayList();
193         for (Iterator it = _filters.entrySet().iterator(); it.hasNext(); )
194         {
195             Map.Entry entry = (Map.Entry)it.next();
196             String filterName = (String)entry.getKey();
197             String filterClassName = (String)entry.getValue();
198             
199             if (!"org.apache.myfaces.component.html.util.ExtensionsFilter".equals(filterClassName) &&
200                 !"org.apache.myfaces.webapp.filter.ExtensionsFilter".equals(filterClassName))
201             {
202                 // not an extensions filter
203                 continue;
204             }
205             
206             Class filterClass = org.apache.myfaces.shared.util.ClassUtils.simpleClassForName(filterClassName);
207             List urlPatterns = (List)_filterMappings.get(filterName);
208             if( urlPatterns != null )
209             {
210                 for (Iterator it2 = urlPatterns.iterator(); it2.hasNext(); )
211                 {
212                     String urlpattern = (String)it2.next();
213                     tempExtensionsFilterMappings.add(new org.apache.myfaces.shared_impl.webapp.webxml.FilterMapping(
214                         filterName, filterClass, urlpattern));
215                     if (log.isLoggable(Level.FINEST))
216                     {
217                         log.finest("adding mapping for filter + " + filterName + " urlpattern = " + urlpattern);
218                     }
219                 }
220             }
221         }
222         
223         //Expose to all threads
224         _facesExtensionsFilterMappings = tempExtensionsFilterMappings;
225         
226         return _facesExtensionsFilterMappings;
227     }
228 
229     protected void setParsingTime(long parsingTime)
230     {
231         this.parsingTime = parsingTime;
232     }
233     
234     private void setDelegateFacesServlet(String delegateFacesServlet)
235     {
236         this._delegateFacesServlet = delegateFacesServlet;
237     }
238     
239     /**
240      * Sets if, the web.xml contains an error-page entry
241      * @param errorPagePresent
242      */
243     public void setErrorPagePresent(boolean errorPagePresent)
244     {
245         this.errorPagePresent = errorPagePresent;
246     }
247     
248     /**
249      * Determines, if the web.xml contains an error-page entry
250      * @return
251      */
252     public boolean isErrorPagePresent()
253     {
254         return errorPagePresent;
255     }
256 
257     protected boolean isOld(ExternalContext context)
258     {
259         if (refreshPeriod > 0)
260         {
261             long ttl = this.parsingTime + refreshPeriod;
262             if (System.currentTimeMillis() > ttl)
263             {
264                 long lastModified = WebXmlParser.getWebXmlLastModified(context);
265                 return lastModified == 0 || lastModified > ttl;
266             }
267         }
268         return false;
269     }
270 
271     private static final String WEB_XML_ATTR = WebXml.class.getName();
272     public static WebXml getWebXml(ExternalContext context)
273     {
274         WebXml webXml = (WebXml)context.getApplicationMap().get(WEB_XML_ATTR);
275         if (webXml == null)
276         {
277             init(context);
278             webXml = (WebXml)context.getApplicationMap().get(WEB_XML_ATTR);
279         }
280         return webXml;
281     }
282 
283     /**
284      * should be called when initialising Servlet
285      * @param context
286      */
287     public static void init(ExternalContext context)
288     {
289         WebXmlParser parser = new WebXmlParser(context);
290         WebXml webXml = parser.parse();
291         context.getApplicationMap().put(WEB_XML_ATTR, webXml);
292         MyfacesConfig mfconfig = MyfacesConfig.getCurrentInstance(context);
293         long configRefreshPeriod = mfconfig.getConfigRefreshPeriod();
294         webXml.setParsingTime(System.currentTimeMillis());
295         webXml.setDelegateFacesServlet(mfconfig.getDelegateFacesServlet());
296         refreshPeriod = (configRefreshPeriod * 1000);
297     }
298 
299     public static void update(ExternalContext context)
300     {
301         if (getWebXml(context).isOld(context))
302         {
303             WebXml.init(context);
304         }
305     }
306 
307 }