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