You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by im...@apache.org on 2006/04/11 08:37:15 UTC

svn commit: r393150 - in /myfaces: shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/ tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/

Author: imario
Date: Mon Apr 10 23:37:13 2006
New Revision: 393150

URL: http://svn.apache.org/viewcvs?rev=393150&view=rev
Log:
replaced my web.xml parsing by the default myfaces one (should have done this earlier)

Added:
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/FilterMapping.java   (with props)
Removed:
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/WebXmlFilterHandler.java
Modified:
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXml.java
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXmlParser.java
    myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/AddResourceFactory.java

Added: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/FilterMapping.java
URL: http://svn.apache.org/viewcvs/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/FilterMapping.java?rev=393150&view=auto
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/FilterMapping.java (added)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/FilterMapping.java Mon Apr 10 23:37:13 2006
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.myfaces.shared.webapp.webxml;
+
+/**
+ * @author Mario Ivankovits (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class FilterMapping
+{
+    private String _filterName;
+    private Class _filterClass;
+    private String _urlPattern;
+    private boolean _isExtensionMapping = false;
+
+    public FilterMapping(String filterName,
+                          Class filterClass,
+                          String urlPattern)
+    {
+        _filterName = filterName;
+        _filterClass = filterClass;
+        _urlPattern = urlPattern;
+        if (_urlPattern != null)
+        {
+            if (_urlPattern.startsWith("*."))
+            {
+                _isExtensionMapping = true;
+            }
+        }
+    }
+
+    public boolean isExtensionMapping()
+    {
+        return _isExtensionMapping;
+    }
+
+    public String getFilterName()
+    {
+        return _filterName;
+    }
+
+    public Class getFilterClass()
+    {
+        return _filterClass;
+    }
+
+    public String getUrlPattern()
+    {
+        return _urlPattern;
+    }
+}

Propchange: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/FilterMapping.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/FilterMapping.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/FilterMapping.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXml.java
URL: http://svn.apache.org/viewcvs/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXml.java?rev=393150&r1=393149&r2=393150&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXml.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXml.java Mon Apr 10 23:37:13 2006
@@ -36,7 +36,11 @@
 
     private Map _servlets = new HashMap();
     private Map _servletMappings = new HashMap();
+    private Map _filters = new HashMap();
+    private Map _filterMappings = new HashMap();
+    
     private List _facesServletMappings = null;
+    private List _facesExtensionsFilterMappings = null;
 
     void addServlet(String servletName, String servletClass)
     {
@@ -50,11 +54,28 @@
         }
     }
 
+    void addFilter(String filterName, String filterClass)
+    {
+        if (_filters.get(filterName) != null)
+        {
+            log.warn("Filter " + filterName + " defined more than once, first definition will be used.");
+        }
+        else
+        {
+            _filters.put(filterName, filterClass);
+        }
+    }
+    
     boolean containsServlet(String servletName)
     {
         return _servlets.containsKey(servletName);
     }
 
+    boolean containsFilter(String filterName)
+    {
+        return _filters.containsKey(filterName);
+    }
+    
     void addServletMapping(String servletName, String urlPattern)
     {
         List mappings = (List)_servletMappings.get(servletName);
@@ -66,6 +87,17 @@
         mappings.add(urlPattern);
     }
 
+    void addFilterMapping(String filterName, String urlPattern)
+    {
+        List mappings = (List)_filterMappings.get(filterName);
+        if (mappings == null)
+        {
+            mappings = new ArrayList();
+            _filterMappings.put(filterName, mappings);
+        }
+        mappings.add(urlPattern);
+    }
+    
     public List getFacesServletMappings()
     {
         if (_facesServletMappings != null) return _facesServletMappings;
@@ -111,6 +143,44 @@
         return _facesServletMappings;
     }
 
+    /**
+     * returns a list of {@see #org.apache.myfaces.shared.webapp.webxml.FilterMapping}s representing a
+     * extensions filter entry
+     */
+    public List getFacesExtensionsFilterMappings()
+    {
+        if (_facesExtensionsFilterMappings != null) return _facesExtensionsFilterMappings;
+
+        _facesExtensionsFilterMappings = new ArrayList();
+        for (Iterator it = _filters.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry)it.next();
+            String filterName = (String)entry.getKey();
+            String filterClassName = (String)entry.getValue();
+            
+    		if (!"org.apache.myfaces.component.html.util.ExtensionsFilter".equals(filterClassName) &&
+    			!"org.apache.myfaces.webapp.filter.ExtensionsFilter".equals(filterClassName))
+    		{
+    			// not an extensions filter
+    			continue;
+    		}
+            
+            Class filterClass = org.apache.myfaces.shared.util.ClassUtils.simpleClassForName(filterClassName);
+            List urlPatterns = (List)_filterMappings.get(filterName);
+            if( urlPatterns != null )
+            {
+                for (Iterator it2 = urlPatterns.iterator(); it2.hasNext(); )
+                {
+                    String urlpattern = (String)it2.next();
+                    _facesExtensionsFilterMappings.add(new org.apache.myfaces.shared.webapp.webxml.FilterMapping(
+                    	filterName, filterClass, urlpattern));
+                    if (log.isTraceEnabled())
+                        log.trace("adding mapping for filter + " + filterName + " urlpattern = " + urlpattern);
+                }
+            }
+        }
+        return _facesExtensionsFilterMappings;
+    }
 
     private static final String WEB_XML_ATTR = WebXml.class.getName();
     public static WebXml getWebXml(ExternalContext context)

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXmlParser.java
URL: http://svn.apache.org/viewcvs/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXmlParser.java?rev=393150&r1=393149&r2=393150&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXmlParser.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXmlParser.java Mon Apr 10 23:37:13 2006
@@ -34,6 +34,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 /**
  * @author Manfred Geiler (latest modification by $Author$)
@@ -60,7 +64,6 @@
     private static final String WEB_APP_2_3_SYSTEM_ID = "http://java.sun.com/dtd/web-app_2_3.dtd";
     private static final String WEB_APP_2_3_RESOURCE  = "javax/servlet/resources/web-app_2_3.dtd";
 
-
     private ExternalContext _context;
     private org.apache.myfaces.shared.webapp.webxml.WebXml _webXml;
 
@@ -197,6 +200,14 @@
                 {
                     readServletMapping((Element)n);
                 }
+                if (n.getNodeName().equals("filter"))
+                {
+                    readFilter((Element)n);
+                }
+                if (n.getNodeName().equals("filter-mapping"))
+                {
+                    readFilterMapping((Element)n);
+                }
             }
             else
             {
@@ -273,4 +284,70 @@
         _webXml.addServletMapping(servletName, urlPattern);
     }
 
+    private void readFilter(Element filterElem)
+    {
+        String filterName = null;
+        String filterClass = null;
+        NodeList nodeList = filterElem.getChildNodes();
+        for (int i = 0, len = nodeList.getLength(); i < len; i++)
+        {
+            Node n = nodeList.item(i);
+            if (n.getNodeType() == Node.ELEMENT_NODE)
+            {
+                if (n.getNodeName().equals("filter-name"))
+                {
+                    filterName = XmlUtils.getElementText((Element)n).trim();
+                }
+                else if (n.getNodeName().equals("filter-class"))
+                {
+                    filterClass = org.apache.myfaces.shared.util.xml.XmlUtils.getElementText((Element)n).trim();
+                }
+                else if (n.getNodeName().equals("description") || n.getNodeName().equals("init-param"))
+                {
+                    //ignore
+                }
+                else
+                {
+                    if (log.isDebugEnabled()) log.debug("Ignored element '" + n.getNodeName() + "' as child of '" + filterElem.getNodeName() + "'.");
+                }
+            }
+            else
+            {
+                if (log.isDebugEnabled()) log.debug("Ignored node '" + n.getNodeName() + "' of type " + n.getNodeType());
+            }
+        }
+        _webXml.addFilter(filterName, filterClass);
+    }
+
+
+    private void readFilterMapping(Element filterMappingElem)
+    {
+        String filterName = null;
+        String urlPattern = null;
+        NodeList nodeList = filterMappingElem.getChildNodes();
+        for (int i = 0, len = nodeList.getLength(); i < len; i++)
+        {
+            Node n = nodeList.item(i);
+            if (n.getNodeType() == Node.ELEMENT_NODE)
+            {
+                if (n.getNodeName().equals("filter-name"))
+                {
+                    filterName = org.apache.myfaces.shared.util.xml.XmlUtils.getElementText((Element)n).trim();
+                }
+                else if (n.getNodeName().equals("url-pattern"))
+                {
+                    urlPattern = org.apache.myfaces.shared.util.xml.XmlUtils.getElementText((Element)n).trim();
+                }
+                else
+                {
+                    if (log.isWarnEnabled()) log.warn("Ignored element '" + n.getNodeName() + "' as child of '" + filterMappingElem.getNodeName() + "'.");
+                }
+            }
+            else
+            {
+                if (log.isDebugEnabled()) log.debug("Ignored node '" + n.getNodeName() + "' of type " + n.getNodeType());
+            }
+        }
+        _webXml.addFilterMapping(filterName, urlPattern);
+    }
 }

Modified: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/AddResourceFactory.java
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/AddResourceFactory.java?rev=393150&r1=393149&r2=393150&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/AddResourceFactory.java (original)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/renderkit/html/util/AddResourceFactory.java Mon Apr 10 23:37:13 2006
@@ -20,9 +20,14 @@
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
@@ -35,254 +40,274 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.shared_tomahawk.config.MyfacesConfig;
+import org.apache.myfaces.shared_tomahawk.webapp.webxml.FilterMapping;
 import org.apache.myfaces.shared_tomahawk.util.ClassUtils;
+import org.apache.myfaces.shared_tomahawk.webapp.webxml.WebXml;
 import org.apache.myfaces.webapp.filter.ExtensionsFilter;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 /**
- * This class provides the ability to instantiate AddResource objects.
- * By default, this class will instantiate instances of
- * org.apache.myfaces.component.html.util.DefaultAddResource.
- * However, the context parameter org.apache.myfaces.ADD_RESOURCE_CLASS
- * can specify an alternative implementation of the AddResource
- * interface. The class must have a constructor with a single String
- * argument, representing the context path.
- * <p/>
- * Mostly used to avoid having to include [script src="..."][/script]
- * in the head of the pages before using a component.
- *
+ * This class provides the ability to instantiate AddResource objects. By
+ * default, this class will instantiate instances of
+ * org.apache.myfaces.component.html.util.DefaultAddResource. However, the
+ * context parameter org.apache.myfaces.ADD_RESOURCE_CLASS can specify an
+ * alternative implementation of the AddResource interface. The class must have
+ * a constructor with a single String argument, representing the context path.
+ * <p/> Mostly used to avoid having to include [script src="..."][/script] in
+ * the head of the pages before using a component.
+ * 
  * @author Peter Mahoney
  * @author Sylvain Vieujot (latest modification by $Author: mmarinschek $)
- * @version $Revision: 358042 $ $Date: 2005-12-20 17:12:56 +0000 (Tue, 20 Dec 2005) $
+ * @version $Revision: 358042 $ $Date: 2005-12-20 17:12:56 +0000 (Tue, 20 Dec
+ *          2005) $
  */
 public class AddResourceFactory
 {
+	private final static Set VALID_EXTFLT_PATH = Collections
+		.unmodifiableSet(new TreeSet(Arrays.asList(new String[]
+		{
+				"/faces/*", "/faces/myFacesExtensionResource/*"
+		})));
+
+	public static class RequestMapWrapper implements Map
+	{
+		private final HttpServletRequest request;
+
+		public RequestMapWrapper(final HttpServletRequest request)
+		{
+			this.request = request;
+		}
+
+		public int size()
+		{
+			throw new UnsupportedOperationException();
+		}
+
+		public boolean isEmpty()
+		{
+			throw new UnsupportedOperationException();
+		}
+
+		public boolean containsKey(Object key)
+		{
+			if (key == null)
+			{
+				throw new UnsupportedOperationException(
+					"'null' key not supported");
+			}
+			return request.getAttribute(key.toString()) != null;
+		}
 
+		public boolean containsValue(Object value)
+		{
+			throw new UnsupportedOperationException();
+		}
 
-    public static class RequestMapWrapper implements Map
-    {
-        private final HttpServletRequest request;
-
-        public RequestMapWrapper(final HttpServletRequest request)
-        {
-            this.request = request;
-        }
-
-        public int size()
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean isEmpty()
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean containsKey(Object key)
-        {
-            if (key == null)
-            {
-                throw new UnsupportedOperationException("'null' key not supported");
-            }
-            return request.getAttribute(key.toString()) != null;
-        }
-
-        public boolean containsValue(Object value)
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        public Object get(Object key)
-        {
-            if (key == null)
-            {
-                throw new UnsupportedOperationException("'null' key not supported");
-            }
-            return request.getAttribute(key.toString());
-        }
-
-        public Object put(Object key, Object value)
-        {
-            if (key == null)
-            {
-                throw new UnsupportedOperationException("'null' key not supported");
-            }
-
-            Object old = request.getAttribute(key.toString());
-            request.setAttribute(key.toString(), value);
-            return old;
-        }
-
-        public Object remove(Object key)
-        {
-            if (key == null)
-            {
-                throw new UnsupportedOperationException("'null' key not supported");
-            }
-
-            Object old = request.getAttribute(key.toString());
-            request.removeAttribute(key.toString());
-            return old;
-        }
-
-        public void putAll(Map arg)
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        public void clear()
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        public Set keySet()
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        public Collection values()
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        public Set entrySet()
-        {
-            throw new UnsupportedOperationException();
-        }
-
-    }
-
-    protected static final Log log = LogFactory.getLog(AddResourceFactory.class);
-
-    private final static String CACHE_MAP_KEY = "org.apache.myfaces.AddResourceFactory.CACHE_MAP_KEY";
-    private final static String ENV_CHECKED_KEY = "org.apache.myfaces.AddResourceFactory.ENV_CHECKED_KEY";
-
-
-    /**
-     * Internal factory method.
-     * <p/>
-     * Return an instance of AddResource keyed by context path, or create one
-     * if no such instance already exists. The instance will be cached using the
-     * given Map, most likely this will the the request map of your servlet request.
-     * Therefore every request uses its own AddResource instance.
-     * </p>
-     * <p/>
-     * Note that this method is package-scope for the purposes of unit-testing only.
-     * This method should be treated as private by non-test code.
-     * </p>
-     *
-     * @param cacheMap             the map used for caching of the instance. if null, a new instance will be created all the time (for tests)
-     * @param contextPath          context path of your web-app
-     * @param addResourceClassName class name of a class implementing the @link AddResource interface
-     */
-    static AddResource getInstance(Map cacheMap, String contextPath, String addResourceClassName)
-    {
-        AddResource instance = null;
-
-        if (cacheMap != null)
-        {
-            instance = (AddResource) cacheMap.get(CACHE_MAP_KEY);
-        }
-
-        if (instance == null)
-        {
-            if (addResourceClassName == null)
-            {
-                // For efficiency don't use reflection unless it is necessary
-                instance = new DefaultAddResource();
-                instance.setContextPath(contextPath);
-            }
-            else
-            {
-                try
-                {
-                    Class addResourceClass = ClassUtils.classForName(addResourceClassName);
-
-                    if (AddResource.class.isAssignableFrom(addResourceClass))
-                    {
-                        AddResource tmpInstance = (AddResource) addResourceClass.newInstance();
-                        tmpInstance.setContextPath(contextPath);
-
-                        // only use a fully initialized instance
-                        instance = tmpInstance;
-                    }
-                    else
-                    {
-                        log.error("Invalid AddResource class (" + addResourceClass.getName()
-                                + "). Must implement the AddResource interface.");
-                    }
-                }
-                catch (ClassNotFoundException e)
-                {
-                    log.error("AddResource class not found. Using default class instead", e);
-                }
-                catch (IllegalArgumentException e)
-                {
-                    // This should not happen as the constructor has been checked
-                    log.error(e);
-                }
-                catch (InstantiationException e)
-                {
-                    log.error("Invalid AddResource class. Must be non-abstract", e);
-                }
-                catch (IllegalAccessException e)
-                {
-                    log.error("Could not access AddResource class", e);
-                }
-                finally
-                {
-                    // Ensure there is always an AddResource object available
-                    if (instance == null)
-                    {
-                        instance = new DefaultAddResource();
-                        instance.setContextPath(contextPath);
-                    }
-                }
-            }
-
-            if (cacheMap != null)
-            {
-                cacheMap.put(CACHE_MAP_KEY, instance);
-            }
-        }
-
-        return instance;
-    }
-
-
-    public static AddResource getInstance
-            (FacesContext
-                    context)
-    {
-    	AddResource addResource = getInstance(
-                context.getExternalContext().getRequestMap(),
-                context.getExternalContext().getRequestContextPath(),
-                MyfacesConfig.getCurrentInstance(context.getExternalContext()).getAddResourceClass());
-    	checkEnvironment(context, addResource);
-    	return addResource;
-    }
-
-	public static AddResource getInstance
-            (HttpServletRequest
-                    request)
-    {
-        ServletContext servletContext = request.getSession().getServletContext();
-        Map requestMap = new RequestMapWrapper(request);
-        AddResource addResource = getInstance(
-        		requestMap,
-                request.getContextPath(),
-                MyfacesConfig.getAddResourceClassFromServletContext(servletContext));
-        //
-        // this will be called by the ExtensionsFilter itself, so no need to check the environment
-        //
-    	return addResource;
-    }
+		public Object get(Object key)
+		{
+			if (key == null)
+			{
+				throw new UnsupportedOperationException(
+					"'null' key not supported");
+			}
+			return request.getAttribute(key.toString());
+		}
+
+		public Object put(Object key, Object value)
+		{
+			if (key == null)
+			{
+				throw new UnsupportedOperationException(
+					"'null' key not supported");
+			}
+
+			Object old = request.getAttribute(key.toString());
+			request.setAttribute(key.toString(), value);
+			return old;
+		}
+
+		public Object remove(Object key)
+		{
+			if (key == null)
+			{
+				throw new UnsupportedOperationException(
+					"'null' key not supported");
+			}
+
+			Object old = request.getAttribute(key.toString());
+			request.removeAttribute(key.toString());
+			return old;
+		}
+
+		public void putAll(Map arg)
+		{
+			throw new UnsupportedOperationException();
+		}
+
+		public void clear()
+		{
+			throw new UnsupportedOperationException();
+		}
+
+		public Set keySet()
+		{
+			throw new UnsupportedOperationException();
+		}
+
+		public Collection values()
+		{
+			throw new UnsupportedOperationException();
+		}
+
+		public Set entrySet()
+		{
+			throw new UnsupportedOperationException();
+		}
+
+	}
+
+	protected static final Log log = LogFactory
+		.getLog(AddResourceFactory.class);
+
+	private final static String CACHE_MAP_KEY = "org.apache.myfaces.AddResourceFactory.CACHE_MAP_KEY";
+	private final static String ENV_CHECKED_KEY = "org.apache.myfaces.AddResourceFactory.ENV_CHECKED_KEY";
+
+	/**
+	 * Internal factory method. <p/> Return an instance of AddResource keyed by
+	 * context path, or create one if no such instance already exists. The
+	 * instance will be cached using the given Map, most likely this will the
+	 * the request map of your servlet request. Therefore every request uses its
+	 * own AddResource instance.
+	 * </p>
+	 * <p/> Note that this method is package-scope for the purposes of
+	 * unit-testing only. This method should be treated as private by non-test
+	 * code.
+	 * </p>
+	 * 
+	 * @param cacheMap
+	 *            the map used for caching of the instance. if null, a new
+	 *            instance will be created all the time (for tests)
+	 * @param contextPath
+	 *            context path of your web-app
+	 * @param addResourceClassName
+	 *            class name of a class implementing the
+	 * @link AddResource interface
+	 */
+	static AddResource getInstance(Map cacheMap, String contextPath,
+			String addResourceClassName)
+	{
+		AddResource instance = null;
+
+		if (cacheMap != null)
+		{
+			instance = (AddResource) cacheMap.get(CACHE_MAP_KEY);
+		}
+
+		if (instance == null)
+		{
+			if (addResourceClassName == null)
+			{
+				// For efficiency don't use reflection unless it is necessary
+				instance = new DefaultAddResource();
+				instance.setContextPath(contextPath);
+			}
+			else
+			{
+				try
+				{
+					Class addResourceClass = ClassUtils
+						.classForName(addResourceClassName);
+
+					if (AddResource.class.isAssignableFrom(addResourceClass))
+					{
+						AddResource tmpInstance = (AddResource) addResourceClass
+							.newInstance();
+						tmpInstance.setContextPath(contextPath);
+
+						// only use a fully initialized instance
+						instance = tmpInstance;
+					}
+					else
+					{
+						log
+							.error("Invalid AddResource class ("
+									+ addResourceClass.getName()
+									+ "). Must implement the AddResource interface.");
+					}
+				}
+				catch (ClassNotFoundException e)
+				{
+					log
+						.error(
+							"AddResource class not found. Using default class instead",
+							e);
+				}
+				catch (IllegalArgumentException e)
+				{
+					// This should not happen as the constructor has been
+					// checked
+					log.error(e);
+				}
+				catch (InstantiationException e)
+				{
+					log.error(
+						"Invalid AddResource class. Must be non-abstract", e);
+				}
+				catch (IllegalAccessException e)
+				{
+					log.error("Could not access AddResource class", e);
+				}
+				finally
+				{
+					// Ensure there is always an AddResource object available
+					if (instance == null)
+					{
+						instance = new DefaultAddResource();
+						instance.setContextPath(contextPath);
+					}
+				}
+			}
+
+			if (cacheMap != null)
+			{
+				cacheMap.put(CACHE_MAP_KEY, instance);
+			}
+		}
+
+		return instance;
+	}
+
+	public static AddResource getInstance(FacesContext context)
+	{
+		AddResource addResource = getInstance(context
+			.getExternalContext().getRequestMap(), context
+			.getExternalContext().getRequestContextPath(), MyfacesConfig
+			.getCurrentInstance(context.getExternalContext())
+			.getAddResourceClass());
+		checkEnvironment(context, addResource);
+		return addResource;
+	}
+
+	public static AddResource getInstance(HttpServletRequest request)
+	{
+		ServletContext servletContext = request
+			.getSession().getServletContext();
+		Map requestMap = new RequestMapWrapper(request);
+		AddResource addResource = getInstance(requestMap, request
+			.getContextPath(), MyfacesConfig
+			.getAddResourceClassFromServletContext(servletContext));
+		//
+		// this will be called by the ExtensionsFilter itself, so no need to
+		// check the environment
+		//
+		return addResource;
+	}
 
 	/**
 	 * check if the extensionsFilter has been correctly setup.
 	 */
-    private static void checkEnvironment(FacesContext context, AddResource addResource)
+	private static void checkEnvironment(FacesContext context, AddResource addResource)
 	{
     	ExternalContext extctx = context.getExternalContext();
     	
@@ -305,78 +330,45 @@
 	    	{
 	    		if (!extctx.getRequestMap().containsKey(ExtensionsFilter.DOFILTER_CALLED))
 	    		{
-	    			throwExtensionsFilterMissing();
+	    			throwExtensionsFilterMissing("JSF mapping missing. JSF pages not covered.");
 	    		}
 	    	}
-	    	
-	    	InputStream webXmlStream = null;
-	    	try
-			{
-				URL url = extctx.getResource("/WEB-INF/web.xml");
-				webXmlStream = url.openStream();
 
-				SAXParser parser = createSAXParser();
-				WebXmlFilterHandler webXmlFilterHandler = new WebXmlFilterHandler();
-				parser.parse(new InputSource(webXmlStream), webXmlFilterHandler);
-				
-				if (!webXmlFilterHandler.isValidEnvironment())
-				{
-					throwExtensionsFilterMissing();
-				}
-			}
-			catch (MalformedURLException e)
-			{
-				log.error("Cant check extensions filter as I can not read /WEB-INF/web.xml", e);
-			}
-			catch (IOException e)
-			{
-				log.error("Cant check extensions filter as I can not read /WEB-INF/web.xml", e);
-			}
-			catch (ParserConfigurationException e)
-			{
-				log.error("Cant check extensions filter as I can not read /WEB-INF/web.xml", e);
-			}
-			catch (SAXException e)
-			{
-				log.error("Cant check extensions filter as I can not read /WEB-INF/web.xml", e);
-			}
-			finally
-			{
-				if (webXmlStream != null)
-				{
-					try
-					{
-						webXmlStream.close();
-					}
-					catch (IOException e)
-					{
-						log.error("cant close /WEB-INF/web.xml", e);
-					}
-				}
-			}
+	    	boolean foundMapping = false;
+	    	
+	    	List facesServletMappings = WebXml.getWebXml(extctx).getFacesExtensionsFilterMappings();
+	    	for (Iterator iterServletMappings = facesServletMappings.iterator(); iterServletMappings.hasNext();)
+	    	{
+	    		FilterMapping filterMapping = (FilterMapping) iterServletMappings.next();
+	    		if (checkFilterPattern(filterMapping))
+	    		{
+	    			foundMapping = true;
+	    			break;
+	    		}
+	    	}
+	    	
+	    	if (!foundMapping)
+	    	{
+	    		throwExtensionsFilterMissing("Resource mapping missing. Resources cant be delivered.");
+	    	}
 	    	
 	    	extctx.getApplicationMap().put(ENV_CHECKED_KEY, Boolean.TRUE);
 		}
 	}
 
-	protected static SAXParser createSAXParser() throws ParserConfigurationException, SAXException
-	{
-		SAXParserFactory saxParserFactory = createSAXParserFactory();
-		SAXParser parser = saxParserFactory.newSAXParser();
-		return parser;
-	}
-
-	protected static SAXParserFactory createSAXParserFactory()
+	protected static boolean checkFilterPattern(FilterMapping filterMapping)
 	{
-		SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
-		saxParserFactory.setValidating(false);
-		//saxParserFactory.setXIncludeAware(true);
-		saxParserFactory.setNamespaceAware(true);
-		return saxParserFactory;
+		if (VALID_EXTFLT_PATH.contains(filterMapping.getUrlPattern()))
+		{
+			return true;
+		}
+		
+		return false;
 	}
 
-	private static void throwExtensionsFilterMissing()
+	private static void throwExtensionsFilterMissing(String detailReason)
 	{
-		throw new IllegalStateException("ExtensionsFilter not correctly configured. Please see: http://myfaces.apache.org/tomahawk/extensionsFilter.html");
+		throw new IllegalStateException(
+			"ExtensionsFilter not correctly configured. " + detailReason + " Please see: http://myfaces.apache.org/tomahawk/extensionsFilter.html");
 	}
 }