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  /**
35   * @author Manfred Geiler (latest modification by $Author: bommel $)
36   * @version $Revision: 1187700 $ $Date: 2011-10-22 07:19:37 -0500 (Sat, 22 Oct 2011) $
37   */
38  public class WebXml
39  {
40      //private static final Log log = LogFactory.getLog(WebXml.class);
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) return _facesServletMappings;
117 
118         List tempFacesServletMappings = new ArrayList();
119         for (Iterator it = _servlets.entrySet().iterator(); it.hasNext(); )
120         {
121             Map.Entry entry = (Map.Entry)it.next();
122             String servletName = (String)entry.getKey();
123             if (null == entry.getValue())
124             {
125                 // the value is null in the case of jsp files listed as servlets
126                 // in cactus
127                 // <servlet>
128                 //   <servlet-name>JspRedirector</servlet-name>
129                 //   <jsp-file>/jspRedirector.jsp</jsp-file>
130                 // </servlet>
131                 continue;
132             }
133             Class servletClass = org.apache.myfaces.shared.util.ClassUtils.simpleClassForName((String)entry.getValue());
134             if (FacesServlet.class.isAssignableFrom(servletClass) ||
135                     DelegatedFacesServlet.class.isAssignableFrom(servletClass) ||
136                     servletClass.getName().equals(_delegateFacesServlet))
137             {
138                 List urlPatterns = (List)_servletMappings.get(servletName);
139                 if( urlPatterns != null )
140                 {
141                     for (Iterator it2 = urlPatterns.iterator(); it2.hasNext(); )
142                     {
143                         String urlpattern = (String)it2.next();
144                         tempFacesServletMappings.add(new org.apache.myfaces.shared.webapp.webxml.ServletMapping(servletName,
145                                                                                                              servletClass,
146                                                                                                              urlpattern));
147                         if (log.isLoggable(Level.FINEST))
148                             log.finest("adding mapping for servlet + " + servletName + " urlpattern = " + urlpattern);
149                     }
150                 }
151             }
152             else
153             {
154                 if (log.isLoggable(Level.FINEST)) log.finest("ignoring servlet + " + servletName + " " + servletClass + " (no FacesServlet)");
155             }
156         }
157         
158         //Expose to all threads
159         _facesServletMappings = tempFacesServletMappings;
160         
161         return _facesServletMappings;
162     }
163 
164     /**
165      * returns a list of {@see #org.apache.myfaces.shared.webapp.webxml.FilterMapping}s representing a
166      * extensions filter entry
167      */
168     public List getFacesExtensionsFilterMappings()
169     {
170         if (_facesExtensionsFilterMappings != null) return _facesExtensionsFilterMappings;
171 
172         List tempExtensionsFilterMappings = new ArrayList();
173         for (Iterator it = _filters.entrySet().iterator(); it.hasNext(); )
174         {
175             Map.Entry entry = (Map.Entry)it.next();
176             String filterName = (String)entry.getKey();
177             String filterClassName = (String)entry.getValue();
178             
179             if (!"org.apache.myfaces.component.html.util.ExtensionsFilter".equals(filterClassName) &&
180                 !"org.apache.myfaces.webapp.filter.ExtensionsFilter".equals(filterClassName))
181             {
182                 // not an extensions filter
183                 continue;
184             }
185             
186             Class filterClass = org.apache.myfaces.shared.util.ClassUtils.simpleClassForName(filterClassName);
187             List urlPatterns = (List)_filterMappings.get(filterName);
188             if( urlPatterns != null )
189             {
190                 for (Iterator it2 = urlPatterns.iterator(); it2.hasNext(); )
191                 {
192                     String urlpattern = (String)it2.next();
193                     tempExtensionsFilterMappings.add(new org.apache.myfaces.shared.webapp.webxml.FilterMapping(
194                         filterName, filterClass, urlpattern));
195                     if (log.isLoggable(Level.FINEST))
196                         log.finest("adding mapping for filter + " + filterName + " urlpattern = " + urlpattern);
197                 }
198             }
199         }
200         
201         //Expose to all threads
202         _facesExtensionsFilterMappings = tempExtensionsFilterMappings;
203         
204         return _facesExtensionsFilterMappings;
205     }
206 
207     protected void setParsingTime(long parsingTime)
208     {
209         this.parsingTime = parsingTime;
210     }
211     
212     private void setDelegateFacesServlet(String delegateFacesServlet)
213     {
214         this._delegateFacesServlet = delegateFacesServlet;
215     }
216     
217     /**
218      * Sets if, the web.xml contains an error-page entry
219      * @param errorPagePresent
220      */
221     public void setErrorPagePresent(boolean errorPagePresent)
222     {
223         this.errorPagePresent = errorPagePresent;
224     }
225     
226     /**
227      * Determines, if the web.xml contains an error-page entry
228      * @return
229      */
230     public boolean isErrorPagePresent()
231     {
232         return errorPagePresent;
233     }
234 
235     protected boolean isOld(ExternalContext context)
236     {
237         if (refreshPeriod > 0) {
238             long ttl = this.parsingTime + refreshPeriod;
239             if (System.currentTimeMillis() > ttl) {
240                 long lastModified = WebXmlParser.getWebXmlLastModified(context);
241                 return lastModified == 0 || lastModified > ttl;
242             }
243         }
244         return false;
245     }
246 
247     private static final String WEB_XML_ATTR = WebXml.class.getName();
248     public static WebXml getWebXml(ExternalContext context)
249     {
250         WebXml webXml = (WebXml)context.getApplicationMap().get(WEB_XML_ATTR);
251         if (webXml == null)
252         {
253             init(context);
254             webXml = (WebXml)context.getApplicationMap().get(WEB_XML_ATTR);
255         }
256         return webXml;
257     }
258 
259     /**
260      * should be called when initialising Servlet
261      * @param context
262      */
263     public static void init(ExternalContext context)
264     {
265         WebXmlParser parser = new WebXmlParser(context);
266         WebXml webXml = parser.parse();
267         context.getApplicationMap().put(WEB_XML_ATTR, webXml);
268         MyfacesConfig mfconfig = MyfacesConfig.getCurrentInstance(context);
269         long configRefreshPeriod = mfconfig.getConfigRefreshPeriod();
270         webXml.setParsingTime(System.currentTimeMillis());
271         webXml.setDelegateFacesServlet(mfconfig.getDelegateFacesServlet());
272         refreshPeriod = (configRefreshPeriod * 1000);
273     }
274 
275     public static void update(ExternalContext context)
276     {
277         if (getWebXml(context).isOld(context)){
278             WebXml.init(context);
279         }
280     }
281 
282 }