Re: [REVIEW] Disable web.xml scanning in ConfigureListener when running in GlassFish
nice feature.
r=rogerk
Ryan Lubke wrote:
>
>------------------------------------------------------------------------
>
>GlassFish has an optimization in place to only call
>ConfiguerListener.contextInitialized() if the
>FacesServlet is present in the web.xml. The Configure
>Listener has similar logic, and in the case of
>GlassFish, the ConfigureListener's version doens't
>need to be invoked.
>
>
>SECTION: Modified Files
>----------------------------
>M src/com/sun/faces/LogStrings.properties
>M src/com/sun/faces/application/ViewHandlerImpl.java
> - Ignore these - this is for issue 236 which I
> haven't checked in.
>
>M src/com/sun/faces/config/ConfigureListener.java
> - add boolean field with protected setter
> that, if true, will disable the web.xml
> scanning optimization.
>M build.xml
> - If we're building for glassfish, update jsf_core.tld
> to use the GlassFishConfigureListener otherwise
> use the default ConfigureListener and use
> the web.xml scanning logic by default (useful when
> Sun's impl is installed in the application classloader
> of Tomcat)
>M conf/share/jsf_core.tld
> - replaced the default value of the listener with a
> String that ANT can replace
>
>
>A src/com/sun/faces/config/GlassFishConfigureListener.java
> - disable web.xml scanning and call super.contextInitialized()
>
>
>SECTION: Diffs
>----------------------------
>Index: build.xml
>===================================================================
>RCS file: /cvs/javaserverfaces-sources/jsf-ri/build.xml,v
>retrieving revision 1.204
>diff -u -r1.204 build.xml
>--- build.xml 7 Feb 2006 20:40:21 -0000 1.204
>+++ build.xml 10 Feb 2006 21:51:28 -0000
>@@ -242,6 +242,21 @@
> toDir="${build.classes.dir}/META-INF"/>
> <copy file="${conf.share.dir}/jsf_core.tld"
> toDir="${build.classes.dir}/META-INF"/>
>+ <if>
>+ <equals arg1="${container.name}" arg2="glassfish"/>
>+ <then>
>+ <property name="listener.class" value="com.sun.faces.config.GlassFishConfigureListener"/>
>+ </then>
>+ <else>
>+ <property name="listener.class" value="com.sun.faces.config.ConfigureListener"/>
>+ </else>
>+ </if>
>+
>+ <echo message="INFO: Updating jsf_core.tld to use ServletContextListener ${listener.class}"/>
>+
>+ <replace file="${build.classes.dir}/META-INF/jsf_core.tld"
>+ token="|CONFIG_LISTEN_CLASS|"
>+ value="${listener.class}"/>
>
> </target>
>
>Index: conf/share/jsf_core.tld
>===================================================================
>RCS file: /cvs/javaserverfaces-sources/jsf-ri/conf/share/jsf_core.tld,v
>retrieving revision 1.57
>diff -u -r1.57 jsf_core.tld
>--- conf/share/jsf_core.tld 22 Aug 2005 22:10:03 -0000 1.57
>+++ conf/share/jsf_core.tld 10 Feb 2006 21:51:28 -0000
>@@ -71,7 +71,7 @@
> application including it is initialized by the container.
> -->
> <listener>
>- <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
>+ <listener-class>|CONFIG_LISTEN_CLASS|</listener-class>
> </listener>
>
>
>Index: src/com/sun/faces/LogStrings.properties
>===================================================================
>RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/LogStrings.properties,v
>retrieving revision 1.6
>diff -u -r1.6 LogStrings.properties
>--- src/com/sun/faces/LogStrings.properties 7 Feb 2006 20:40:22 -0000 1.6
>+++ src/com/sun/faces/LogStrings.properties 10 Feb 2006 21:51:28 -0000
>@@ -37,5 +37,6 @@
> jsf.navigation.no_matching_outcome_action="JSF1013: Unable to find matching navigation case from view ID ''{0}'' for outcome ''{1}'' and action ''{2}''
> jsf.util_no_annotation_processed=JSF1014: Unable to load annotation class ''{0}''. As a result, this annotation will not be processed.
> jsf.config.listener.version=Initializing Sun''s JavaServer Faces implementation (|version.string|) for context ''{0}''
>+jsf.viewhandler.requestpath.recursion="JSF1015: Request path ''{0}'' begins with one or more occurrences of the FacesServlet prefix path mapping ''{1}''.
> # core tags
> jsf.core.tags.eval_result_not_expected_type=JSF1011: Evaluation of expression for attribute ''{0}'' resulted in unexpected type. Expected {1}, but received {2}.
>Index: src/com/sun/faces/application/ViewHandlerImpl.java
>===================================================================
>RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/application/ViewHandlerImpl.java,v
>retrieving revision 1.64
>diff -u -r1.64 ViewHandlerImpl.java
>--- src/com/sun/faces/application/ViewHandlerImpl.java 23 Jan 2006 21:01:43 -0000 1.64
>+++ src/com/sun/faces/application/ViewHandlerImpl.java 10 Feb 2006 21:51:28 -0000
>@@ -374,12 +374,24 @@
> throw new NullPointerException(message);
> }
>
>- String requestURI = viewToExecute.getViewId();
>- if (logger.isLoggable(Level.FINE)) {
>+ String mapping = getFacesMapping(context);
>+ String requestURI =
>+ updateRequestURI(viewToExecute.getViewId(), mapping);
>+
>+ if (mapping.equals(requestURI)) {
>+ // The request was to the FacesServlet only - no path info
>+ // on some containers this causes a recursion in the
>+ // RequestDispatcher and the request appears to hang.
>+ // If this is detected, return status 404
>+ HttpServletResponse response = (HttpServletResponse)
>+ context.getExternalContext().getResponse();
>+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
>+ return;
>+ }
>+ if (logger.isLoggable(Level.FINE)) {
> logger.fine("About to execute view " + requestURI);
> }
>-
>- String mapping = getFacesMapping(context);
>+
> String newViewId = requestURI;
> // If we have a valid mapping (meaning we were invoked via the
> // FacesServlet) and we're extension mapped, do the replacement.
>@@ -746,6 +758,39 @@
> } else {
> // Servlet invoked using extension mapping
> return servletPath.substring(servletPath.lastIndexOf('.'));
>+ }
>+ }
>+
>+ /**
>+ * <p>if the specified mapping is a prefix mapping, and the provided
>+ * request URI (usually the value from <code>ExternalContext.getRequestServletPath()</code>)
>+ * starts with <code>mapping + '/'</code>, prune the mapping from the
>+ * URI and return it, otherwise, return the original URI.
>+ * @param uri the servlet request path
>+ * @param mapping the FacesServlet mapping used for this request
>+ * @return the URI without additional FacesServlet mappings
>+ * @since 1.2
>+ */
>+ private String updateRequestURI(String uri, String mapping) {
>+
>+ if (!isPrefixMapped(mapping)) {
>+ return uri;
>+ } else {
>+ int length = mapping.length() + 1;
>+ StringBuilder builder = new StringBuilder(length);
>+ builder.append(mapping).append('/');
>+ String mappingMod = builder.toString();
>+ boolean logged = false;
>+ while (uri.startsWith(mappingMod)) {
>+ if (!logged && logger.isLoggable(Level.WARNING)) {
>+ logged = true;
>+ logger.log(Level.WARNING,
>+ "jsf.viewhandler.requestpath.recursion",
>+ new Object[] {uri, mapping});
>+ }
>+ uri = uri.substring(length - 1);
>+ }
>+ return uri;
> }
> }
>
>Index: src/com/sun/faces/config/ConfigureListener.java
>===================================================================
>RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/config/ConfigureListener.java,v
>retrieving revision 1.60
>diff -u -r1.60 ConfigureListener.java
>--- src/com/sun/faces/config/ConfigureListener.java 9 Feb 2006 20:18:38 -0000 1.60
>+++ src/com/sun/faces/config/ConfigureListener.java 10 Feb 2006 21:51:28 -0000
>@@ -273,6 +273,10 @@
> private PropertyResolver legacyPRChainHead = null;
> private ArrayList<ELResolver> elResolversFromFacesConfig = null;
>
>+ // flag to disable web.xml scanning completely - to be used
>+ // by subclasses of ConfigureListener.
>+ private boolean shouldScanWebXml = true;
>+
> // ------------------------------------------ ServletContextListener Methods
>
> /**
>@@ -365,7 +369,8 @@
> // Check to see if the FacesServlet is present in the
> // web.xml. If it is, perform faces configuration as normal,
> // otherwise, simply return.
>- if (!isFeatureEnabled(context, FORCE_LOAD_CONFIG)) {
>+ if (shouldScanWebXml &&
>+ !isFeatureEnabled(context, FORCE_LOAD_CONFIG)) {
> WebXmlProcessor processor = new WebXmlProcessor(context);
> if (!processor.isFacesServletPresent()) {
> if (LOGGER.isLoggable(Level.FINE)) {
>@@ -691,6 +696,11 @@
> return afactory.getApplication();
>
> }
>+
>+
>+ protected void scanWebXml(boolean shouldScan) {
>+ this.shouldScanWebXml = shouldScan;
>+ }
>
>
> /**
>@@ -811,7 +821,9 @@
> prevInChain = instance;
> }
> legacyPRChainHead = (PropertyResolver) instance;
>- associate.setLegacyPRChainHead(legacyPRChainHead);
>+ if (associate != null) {
>+ associate.setLegacyPRChainHead(legacyPRChainHead);
>+ }
> }
>
> // process custom el-resolver elements if any
>@@ -864,7 +876,9 @@
> prevInChain = instance;
> }
> legacyVRChainHead = (VariableResolver) instance;
>- associate.setLegacyVRChainHead(legacyVRChainHead);
>+ if (associate != null) {
>+ associate.setLegacyVRChainHead(legacyVRChainHead);
>+ }
> }
>
> values = config.getViewHandlers();
>@@ -1741,15 +1755,19 @@
> // register an empty resolver for now. It will be populated after the
> // first request is serviced.
> CompositeELResolver compositeELResolverForJsp =
>- new FacesCompositeELResolver();
>- appAssociate.setFacesELResolverForJsp(compositeELResolverForJsp);
>+ new FacesCompositeELResolver();
>+ if (appAssociate != null) {
>+ appAssociate.setFacesELResolverForJsp(compositeELResolverForJsp);
>+ }
>
> // get JspApplicationContext.
> JspApplicationContext jspAppContext = JspFactory.getDefaultFactory()
> .getJspApplicationContext(context);
>
> // cache the ExpressionFactory instance in ApplicationAssociate
>- appAssociate.setExpressionFactory(jspAppContext.getExpressionFactory());
>+ if (appAssociate != null) {
>+ appAssociate.setExpressionFactory(jspAppContext.getExpressionFactory());
>+ }
>
> // register compositeELResolver with JSP
> try {
>
>
>SECTION: New Files
>----------------------------
>SEE ATTACHMENTS
>
>
>------------------------------------------------------------------------
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: dev-unsubscribe_at_javaserverfaces.dev.java.net
>For additional commands, e-mail: dev-help_at_javaserverfaces.dev.java.net
>
>