Author: craigmcc
Date: Sun May 21 20:51:47 2006
New Revision: 408560

URL: http://svn.apache.org/viewvc?rev=408560&view=rev
Log:
Implement servlet scoped (request, session, application) event callbacks via
annotations, in addition to the support found in org.apache.shale.view.
Abstract{Request,Session,Application}Bean.  This support enables zero-config
lifecycle support for arbitrary application beans, without having to implement
things like a ServletContextAttributeListener.  Includes tests cases.

Added:
    struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Activate.java
    
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Application.java
    struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Passivate.java
    struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Request.java
    struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Session.java
    
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java
    
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean1.java
    
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean2.java
    
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java
    
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean1.java
    
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean2.java
    
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean1.java
    
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean2.java
Modified:
    struts/shale/trunk/sql-browser/nbproject/project.xml
    struts/shale/trunk/tiger/nbproject/private/private.xml
    struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Destroy.java
    struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Init.java
    struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/package.html

Modified: struts/shale/trunk/sql-browser/nbproject/project.xml
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/sql-browser/nbproject/project.xml?rev=408560&r1=408559&r2=408560&view=diff
==============================================================================
--- struts/shale/trunk/sql-browser/nbproject/project.xml (original)
+++ struts/shale/trunk/sql-browser/nbproject/project.xml Sun May 21 20:51:47 
2006
@@ -94,7 +94,7 @@
                 <package-root>src/systest</package-root>
                 <package-root>src/test</package-root>
                 <package-root>src/web</package-root>
-                <classpath 
mode="compile">../target/dist/shale-core.jar:../target/dist/shale-tiger.jar:../lib/myfaces/myfaces-api.jar:../lib/servlet-api/servlet-api.jar:../lib/myfaces/myfaces-api.jar:../../../../../../../usr/local/db-derby-10.1.2.1-bin/lib/derby.jar</classpath>
+                <classpath 
mode="compile">../target/dist/shale-core.jar;../target/dist/shale-tiger.jar;../lib/myfaces/myfaces-api.jar;../lib/servlet-api/servlet-api.jar;../lib/myfaces/myfaces-api.jar;../../../../../usr/local/db-derby-10.1.2.1-bin/lib/derby.jar;../lib/jsf-ri/jsf-api.jar</classpath>
                 <source-level>1.5</source-level>
             </compilation-unit>
         </java-data>

Modified: struts/shale/trunk/tiger/nbproject/private/private.xml
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/nbproject/private/private.xml?rev=408560&r1=408559&r2=408560&view=diff
==============================================================================
--- struts/shale/trunk/tiger/nbproject/private/private.xml (original)
+++ struts/shale/trunk/tiger/nbproject/private/private.xml Sun May 21 20:51:47 
2006
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project-private xmlns="http://www.netbeans.org/ns/project-private/1";>
-    <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
-</project-private>
+<?xml version="1.0" encoding="UTF-8"?>
+<project-private xmlns="http://www.netbeans.org/ns/project-private/1";>
+    <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
+</project-private>

Added: 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Activate.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Activate.java?rev=408560&view=auto
==============================================================================
--- struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Activate.java 
(added)
+++ struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Activate.java 
Sun May 21 20:51:47 2006
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Method-level annotation indicating that the decorated method should
+ * have the semantics of
+ * <code>org.apache.shale.view.AbstractSessionBean.activate()</code>,
+ * even if it is named differently.</p>
+ *
+ * <p><strong>ASSERTION</strong> - the annotated method is public, has
+ * a return type of <code>void</code>, and takes no parameters.</p>
+ *
+ * <p><strong>ASSERTION</strong> - the annotated method is part of a class
+ * that is annotated with the [EMAIL PROTECTED] Session} annotation.</p>
+ *
+ * @since 1.0.3
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED](ElementType.METHOD)
+public @interface Activate {
+}

Added: 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Application.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Application.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Application.java 
(added)
+++ 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Application.java 
Sun May 21 20:51:47 2006
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Class-level annotation indicating that the decorated class should be
+ * treated semantically as if it extended
+ * <code>org.apache.shale.view.AbstractApplicationBean</code>, even if it does 
not.</p>
+ *
+ * <p><strong>WARNING</strong> - it may turn out that this annotation is
+ * unnecessary, because an annotation processor can simply look for a class
+ * that has method(s) implementing the method level annotations.</p>
+ *
+ * @since 1.0.3
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED](ElementType.TYPE)
+public @interface Application {
+}

Modified: 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Destroy.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Destroy.java?rev=408560&r1=408559&r2=408560&view=diff
==============================================================================
--- struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Destroy.java 
(original)
+++ struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Destroy.java 
Sun May 21 20:51:47 2006
@@ -25,13 +25,15 @@
  * <p>Method-level annotation indicating that the decorated method should
  * have the semantics of
  * <code>org.apache.shale.view.ViewController.destroy()</code>,
+ * or one of the scoped data bean destroy() methods,
  * even if it is named differently.</p>
  *
  * <p><strong>ASSERTION</strong> - the annotated method is public, has
  * a return type of <code>void</code>, and takes no parameters.</p>
  *
  * <p><strong>ASSERTION</strong> - the annotated method is part of a class
- * that is annotated with the [EMAIL PROTECTED] View} annotation.</p>
+ * that is annotated with the [EMAIL PROTECTED] Application}, [EMAIL 
PROTECTED] Request},
+ * [EMAIL PROTECTED] Session}, or [EMAIL PROTECTED] View} annotation.</p>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)

Modified: 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Init.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Init.java?rev=408560&r1=408559&r2=408560&view=diff
==============================================================================
--- struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Init.java 
(original)
+++ struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Init.java Sun 
May 21 20:51:47 2006
@@ -25,13 +25,15 @@
  * <p>Method-level annotation indicating that the decorated method should
  * have the semantics of
  * <code>org.apache.shale.view.ViewController.init()</code>,
+ * or one of the scoped data bean init() methods,
  * even if it is named differently.</p>
  *
  * <p><strong>ASSERTION</strong> - the annotated method is public, has
  * a return type of <code>void</code>, and takes no parameters.</p>
  *
  * <p><strong>ASSERTION</strong> - the annotated method is part of a class
- * that is annotated with the [EMAIL PROTECTED] View} annotation.</p>
+ * that is annotated with the [EMAIL PROTECTED] Application}, [EMAIL 
PROTECTED] Request},
+ * [EMAIL PROTECTED] Session}, or [EMAIL PROTECTED] View} annotation.</p>
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)

Added: 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Passivate.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Passivate.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Passivate.java 
(added)
+++ 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Passivate.java 
Sun May 21 20:51:47 2006
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Method-level annotation indicating that the decorated method should
+ * have the semantics of
+ * <code>org.apache.shale.view.AbstractSessionBean.passivate()</code>,
+ * even if it is named differently.</p>
+ *
+ * <p><strong>ASSERTION</strong> - the annotated method is public, has
+ * a return type of <code>void</code>, and takes no parameters.</p>
+ *
+ * <p><strong>ASSERTION</strong> - the annotated method is part of a class
+ * that is annotated with the [EMAIL PROTECTED] Session} annotation.</p>
+ *
+ * @since 1.0.3
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED](ElementType.METHOD)
+public @interface Passivate {
+}

Added: 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Request.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Request.java?rev=408560&view=auto
==============================================================================
--- struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Request.java 
(added)
+++ struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Request.java 
Sun May 21 20:51:47 2006
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Class-level annotation indicating that the decorated class should be
+ * treated semantically as if it extended
+ * <code>org.apache.shale.view.AbstractRequestBean</code>, even if it does 
not.</p>
+ *
+ * <p><strong>WARNING</strong> - it may turn out that this annotation is
+ * unnecessary, because an annotation processor can simply look for a class
+ * that has method(s) implementing the method level annotations.</p>
+ *
+ * @since 1.0.3
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED](ElementType.TYPE)
+public @interface Request {
+}

Added: 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Session.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Session.java?rev=408560&view=auto
==============================================================================
--- struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Session.java 
(added)
+++ struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Session.java 
Sun May 21 20:51:47 2006
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Class-level annotation indicating that the decorated class should be
+ * treated semantically as if it extended
+ * <code>org.apache.shale.view.AbstractSessionBean</code>, even if it does 
not.</p>
+ *
+ * <p><strong>WARNING</strong> - it may turn out that this annotation is
+ * unnecessary, because an annotation processor can simply look for a class
+ * that has method(s) implementing the method level annotations.</p>
+ *
+ * @since 1.0.3
+ */
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED](ElementType.TYPE)
+public @interface Session {
+}

Added: 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java
 (added)
+++ 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/LifecycleListener2.java
 Sun May 21 20:51:47 2006
@@ -0,0 +1,597 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view.faces;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import javax.servlet.ServletContextAttributeEvent;
+import javax.servlet.ServletRequestAttributeEvent;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionEvent;
+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;
+import org.apache.shale.tiger.view.Preprocess;
+import org.apache.shale.tiger.view.Prerender;
+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.view.AbstractApplicationBean;
+import org.apache.shale.view.AbstractRequestBean;
+import org.apache.shale.view.AbstractSessionBean;
+import org.apache.shale.view.faces.LifecycleListener;
+
+/**
+ * <p>Specialized version of 
<code>org.apache.shale.view.faces.LifecycleListener</code>
+ * that implements callbacks to methods tagged by appropriate annotations,
+ * rather than requiring the containing classes to implement a particular
+ * interface or extend a particular subclass.</p>
+ *
+ * $Id$
+ *
+ * @since 1.0.3
+ */
+public class LifecycleListener2 extends LifecycleListener {
+    
+
+    // ------------------------------------------------------------- 
Constructor
+
+
+    /**
+     * <p>Create a new lifecycle listener.</p>
+     */
+    public LifecycleListener2() {      
+    }
+    
+
+    // ------------------------------------------------------ Instance 
Variables
+
+
+    /**
+     * <p>Parameter values array that passes no parameters.</p>
+     */
+    private static final Object PARAMETERS[] = new Object[0];
+
+
+    // --------------------------------- ServletContextAttributeListener 
Methods
+
+
+    /**
+     * <p>Respond to an application scope attribute being added.  If the
+     * value is an [EMAIL PROTECTED] AbstractApplicationBean}, call its
+     * <code>init()</code> method.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void attributeAdded(ServletContextAttributeEvent event) {
+
+        Object value = event.getValue();
+        if (value != null) {
+            fireApplicationInit(value);
+        }
+
+    }
+
+
+    /**
+     * <p>Respond to an application scope attribute being replaced.
+     * If the old value was an [EMAIL PROTECTED] AbstractApplicationBean}, call
+     * its <code>destroy()</code> method.  If the new value is an
+     * [EMAIL PROTECTED] AbstractApplicationBean}, call its <code>init()</code>
+     * method.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void attributeReplaced(ServletContextAttributeEvent event) {
+
+        Object value = event.getValue();
+        if (value != null) {
+            fireApplicationDestroy(value);
+        }
+
+        value = event.getServletContext().getAttribute(event.getName());
+        if (value != null) {
+            fireApplicationInit(value);
+        }
+
+    }
+
+
+    /**
+     * <p>Respond to an application scope attribute being removed.
+     * If the old value was an [EMAIL PROTECTED] AbstractApplicationBean}, call
+     * its <code>destroy()</code> method.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void attributeRemoved(ServletContextAttributeEvent event) {
+
+        Object value = event.getValue();
+        if (value != null) {
+            fireApplicationDestroy(value);
+        }
+
+    }
+
+
+    // ----------------------------------- HttpSessionActivationListener 
Methods
+
+
+    /**
+     * <p>Respond to a "session will passivate" event.  Notify all session
+     * scope attributes that are [EMAIL PROTECTED] AbstractSessionBean}s.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void sessionWillPassivate(HttpSessionEvent event) {
+
+        Enumeration names = event.getSession().getAttributeNames();
+        while (names.hasMoreElements()) {
+            String name = (String) names.nextElement();
+            Object value = event.getSession().getAttribute(name);
+            if (value != null) {
+                fireSessionPassivate(value);
+            }
+        }
+
+    }
+
+
+    /**
+     * <p>Respond to a "session did activate" event.  Notify all session
+     * scope attributes that are [EMAIL PROTECTED] AbstractSessionBean}s.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void sessionDidActivate(HttpSessionEvent event) {
+
+        Enumeration names = event.getSession().getAttributeNames();
+        while (names.hasMoreElements()) {
+            String name = (String) names.nextElement();
+            Object value = event.getSession().getAttribute(name);
+            if (value != null) {
+                fireSessionActivate(value);
+            }
+        }
+
+    }
+
+
+    // ------------------------------------ HttpSessionAttributeListener 
Methods
+
+
+    /**
+     * <p>Respond to a session scope attribute being added.  If the
+     * value is an [EMAIL PROTECTED] AbstractSessionBean}, call its
+     * <code>init()</code> method.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void attributeAdded(HttpSessionBindingEvent event) {
+
+        Object value = event.getValue();
+        if (value != null) {
+            fireSessionInit(value);
+        }
+
+    }
+
+
+    /**
+     * <p>Respond to a session scope attribute being replaced.
+     * If the old value was an [EMAIL PROTECTED] AbstractSessionBean}, call
+     * its <code>destroy()</code> method.  If the new value is an
+     * [EMAIL PROTECTED] AbstractSessionBean}, call its <code>init()</code>
+     * method.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void attributeReplaced(HttpSessionBindingEvent event) {
+
+        Object value = event.getValue();
+        if (value != null) {
+            fireSessionDestroy(value);
+        }
+
+        value = event.getSession().getAttribute(event.getName());
+        if (value != null) {
+            fireSessionInit(value);
+        }
+
+    }
+
+
+    /**
+     * <p>Respond to a session scope attribute being removed.
+     * If the old value was an [EMAIL PROTECTED] AbstractSessionBean}, call
+     * its <code>destroy()</code> method.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void attributeRemoved(HttpSessionBindingEvent event) {
+
+        Object value = event.getValue();
+        if (value != null) {
+            fireSessionDestroy(value);
+        }
+
+    }
+
+
+    // --------------------------------- ServletRequestAttributeListener 
Methods
+
+
+    /**
+     * <p>Respond to a request scope attribute being added.  If the
+     * value is an [EMAIL PROTECTED] AbstractRequestBean}, call its 
<code>init()</code> method.
+     * </p>
+     *
+     * @param event Event to be processed
+     */
+    public void attributeAdded(ServletRequestAttributeEvent event) {
+
+        Object value = event.getValue();
+        if (value != null) {
+            fireRequestInit(value);
+        }
+
+    }
+
+
+    /**
+     * <p>Respond to a request scope attribute being replaced.
+     * If the old value was an [EMAIL PROTECTED] AbstractRequestBean},
+     * call its <code>destroy()</code> method.  If the new value is an
+     * [EMAIL PROTECTED] AbstractRequestBean}, call its <code>init()</code> 
method.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void attributeReplaced(ServletRequestAttributeEvent event) {
+
+        Object value = event.getValue();
+        if (value != null) {
+            fireRequestDestroy(value);
+        }
+
+        value = event.getServletRequest().getAttribute(event.getName());
+        if (value != null) {
+            fireRequestInit(value);
+        }
+
+    }
+
+
+    /**
+     * <p>Respond to a request scope attribute being removed.
+     * If the old value was an [EMAIL PROTECTED] AbstractRequestBean},
+     * call its <code>destroy()</code> method.</p>
+     *
+     * @param event Event to be processed
+     */
+    public void attributeRemoved(ServletRequestAttributeEvent event) {
+
+        Object value = event.getValue();
+        if (value != null) {
+            fireRequestDestroy(value);
+        }
+
+    }
+
+
+    // ------------------------------------------------------- Protected 
Methods
+
+
+    /**
+     * <p>Fire a destroy event on an @{link AbstractApplicationBean}.</p>
+     *
+     * @param bean [EMAIL PROTECTED] AbstractApplicationBean} to fire event on
+     */
+    protected void fireApplicationDestroy(Object bean) {
+
+        if (bean instanceof AbstractApplicationBean) {
+            super.fireApplicationDestroy(bean);
+            return;
+        }
+
+        try {
+            Method method = method(bean, Destroy.class);
+            if (method != null) {
+                method.invoke(bean, PARAMETERS);
+            }
+        } catch (InvocationTargetException e) {
+            cacheException((Exception) e.getCause());
+        } catch (Exception e) {
+            cacheException(e);
+        }
+
+    }
+
+
+    /**
+     * <p>Fire an init event on an [EMAIL PROTECTED] 
AbstractApplicationBean}.</p>
+     *
+     * @param bean [EMAIL PROTECTED] AbstractApplicationBean} to fire event on
+     */
+    protected void fireApplicationInit(Object bean) {
+
+        if (bean instanceof AbstractApplicationBean) {
+            super.fireApplicationInit(bean);
+            return;
+        }
+
+        try {
+            Method method = method(bean, Init.class);
+            if (method != null) {
+                method.invoke(bean, PARAMETERS);
+            }
+        } catch (InvocationTargetException e) {
+            cacheException((Exception) e.getCause());
+        } catch (Exception e) {
+            cacheException(e);
+        }
+
+    }
+
+
+    /**
+     * <p>Fire a destroy event on an @{link AbstractRequestBean}.</p>
+     *
+     * @param bean [EMAIL PROTECTED] AbstractRequestBean} to fire event on
+     */
+    protected void fireRequestDestroy(Object bean) {
+
+        if (bean instanceof AbstractRequestBean) {
+            super.fireRequestDestroy(bean);
+            return;
+        }
+
+        try {
+            Method method = method(bean, Destroy.class);
+            if (method != null) {
+                method.invoke(bean, PARAMETERS);
+            }
+        } catch (InvocationTargetException e) {
+            cacheException((Exception) e.getCause());
+        } catch (Exception e) {
+            cacheException(e);
+        }
+
+    }
+
+
+    /**
+     * <p>Fire an init event on an [EMAIL PROTECTED] AbstractRequestBean}.</p>
+     *
+     * @param bean [EMAIL PROTECTED] AbstractRequestBean} to fire event on
+     */
+    protected void fireRequestInit(Object bean) {
+
+        if (bean instanceof AbstractRequestBean) {
+            super.fireRequestInit(bean);
+            return;
+        }
+
+        try {
+            Method method = method(bean, Init.class);
+            if (method != null) {
+                method.invoke(bean, PARAMETERS);
+            }
+        } catch (InvocationTargetException e) {
+            cacheException((Exception) e.getCause());
+        } catch (Exception e) {
+            cacheException(e);
+        }
+
+    }
+
+
+    /**
+     * <p>Fire an activate event on an @{link AbstractSessionBean}.</p>
+     *
+     * @param bean [EMAIL PROTECTED] AbstractSessionBean} to fire event on
+     */
+    protected void fireSessionActivate(Object bean) {
+
+        if (bean instanceof AbstractSessionBean) {
+            super.fireSessionActivate(bean);
+            return;
+        }
+
+        try {
+            Method method = method(bean, Activate.class);
+            if (method != null) {
+                method.invoke(bean, PARAMETERS);
+            }
+        } catch (InvocationTargetException e) {
+            cacheException((Exception) e.getCause());
+        } catch (Exception e) {
+            cacheException(e);
+        }
+
+    }
+
+
+    /**
+     * <p>Fire a destroy event on an @{link AbstractSessionBean}.</p>
+     *
+     * @param bean [EMAIL PROTECTED] AbstractSessionBean} to fire event on
+     */
+    protected void fireSessionDestroy(Object bean) {
+
+        if (bean instanceof AbstractSessionBean) {
+            super.fireSessionDestroy(bean);
+            return;
+        }
+
+        try {
+            Method method = method(bean, Destroy.class);
+            if (method != null) {
+                method.invoke(bean, PARAMETERS);
+            }
+        } catch (InvocationTargetException e) {
+            cacheException((Exception) e.getCause());
+        } catch (Exception e) {
+            cacheException(e);
+        }
+
+    }
+
+
+    /**
+     * <p>Fire an init event on an [EMAIL PROTECTED] AbstractSessionBean}.</p>
+     *
+     * @param bean [EMAIL PROTECTED] AbstractSessionBean} to fire event on
+     */
+    protected void fireSessionInit(Object bean) {
+
+        if (bean instanceof AbstractSessionBean) {
+            super.fireSessionInit(bean);
+            return;
+        }
+
+        try {
+            Method method = method(bean, Init.class);
+            if (method != null) {
+                method.invoke(bean, PARAMETERS);
+            }
+        } catch (InvocationTargetException e) {
+            cacheException((Exception) e.getCause());
+        } catch (Exception e) {
+            cacheException(e);
+        }
+
+    }
+
+
+    /**
+     * <p>Fire an passivate event on an @{link AbstractSessionBean}.</p>
+     *
+     * @param bean [EMAIL PROTECTED] AbstractSessionBean} to fire event on
+     */
+    protected void fireSessionPassivate(Object bean) {
+
+        if (bean instanceof AbstractSessionBean) {
+            super.fireSessionPassivate(bean);
+            return;
+        }
+
+        try {
+            Method method = method(bean, Passivate.class);
+            if (method != null) {
+                method.invoke(bean, PARAMETERS);
+            }
+        } catch (InvocationTargetException e) {
+            cacheException((Exception) e.getCause());
+        } catch (Exception e) {
+            cacheException(e);
+        }
+
+    }
+
+
+    // --------------------------------------------------------- Private 
Methods
+
+
+    /**
+     * <p>The set of method annotations for callbacks of interest.</p>
+     */
+    private static final Class annotations[] =
+    { Init.class, Preprocess.class, Prerender.class, Destroy.class,
+      Activate.class, Passivate.class };
+
+
+
+    /**
+     * <p>The set of class annotations for classes of interest.</p>
+     */
+    private static final Class markers[] =
+    { View.class, Request.class, Session.class, Application.class };
+
+
+    /**
+     * <p>Data structure to maintain information about annotated
+     * methods.  In this map, the key is the Class being analyzed,
+     * and the value is an inner map.  In the inner map, the key
+     * is an Annotation class, and the value is the corresponding
+     * Method instance.</p>
+     */
+    private transient Map<Class,Map<Class,Method>> maps =
+      new HashMap<Class,Map<Class,Method>>();
+
+
+    /**
+     * <p>Return the <code>Method</code> to be called for the specified
+     * annotation on the specified instance, if any.  If there is no such
+     * method, return <code>null</code>.</p>
+     *
+     * @param instance Instance on which callbacks will be performed
+     * @param annotation Annotation for which to return a method
+     */
+    private Method method(Object instance, Class annotation) {
+
+
+        // Does the underlying class implement a relevant class annotation?
+        // If not, exit early
+        Class clazz = instance.getClass();
+        boolean found = false;
+        for (Class marker : markers) {
+            if (clazz.getAnnotation(marker) != null) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            return null;
+        }
+
+        synchronized (maps) {
+
+            // If we have seen this Class already, simply return the
+            // previously located Method (if any)
+            Map<Class,Method> map = maps.get(clazz);
+            if (map != null) {
+                return map.get(annotation);
+            }
+
+            // Construct and cache a new Map identifying the
+            // methods of interest for these callbacks
+            map = new HashMap<Class,Method>();
+            Method methods[] = clazz.getMethods();
+            for (Method method : methods) {
+                if (method.getParameterTypes().length > 0) {
+                    continue;
+                }
+                for (Class anno : annotations) {
+                    if (method.getAnnotation(anno) != null) {
+                        map.put(anno, method);
+                    }
+                }
+            }
+            maps.put(clazz, map);
+            return map.get(annotation);
+
+        }
+
+    }
+
+
+}

Modified: 
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/package.html
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/package.html?rev=408560&r1=408559&r2=408560&view=diff
==============================================================================
--- struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/package.html 
(original)
+++ struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/package.html 
Sun May 21 20:51:47 2006
@@ -39,6 +39,14 @@
     }
 </pre>
 
+<p>In addition, the class level annotations <code>Application</code>,
+<code>Request</code>, and <code>Session</code> mark beans that should
+be treated as if they extended <code>AbstractApplicationBean</code>,
+<code>AbstractRequestBean</code>, or <code>AbstractSessionBean</code>
+respectively, even if they do not.  Such beans will have lifecycle event
+callbacks performed on methods that are marked with the corresponding
+method level annotation.</p>
+
 <p>API STATUS:  Experimental.</p>
 
 <p>IMPLEMENTATION STATUS:  Implemented, but only lightly tested.</p>

Added: 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean1.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean1.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean1.java
 (added)
+++ 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean1.java
 Sun May 21 20:51:47 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view.faces;
+
+import org.apache.shale.view.AbstractApplicationBean;
+
+/**
+ * <p>Test bean that subclasses <code>AbstractApplicationBean</code> so we can
+ * test pass-through calls to "regular" bean instances.</p>
+ */
+public class ApplicationBean1 extends AbstractApplicationBean {
+    
+
+    private StringBuffer sb = new StringBuffer();
+
+
+    // -------------------------------------------------------- Callback 
Methods
+
+
+    public void init() {
+        sb.append("init/");
+    }
+
+
+    public void destroy() {
+        sb.append("destroy/");
+    }
+
+
+    // ---------------------------------------------------------- Public 
Methods
+
+
+    public String log() {
+        return sb.toString();
+    }
+
+
+}

Added: 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean2.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean2.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean2.java
 (added)
+++ 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ApplicationBean2.java
 Sun May 21 20:51:47 2006
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view.faces;
+
+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.view.AbstractApplicationBean;
+
+/**
+ * <p>Test bean that does not subclass <code>AbstractApplicationBean</code>,
+ * but uses corresponding annotations, so that we can test callback events.</p>
+ */
[EMAIL PROTECTED]
+public class ApplicationBean2 {
+    
+
+    private StringBuffer sb = new StringBuffer();
+
+
+    // -------------------------------------------------------- Callback 
Methods
+
+
+    @Init
+    public void doInit() {
+        sb.append("init/");
+    }
+
+
+    @Destroy
+    public void doDestroy() {
+        sb.append("destroy/");
+    }
+
+
+    // ---------------------------------------------------------- Public 
Methods
+
+
+    public String log() {
+        return sb.toString();
+    }
+
+
+}

Added: 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java
 (added)
+++ 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/LifecycleListener2TestCase.java
 Sun May 21 20:51:47 2006
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view.faces;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.shale.test.base.AbstractJsfTestCase;
+import org.apache.shale.view.faces.LifecycleListener;
+
+/**
+ * <p>Test case for 
<code>org.apache.shale.tiger.view.faces.LifecycleListener</code>.</p>
+ */
+public class LifecycleListener2TestCase extends AbstractJsfTestCase {
+    
+    
+    // ------------------------------------------------------------ 
Constructors
+
+
+    // Construct a new instance of this test case.
+    public LifecycleListener2TestCase(String name) {
+        super(name);
+    }
+
+
+    // ---------------------------------------------------- Overall Test 
Methods
+
+
+    // Set up instance variables required by this test case.
+    public void setUp() {
+
+        super.setUp();
+
+        // Set up our listener and bind it to context/session/request objects
+        listener = new LifecycleListener();
+        servletContext.addAttributeListener(listener);
+        session.addAttributeListener(listener);
+        request.addAttributeListener(listener);
+        
+    }
+
+
+    // Return the tests included in this test case.
+    public static Test suite() {
+
+        return (new TestSuite(LifecycleListener2TestCase.class));
+
+    }
+
+
+    // Tear down instance variables required by this test case.
+    public void tearDown() {
+
+//        callbacks = null;
+        lifecycle = null;
+
+        super.tearDown();
+
+    }
+
+
+    // ------------------------------------------------------ Instance 
Variables
+
+
+    private LifecycleListener listener = null;
+
+
+    // ------------------------------------------------------------ Test 
Methods
+
+
+    // Test standard application bean
+    public void testApplicationBean1() {
+
+        ApplicationBean1 bean = new ApplicationBean1();
+        assertEquals("", bean.log());
+        servletContext.setAttribute("bean", bean);
+        assertEquals("init/", bean.log());
+        servletContext.setAttribute("bean", bean);
+        assertEquals("init/destroy/init/", bean.log());
+        servletContext.removeAttribute("bean");
+        assertEquals("init/destroy/init/destroy/", bean.log());
+
+    }
+
+
+    // Test annotated application bean
+    public void testApplicationBean2() {
+
+        ApplicationBean2 bean = new ApplicationBean2();
+        assertEquals("", bean.log());
+        servletContext.setAttribute("bean", bean);
+        assertEquals("init/", bean.log());
+        servletContext.setAttribute("bean", bean);
+        assertEquals("init/destroy/init/", bean.log());
+        servletContext.removeAttribute("bean");
+        assertEquals("init/destroy/init/destroy/", bean.log());
+
+    }
+
+
+    // Test a prisine instance
+    public void testPristine() {
+
+        ;
+
+    }
+
+
+    // Test standard request bean
+    public void testRequestBean1() {
+
+        RequestBean1 bean = new RequestBean1();
+        assertEquals("", bean.log());
+        request.setAttribute("bean", bean);
+        assertEquals("init/", bean.log());
+        request.setAttribute("bean", bean);
+        assertEquals("init/destroy/init/", bean.log());
+        request.removeAttribute("bean");
+        assertEquals("init/destroy/init/destroy/", bean.log());
+
+    }
+
+
+    // Test annotated request bean
+    public void testRequestBean2() {
+
+        RequestBean2 bean = new RequestBean2();
+        assertEquals("", bean.log());
+        request.setAttribute("bean", bean);
+        assertEquals("init/", bean.log());
+        request.setAttribute("bean", bean);
+        assertEquals("init/destroy/init/", bean.log());
+        request.removeAttribute("bean");
+        assertEquals("init/destroy/init/destroy/", bean.log());
+
+    }
+
+
+    // Test standard session bean
+    public void testSessionBean1() {
+
+        SessionBean1 bean = new SessionBean1();
+        assertEquals("", bean.log());
+        session.setAttribute("bean", bean);
+        assertEquals("init/", bean.log());
+        session.setAttribute("bean", bean);
+        assertEquals("init/destroy/init/", bean.log());
+        session.removeAttribute("bean");
+        assertEquals("init/destroy/init/destroy/", bean.log());
+
+    }
+
+
+    // Test annotated session bean
+    public void testSessionBean2() {
+
+        SessionBean2 bean = new SessionBean2();
+        assertEquals("", bean.log());
+        session.setAttribute("bean", bean);
+        assertEquals("init/", bean.log());
+        session.setAttribute("bean", bean);
+        assertEquals("init/destroy/init/", bean.log());
+        session.removeAttribute("bean");
+        assertEquals("init/destroy/init/destroy/", bean.log());
+
+    }
+
+
+}

Added: 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean1.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean1.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean1.java
 (added)
+++ 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean1.java
 Sun May 21 20:51:47 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view.faces;
+
+import org.apache.shale.view.AbstractRequestBean;
+
+/**
+ * <p>Test bean that subclasses <code>AbstractRequestBean</code> so we can
+ * test pass-through calls to "regular" bean instances.</p>
+ */
+public class RequestBean1 extends AbstractRequestBean {
+    
+
+    private StringBuffer sb = new StringBuffer();
+
+
+    // -------------------------------------------------------- Callback 
Methods
+
+
+    public void init() {
+        sb.append("init/");
+    }
+
+
+    public void destroy() {
+        sb.append("destroy/");
+    }
+
+
+    // ---------------------------------------------------------- Public 
Methods
+
+
+    public String log() {
+        return sb.toString();
+    }
+
+
+}

Added: 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean2.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean2.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean2.java
 (added)
+++ 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/RequestBean2.java
 Sun May 21 20:51:47 2006
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view.faces;
+
+import org.apache.shale.tiger.view.Destroy;
+import org.apache.shale.tiger.view.Init;
+import org.apache.shale.tiger.view.Request;
+
+/**
+ * <p>Test bean that does not subclass <code>AbstractRequestBean</code>,
+ * but uses corresponding annotations, so that we can test callback events.</p>
+ */
[EMAIL PROTECTED]
+public class RequestBean2 {
+    
+
+    private StringBuffer sb = new StringBuffer();
+
+
+    // -------------------------------------------------------- Callback 
Methods
+
+
+    @Init
+    public void doInit() {
+        sb.append("init/");
+    }
+
+
+    @Destroy
+    public void doDestroy() {
+        sb.append("destroy/");
+    }
+
+
+    // ---------------------------------------------------------- Public 
Methods
+
+
+    public String log() {
+        return sb.toString();
+    }
+
+
+}

Added: 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean1.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean1.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean1.java
 (added)
+++ 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean1.java
 Sun May 21 20:51:47 2006
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view.faces;
+
+import org.apache.shale.view.AbstractSessionBean;
+
+/**
+ * <p>Test bean that subclasses <code>AbstractSessionBean</code> so we can
+ * test pass-through calls to "regular" bean instances.</p>
+ */
+public class SessionBean1 extends AbstractSessionBean {
+    
+
+    private StringBuffer sb = new StringBuffer();
+
+
+    // -------------------------------------------------------- Callback 
Methods
+
+
+    public void init() {
+        sb.append("init/");
+    }
+
+
+    public void destroy() {
+        sb.append("destroy/");
+    }
+
+
+    // ---------------------------------------------------------- Public 
Methods
+
+
+    public String log() {
+        return sb.toString();
+    }
+
+
+}

Added: 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean2.java
URL: 
http://svn.apache.org/viewvc/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean2.java?rev=408560&view=auto
==============================================================================
--- 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean2.java
 (added)
+++ 
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/SessionBean2.java
 Sun May 21 20:51:47 2006
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiger.view.faces;
+
+import org.apache.shale.tiger.view.Destroy;
+import org.apache.shale.tiger.view.Init;
+import org.apache.shale.tiger.view.Session;
+
+/**
+ * <p>Test bean that does not subclass <code>AbstractSessionBean</code>,
+ * but uses corresponding annotations, so that we can test callback events.</p>
+ */
[EMAIL PROTECTED]
+public class SessionBean2 {
+    
+
+    private StringBuffer sb = new StringBuffer();
+
+
+    // -------------------------------------------------------- Callback 
Methods
+
+
+    @Init
+    public void doInit() {
+        sb.append("init/");
+    }
+
+
+    @Destroy
+    public void doDestroy() {
+        sb.append("destroy/");
+    }
+
+
+    // ---------------------------------------------------------- Public 
Methods
+
+
+    public String log() {
+        return sb.toString();
+    }
+
+
+}


Reply via email to