You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shale.apache.org by cr...@apache.org on 2006/08/19 04:12:10 UTC

svn commit: r432781 - in /shale/framework/trunk: shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/ shale-apps/shale-test-tiger/src/main/webapp/ shale-core/src/main/java/org/apache/shale/faces/ shale-core/src/main/java/org/...

Author: craigmcc
Date: Fri Aug 18 19:12:09 2006
New Revision: 432781

URL: http://svn.apache.org/viewvc?rev=432781&view=rev
Log:
Refactor the logic that was in
org.apache.shale.tiger.faces.LifecycleListener into class
org.apache.shale.tiger.view.faces.LifecycleListener2 instead.  Besides
reducing the two similar-focused classes into one, this also enables the
use of annotated managed beans even if the Shale Application Filter is
not configured.

Leaving the relevant issue (SHALE-256) open until a system integration
test is added to catch any future regressions on this functionality.

Removed:
    shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/faces/LifecycleListener.java
    shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/LifecycleListenerTestCase.java
Modified:
    shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/ApplicationBean.java
    shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/Managed.java
    shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/RequestBean.java
    shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/SessionBean.java
    shale/framework/trunk/shale-apps/shale-test-tiger/src/main/webapp/managed.jsp
    shale/framework/trunk/shale-core/src/main/java/org/apache/shale/faces/ShaleApplicationFilter.java
    shale/framework/trunk/shale-core/src/main/java/org/apache/shale/view/faces/LifecycleListener.java
    shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/faces/VariableResolverImpl.java
    shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java
    shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl4TestCase.java
    shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl5TestCase.java
    shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImplTestCase.java
    shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java

Modified: shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/ApplicationBean.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/ApplicationBean.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/ApplicationBean.java (original)
+++ shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/ApplicationBean.java Fri Aug 18 19:12:09 2006
@@ -27,14 +27,6 @@
 
 
     /**
-     * <p>Render a stringified version of this instance.</p>
-     */
-    public String getDisplay() {
-        return toString();
-    }
-
-
-    /**
      * <p>Return the events that have occurred so far.</p>
      */
     private StringBuffer events = new StringBuffer();

Modified: shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/Managed.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/Managed.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/Managed.java (original)
+++ shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/Managed.java Fri Aug 18 19:12:09 2006
@@ -22,8 +22,8 @@
  * <p>View controller for the <code>/managed.jsp</code> view,
  * completely configured via annotations.</p>
  */
-@View
 @Bean(name="managed", scope=Scope.REQUEST)
+@View
 public class Managed {
     
 
@@ -46,22 +46,29 @@
 
 
     /**
-     * <p>Render a stringified version of this instance.</p>
+     * <p>Return the events that have occurred so far.</p>
      */
-    public String getDisplay() {
-        return toString();
+    private StringBuffer events = new StringBuffer();
+
+    public String getEvents() {
+        return events.toString();
     }
 
 
+
     /**
-     * <p>Return the events that have occurred so far.</p>
+     * <p>Injected request bean instance.</p>
      */
-    private StringBuffer events = new StringBuffer();
+    @Property(value="#{requestBean}")
+    private RequestBean requestBean;
 
-    public String getEvents() {
-        return events.toString();
+    public RequestBean getRequestBean() {
+        return this.requestBean;
     }
 
+    public void setRequestBean(RequestBean requestBean) {
+        this.requestBean = requestBean;
+    }
 
 
     /**

Modified: shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/RequestBean.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/RequestBean.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/RequestBean.java (original)
+++ shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/RequestBean.java Fri Aug 18 19:12:09 2006
@@ -43,14 +43,6 @@
 
 
     /**
-     * <p>Render a stringified version of this instance.</p>
-     */
-    public String getDisplay() {
-        return toString();
-    }
-
-
-    /**
      * <p>Return the events that have occurred so far.</p>
      */
     private StringBuffer events = new StringBuffer();

Modified: shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/SessionBean.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/SessionBean.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/SessionBean.java (original)
+++ shale/framework/trunk/shale-apps/shale-test-tiger/src/main/java/org/apache/shale/examples/test/tiger/SessionBean.java Fri Aug 18 19:12:09 2006
@@ -45,14 +45,6 @@
 
 
     /**
-     * <p>Render a stringified version of this instance.</p>
-     */
-    public String getDisplay() {
-        return toString();
-    }
-
-
-    /**
      * <p>Return the events that have occurred so far.</p>
      */
     private StringBuffer events = new StringBuffer();

Modified: shale/framework/trunk/shale-apps/shale-test-tiger/src/main/webapp/managed.jsp
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-apps/shale-test-tiger/src/main/webapp/managed.jsp?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-apps/shale-test-tiger/src/main/webapp/managed.jsp (original)
+++ shale/framework/trunk/shale-apps/shale-test-tiger/src/main/webapp/managed.jsp Fri Aug 18 19:12:09 2006
@@ -39,51 +39,51 @@
         <tr>
             <th align="right">managed</th>
             <td><h:outputText id="managedValue"
-                           value="#{managed.display}"/></td>
+                           value="#{managed}"/></td>
             <td><h:outputText id="managedEvents"
-                            value="#{managed.events}"/></td>
+                           value="#{managed.events}"/></td>
         </tr>
         <tr>
             <th align="right">managed.applicationBean</th>
             <td><h:outputText id="managedApplicationValue"
-                           value="#{managed.applicationBean.display}"/></td>
+                           value="#{managed.applicationBean}"/></td>
             <td><h:outputText id="managedApplicationEvents"
-                            value="#{managed.applicationBean.events}"/></td>
+                           value="#{managed.applicationBean.events}"/></td>
         </tr>
         <tr>
             <th align="right">managed.requestBean</th>
             <td><h:outputText id="managedRequestValue"
-                           value="#{managed.requestBean.display}"/></td>
+                           value="#{managed.requestBean}"/></td>
             <td><h:outputText id="managedRequestEvents"
-                            value="#{managed.requestBean.events}"/></td>
+                           value="#{managed.requestBean.events}"/></td>
         </tr>
         <tr>
             <th align="right">managed.sessionBean</th>
             <td><h:outputText id="managedSessionValue"
-                           value="#{managed.sessionBean.display}"/></td>
+                           value="#{managed.sessionBean}"/></td>
             <td><h:outputText id="managedSessionEvents"
-                            value="#{managed.sessionBean.events}"/></td>
+                           value="#{managed.sessionBean.events}"/></td>
         </tr>
         <tr>
             <th align="right">applicationBean</th>
             <td><h:outputText id="applicationValue"
-                           value="#{applicationBean.display}"/></td>
+                           value="#{applicationBean}"/></td>
             <td><h:outputText id="applicationEvents"
-                            value="#{applicationBean.events}"/></td>
+                           value="#{applicationBean.events}"/></td>
         </tr>
         <tr>
             <th align="right">requestBean</th>
             <td><h:outputText id="requestValue"
-                           value="#{requestBean.display}"/></td>
+                           value="#{requestBean}"/></td>
             <td><h:outputText id="requestEvents"
-                            value="#{requestBean.events}"/></td>
+                           value="#{requestBean.events}"/></td>
         </tr>
         <tr>
             <th align="right">sessionBean</th>
             <td><h:outputText id="sessionValue"
-                           value="#{sessionBean.display}"/></td>
+                           value="#{sessionBean}"/></td>
             <td><h:outputText id="applicationEvents"
-                            value="#{sessionBean.events}"/></td>
+                           value="#{sessionBean.events}"/></td>
         </tr>
     </table>
 

Modified: shale/framework/trunk/shale-core/src/main/java/org/apache/shale/faces/ShaleApplicationFilter.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-core/src/main/java/org/apache/shale/faces/ShaleApplicationFilter.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-core/src/main/java/org/apache/shale/faces/ShaleApplicationFilter.java (original)
+++ shale/framework/trunk/shale-core/src/main/java/org/apache/shale/faces/ShaleApplicationFilter.java Fri Aug 18 19:12:09 2006
@@ -205,9 +205,6 @@
             }
         }
 
-        // Finialize the Shale Tiger Extensions (if present)
-        destroyTiger();
-
         // Clean up JavaServer Faces integration linkages
         context = null;
         catalog = null;
@@ -305,9 +302,6 @@
 
         context = config.getServletContext();
 
-        // Initialize the Shale Tiger Extensions (if present)
-        initTiger(config);
-
         // Look up the "shale" catalog and ensure "standard" is defined
         try {
             catalog = getCatalog();
@@ -377,96 +371,6 @@
         parser.parse(url);
 
         return catalog;
-
-    }
-
-
-    /**
-     * <p>The servlet context "listener" object for the Shale Tiger
-     * Extensions library, if it is present.  This object is accessed
-     * only via reflection, to avoid classpath problems if the
-     * <code>shale-tiger.jar</code> archive is not included.</p>
-     */
-    private Object tiger = null;
-
-
-    /**
-     * <p>Finalize the Shale Tiger Extensions (if present).</p>
-     */
-    private void destroyTiger() {
-
-        // If we have a tiger "listener" instance, send the contextDestroyed event
-        if (tiger != null) {
-            ServletContextEvent event = new ServletContextEvent(context);
-            try {
-                Method method =
-                  tiger.getClass().getMethod("contextDestroyed",
-                                             new Class[] { ServletContextEvent.class });
-                method.invoke(tiger, new Object[] { event });
-            } catch (InvocationTargetException e) {
-                Throwable cause = e.getCause();
-                if (cause instanceof RuntimeException) {
-                    throw (RuntimeException) cause;
-                } else {
-                    throw new FacesException(cause);
-                }
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new FacesException(e);
-            }
-        }
-
-    }
-
-
-    /**
-     * <p>Initialize the Shale Tiger Extensions (if present).</p>
-     *
-     * @param config <code>FilterConfig</code> for this initialization
-     *
-     * @exception ServletException if an initialization error occurs
-     */
-    private void initTiger(FilterConfig config) throws ServletException {
-
-        // Create an instance of the tiger "listener" if possible
-        try {
-            ClassLoader cl = Thread.currentThread().getContextClassLoader();
-            if (cl == null) {
-                cl = this.getClass().getClassLoader();
-            }
-            Class clazz =
-              cl.loadClass("org.apache.shale.tiger.faces.LifecycleListener");
-            tiger = clazz.newInstance();
-        } catch (ClassNotFoundException e) {
-            ; // Do nothing
-        } catch (RuntimeException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new ServletException(e);
-        }
-
-        // If we have a tiger "listener" instance, send the contextInitialized event
-        if (tiger != null) {
-            ServletContextEvent event = new ServletContextEvent(context);
-            try {
-                Method method =
-                  tiger.getClass().getMethod("contextInitialized",
-                                             new Class[] { ServletContextEvent.class });
-                method.invoke(tiger, new Object[] { event });
-            } catch (InvocationTargetException e) {
-                Throwable cause = e.getCause();
-                if (cause instanceof RuntimeException) {
-                    throw (RuntimeException) cause;
-                } else {
-                    throw new ServletException(cause);
-                }
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new ServletException(e);
-            }
-        }
 
     }
 

Modified: shale/framework/trunk/shale-core/src/main/java/org/apache/shale/view/faces/LifecycleListener.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-core/src/main/java/org/apache/shale/view/faces/LifecycleListener.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-core/src/main/java/org/apache/shale/view/faces/LifecycleListener.java (original)
+++ shale/framework/trunk/shale-core/src/main/java/org/apache/shale/view/faces/LifecycleListener.java Fri Aug 18 19:12:09 2006
@@ -473,7 +473,11 @@
      */
     public void requestInitialized(ServletRequestEvent event) {
 
-        // No processing is required
+        // Delegate to the Tiger Extensions instance if it exists
+        LifecycleListener tiger = tiger();
+        if (tiger != null) {
+            tiger.requestInitialized(event);
+        }
 
     }
 
@@ -487,6 +491,12 @@
      * @param event Event to be processed
      */
     public void requestDestroyed(ServletRequestEvent event) {
+
+        // Delegate to the Tiger Extensions instance if it exists
+        LifecycleListener tiger = tiger();
+        if (tiger != null) {
+            tiger.requestDestroyed(event);
+        }
 
         // Remove any AbstractRequestBean attributes,
         // which will trigger an attributeRemoved event

Modified: shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/faces/VariableResolverImpl.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/faces/VariableResolverImpl.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/faces/VariableResolverImpl.java (original)
+++ shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/faces/VariableResolverImpl.java Fri Aug 18 19:12:09 2006
@@ -37,6 +37,7 @@
 import org.apache.shale.tiger.managed.config.ManagedPropertyConfig;
 import org.apache.shale.tiger.managed.config.MapEntriesConfig;
 import org.apache.shale.tiger.managed.config.MapEntryConfig;
+import org.apache.shale.tiger.view.faces.LifecycleListener2;
 import org.apache.shale.util.ConverterHelper;
 import org.apache.shale.util.Messages;
 import org.apache.shale.util.PropertyHelper;
@@ -189,7 +190,8 @@
         }
 
         // Configure and return a new managed bean
-        return create(context, mb);
+        Object created = create(context, mb);
+        return created;
 
     }
 
@@ -215,7 +217,7 @@
         if (config == null) {
             config = (FacesConfigConfig)
               context.getExternalContext().getApplicationMap().
-              get(LifecycleListener.FACES_CONFIG_CONFIG);
+              get(LifecycleListener2.FACES_CONFIG_CONFIG);
         }
         return config;
 

Modified: shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java (original)
+++ shale/framework/trunk/shale-tiger/src/main/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java Fri Aug 18 19:12:09 2006
@@ -16,19 +16,55 @@
 
 package org.apache.shale.tiger.view.faces;
 
+import java.io.IOException;
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
 import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseListener;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
+import javax.faces.render.RenderKit;
+import javax.faces.render.RenderKitFactory;
+import javax.faces.render.Renderer;
+import javax.servlet.ServletContext;
 import javax.servlet.ServletContextAttributeEvent;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletRequestAttributeEvent;
+import javax.servlet.ServletRequestEvent;
 import javax.servlet.http.HttpSessionBindingEvent;
 import javax.servlet.http.HttpSessionEvent;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shale.tiger.config.FacesConfigConfig;
+import org.apache.shale.tiger.config.FacesConfigParser;
+import org.apache.shale.tiger.managed.Bean;
+import org.apache.shale.tiger.managed.Property;
+import org.apache.shale.tiger.managed.Value;
+import org.apache.shale.tiger.managed.config.ManagedBeanConfig;
+import org.apache.shale.tiger.managed.config.ManagedPropertyConfig;
+import org.apache.shale.tiger.register.FacesComponent;
+import org.apache.shale.tiger.register.FacesConverter;
+import org.apache.shale.tiger.register.FacesPhaseListener;
+import org.apache.shale.tiger.register.FacesRenderer;
+import org.apache.shale.tiger.register.FacesValidator;
+import org.apache.shale.tiger.register.faces.PhaseListenerAdapter;
 import org.apache.shale.tiger.view.Activate;
-import org.apache.shale.tiger.view.Application;
 import org.apache.shale.tiger.view.Destroy;
 import org.apache.shale.tiger.view.Init;
 import org.apache.shale.tiger.view.Passivate;
@@ -37,12 +73,14 @@
 import org.apache.shale.tiger.view.Request;
 import org.apache.shale.tiger.view.Session;
 import org.apache.shale.tiger.view.View;
+import org.apache.shale.util.Messages;
 import org.apache.shale.view.AbstractApplicationBean;
 import org.apache.shale.view.AbstractRequestBean;
 import org.apache.shale.view.AbstractSessionBean;
 import org.apache.shale.view.ViewController;
 import org.apache.shale.view.faces.FacesConstants;
 import org.apache.shale.view.faces.LifecycleListener;
+import org.xml.sax.SAXException;
 
 /**
  * <p>Specialized version of
@@ -75,6 +113,49 @@
     }
 
 
+    // ------------------------------------------------------ Manifest Constants
+
+
+    /**
+     * <p>Application scope attribute under which a configured
+     * {@link FacesConfigConfig} bean will be stored, containing
+     * information parsed from the relevant <code>faces-config.xml</code>
+     * resource(s) for this application.</p>
+     */
+    public static final String FACES_CONFIG_CONFIG =
+            "org.apache.shale.tiger.FACES_CONFIG_CONFIG";
+
+
+    /**
+     * <p>Context relative path to the default <code>faces-config.xml</code>
+     * resource for a JavaServer Faces application.</p>
+     */
+    private static final String FACES_CONFIG_DEFAULT =
+            "/WEB-INF/faces-config.xml";
+
+
+    /**
+     * <p>Resource path used to acquire implicit resources buried
+     * inside application JARs.</p>
+     */
+    private static final String FACES_CONFIG_IMPLICIT =
+            "META-INF/faces-config.xml";
+
+
+    /**
+     * <p>Prefix path used to locate web application classes for this
+     * web application.</p>
+     */
+    private static final String WEB_CLASSES_PREFIX = "/WEB-INF/classes/";
+
+
+    /**
+     * <p>Prefix path used to locate web application libraries for this
+     * web application.</p>
+     */
+    private static final String WEB_LIB_PREFIX = "/WEB-INF/lib/";
+
+
     // ------------------------------------------------------ Instance Variables
 
 
@@ -84,33 +165,150 @@
     private static final Object[] PARAMETERS = new Object[0];
 
 
+    /**
+     * <p>The <code>ServletContext</code> instance for this application.</p>
+     */
+    private transient ServletContext servletContext = null;
+
+
     // ------------------------------------------ ServletContextListener Methods
 
 
     /**
      * <p>Respond to a context initialized event.  Forcibly replace
      * the managed bean services that are different when the Tiger
-     * extensions are loaded.</p>
+     * extensions are loaded.  Then, process the <code>faces-config.xml</code>
+     * resources for this application in order to record the configuration
+     * of managed beans.</p>
      *
      * @param event Event to be processed
      */
     public void contextInitialized(ServletContextEvent event) {
 
-        event.getServletContext().setAttribute(FacesConstants.VIEW_CALLBACKS,
-                                               new ViewControllerCallbacks2());
+        if (log().isInfoEnabled()) {
+            log().info(messages().getMessage("lifecycle.initialized"));
+        }
+
+        // Replace the ViewControllerCallbacks handler
+        servletContext = event.getServletContext();
+        servletContext.setAttribute(FacesConstants.VIEW_CALLBACKS,
+                                    new ViewControllerCallbacks2());
+
+        // Create an empty FacesConfigConfig instance and stash it as
+        // an application scope attribute
+        FacesConfigConfig config = facesConfigConfig();
+        servletContext.setAttribute(FACES_CONFIG_CONFIG, config);
+
+        // Determine if the JSF implementation has been initialized yet.
+        // If it has, we will be able to register interesting classes
+        // directly.  Otherwise, they will have to be queued up for
+        // later processing.
+        Application application = null;
+        try {
+            application = application();
+        } catch (Exception e) {
+            ; // Null means it is not initialized yet
+        }
+
+        // Scan the classes in /WEB-INF/classes for interesting annotations
+        List<Class> classes = null;
+
+        try {
+            classes = webClasses(servletContext);
+            for (Class clazz : classes) {
+                if (application != null) {
+                    registerClass(clazz, application);
+                } else {
+                    queueClass(clazz);
+                }
+                scanClass(clazz, config);
+            }
+        } catch (Exception e) {
+            throw new FacesException(e);
+        }
+
+        // Scan the classes in /WEB-INF/lib for interesting annotations
+        List<JarFile> archives = null;
+
+        try {
+            archives = webArchives(servletContext);
+            for (JarFile archive : archives) {
+                classes = archiveClasses(servletContext, archive);
+                for (Class clazz : classes) {
+                    if (application != null) {
+                        registerClass(clazz, application);
+                    } else {
+                        queueClass(clazz);
+                    }
+                    scanClass(clazz, config);
+                }
+            }
+        } catch (Exception e) {
+            throw new FacesException(e);
+        }
+
+        // Create a parser instance used to parse faces-config.xml resources
+        FacesConfigParser parser = facesConfigParser(config);
+        List<URL> resources = null;
+        URL url = null;
+
+        // Parse the implicit faces-config.xml resources for this application
+        try {
+            resources = implicitResources(servletContext);
+            for (URL resource : resources) {
+                url = resource;
+                parseResource(parser, resource);
+            }
+        } catch (Exception e) {
+            throw new FacesException(messages().getMessage("lifecycle.exception",
+                                                           new Object[] { url.toExternalForm() }), e);
+        }
+
+        // Parse the configured faces-config.xml resource(s) for this application
+        try {
+            resources = explicitResources(servletContext);
+            for (URL resource : resources) {
+                url = resource;
+                parseResource(parser, resource);
+            }
+        } catch (Exception e) {
+            throw new FacesException(messages().getMessage("lifecycle.exception",
+                                                           new Object[] { url.toExternalForm() }), e);
+        }
+
+        // If not already processed, and if it actually exists, parse
+        // the default faces-config.xml resource for this application
+        try {
+            url = servletContext.getResource(FACES_CONFIG_DEFAULT);
+            if ((url != null) && !resources.contains(url)) {
+                parseResource(parser, url);
+            }
+        } catch (Exception e) {
+            throw new FacesException(messages().getMessage("lifecycle.exception",
+                                                           new Object[] { url.toExternalForm() }), e);
+        }
+
+        if (log().isInfoEnabled()) {
+            log().info(messages().getMessage("lifecycle.completed"));
+        }
 
     }
 
 
     /**
-     * <p>Respond to a context destroyed event.  No special
-     * processing is required.</p>
+     * <p>Respond to a context destroyed event.  Clean up our allocated
+     * application scope attributes.</p>
      *
      * @param event Event to be processed
      */
     public void contextDestroyed(ServletContextEvent event) {
 
-        // No special processing is required.
+        if (log().isInfoEnabled()) {
+            log().info(messages().getMessage("lifecycle.destroyed"));
+        }
+
+        // Clean up our allocated application scope attributes
+        event.getServletContext().removeAttribute(FACES_CONFIG_CONFIG);
 
     }
 
@@ -309,6 +507,36 @@
     }
 
 
+    // ------------------------------------------ ServletRequestListener Methods
+
+
+    /**
+     * <p>Respond to a request created event.  If we have accumulated any
+     * classes to register with our JSF implementation (but could not initially
+     * because it was not initialized before we were), register them now.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void requestInitialized(ServletRequestEvent event) {
+
+        queueRegister();
+
+    }
+
+
+    /**
+     * <p>Respond to a request destroyed event.  No special processing
+     * is required.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void requestDestroyed(ServletRequestEvent event) {
+
+        // No special processing is required
+
+    }
+
+
     // --------------------------------- ServletRequestAttributeListener Methods
 
 
@@ -586,6 +814,241 @@
 
 
     /**
+     * <p>The Application instance for this application.</p>
+     */
+    private Application application = null;
+
+
+    /**
+     * <p>Return the <code>Application</code> for this application.</p>
+     */
+    private Application application() {
+
+        if (application == null) {
+            application = ((ApplicationFactory) FactoryFinder.
+              getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication();
+        }
+        return application;
+
+    }
+
+
+    /**
+     * <p>Return a list of classes to examine from the specified JAR archive.
+     * If this archive has no classes in it, a zero-length list is returned.</p>
+     *
+     * @param context <code>ServletContext</code> instance for
+     *  this application
+     * @param jar <code>JarFile</code> for the archive to be scanned
+     *
+     * @exception ClassNotFoundException if a located class cannot be loaded
+     */
+    private List<Class> archiveClasses(ServletContext context, JarFile jar)
+        throws ClassNotFoundException {
+
+        // Accumulate and return a list of classes in this JAR file
+        List<Class> list = new ArrayList<Class>();
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        if (loader == null) {
+            loader = this.getClass().getClassLoader();
+        }
+        Enumeration<JarEntry> entries = jar.entries();
+        while (entries.hasMoreElements()) {
+            JarEntry entry = entries.nextElement();
+            if (entry.isDirectory()) {
+                continue;                         // This is a directory
+            }
+            String name = entry.getName();
+            if (name.startsWith("META-INF/")) {
+                continue;                         // Attribute files
+            }
+            if (!name.endsWith(".class")) {
+                continue;                         // This is not a class
+            }
+            name = name.substring(0, name.length() - 6); // Trim ".class"
+            Class clazz = null;
+            try {
+                clazz = loader.loadClass(name.replace('/', '.'));
+            } catch (NoClassDefFoundError e) {
+                ;  // Skip this class - we cannot analyze classes we cannot load
+            } catch (Exception e) {
+                ;  // Skip this class - we cannot analyze classes we cannot load
+            }
+            if (clazz != null) {
+                list.add(clazz);
+            }
+        }
+        return list;
+
+    }
+
+
+    /**
+     * <p>Return a list of URLs of <code>faces-config.xml</code>
+     * resources for this web application that have been explicitly listed
+     * in the appropriate context initialization parameter.  If there are no
+     * such resources, a zero-length list is returned.</p>
+     *
+     * @param servletContext <code>ServletContext</code> instance for this
+     *  application
+     *
+     * @exception MalformedURLException if a context relative resource path
+     *  has incorrect syntax
+     */
+    private List<URL> explicitResources(ServletContext servletContext)
+        throws MalformedURLException {
+
+        // Create an empty list to contain our results
+        List<URL> list = new ArrayList<URL>();
+
+        // If no initialization parameter was listed, return an empty list
+        String resources = servletContext.getInitParameter("javax.faces.CONFIG_FILES");
+        if (resources == null) {
+            return list;
+        }
+
+        // Parse the comma-delimited list of context-relative resource paths
+        while (resources.length() > 0) {
+            int comma = resources.indexOf(',');
+            if (comma < 0) {
+                resources = resources.trim();
+                if (resources.length() > 0) {
+                    list.add(servletContext.getResource(resources));
+                }
+                resources = "";
+            } else {
+                list.add(servletContext.getResource(resources.substring(0, comma).trim()));
+                resources = resources.substring(comma + 1);
+            }
+        }
+
+        // Return the completed list
+        return list;
+
+    }
+
+    /**
+     * <p>Create and return an empty {@link FacesConfigConfig} bean that will
+     * be filled with information later on.</p>
+     */
+    private FacesConfigConfig facesConfigConfig() {
+
+        return new FacesConfigConfig();
+
+    }
+
+
+    /**
+     * <p>Create and return a configured {@link FacesConfigParser} instance
+     * to be used for parsing <code>faces-config.xml</code> resources.  The
+     * caller will need to set the <code>resource</code> property on this
+     * instance before calling the <code>parse()</code> method.</p>
+     *
+     * @param config <code>FacesConfigBean</code> used to store the
+     *  information gathered while parsing configuration resources
+     */
+    private FacesConfigParser facesConfigParser(FacesConfigConfig config) {
+
+        FacesConfigParser parser = new FacesConfigParser();
+        parser.setFacesConfig(config);
+        parser.setValidating(true);
+        return parser;
+
+    }
+
+
+    /**
+     * <p>Return a list of URLs to implicit configuration resources
+     * embedded in this application.</p>
+     *
+     * @param servletContext <code>ServletContext</code> instance for this
+     *  application
+     *
+     * @exception IOException if an input/output error occurs
+     */
+    private List<URL> implicitResources(ServletContext servletContext)
+        throws IOException {
+
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        if (loader == null) {
+            loader = this.getClass().getClassLoader();
+        }
+        Enumeration items = loader.getResources(FACES_CONFIG_IMPLICIT);
+        List<URL> list = new ArrayList<URL>();
+        while (items.hasMoreElements()) {
+            list.add((URL) items.nextElement());
+        }
+        return list;
+
+    }
+
+
+    /**
+     * <p>The lifecycle instance for this application.</p>
+     */
+    private Lifecycle lifecycle = null;
+
+
+    /**
+     * <p>Return the <code>Lifecycle</code> for this application.</p>
+     */
+    private Lifecycle lifecycle() {
+
+        if (lifecycle == null) {
+            String lifecycleId = servletContext.getInitParameter("javax.faces.LIFECYCLE_ID");
+            if (lifecycleId == null) {
+                lifecycleId = LifecycleFactory.DEFAULT_LIFECYCLE;
+            }
+            lifecycle = ((LifecycleFactory) FactoryFinder.
+              getFactory(FactoryFinder.LIFECYCLE_FACTORY)).getLifecycle(lifecycleId);
+        }
+        return lifecycle;
+
+    }
+
+
+    /**
+     * <p>The <code>Log</code> instance we will be using.</p>
+     */
+    private transient Log log = null;
+
+
+    /**
+     * <p>Return the <code>Log</code> instance to be used for this class,
+     * instantiating a new one if necessary.</p>
+     */
+    private Log log() {
+
+        if (log == null) {
+            log = LogFactory.getLog(LifecycleListener2.class);
+        }
+        return log;
+
+    }
+
+
+    /**
+     * <p>The <code>Messages</code> instance we will be using.</p>
+     */
+    private transient Messages messages = null;
+
+
+    /**
+     * <p>Return the <code>Messages</code> instance to be used for this class,
+     * instantiating a new one if necessary.</p>
+     */
+    private Messages messages() {
+
+        if (messages == null) {
+            messages = new Messages("org.apache.shale.tiger.faces.Bundle",
+                                    Thread.currentThread().getContextClassLoader());
+        }
+        return messages;
+
+    }
+
+
+    /**
      * <p>The set of method annotations for callbacks of interest.</p>
      */
     private static final Class[] annotations =
@@ -598,7 +1061,9 @@
      * <p>The set of class annotations for classes of interest.</p>
      */
     private static final Class[] markers =
-    { View.class, Request.class, Session.class, Application.class };
+    { View.class, Request.class, Session.class,
+      org.apache.shale.tiger.view.Application.class };
+
 
 
     /**
@@ -646,6 +1111,7 @@
                 return map.get(annotation);
             }
 
+    
             // Construct and cache a new Map identifying the
             // methods of interest for these callbacks
             map = new HashMap<Class,Method>();
@@ -666,6 +1132,351 @@
         }
 
     }
+
+
+    /**
+     * <p>Use the specified parser to parse the resource at the specified
+     * URL, which will accumulate additional information into the
+     * <code>FacesConfigConfig</code> instance configured on the parser.</p>
+     *
+     * @param parser FacesConfigParser instance to be used
+     * @param resource URL of the resource to be parsed
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception SAXException if an XML parsing error occurs
+     */
+    private void parseResource(FacesConfigParser parser, URL resource)
+        throws IOException, SAXException {
+
+        if (log().isDebugEnabled()) {
+            log().debug("Parsing faces-config.xml resource '"
+                        + resource.toExternalForm() + "'");
+        }
+        parser.setResource(resource);
+        parser.parse();
+
+    }
+
+
+
+    /**
+     * <p>A list of classes that need to be registered with the JSF implementation
+     * after it has been started.</p>
+     */
+    private List<Class> queue = new ArrayList();
+
+
+    /**
+     * <p>Queue the specified class to be registered (via <code>registerClass()</code>)
+     * at a later time.</p>
+     *
+     * @param clazz Class instance to be queued
+     */
+    private void queueClass(Class clazz) {
+        queue.add(clazz);
+    }
+
+
+    /**
+     * <p>Register any classes that have been queued.  This method is synchronzied
+     * because it is called from a request listener, and may therefore be subject
+     * to race conditions if multiple requests are received simultaneously.</p>
+     */
+    private synchronized void queueRegister() {
+
+        if (queue == null) {
+            return;
+        }
+        for (Class clazz : queue) {
+            registerClass(clazz, application());
+        }
+        queue = null;
+
+    }
+
+
+    /**
+     * <p>The render kit factory for this application.</p>
+     */
+    private RenderKitFactory rkFactory = null;
+
+
+    /**
+     * <p>Return the <code>RenderKitFactory</code> for this application.</p>
+     */
+    private RenderKitFactory renderKitFactory() {
+
+        if (rkFactory == null) {
+            rkFactory = (RenderKitFactory)
+              FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+        }
+        return rkFactory;
+
+    }
+
+
+    /**
+     * <p>Register the specified class with the specified JavaServer Faces
+     * <code>Application</code> instance, based on annotations that the
+     * class is annotated with.</p>
+     *
+     * @param clazz Class to be registered
+     * @param application <code>Application</code> instance with which to
+     *  register this class
+     */
+    private void registerClass(Class clazz, Application application) {
+
+        if (log().isTraceEnabled()) {
+            log().trace("registerClass(" + clazz.getName() + ")");
+        }
+        FacesComponent comp = (FacesComponent) clazz.getAnnotation(FacesComponent.class);
+        if (comp != null) {
+            if (log().isTraceEnabled()) {
+                log().trace("addComponent(" + comp.value() + "," + clazz.getName() + ")");
+            }
+            application().addComponent(comp.value(), clazz.getName());
+        }
+
+        FacesConverter conv = (FacesConverter) clazz.getAnnotation(FacesConverter.class);
+        if (conv != null) {
+            if (log().isTraceEnabled()) {
+                log().trace("addConverter(" + conv.value() + "," + clazz.getName() + ")");
+            }
+            application().addConverter(conv.value(), clazz.getName());
+        }
+
+        FacesPhaseListener list = (FacesPhaseListener) clazz.getAnnotation(FacesPhaseListener.class);
+        if (list != null) {
+            try {
+                Lifecycle lifecycle = lifecycle();
+                Object instance = clazz.newInstance();
+                if (instance instanceof PhaseListener) {
+                    lifecycle.addPhaseListener((PhaseListener) instance);
+                } else {
+                    lifecycle.addPhaseListener(new PhaseListenerAdapter(instance));
+                }
+            } catch (FacesException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new FacesException(e);
+            }
+        }
+
+        FacesRenderer rend = (FacesRenderer) clazz.getAnnotation(FacesRenderer.class);
+        if (rend != null) {
+            String renderKitId = rend.renderKitId();
+            if (renderKitId == null) {
+                renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
+            }
+            if (log().isTraceEnabled()) {
+                log().trace("addRenderer(" + renderKitId + ", " + rend.componentFamily()
+                  + ", " + rend.rendererType() + ", " + clazz.getName() + ")");
+            }
+            try {
+                RenderKit rk = renderKitFactory().getRenderKit(null, renderKitId);
+                rk.addRenderer(rend.componentFamily(), rend.rendererType(),
+                               (Renderer) clazz.newInstance());
+            } catch (Exception e) {
+                throw new FacesException(e);
+            }
+        }
+
+        FacesValidator val = (FacesValidator) clazz.getAnnotation(FacesValidator.class);
+        if (val != null) {
+            if (log().isTraceEnabled()) {
+                log().trace("addValidator(" + val.value() + "," + clazz.getName() + ")");
+            }
+            application().addValidator(val.value(), clazz.getName());
+        }
+
+    }
+
+
+    /**
+     * <p>Scan the specified class for those that have annotations
+     * of interest, and construct appropriate configuration metadata attached
+     * to the specified {@link FacesConfigConfig} bean.</p>
+     *
+     * @param clazz Class to be scanned
+     * @param config {@link FacesConfigConfig} to be updated
+     */
+    private void scanClass(Class clazz, FacesConfigConfig config) {
+
+        if (log().isTraceEnabled()) {
+            log().trace("Scanning class '" + clazz.getName() + "'");
+        }
+        Bean bean = (Bean) clazz.getAnnotation(Bean.class);
+        if (bean != null) {
+            if (log().isDebugEnabled()) {
+                log().debug("Class '" + clazz.getName() + "' has an @Bean annotation");
+            }
+            ManagedBeanConfig mbc = new ManagedBeanConfig();
+            mbc.setName(bean.name());
+            mbc.setType(clazz.getName());
+            switch (bean.scope()) {
+                case APPLICATION:
+                    mbc.setScope("application");
+                    break;
+                case REQUEST:
+                    mbc.setScope("request");
+                    break;
+                case SESSION:
+                    mbc.setScope("session");
+                    break;
+                default:
+                    break;
+            }
+            // FIXME - should we look for inherited fields with @Property/@Value too?
+            for (Field field : clazz.getDeclaredFields()) {
+                if (log().isTraceEnabled()) {
+                    log().trace("  Scanning field '" + field.getName() + "'");
+                }
+                Property property = (Property) field.getAnnotation(Property.class);
+                if (property != null) {
+                    if (log().isDebugEnabled()) {
+                        log().debug("  Field '" + field.getName() + "' has a @Property annotation");
+                    }
+                    ManagedPropertyConfig mpc = new ManagedPropertyConfig();
+                    String name = property.name();
+                    if ((name == null) || "".equals(name)) {
+                        name = field.getName();
+                    }
+                    mpc.setName(name);
+                    mpc.setType(field.getType().getName()); // FIXME - primitives, arrays, etc.
+                    mpc.setValue(property.value());
+                    mbc.addProperty(mpc);
+                    continue;
+                }
+                // Support deprecated @Value annotation as well
+                Value value = (Value) field.getAnnotation(Value.class);
+                if (value != null) {
+                    if (log().isDebugEnabled()) {
+                        log().debug("  Field '" + field.getName() + "' has a @Value annotation");
+                    }
+                    ManagedPropertyConfig mpc = new ManagedPropertyConfig();
+                    mpc.setName(field.getName());
+                    mpc.setType(field.getType().getName()); // FIXME - primitives, arrays, etc.
+                    mpc.setValue(value.value());
+                    mbc.addProperty(mpc);
+                    continue;
+                }
+            }
+            config.addManagedBean(mbc);
+        }
+
+    }
+
+
+    /**
+     * <p>Return a list of the JAR archives defined under the
+     * <code>/WEB-INF/lib</code> directory of this web application
+     * that contain a <code>META-INF/faces-config.xml</code> resource
+     * (even if that resource is empty).  If there are no such JAR archives,
+     * a zero-length list will be returned.</p>
+     *
+     * @param servletContext <code>ServletContext</code> instance for
+     *  this application
+     *
+     * @exception IOException if an input/output error occurs
+     */
+    private List<JarFile> webArchives(ServletContext servletContext)
+        throws IOException {
+
+        List<JarFile> list = new ArrayList<JarFile>();
+        Set<Object> paths = servletContext.getResourcePaths(WEB_LIB_PREFIX);
+        for (Object pathObject : paths) {
+            String path = (String) pathObject;
+            if (!path.endsWith(".jar")) {
+                continue;
+            }
+            URL url = servletContext.getResource(path);
+            String jarURLString = "jar:" + url.toString() + "!/";
+            url = new URL(jarURLString);
+            JarFile jarFile = ((JarURLConnection) url.openConnection()).getJarFile();
+            // Skip this JAR file if it does not have a META-INF/faces-config.xml
+            // resource (even if that resource is empty)
+            JarEntry signal = jarFile.getJarEntry(FACES_CONFIG_IMPLICIT);
+            if (signal == null) {
+                if (log().isTraceEnabled()) {
+                    log().trace("Skip JAR file " + path + " because it has no META-INF/faces-config.xml resource");
+                }
+                continue;
+            }
+            list.add(jarFile);
+        }
+        return list;
+
+    }
+
+
+    /**
+     * <p>Return a list of the classes defined under the
+     * <code>/WEB-INF/classes</code> directory of this web
+     * application.  If there are no such classes, a zero-length list
+     * will be returned.</p>
+     *
+     * @param servletContext <code>ServletContext</code> instance for
+     *  this application
+     *
+     * @exception ClassNotFoundException if a located class cannot be loaded
+     */
+    private List<Class> webClasses(ServletContext servletContext)
+        throws ClassNotFoundException {
+
+        List<Class> list = new ArrayList<Class>();
+        webClasses(servletContext, WEB_CLASSES_PREFIX, list);
+        return list;
+
+    }
+
+
+    /**
+     * <p>Add classes found in the specified directory to the specified
+     * list, recursively calling this method when a directory is encountered.</p>
+     *
+     * @param servletContext <code>ServletContext</code> instance for
+     *  this application
+     * @param prefix Prefix specifying the "directory path" to be searched
+     * @param list List to be appended to
+     *
+     * @exception ClassNotFoundException if a located class cannot be loaded
+     */
+    private void webClasses(ServletContext servletContext, String prefix, List<Class> list)
+        throws ClassNotFoundException {
+
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        if (loader == null) {
+            loader = this.getClass().getClassLoader();
+        }
+        Set<Object> paths = servletContext.getResourcePaths(prefix);
+        if (log().isTraceEnabled()) {
+            log().trace("webClasses(" + prefix + ") - Received " + paths.size() + " paths to check");
+        }
+        String path = null;
+        for (Object pathObject : paths) {
+            path = (String) pathObject;
+            if (path.endsWith("/")) {
+                webClasses(servletContext, path, list);
+            } else if (path.endsWith(".class")) {
+                path = path.substring(WEB_CLASSES_PREFIX.length()); // Strip prefix
+                path = path.substring(0, path.length() - 6);        // Strip suffix
+                path = path.replace('/', '.'); // Convert to FQCN
+                Class clazz = null;
+                try {
+                    clazz = loader.loadClass(path);
+                } catch (NoClassDefFoundError e) {
+                    ; // Skip this class - we cannot analyze classes we cannot load
+                } catch (Exception e) {
+                    ; // Skip this class - we cannot analyze classes we cannot load
+                }
+                if (clazz != null) {
+                    list.add(clazz);
+                }
+            }
+        }
+
+    }
+
 
 
 }

Modified: shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl4TestCase.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl4TestCase.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl4TestCase.java (original)
+++ shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl4TestCase.java Fri Aug 18 19:12:09 2006
@@ -34,6 +34,8 @@
 import org.apache.shale.tiger.config.TestBean4;
 import org.apache.shale.tiger.managed.config.ManagedBeanConfig;
 import org.apache.shale.tiger.managed.config.ManagedPropertyConfig;
+import org.apache.shale.tiger.view.faces.LifecycleListener2;
+import org.apache.shale.view.faces.LifecycleListener;
 
 /**
  * <p>Test case for <code>org.apache.shale.tiger.faces.VariableResolverImpl</code>
@@ -65,7 +67,7 @@
         servletContext.setDocumentRoot(root);
 
         // Process our configuration information
-        listener = new LifecycleListener();
+        listener = new LifecycleListener2();
         listener.contextInitialized(new ServletContextEvent(servletContext));
 
         // Create resolver instance to be tested

Modified: shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl5TestCase.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl5TestCase.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl5TestCase.java (original)
+++ shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImpl5TestCase.java Fri Aug 18 19:12:09 2006
@@ -35,6 +35,8 @@
 import org.apache.shale.tiger.config.TestBean5;
 import org.apache.shale.tiger.managed.config.ManagedBeanConfig;
 import org.apache.shale.tiger.managed.config.ManagedPropertyConfig;
+import org.apache.shale.tiger.view.faces.LifecycleListener2;
+import org.apache.shale.view.faces.LifecycleListener;
 
 /**
  * <p>Test case for <code>org.apache.shale.tiger.faces.VariableResolverImpl</code>
@@ -66,7 +68,7 @@
         servletContext.setDocumentRoot(root);
 
         // Process our configuration information
-        listener = new LifecycleListener();
+        listener = new LifecycleListener2();
         listener.contextInitialized(new ServletContextEvent(servletContext));
 
         // Create resolver instance to be tested

Modified: shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImplTestCase.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImplTestCase.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImplTestCase.java (original)
+++ shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/faces/VariableResolverImplTestCase.java Fri Aug 18 19:12:09 2006
@@ -28,6 +28,8 @@
 import org.apache.shale.tiger.config.TestBean;
 import org.apache.shale.tiger.managed.config.ManagedBeanConfig;
 import org.apache.shale.tiger.managed.config.ManagedPropertyConfig;
+import org.apache.shale.tiger.view.faces.LifecycleListener2;
+import org.apache.shale.view.faces.LifecycleListener;
 
 /**
  * <p>Test case for <code>org.apache.shale.tiger.faces.VariableResolverImpl</code>.</p>
@@ -61,7 +63,7 @@
         servletContext.setDocumentRoot(root);
 
         // Process our configuration information
-        listener = new LifecycleListener();
+        listener = new LifecycleListener2();
         listener.contextInitialized(new ServletContextEvent(servletContext));
 
         // Create resolver instance to be tested
@@ -219,7 +221,7 @@
         assertNotNull(application.getVariableResolver());
         FacesConfigConfig config = (FacesConfigConfig)
             externalContext.getApplicationMap().
-            get(LifecycleListener.FACES_CONFIG_CONFIG);
+            get(LifecycleListener2.FACES_CONFIG_CONFIG);
         assertNotNull(config);
         assertEquals(8, config.getManagedBeans().size());
 

Modified: shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java?rev=432781&r1=432780&r2=432781&view=diff
==============================================================================
--- shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java (original)
+++ shale/framework/trunk/shale-tiger/src/test/java/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java Fri Aug 18 19:12:09 2006
@@ -16,10 +16,22 @@
 
 package org.apache.shale.tiger.view.faces;
 
+import java.io.File;
+import java.util.Map;
+import javax.faces.component.UIComponent;
+import javax.faces.convert.Converter;
+import javax.faces.event.PhaseListener;
+import javax.faces.render.Renderer;
+import javax.faces.validator.Validator;
+import javax.servlet.ServletContextEvent;
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
 import org.apache.shale.test.base.AbstractJsfTestCase;
+import org.apache.shale.tiger.config.FacesConfigConfig;
+import org.apache.shale.tiger.managed.config.ManagedBeanConfig;
+import org.apache.shale.tiger.managed.config.ManagedPropertyConfig;
+import org.apache.shale.tiger.register.faces.PhaseListenerAdapter;
 import org.apache.shale.view.faces.LifecycleListener;
 
 /**
@@ -51,6 +63,14 @@
         session.addAttributeListener(listener);
         request.addAttributeListener(listener);
         
+        // Set up mock web application environment
+        servletContext.addInitParameter("javax.faces.CONFIG_FILES",
+                                        "/WEB-INF/test-config-0.xml," +
+                                        "/WEB-INF/test-config-1.xml," +
+                                        "/WEB-INF/test-config-2.xml");
+        File root = new File(System.getProperty("basedir") + "/target/test-webapp");
+        servletContext.setDocumentRoot(root);
+
     }
 
 
@@ -112,10 +132,297 @@
     }
 
 
+    // Test basic operations -- can we initialize and destroy with no exceptions?
+    public void testBasic() {
+
+        // Create a ServletContextEvent we will pass to the event methods
+        ServletContextEvent event = new ServletContextEvent(servletContext);
+
+        // Initialize the servlet context listener
+        listener.contextInitialized(event);
+
+        // Finalize the servlet context listener
+        listener.contextDestroyed(event);
+
+    }
+
+
+    // Test configuration of managed beans
+    public void testManagedBeans() {
+
+        // Create a ServletContextEvent we will pass to the event methods
+        ServletContextEvent event = new ServletContextEvent(servletContext);
+
+        // Initialize the servlet context listener
+        listener.contextInitialized(event);
+
+        // Check out the managed beans configuration information
+        FacesConfigConfig fcConfig =
+          (FacesConfigConfig) servletContext.getAttribute(LifecycleListener2.FACES_CONFIG_CONFIG);
+        assertNotNull(config);
+        Map<String,ManagedBeanConfig> mbMap = fcConfig.getManagedBeans();
+        assertNotNull(mbMap);
+        assertEquals(8, mbMap.size());
+
+        ManagedPropertyConfig mpConfig = null;
+
+        // Validate configuration of bean0
+        ManagedBeanConfig bean0 = fcConfig.getManagedBean("bean0");
+        assertNotNull(bean0);
+        assertTrue(bean0 == mbMap.get("bean0"));
+        assertEquals("bean0", bean0.getName());
+        assertEquals("org.apache.shale.tiger.config.TestBean", bean0.getType());
+        assertEquals("request", bean0.getScope());
+        assertNull(bean0.getListEntries());
+        assertNull(bean0.getMapEntries());
+        Map<String,ManagedPropertyConfig> bean0Map = bean0.getProperties();
+        assertNotNull(bean0Map);
+        assertEquals(1, bean0Map.size());
+
+        mpConfig = bean0.getProperty("stringProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean0Map.get("stringProperty"));
+        assertEquals("stringProperty", mpConfig.getName());
+        assertEquals("java.lang.String", mpConfig.getType());
+        assertNull(mpConfig.getValue());
+        assertTrue(mpConfig.isNullValue());
+
+        // Validate configuration of bean1
+        ManagedBeanConfig bean1 = fcConfig.getManagedBean("bean1");
+        assertNotNull(bean1);
+        assertTrue(bean1 == mbMap.get("bean1"));
+        assertEquals("bean1", bean1.getName());
+        assertEquals("org.apache.shale.tiger.config.TestBean", bean1.getType());
+        assertEquals("session", bean1.getScope());
+        assertNull(bean1.getListEntries());
+        assertNull(bean1.getMapEntries());
+        Map<String,ManagedPropertyConfig> bean1Map = bean1.getProperties();
+        assertNotNull(bean1Map);
+        assertEquals(3, bean1Map.size());
+
+        mpConfig = bean1.getProperty("byteProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean1Map.get("byteProperty"));
+        assertEquals("byteProperty", mpConfig.getName());
+        assertEquals("byte", mpConfig.getType());
+        assertEquals("11", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean1.getProperty("doubleProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean1Map.get("doubleProperty"));
+        assertEquals("doubleProperty", mpConfig.getName());
+        assertEquals("double", mpConfig.getType());
+        assertEquals("222.0", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean1.getProperty("intProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean1Map.get("intProperty"));
+        assertEquals("intProperty", mpConfig.getName());
+        assertEquals("int", mpConfig.getType());
+        assertEquals("44", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        // Validate configuration of bean2
+        ManagedBeanConfig bean2 = fcConfig.getManagedBean("bean2");
+        assertNotNull(bean2);
+        assertTrue(bean2 == mbMap.get("bean2"));
+        assertEquals("bean2", bean2.getName());
+        assertEquals("org.apache.shale.tiger.config.TestBean", bean2.getType());
+        assertEquals("request", bean2.getScope());
+        assertNull(bean2.getListEntries());
+        assertNull(bean2.getMapEntries());
+        Map<String,ManagedPropertyConfig> bean2Map = bean2.getProperties();
+        assertNotNull(bean2Map);
+        assertEquals(8, bean2Map.size());
+
+        mpConfig = bean2.getProperty("byteProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean2Map.get("byteProperty"));
+        assertEquals("byteProperty", mpConfig.getName());
+        assertEquals("byte", mpConfig.getType());
+        assertEquals("-1", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean2.getProperty("charProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean2Map.get("charProperty"));
+        assertEquals("charProperty", mpConfig.getName());
+        assertEquals("char", mpConfig.getType());
+        assertEquals("z", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean2.getProperty("doubleProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean2Map.get("doubleProperty"));
+        assertEquals("doubleProperty", mpConfig.getName());
+        assertEquals("double", mpConfig.getType());
+        assertEquals("-2.0", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean2.getProperty("floatProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean2Map.get("floatProperty"));
+        assertEquals("floatProperty", mpConfig.getName());
+        assertEquals("float", mpConfig.getType());
+        assertEquals("-3.0", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean2.getProperty("intProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean2Map.get("intProperty"));
+        assertEquals("intProperty", mpConfig.getName());
+        assertEquals("int", mpConfig.getType());
+        assertEquals("-4", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean2.getProperty("longProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean2Map.get("longProperty"));
+        assertEquals("longProperty", mpConfig.getName());
+        assertEquals("long", mpConfig.getType());
+        assertEquals("-5", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean2.getProperty("shortProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean2Map.get("shortProperty"));
+        assertEquals("shortProperty", mpConfig.getName());
+        assertEquals("short", mpConfig.getType());
+        assertEquals("-6", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean2.getProperty("stringProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean2Map.get("stringProperty"));
+        assertEquals("stringProperty", mpConfig.getName());
+        assertEquals("java.lang.String", mpConfig.getType());
+        assertEquals("Override The Annotation", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        // Validate configuration of bean3
+        ManagedBeanConfig bean3 = fcConfig.getManagedBean("bean3");
+        assertNotNull(bean3);
+        assertTrue(bean3 == mbMap.get("bean3"));
+        assertEquals("bean3", bean3.getName());
+        assertEquals("org.apache.shale.tiger.config.TestBean3", bean3.getType());
+        assertEquals("session", bean3.getScope());
+        assertNull(bean3.getListEntries());
+        assertNull(bean3.getMapEntries());
+        Map<String,ManagedPropertyConfig> bean3Map = bean3.getProperties();
+        assertNotNull(bean3Map);
+        assertEquals(8, bean3Map.size());
+
+        mpConfig = bean3.getProperty("byteProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean3Map.get("byteProperty"));
+        assertEquals("byteProperty", mpConfig.getName());
+        assertEquals("byte", mpConfig.getType());
+        assertEquals("-1", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean3.getProperty("charProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean3Map.get("charProperty"));
+        assertEquals("charProperty", mpConfig.getName());
+        assertEquals("char", mpConfig.getType());
+        assertEquals("z", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean3.getProperty("doubleProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean3Map.get("doubleProperty"));
+        assertEquals("doubleProperty", mpConfig.getName());
+        assertEquals("double", mpConfig.getType());
+        assertEquals("-2.0", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean3.getProperty("floatProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean3Map.get("floatProperty"));
+        assertEquals("floatProperty", mpConfig.getName());
+        assertEquals("float", mpConfig.getType());
+        assertEquals("-3.0", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean3.getProperty("intProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean3Map.get("intProperty"));
+        assertEquals("intProperty", mpConfig.getName());
+        assertEquals("int", mpConfig.getType());
+        assertEquals("-4", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean3.getProperty("longProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean3Map.get("longProperty"));
+        assertEquals("longProperty", mpConfig.getName());
+        assertEquals("long", mpConfig.getType());
+        assertEquals("-5", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean3.getProperty("shortProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean3Map.get("shortProperty"));
+        assertEquals("shortProperty", mpConfig.getName());
+        assertEquals("short", mpConfig.getType());
+        assertEquals("-6", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        mpConfig = bean3.getProperty("stringProperty");
+        assertNotNull(mpConfig);
+        assertTrue(mpConfig == bean3Map.get("stringProperty"));
+        assertEquals("stringProperty", mpConfig.getName());
+        assertEquals("java.lang.String", mpConfig.getType());
+        assertEquals("Annotated", mpConfig.getValue());
+        assertTrue(!mpConfig.isNullValue());
+
+        // Test existence of "org.apache.shale.TAG_UTILITY_BEAN" managed bean
+        ManagedBeanConfig tagUtilityBean = fcConfig.getManagedBean("org.apache.shale.TAG_UTILITY_BEAN");
+        assertNotNull(tagUtilityBean);
+
+        // Finalize the servlet context listener
+        listener.contextDestroyed(event);
+
+    }
+
+
     // Test a prisine instance
     public void testPristine() {
 
-        ;
+        assertNotNull(listener);
+
+    }
+
+
+    // Test registration of JavaServer Faces objects
+    public void testRegister() {
+
+        // Create a ServletContextEvent we will pass to the event methods
+        ServletContextEvent event = new ServletContextEvent(servletContext);
+
+        // Initialize the servlet context listener
+        listener.contextInitialized(event);
+
+        // Check for the widgets that should have been registered
+        UIComponent comp = application.createComponent("foo.MyComponent");
+        assertNotNull(comp);
+        Converter conv = application.createConverter("foo.MyConverter");
+        assertNotNull(conv);
+        Renderer rend = renderKit.getRenderer("foo.MyFamily", "foo.MyRenderer");
+        assertNotNull(rend);
+        Validator val = application.createValidator("foo.MyValidator");
+        assertNotNull(val);
+
+        // Check our lifecycle instance as well
+        PhaseListener listeners[] = lifecycle.getPhaseListeners();
+        assertNotNull(listeners);
+        assertEquals(1, listeners.length);
+        assertTrue(listeners[0] instanceof PhaseListenerAdapter);
+
+        // Finalize the servlet context listener
+        listener.contextDestroyed(event);
 
     }