Author: craigmcc
Date: Sat Jan 14 18:25:29 2006
New Revision: 369163
URL: http://svn.apache.org/viewcvs?rev=369163&view=rev
Log:
Fully implement view controller callbacks via annotations (instead of requiring
a backing bean to implement ViewController) when running on a Java SE 5 or later
platform. These features are enabled automatically by virtue of including
"shale-tiger.jar" with your web application -- no special configuration is
required.
Added:
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2.java
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/package.html
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/CallbacksFactoryTestCase.java
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/TestViewController.java
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2TestCase.java
Modified:
struts/shale/trunk/tiger/build.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/Prerender.java
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/package.html
Modified: struts/shale/trunk/tiger/build.xml
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/build.xml?rev=369163&r1=369162&r2=369163&view=diff
==============================================================================
--- struts/shale/trunk/tiger/build.xml (original)
+++ struts/shale/trunk/tiger/build.xml Sat Jan 14 18:25:29 2006
@@ -176,6 +176,7 @@
<copy todir="${build.home}/classes">
<fileset dir="src/java">
<exclude name="**/*.java"/>
+ <exclude name="**/package.html"/>
</fileset>
</copy>
Modified:
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Destroy.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Destroy.java?rev=369163&r1=369162&r2=369163&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
Sat Jan 14 18:25:29 2006
@@ -22,7 +22,7 @@
import java.lang.annotation.Target;
/**
- * <p>Methoid-level annotation indicating that the decorated method should
+ * <p>Method-level annotation indicating that the decorated method should
* have the semantics of
* <code>org.apache.shale.view.ViewController.destroy()</code>,
* even if it is named differently.</p>
Modified:
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Init.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Init.java?rev=369163&r1=369162&r2=369163&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 Sat
Jan 14 18:25:29 2006
@@ -22,7 +22,7 @@
import java.lang.annotation.Target;
/**
- * <p>Methoid-level annotation indicating that the decorated method should
+ * <p>Method-level annotation indicating that the decorated method should
* have the semantics of
* <code>org.apache.shale.view.ViewController.init()</code>,
* even if it is named differently.</p>
Modified:
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Prerender.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Prerender.java?rev=369163&r1=369162&r2=369163&view=diff
==============================================================================
---
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Prerender.java
(original)
+++
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/Prerender.java
Sat Jan 14 18:25:29 2006
@@ -22,7 +22,7 @@
import java.lang.annotation.Target;
/**
- * <p>Methoid-level annotation indicating that the decorated method should
+ * <p>Method-level annotation indicating that the decorated method should
* have the semantics of
* <code>org.apache.shale.view.ViewController.prerender()</code>,
* even if it is named differently.</p>
Added:
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2.java?rev=369163&view=auto
==============================================================================
---
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2.java
(added)
+++
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2.java
Sat Jan 14 18:25:29 2006
@@ -0,0 +1,237 @@
+/*
+ * 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.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import javax.faces.FacesException;
+import org.apache.shale.tiger.view.Destroy;
+import org.apache.shale.tiger.view.Init;
+import org.apache.shale.tiger.view.Preprocess;
+import org.apache.shale.tiger.view.Prerender;
+import org.apache.shale.tiger.view.View;
+import org.apache.shale.view.ViewController;
+import org.apache.shale.view.faces.ViewControllerCallbacks;
+
+/**
+ * <p>Utility class to perform the event callbacks specified by the
+ * [EMAIL PROTECTED] ViewController} interface. This version will call through
+ * to ViewController methods if the bean class actually implements this
+ * interface, or ituses annotations to identify the relevant methods.</p>
+ *
+ * <p><strong>NOTE</strong> - The annotated callback methods must be
+ * public, and take no arguments. They may exist on the class of the
+ * instance being passed in, or be inherited from a superclass.</p>
+ *
+ * $Id: ViewPhaseListener.java 367148 2006-01-09 01:01:56Z craigmcc $
+ *
+ * @since 1.0.1
+ */
+public class ViewControllerCallbacks2 extends ViewControllerCallbacks {
+
+
+ // ------------------------------------------------------------
Constructors
+
+
+ // ------------------------------------------------------ Instance
Variables
+
+
+ // ---------------------------------------------------------- Public
Methods
+
+
+ /**
+ * <p>Perform the <code>init</code> callback on the specified
+ * instance.</p>
+ *
+ * @param instance Bean instance on which to perform this callback
+ */
+ public void init(Object instance) {
+
+ if (instance instanceof ViewController) {
+ ((ViewController) instance).init();
+ return;
+ }
+
+ Method method = method(instance, Init.class);
+ if (method != null) {
+ try {
+ method.invoke(instance, new Object[0]);
+ } catch (IllegalAccessException e) {
+ throw new FacesException(e);
+ } catch (InvocationTargetException e) {
+ throw new FacesException(e.getCause());
+ }
+ }
+
+ }
+
+
+ /**
+ * <p>Perform the <code>preprocess</code> callback on the specified
+ * instance.</p>
+ *
+ * @param instance Bean instance on which to perform this callback
+ */
+ public void preprocess(Object instance) {
+
+ if (instance instanceof ViewController) {
+ ((ViewController) instance).preprocess();
+ return;
+ }
+
+ Method method = method(instance, Preprocess.class);
+ if (method != null) {
+ try {
+ method.invoke(instance, new Object[0]);
+ } catch (IllegalAccessException e) {
+ throw new FacesException(e);
+ } catch (InvocationTargetException e) {
+ throw new FacesException(e.getCause());
+ }
+ }
+
+ }
+
+
+ /**
+ * <p>Perform the <code>prerender</code> callback on the specified
+ * instance.</p>
+ *
+ * @param instance Bean instance on which to perform this callback
+ */
+ public void prerender(Object instance) {
+
+ if (instance instanceof ViewController) {
+ ((ViewController) instance).prerender();
+ return;
+ }
+
+ Method method = method(instance, Prerender.class);
+ if (method != null) {
+ try {
+ method.invoke(instance, new Object[0]);
+ } catch (IllegalAccessException e) {
+ throw new FacesException(e);
+ } catch (InvocationTargetException e) {
+ throw new FacesException(e.getCause());
+ }
+ }
+
+ }
+
+
+ /**
+ * <p>Perform the <code>destroy</code> callback on the specified
+ * instance.</p>
+ *
+ * @param instance Bean instance on which to perform this callback
+ */
+ public void destroy(Object instance) {
+
+ if (instance instanceof ViewController) {
+ ((ViewController) instance).destroy();
+ return;
+ }
+
+ Method method = method(instance, Destroy.class);
+ if (method != null) {
+ try {
+ method.invoke(instance, new Object[0]);
+ } catch (IllegalAccessException e) {
+ throw new FacesException(e);
+ } catch (InvocationTargetException e) {
+ throw new FacesException(e.getCause());
+ }
+ }
+
+ }
+
+
+ // --------------------------------------------------------- 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 };
+
+
+
+ /**
+ * <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 the View annotation?
+ // If not, exit early
+ Class clazz = instance.getClass();
+ if (clazz.getAnnotation(View.class) == null) {
+ 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 (int i = 0; i < methods.length; i++) {
+ if (methods[i].getParameterTypes().length > 0) {
+ continue;
+ }
+ for (int j = 0; j < annotations.length; j++) {
+ if (methods[i].getAnnotation(annotations[j]) != null) {
+ map.put(annotations[j], methods[i]);
+ }
+ }
+ }
+ maps.put(clazz, map);
+ return map.get(annotation);
+
+ }
+
+ }
+
+
+}
Added:
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/package.html
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/package.html?rev=369163&view=auto
==============================================================================
---
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/package.html
(added)
+++
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/faces/package.html
Sat Jan 14 18:25:29 2006
@@ -0,0 +1,26 @@
+<!--
+ * Copyright 2004-2005 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.
+-->
+
+<!-- $Id: package.html 293010 2005-10-01 17:58:52Z wsmoak $ -->
+
+<body>
+
+<p>This package contains implementations of the event callback support
+described in the <code>org.apache.shale.tiger.view</code> package.</p>
+
[EMAIL PROTECTED] 1.0.1
+
+</body>
Modified:
struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/package.html
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/src/java/org/apache/shale/tiger/view/package.html?rev=369163&r1=369162&r2=369163&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
Sat Jan 14 18:25:29 2006
@@ -41,7 +41,7 @@
<p>API STATUS: Experimental.</p>
-<p>IMPLEMENTATION STATUS: Not yet implemented.</p>
+<p>IMPLEMENTATION STATUS: Implemented, but only lightly tested.</p>
@since 1.0.1
Added:
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/CallbacksFactoryTestCase.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/CallbacksFactoryTestCase.java?rev=369163&view=auto
==============================================================================
---
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/CallbacksFactoryTestCase.java
(added)
+++
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/CallbacksFactoryTestCase.java
Sat Jan 14 18:25:29 2006
@@ -0,0 +1,99 @@
+/*
+ * 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.view.faces.CallbacksFactory;
+import org.apache.shale.view.faces.ViewControllerCallbacks;
+
+/**
+ * <p>Test case for <code>org.apache.shale.view.faces.CallbacksFactory</code>
+ * when the Shale Tiger extensions are available.</p>
+ */
+public class CallbacksFactoryTestCase extends TestCase {
+
+
+ // ------------------------------------------------------------
Constructors
+
+
+ // Construct a new instance of this test case.
+ public CallbacksFactoryTestCase(String name) {
+ super(name);
+ }
+
+
+ // ---------------------------------------------------- Overall Test
Methods
+
+
+ // Set up instance variables required by this test case.
+ public void setUp() {
+
+ factory = CallbacksFactory.getInstance();
+
+ }
+
+
+ // Return the tests included in this test case.
+ public static Test suite() {
+
+ return (new TestSuite(CallbacksFactoryTestCase.class));
+
+ }
+
+
+ // Tear down instance variables required by this test case.
+ public void tearDown() {
+
+ factory = null;
+
+ }
+
+
+ // ------------------------------------------------------ Instance
Variables
+
+
+ private CallbacksFactory factory = null;
+
+
+ // ------------------------------------------------------------ Test
Methods
+
+
+
+ // Test a prisine instance
+ public void testPristine() {
+
+ ;
+
+ }
+
+
+ // Test returning a ViewControllerCallbacks instance
+ public void testViewControllerCallbacks() {
+
+ ViewControllerCallbacks vcc = factory.getViewControllerCallbacks();
+ assertNotNull(vcc);
+
assertEquals("org.apache.shale.tiger.view.faces.ViewControllerCallbacks2",
+ vcc.getClass().getName());
+
+ }
+
+
+
+
+}
Added:
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/TestViewController.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/TestViewController.java?rev=369163&view=auto
==============================================================================
---
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/TestViewController.java
(added)
+++
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/TestViewController.java
Sat Jan 14 18:25:29 2006
@@ -0,0 +1,55 @@
+/*
+ * 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.Preprocess;
+import org.apache.shale.tiger.view.Prerender;
+import org.apache.shale.tiger.view.View;
+import org.apache.shale.view.ViewController;
+
+/**
+ * <p>Test implementation of a view controller that is marked
+ * with annotations, rather than implementing the
+ * <code>ViewController</code> interface directly.</p>
+ */
[EMAIL PROTECTED] public class TestViewController {
+
+ private StringBuffer sb = new StringBuffer();
+
+ @Prerender public void doPrerender() {
+ sb.append("prerender/");
+ }
+
+ @Preprocess public void doPreprocess() {
+ sb.append("preprocess/");
+ }
+
+ @Destroy public void doDestroy() {
+ sb.append("destroy/");
+ }
+
+ @Init public void doInit() {
+ sb.append("init/");
+ }
+
+ public String log() {
+ return sb.toString();
+ }
+
+}
Added:
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2TestCase.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2TestCase.java?rev=369163&view=auto
==============================================================================
---
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2TestCase.java
(added)
+++
struts/shale/trunk/tiger/src/test/org/apache/shale/tiger/view/faces/ViewControllerCallbacks2TestCase.java
Sat Jan 14 18:25:29 2006
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+/**
+ * <p>Test case for
<code>org.apache.shale.tiger.view.faces.ViewControllerCallbacks2</code>.</p>
+ */
+public class ViewControllerCallbacks2TestCase extends TestCase {
+
+
+ // ------------------------------------------------------------
Constructors
+
+
+ // Construct a new instance of this test case.
+ public ViewControllerCallbacks2TestCase(String name) {
+ super(name);
+ }
+
+
+ // ---------------------------------------------------- Overall Test
Methods
+
+
+ // Set up instance variables required by this test case.
+ public void setUp() {
+
+ callbacks = new ViewControllerCallbacks2();
+
+ }
+
+
+ // Return the tests included in this test case.
+ public static Test suite() {
+
+ return (new TestSuite(ViewControllerCallbacks2TestCase.class));
+
+ }
+
+
+ // Tear down instance variables required by this test case.
+ public void tearDown() {
+
+ callbacks = null;
+
+ }
+
+
+ // ------------------------------------------------------ Instance
Variables
+
+
+ private ViewControllerCallbacks2 callbacks = null;
+
+
+ // ------------------------------------------------------------ Test
Methods
+
+
+
+ // Test a prisine instance
+ public void testPristine() {
+
+ ;
+
+ }
+
+
+ // Test calling all of the appropriate methods in order
+ public void testViewControllerCallbacks() {
+
+ TestViewController tvc = new TestViewController();
+ callbacks.init(tvc);
+ callbacks.preprocess(tvc);
+ callbacks.prerender(tvc);
+ callbacks.destroy(tvc);
+ assertEquals("init/preprocess/prerender/destroy/",
+ tvc.log());
+
+ }
+
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]