Author: craigmcc Date: Sun Jan 8 22:14:12 2006 New Revision: 367218 URL: http://svn.apache.org/viewcvs?rev=367218&view=rev Log: [38190] Finish the fix, by actually parsing /WEB-INF/web.xml to see what URL patterns FacesServlet is mapped to, rather than wimping out and hard coding an assumption of just "*.faces". The mapping information is actually useful generally, so store it in the Mappings instance that is placed into application scope.
Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleApplicationFilter.java struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/Bundle.properties struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/faces/RemotingPhaseListener.java Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleApplicationFilter.java URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleApplicationFilter.java?rev=367218&r1=367217&r2=367218&view=diff ============================================================================== --- struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleApplicationFilter.java (original) +++ struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleApplicationFilter.java Sun Jan 8 22:14:12 2006 @@ -164,13 +164,6 @@ "org.apache.shale.view.VIEW_CONTROLLER_MAPPER"; - /** - * <p>The <code>Log</code> instance for this class.</p> - */ - private static final Log log = - LogFactory.getLog(ShaleApplicationFilter.class); - - // ------------------------------------------------------ Instance Variables @@ -187,6 +180,12 @@ /** + * <p>The <code>Log</code> instance for this class.</p> + */ + private transient Log log = null; + + + /** * <p>Message resources for this class.</p> */ private static Messages messages = @@ -202,7 +201,9 @@ */ public void destroy() { - log.info(messages.getMessage("filter.finalizing")); + if (log().isInfoEnabled()) { + log().info(messages.getMessage("filter.finalizing")); + } // Execute the "destroy" command in the "shale" catalog (if any) Command command = catalog.getCommand(COMMAND_DESTROY); @@ -211,7 +212,9 @@ try { command.execute(webContext); } catch (Exception e) { - log.error(messages.getMessage("filter.destroyException"), e); + if (log().isErrorEnabled()) { + log().error(messages.getMessage("filter.destroyException"), e); + } } } @@ -301,7 +304,9 @@ */ public void init(FilterConfig config) throws ServletException { - log.info(messages.getMessage("filter.initializing")); + if (log().isInfoEnabled()) { + log().info(messages.getMessage("filter.initializing")); + } context = config.getServletContext(); context.setAttribute(Constants.VIEW_MAPPER, @@ -323,7 +328,9 @@ try { command.execute(webContext); } catch (Exception e) { - log.error(messages.getMessage("filter.initException"), e); + if (log().isErrorEnabled()) { + log().error(messages.getMessage("filter.initException"), e); + } throw new ServletException(e); } } @@ -353,18 +360,18 @@ // Create a new catalog (if necessary) if (catalog == null) { - if (log.isDebugEnabled()) { - log.debug(messages.getMessage("filter.creatingCatalog", - new Object[] { CATALOG_NAME })); + if (log().isDebugEnabled()) { + log().debug(messages.getMessage("filter.creatingCatalog", + new Object[] { CATALOG_NAME })); } catalog = new CatalogBase(); CatalogFactory.getInstance().addCatalog(CATALOG_NAME, catalog); } // Configure this catalog based on our default resource - if (log.isDebugEnabled()) { - log.debug(messages.getMessage("filter.parsingResource", - new Object[] { RESOURCE_NAME })); + if (log().isDebugEnabled()) { + log().debug(messages.getMessage("filter.parsingResource", + new Object[] { RESOURCE_NAME })); } ConfigParser parser = new ConfigParser(); URL url = this.getClass().getClassLoader().getResource(RESOURCE_NAME); @@ -432,6 +439,19 @@ (messages.getMessage("filter.vcmInstantiate", new Object[] { className }), e); } + + } + + + /** + * <p>Return the <code>Log</code> instance to use, creating one if needed.</p> + */ + private Log log() { + + if (this.log == null) { + log = LogFactory.getLog(ShaleApplicationFilter.class); + } + return log; } Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/Bundle.properties URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/Bundle.properties?rev=367218&r1=367217&r2=367218&view=diff ============================================================================== --- struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/Bundle.properties (original) +++ struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/Bundle.properties Sun Jan 8 22:14:12 2006 @@ -1,6 +1,7 @@ contentType.exception=Exception occurred setting content type on response mapping.configure=Configuring processor mapping mappings.configure=Configuring Mappings instance of type +mappings.parseWebXml=Exception occurred while parsing /WEB-INF/web.xml mimeType.exception=Exception occurred checking MIME type mapping resource.exception=Exception occurred retrieving URL for a resource resource.refuse=Refusing access to restricted resource Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/faces/RemotingPhaseListener.java URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/faces/RemotingPhaseListener.java?rev=367218&r1=367217&r2=367218&view=diff ============================================================================== --- struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/faces/RemotingPhaseListener.java (original) +++ struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/faces/RemotingPhaseListener.java Sun Jan 8 22:14:12 2006 @@ -17,6 +17,10 @@ package org.apache.shale.remoting.faces; import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ResourceBundle; @@ -26,6 +30,8 @@ import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.shale.remoting.Constants; @@ -35,6 +41,10 @@ import org.apache.shale.remoting.Processor; import org.apache.shale.remoting.impl.MappingImpl; import org.apache.shale.remoting.impl.MappingsImpl; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** * <p>A JavaServer Faces <code>PhaseListener</code> that provides support for @@ -61,7 +71,8 @@ /** * <p><code>ResourceBundle</code> containing our localized messages.</p> */ - private ResourceBundle bundle = ResourceBundle.getBundle("org.apache.shale.remoting.Bundle"); + private ResourceBundle bundle = + ResourceBundle.getBundle("org.apache.shale.remoting.Bundle"); /** @@ -83,8 +94,8 @@ // Acquire a reference to the FacesContext for this request FacesContext context = event.getFacesContext(); - if (log().isInfoEnabled()) { // FIXME - trace - log().info("Checking view identifier '" + context.getViewRoot().getViewId() + "'"); + if (log().isTraceEnabled()) { + log().trace("Checking view identifier '" + context.getViewRoot().getViewId() + "'"); } // Match this view identifier against our configured patterns @@ -93,8 +104,8 @@ Mapping mapping = (Mapping) mappings.next(); String resourceId = mapping.mapViewId(context); if (resourceId != null) { - if (log().isInfoEnabled()) { // FIXME - debug - log().info("View identifier '" + context.getViewRoot().getViewId() + + if (log().isDebugEnabled()) { + log().debug("View identifier '" + context.getViewRoot().getViewId() + "' matched pattern '" + mapping.getPattern() + "' with resource id '" + resourceId + "'"); } @@ -218,19 +229,6 @@ } } - // Calculate and set the replacement extension, to be used - // if FacesServlet is extension mapped - String extension = context.getExternalContext(). - getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME); - if (extension == null) { - extension = ViewHandler.DEFAULT_SUFFIX; - } - mappings.setExtension(extension); - - // Calculate and set the URL patterns that FacesServlet is mapped with - // FIXME - hard coded to "*.faces" for now - mappings.setPatterns(new String[] { "*.faces" }); - } @@ -283,6 +281,25 @@ Mechanism.WEBAPP_RESOURCE, "/webapp/*:org.apache.shale.remoting.impl.WebResourceProcessor"); + // Calculate and set the replacement extension, to be used + // if FacesServlet is extension mapped + String extension = context.getExternalContext(). + getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME); + if (extension == null) { + extension = ViewHandler.DEFAULT_SUFFIX; + } + mappings.setExtension(extension); + + // Calculate and set the URL patterns that FacesServlet is mapped with + // FIXME - hard coded to "*.faces" for now + String patterns[] = patterns(context); + if (log().isTraceEnabled()) { + for (int i = 0; i < patterns.length; i++) { + log().trace("FacesServlet is mapped with URL pattern '" + patterns[i] + "'"); + } + } + mappings.setPatterns(patterns); + // Return the configured Mappings instance return mappings; @@ -339,6 +356,124 @@ log = LogFactory.getLog(RemotingPhaseListener.class); } return log; + + } + + + /** + * <p>Return an array of URL patterns that <code>FacesServlet</code> is + * mapped to for this application.</p> + * + * @param context <code>FacesContext</code> for the current request + */ + private String[] patterns(FacesContext context) { + + Document document = null; + InputStream stream = null; + + try { + + // Acquire a URL for /WEB-INF/web.xml (if any) + Object ctxt = context.getExternalContext().getContext(); + Method method = + ctxt.getClass().getMethod("getResource", + new Class[] { String.class }); + URL url = (URL) method.invoke(ctxt, new Object[] { "/WEB-INF/web.xml" }); + if (url == null) { + if (log().isTraceEnabled()) { + log().trace("No /WEB-INF/web.xml resource available, returning empty list"); + } + return new String[0]; + } + + // Parse this resource into a DOM tree + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + stream = url.openStream(); + document = db.parse(stream); + + } catch (Exception e) { + + if (log().isErrorEnabled()) { + log().error(bundle.getString("mappings.parseWebXml"), e); + } + return new String[0]; + + } finally { + + if (stream != null) { + try { stream.close(); } catch (Exception e) {} + } + + } + + // Identify the servlet name of the JavaServer Faces controller servlet + String name = null; + NodeList servletNodes = document.getElementsByTagName("servlet"); + for (int i = 0; i < servletNodes.getLength(); i++) { + Node servletNode = servletNodes.item(i); + String servletName = null; + String servletClass = null; + NodeList kids = servletNode.getChildNodes(); + for (int j = 0; j < kids.getLength(); j++) { + Node kid = kids.item(j); + if ("servlet-name".equals(kid.getNodeName())) { + servletName = text(kid); + } else if ("servlet-class".equals(kid.getNodeName())) { + servletClass = text(kid); + } + } + if ("javax.faces.webapp.FacesServlet".equals(servletClass)) { + name = servletName; +// break; + } + } + if (name == null) { + return new String[0]; + } + + // Identify the URL patterns to which this servlet is mapped + List list = new ArrayList(); + NodeList mappingNodes = document.getElementsByTagName("servlet-mapping"); + for (int i = 0; i < mappingNodes.getLength(); i++) { + Node mappingNode = mappingNodes.item(i); + String servletName = null; + String urlPattern = null; + NodeList kids = mappingNode.getChildNodes(); + for (int j = 0; j < kids.getLength(); j++) { + Node kid = kids.item(j); + if ("servlet-name".equals(kid.getNodeName())) { + servletName = text(kid); + } else if ("url-pattern".equals(kid.getNodeName())) { + urlPattern = text(kid); + } + } + if (name.equals(servletName)) { + list.add(urlPattern); + } + } + + // Return the resulting list + return (String[]) list.toArray(new String[list.size()]); + + } + + + /** + * <p>Return the text content inside the specified node.</p> + * + * @param node Node from which text is to be extracted + */ + private String text(Node node) { + + NodeList kids = node.getChildNodes(); + for (int k = 0; k < kids.getLength(); k++) { + Node kid = kids.item(k); + if ("#text".equals(kid.getNodeName())) { + return kid.getNodeValue().trim(); + } + } + return ""; } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]