You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mr...@apache.org on 2006/05/21 06:13:55 UTC
svn commit: r408129 - in /struts/action2/trunk: apps/showcase/
apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/
apps/showcase/src/main/webapp/WEB-INF/
apps/showcase/src/main/webapp/WEB-INF/classes/
apps/showcase/src/main/webapp/WEB-I...
Author: mrdon
Date: Sat May 20 21:13:53 2006
New Revision: 408129
URL: http://svn.apache.org/viewvc?rev=408129&view=rev
Log:
Merges JSF into Action 2, allowing JSF components and backing beans to
be able to be used along side regular saf2 actions. Furthermore, the
familiar feel of an action-based framework is brought to JSF pages,
giving each page its own action and making that action available in the
component's expressions. This commit also includes a new section in the
showcase, demonstrating the JSF support.
WW-1320
Added:
struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/
struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/Employee.java
struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeAction.java
struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeDao.java
struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/IndexAction.java
struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork-jsf.xml
struts/action2/trunk/apps/showcase/src/main/webapp/jsf/
struts/action2/trunk/apps/showcase/src/main/webapp/jsf/employee.jsp
struts/action2/trunk/apps/showcase/src/main/webapp/jsf/index.jsp
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesInterceptor.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSetupInterceptor.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSupport.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsNavigationHandler.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsVariableResolver.java
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java
struts/action2/trunk/core/src/main/resources/org/apache/struts/action2/jsf/
struts/action2/trunk/core/src/main/resources/org/apache/struts/action2/jsf/package.html
Modified:
struts/action2/trunk/apps/showcase/pom.xml
struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork.xml
struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp
struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/web.xml
struts/action2/trunk/core/pom.xml
struts/action2/trunk/core/src/main/resources/struts-default.xml
Modified: struts/action2/trunk/apps/showcase/pom.xml
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/pom.xml?rev=408129&r1=408128&r2=408129&view=diff
==============================================================================
--- struts/action2/trunk/apps/showcase/pom.xml (original)
+++ struts/action2/trunk/apps/showcase/pom.xml Sat May 20 21:13:53 2006
@@ -83,6 +83,17 @@
<version>1.2.1</version>
<scope>provided</scope>
</dependency>
+
+ <dependency>
+ <groupId>myfaces</groupId>
+ <artifactId>myfaces-impl</artifactId>
+ <version>1.1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>myfaces</groupId>
+ <artifactId>myfaces-api</artifactId>
+ <version>1.1.2</version>
+ </dependency>
</dependencies>
Added: struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/Employee.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/Employee.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/Employee.java (added)
+++ struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/Employee.java Sat May 20 21:13:53 2006
@@ -0,0 +1,37 @@
+package org.apache.struts.action2.showcase.jsf;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class Employee {
+ private String name;
+ private int id;
+ private List skills;
+
+ public Employee() {}
+
+ public Employee(int id, String name, String[] skills) {
+ this.id = id;
+ this.name = name;
+ this.skills = Arrays.asList(skills);
+ }
+
+ public int getId() {
+ return id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public List getSkills() {
+ return skills;
+ }
+ public void setSkills(List skills) {
+ this.skills = skills;
+ }
+}
Added: struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeAction.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeAction.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeAction.java (added)
+++ struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeAction.java Sat May 20 21:13:53 2006
@@ -0,0 +1,58 @@
+/*
+ * $Id: QuizAction.java 394498 2006-04-16 15:28:06Z tmjee $
+ *
+ * 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.struts.action2.showcase.jsf;
+
+import java.util.List;
+
+import com.opensymphony.xwork.ActionSupport;
+
+public class EmployeeAction extends ActionSupport {
+
+ private static final long serialVersionUID = 1L;
+
+ private Employee employee;
+ private int id;
+
+ public EmployeeAction() {
+ employee = new Employee();
+ }
+
+ public Employee getEmployee() {
+ return employee;
+ }
+
+ public String[] getAllSkills() {
+ return EmployeeDao.getSkills();
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String execute() {
+ this.employee = EmployeeDao.getEmployee(id);
+ return SUCCESS;
+ }
+
+ public String save() {
+ EmployeeDao.save(employee);
+ return "index";
+ }
+
+}
+
Added: struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeDao.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeDao.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeDao.java (added)
+++ struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/EmployeeDao.java Sat May 20 21:13:53 2006
@@ -0,0 +1,37 @@
+package org.apache.struts.action2.showcase.jsf;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class EmployeeDao {
+
+ private static String[] skills;
+
+ private static List<Employee> employees;
+
+ static {
+ employees = new ArrayList<Employee>();
+ employees.add(new Employee(0, "Tom Jones", new String[]{"Java", "PHP"}));
+ employees.add(new Employee(1, "Bart Simpson", new String[]{"PHP"}));
+ employees.add(new Employee(2, "Sofia Jones", new String[]{"Java"}));
+
+ skills = new String[]{"Java", "PHP", "C#"};
+ }
+
+ public static List<Employee> getEmployees() {
+ return employees;
+ }
+
+ public static Employee getEmployee(int id) {
+ return employees.get(id);
+ }
+
+ public static void save(Employee e) {
+ employees.set(e.getId(), e);
+ }
+
+ public static String[] getSkills() {
+ return skills;
+ }
+}
Added: struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/IndexAction.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/IndexAction.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/IndexAction.java (added)
+++ struts/action2/trunk/apps/showcase/src/main/java/org/apache/struts/action2/showcase/jsf/IndexAction.java Sat May 20 21:13:53 2006
@@ -0,0 +1,43 @@
+/*
+ * $Id: QuizAction.java 394498 2006-04-16 15:28:06Z tmjee $
+ *
+ * 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.struts.action2.showcase.jsf;
+
+import java.util.List;
+
+import com.opensymphony.xwork.ActionSupport;
+
+public class IndexAction extends ActionSupport {
+
+ private static final long serialVersionUID = 1L;
+
+ private List loadedEmployees;
+
+ public List getEmployees() {
+ System.out.println("getting employees:"+loadedEmployees);
+ return loadedEmployees;
+ }
+
+ public String execute() {
+ System.out.println("executing");
+ loadedEmployees = EmployeeDao.getEmployees();
+
+ return SUCCESS;
+ }
+
+}
+
Added: struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork-jsf.xml
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork-jsf.xml?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork-jsf.xml (added)
+++ struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork-jsf.xml Sat May 20 21:13:53 2006
@@ -0,0 +1,21 @@
+<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">
+<xwork>
+ <include file="struts-default.xml"/>
+
+ <package name="jsf" extends="struts-default" namespace="/jsf">
+
+ <action name="index" class="org.apache.struts.action2.showcase.jsf.IndexAction">
+ <interceptor-ref name="jsfStack"/>
+ <result name="success" type="jsf" />
+ </action>
+
+ <action name="employee" class="org.apache.struts.action2.showcase.jsf.EmployeeAction">
+ <interceptor-ref name="basicStack"/>
+ <interceptor-ref name="jsfStack"/>
+ <result name="success" type="jsf" />
+ <result name="index" type="redirect-action">index</result>
+ </action>
+
+ </package>
+
+</xwork>
Modified: struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork.xml
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork.xml?rev=408129&r1=408128&r2=408129&view=diff
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork.xml (original)
+++ struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/classes/xwork.xml Sat May 20 21:13:53 2006
@@ -23,6 +23,8 @@
<include file="xwork-person.xml" />
<include file="xwork-wait.xml" />
+
+ <include file="xwork-jsf.xml" />
<include file="xwork-token.xml" />
Modified: struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp?rev=408129&r1=408128&r2=408129&view=diff
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp (original)
+++ struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp Sat May 20 21:13:53 2006
@@ -75,6 +75,7 @@
<li><a href="<saf:url value="/wait/index.jsp"/>">Execute & Wait</a></li>
<li><a href="<saf:url value="/token/index.jsp"/>">Token</a></li>
<li><a href="<saf:url value="/filedownload/index.jsp"/>">File Download</a></li>
+ <li><a href="<saf:url action="index" namespace="/jsf"/>">JSF</a></li>
<li class="last"><a href="<saf:url value="/help.jsp"/>">Help</a></li>
</ul>
</div>
Modified: struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/web.xml?rev=408129&r1=408128&r2=408129&view=diff
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/web.xml (original)
+++ struts/action2/trunk/apps/showcase/src/main/webapp/WEB-INF/web.xml Sat May 20 21:13:53 2006
@@ -4,6 +4,7 @@
<display-name>WebWork Showcase Application</display-name>
+
<filter>
<filter-name>action2-cleanup</filter-name>
<filter-class>org.apache.struts.action2.dispatcher.ActionContextCleanUp</filter-class>
@@ -18,6 +19,8 @@
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>
+
+
<filter-mapping>
<filter-name>action2-cleanup</filter-name>
@@ -38,8 +41,13 @@
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
-
-
+
+ <listener>
+ <listener-class>
+ org.apache.myfaces.webapp.StartupServletContextListener
+ </listener-class>
+ </listener>
+
<!-- SNIPPET START: dwr -->
<servlet>
@@ -50,6 +58,19 @@
<param-value>true</param-value>
</init-param>
</servlet>
+
+ <!-- JavaServer Faces Servlet Configuration, not used directly -->
+ <servlet>
+ <servlet-name>faces</servlet-name>
+ <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <!-- JavaServer Faces Servlet Mapping, not called directly -->
+ <servlet-mapping>
+ <servlet-name>faces</servlet-name>
+ <url-pattern>*.action</url-pattern>
+ </servlet-mapping>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
Added: struts/action2/trunk/apps/showcase/src/main/webapp/jsf/employee.jsp
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/webapp/jsf/employee.jsp?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/webapp/jsf/employee.jsp (added)
+++ struts/action2/trunk/apps/showcase/src/main/webapp/jsf/employee.jsp Sat May 20 21:13:53 2006
@@ -0,0 +1,61 @@
+<%--
+
+ 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.
+
+ $Id: welcome.jsp 371852 2006-01-24 07:25:10Z craigmcc $
+
+--%>
+
+<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
+<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
+
+<f:view>
+
+<html>
+
+ <head>
+ <title>JSF Integration Examples</title>
+ </head>
+
+ <body>
+
+ <h2>Modify Employee</h2>
+
+ <h:form>
+ <h:inputHidden value="#{action.employee.id}" />
+ <h:panelGrid columns="2">
+ <h:outputText value="ID:" />
+ <h:outputText value="#{action.employee.id}" />
+ <h:outputText value="Name:" />
+ <h:inputText size="30" value="#{action.employee.name}" />
+ <h:outputText value="Skills:" />
+ <h:selectManyCheckbox value="#{action.employee.skills}">
+ <f:selectItem itemValue="Java" itemLabel="Java" />
+ <f:selectItem itemValue="PHP" itemLabel="PHP" />
+ <f:selectItem itemValue="Ruby" itemLabel="Ruby" />
+ </h:selectManyCheckbox>
+ </h:panelGrid>
+
+ <h:commandButton value="Submit" action="#{action.save}" />
+ <br /><br />
+ <h:outputLink value="index.action">
+ <h:outputText value="Back" />
+ </h:outputLink>
+ </h:form>
+ </body>
+
+</html>
+
+</f:view>
Added: struts/action2/trunk/apps/showcase/src/main/webapp/jsf/index.jsp
URL: http://svn.apache.org/viewvc/struts/action2/trunk/apps/showcase/src/main/webapp/jsf/index.jsp?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/apps/showcase/src/main/webapp/jsf/index.jsp (added)
+++ struts/action2/trunk/apps/showcase/src/main/webapp/jsf/index.jsp Sat May 20 21:13:53 2006
@@ -0,0 +1,68 @@
+<%--
+
+ 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.
+
+ $Id: welcome.jsp 371852 2006-01-24 07:25:10Z craigmcc $
+
+--%>
+
+<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
+<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
+
+<f:view>
+
+<html>
+
+ <head>
+ <title>JSF Integration Examples</title>
+ </head>
+
+ <body>
+ <h2>JSF Integration Examples</h2>
+ <p>
+ The following pages show how Struts Action 2 and JSF components can work together,
+ each doing what they do best.
+ </p>
+
+ <h3>Employee List</h3>
+
+ <h:dataTable value="#{action.employees}" var="e">
+ <h:column>
+ <f:facet name="header">
+ <h:outputText value="ID" />
+ </f:facet>
+ <h:outputLink value="employee.action">
+ <f:param name="id" value="#{e.id}" />
+ <h:outputText value="#{e.id}" />
+ </h:outputLink>
+ </h:column>
+ <h:column>
+ <f:facet name="header">
+ <h:outputText value="Name" />
+ </f:facet>
+ <h:outputText value="#{e.name}" />
+ </h:column>
+ <h:column>
+ <f:facet name="header">
+ <h:outputText value="Skills" />
+ </f:facet>
+ <h:outputText value="#{e.skills}" />
+ </h:column>
+ </h:dataTable>
+ </body>
+
+</html>
+
+</f:view>
Modified: struts/action2/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/pom.xml?rev=408129&r1=408128&r2=408129&view=diff
==============================================================================
--- struts/action2/trunk/core/pom.xml (original)
+++ struts/action2/trunk/core/pom.xml Sat May 20 21:13:53 2006
@@ -258,6 +258,13 @@
<version>1.2.6</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>myfaces</groupId>
+ <artifactId>myfaces-jsf-api</artifactId>
+ <version>1.0.9</version>
+ <scope>provided</scope>
+ </dependency>
<!-- Test dependencies -->
<dependency>
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java Sat May 20 21:13:53 2006
@@ -0,0 +1,70 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Applies the request values to the component tree
+ */
+public class ApplyRequestValuesInterceptor extends FacesInterceptor {
+
+ private static final long serialVersionUID = -1471180154211835323L;
+
+ /**
+ * Apply Request Values (JSF.2.2.2)
+ *
+ * @param viewId The view id
+ * @param facesContext The faces context
+ * @return true, if response is complete
+ */
+ protected boolean executePhase(String viewId, FacesContext facesContext)
+ throws FacesException {
+ boolean skipFurtherProcessing = false;
+ if (log.isTraceEnabled())
+ log.trace("entering applyRequestValues");
+
+ informPhaseListenersBefore(facesContext, PhaseId.APPLY_REQUEST_VALUES);
+
+ if (isResponseComplete(facesContext, "applyRequestValues", true)) {
+ // have to return right away
+ return true;
+ }
+ if (shouldRenderResponse(facesContext, "applyRequestValues", true)) {
+ skipFurtherProcessing = true;
+ }
+
+ facesContext.getViewRoot().processDecodes(facesContext);
+
+ informPhaseListenersAfter(facesContext, PhaseId.APPLY_REQUEST_VALUES);
+
+ if (isResponseComplete(facesContext, "applyRequestValues", false)
+ || shouldRenderResponse(facesContext, "applyRequestValues",
+ false)) {
+ // since this phase is completed we don't need to return right away
+ // even if the response is completed
+ skipFurtherProcessing = true;
+ }
+
+ if (!skipFurtherProcessing && log.isTraceEnabled())
+ log.trace("exiting applyRequestValues");
+ return skipFurtherProcessing;
+ }
+}
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesInterceptor.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesInterceptor.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesInterceptor.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesInterceptor.java Sat May 20 21:13:53 2006
@@ -0,0 +1,90 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import javax.faces.context.FacesContext;
+
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.interceptor.Interceptor;
+
+/**
+ * Translates JSF phases into individual interceptors, and adapts their expected
+ * workflow to Action 2
+ */
+public class FacesInterceptor extends FacesSupport implements Interceptor {
+
+ private static final long serialVersionUID = -5418255964277566516L;
+
+ /**
+ * Not used
+ */
+ public void init() {
+ }
+
+ /**
+ * Adapts the phase workflow to Action 2
+ *
+ * @param invocation
+ * The action invocation
+ * @return The string result code
+ */
+ public String intercept(ActionInvocation invocation) throws Exception {
+
+ FacesContext context = FacesContext.getCurrentInstance();
+
+ if (context.getRenderResponse()) {
+ return invocation.invoke();
+ } else {
+ String viewId = invocation.getProxy().getNamespace() + '/'
+ + invocation.getProxy().getActionName();
+ executePhase(viewId, context);
+
+ if (context.getResponseComplete()) {
+ // Abort the chain as the result is done
+ return null;
+ } else {
+ if (invocation.getResultCode() != null) {
+ return invocation.getResultCode();
+ } else {
+ return invocation.invoke();
+ }
+ }
+ }
+ }
+
+ /**
+ * Executes the specific phase. The phase id is constructed as a composite
+ * of the namespace and action name.
+ *
+ * @param viewId
+ * The view id
+ * @param facesContext
+ * The current faces context
+ * @return True if the next phases should be skipped
+ */
+ protected boolean executePhase(String viewId, FacesContext facesContext) {
+ return false;
+ }
+
+ /**
+ * Not used
+ */
+ public void destroy() {
+ }
+
+}
\ No newline at end of file
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java Sat May 20 21:13:53 2006
@@ -0,0 +1,85 @@
+/*
+ * $Id: PlainTextResult.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import java.io.IOException;
+
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.application.ViewHandler;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.Result;
+
+/**
+ * Executes the JSF render phase
+ */
+public class FacesResult extends FacesSupport implements Result {
+
+ private static final long serialVersionUID = -3548970638740937804L;
+
+ /**
+ * Executes the result
+ */
+ public void execute(ActionInvocation invocation) throws Exception {
+ render(FacesContext.getCurrentInstance());
+ }
+
+ /**
+ * Executes the render phase, borrowed from MyFaces
+ *
+ * @param facesContext
+ * The faces context
+ * @throws FacesException
+ * If anything goes wrong
+ */
+ public void render(FacesContext facesContext) throws FacesException {
+ // if the response is complete we should not be invoking the phase
+ // listeners
+ if (isResponseComplete(facesContext, "render", true)) {
+ return;
+ }
+ if (log.isTraceEnabled())
+ log.trace("entering renderResponse");
+
+ informPhaseListenersBefore(facesContext, PhaseId.RENDER_RESPONSE);
+ // also possible that one of the listeners completed the response
+ if (isResponseComplete(facesContext, "render", true)) {
+ return;
+ }
+ Application application = facesContext.getApplication();
+ ViewHandler viewHandler = application.getViewHandler();
+ try {
+ viewHandler.renderView(facesContext, facesContext.getViewRoot());
+ } catch (IOException e) {
+ throw new FacesException(e.getMessage(), e);
+ }
+
+ informPhaseListenersAfter(facesContext, PhaseId.RENDER_RESPONSE);
+ if (log.isTraceEnabled()) {
+ // Note: DebugUtils Logger must also be in trace level
+ // DebugUtils.traceView("View after rendering");
+ }
+
+ if (log.isTraceEnabled())
+ log.trace("exiting renderResponse");
+ }
+
+}
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSetupInterceptor.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSetupInterceptor.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSetupInterceptor.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSetupInterceptor.java Sat May 20 21:13:53 2006
@@ -0,0 +1,110 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import javax.faces.FactoryFinder;
+import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
+import javax.faces.context.FacesContext;
+import javax.faces.context.FacesContextFactory;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
+
+import org.apache.struts.action2.ServletActionContext;
+
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.interceptor.Interceptor;
+
+/**
+ * Initializes the JSF context for this request
+ */
+public class FacesSetupInterceptor extends FacesSupport implements Interceptor {
+
+ private static final long serialVersionUID = -621512342655103941L;
+
+ private String lifecycleId = LifecycleFactory.DEFAULT_LIFECYCLE;
+
+ private FacesContextFactory facesContextFactory;
+
+ private Lifecycle lifecycle;
+
+ /**
+ * Sets the lifecycle id
+ *
+ * @param id
+ * The id
+ */
+ public void setLifecycleId(String id) {
+ this.lifecycleId = id;
+ }
+
+ /**
+ * Initializes the lifecycle and factories
+ */
+ public void init() {
+ facesContextFactory = (FacesContextFactory) FactoryFinder
+ .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
+ // Javadoc says: Lifecycle instance is shared across multiple
+ // simultaneous requests, it must be implemented in a thread-safe
+ // manner.
+ // So we can acquire it here once:
+ LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
+ .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+ lifecycle = lifecycleFactory.getLifecycle(lifecycleId);
+
+ Application application = ((ApplicationFactory) FactoryFinder
+ .getFactory(FactoryFinder.APPLICATION_FACTORY))
+ .getApplication();
+ if (!(application.getNavigationHandler() instanceof StrutsNavigationHandler)) {
+ application.setNavigationHandler(new StrutsNavigationHandler());
+ }
+ if (!(application.getVariableResolver() instanceof StrutsVariableResolver)) {
+ application.setVariableResolver(new StrutsVariableResolver(
+ application.getVariableResolver()));
+ }
+ }
+
+ /**
+ * Creates the faces context for other phases.
+ *
+ * @param invocation
+ * The action invocation
+ */
+ public String intercept(ActionInvocation invocation) throws Exception {
+ FacesContext facesContext = facesContextFactory.getFacesContext(
+ ServletActionContext.getServletContext(), ServletActionContext
+ .getRequest(), ServletActionContext.getResponse(),
+ lifecycle);
+
+ setLifecycle(lifecycle);
+
+ try {
+ return invocation.invoke();
+ } finally {
+ facesContext.release();
+ }
+ }
+
+ /**
+ * Cleans up the lifecycle and factories
+ */
+ public void destroy() {
+ facesContextFactory = null;
+ lifecycle = null;
+ }
+}
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSupport.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSupport.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSupport.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesSupport.java Sat May 20 21:13:53 2006
@@ -0,0 +1,164 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+import javax.faces.lifecycle.Lifecycle;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.opensymphony.xwork.ActionContext;
+
+/**
+ * Provides common lifecycle phase methods needed by interceptors and results.
+ */
+public class FacesSupport {
+
+ private static final String LIFECYCLE_KEY = "lifecycle";
+
+ /** Log instance for each class */
+ protected Log log;
+
+ /** Initializes log instance for the instance object */
+ protected FacesSupport() {
+ log = LogFactory.getLog(getClass());
+ }
+
+ /**
+ * Gets the shared lifecycle for this request
+ *
+ * @return The lifecycle
+ */
+ private Lifecycle getLifecycle() {
+ return (Lifecycle) ActionContext.getContext().get(LIFECYCLE_KEY);
+ }
+
+ /**
+ * Sets the lifecycle for this request
+ *
+ * @param lifecycle
+ * The lifecycle
+ */
+ protected void setLifecycle(Lifecycle lifecycle) {
+ ActionContext.getContext().put(LIFECYCLE_KEY, lifecycle);
+ }
+
+ /**
+ * Informs phase listeners before a phase is executed
+ *
+ * @param facesContext
+ * The current faces context
+ * @param phaseId
+ * The phase id about to be executed
+ */
+ protected void informPhaseListenersBefore(FacesContext facesContext,
+ PhaseId phaseId) {
+ Lifecycle lifecycle = getLifecycle();
+ PhaseListener[] phaseListeners = lifecycle.getPhaseListeners();
+ for (int i = 0; i < phaseListeners.length; i++) {
+ PhaseListener phaseListener = phaseListeners[i];
+ int listenerPhaseId = phaseListener.getPhaseId().getOrdinal();
+ if (listenerPhaseId == PhaseId.ANY_PHASE.getOrdinal()
+ || listenerPhaseId == phaseId.getOrdinal()) {
+ phaseListener.beforePhase(new PhaseEvent(FacesContext
+ .getCurrentInstance(), phaseId, lifecycle));
+ }
+ }
+
+ }
+
+ /**
+ * Informs phase listeners after a phase is executed
+ *
+ * @param facesContext
+ * The current faces context
+ * @param phaseId
+ * The phase id that was executed
+ */
+ protected void informPhaseListenersAfter(FacesContext facesContext,
+ PhaseId phaseId) {
+ Lifecycle lifecycle = getLifecycle();
+ PhaseListener[] phaseListeners = lifecycle.getPhaseListeners();
+ for (int i = 0; i < phaseListeners.length; i++) {
+ PhaseListener phaseListener = phaseListeners[i];
+ int listenerPhaseId = phaseListener.getPhaseId().getOrdinal();
+ if (listenerPhaseId == PhaseId.ANY_PHASE.getOrdinal()
+ || listenerPhaseId == phaseId.getOrdinal()) {
+ phaseListener.afterPhase(new PhaseEvent(FacesContext
+ .getCurrentInstance(), phaseId, lifecycle));
+ }
+ }
+
+ }
+
+ /**
+ * Checks to see if the response has been completed. Mainly used for better
+ * debugging messages.
+ *
+ * @param facesContext
+ * The current faces context
+ * @param phase
+ * The phase id in execution
+ * @param before
+ * Whether the phase has been executed or not
+ * @return True if the response is complete
+ */
+ protected boolean isResponseComplete(FacesContext facesContext,
+ String phase, boolean before) {
+ boolean flag = false;
+ if (facesContext.getResponseComplete()) {
+ if (log.isDebugEnabled())
+ log
+ .debug("exiting from lifecycle.execute in "
+ + phase
+ + " because getResponseComplete is true from one of the "
+ + (before ? "before" : "after") + " listeners");
+ flag = true;
+ }
+ return flag;
+ }
+
+ /**
+ * Checks to see the render phase should be executed next. Mainly used for
+ * better debugging messages.
+ *
+ * @param facesContext
+ * The current faces context
+ * @param phase
+ * The phase id in execution
+ * @param before
+ * Whether the phase has been executed or not
+ * @return True if the response is complete
+ */
+ protected boolean shouldRenderResponse(FacesContext facesContext,
+ String phase, boolean before) {
+ boolean flag = false;
+ if (facesContext.getRenderResponse()) {
+ if (log.isDebugEnabled())
+ log.debug("exiting from lifecycle.execute in " + phase
+ + " because getRenderResponse is true from one of the "
+ + (before ? "before" : "after") + " listeners");
+ flag = true;
+ }
+ return flag;
+ }
+}
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java Sat May 20 21:13:53 2006
@@ -0,0 +1,73 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Invokes the application
+ */
+public class InvokeApplicationInterceptor extends FacesInterceptor {
+
+ private static final long serialVersionUID = -7388153356410171208L;
+
+ /**
+ * Invoke Application (JSF.2.2.5)
+ *
+ * @param viewId
+ * The view id
+ * @param facesContext
+ * The faces context
+ * @return true, if response is complete
+ */
+ protected boolean executePhase(String viewId, FacesContext facesContext)
+ throws FacesException {
+ boolean skipFurtherProcessing = false;
+ if (log.isTraceEnabled())
+ log.trace("entering invokeApplication");
+
+ informPhaseListenersBefore(facesContext, PhaseId.INVOKE_APPLICATION);
+
+ if (isResponseComplete(facesContext, "invokeApplication", true)) {
+ // have to return right away
+ return true;
+ }
+ if (shouldRenderResponse(facesContext, "invokeApplication", true)) {
+ skipFurtherProcessing = true;
+ }
+
+ facesContext.getViewRoot().processApplication(facesContext);
+
+ informPhaseListenersAfter(facesContext, PhaseId.INVOKE_APPLICATION);
+
+ if (isResponseComplete(facesContext, "invokeApplication", false)
+ || shouldRenderResponse(facesContext, "invokeApplication",
+ false)) {
+ // since this phase is completed we don't need to return right away
+ // even if the response is completed
+ skipFurtherProcessing = true;
+ }
+
+ if (!skipFurtherProcessing && log.isTraceEnabled())
+ log.trace("exiting invokeApplication ");
+
+ return skipFurtherProcessing;
+ }
+}
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java Sat May 20 21:13:53 2006
@@ -0,0 +1,72 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Processes validations on the component tree
+ */
+public class ProcessValidationsInterceptor extends FacesInterceptor {
+
+ private static final long serialVersionUID = 8785236570688278147L;
+
+ /**
+ * Process Validations (JSF.2.2.3)
+ *
+ * @param viewId
+ * The view id
+ * @param facesContext
+ * The faces context
+ * @return true, if response is complete
+ */
+ protected boolean executePhase(String viewId, FacesContext facesContext)
+ throws FacesException {
+ boolean skipFurtherProcessing = false;
+ if (log.isTraceEnabled())
+ log.trace("entering processValidations");
+
+ informPhaseListenersBefore(facesContext, PhaseId.PROCESS_VALIDATIONS);
+
+ if (isResponseComplete(facesContext, "processValidations", true)) {
+ // have to return right away
+ return true;
+ }
+ if (shouldRenderResponse(facesContext, "processValidations", true)) {
+ skipFurtherProcessing = true;
+ }
+
+ facesContext.getViewRoot().processValidators(facesContext);
+
+ informPhaseListenersAfter(facesContext, PhaseId.PROCESS_VALIDATIONS);
+
+ if (isResponseComplete(facesContext, "processValidations", false)
+ || shouldRenderResponse(facesContext, "processValidations",
+ false)) {
+ // since this phase is completed we don't need to return right away
+ // even if the response is completed
+ skipFurtherProcessing = true;
+ }
+
+ if (!skipFurtherProcessing && log.isTraceEnabled())
+ log.trace("exiting processValidations");
+ return skipFurtherProcessing;
+ }
+}
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java Sat May 20 21:13:53 2006
@@ -0,0 +1,221 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+import javax.faces.event.PhaseId;
+
+/**
+ * Restores the view or component tree
+ */
+public class RestoreViewInterceptor extends FacesInterceptor {
+
+ private static final long serialVersionUID = -1500785113037140668L;
+
+ /**
+ * Restore View (JSF.2.2.1)
+ *
+ * @param viewId
+ * The view id
+ * @param facesContext
+ * The faces context
+ * @return true, if immediate rendering should occur
+ */
+ protected boolean executePhase(String viewId, FacesContext facesContext) {
+ boolean skipFurtherProcessing = false;
+ if (log.isTraceEnabled())
+ log.trace("entering restoreView");
+
+ informPhaseListenersBefore(facesContext, PhaseId.RESTORE_VIEW);
+
+ if (isResponseComplete(facesContext, "restoreView", true)) {
+ // have to skips this phase
+ return true;
+ }
+ if (shouldRenderResponse(facesContext, "restoreView", true)) {
+ skipFurtherProcessing = true;
+ }
+
+ ExternalContext externalContext = facesContext.getExternalContext();
+ String defaultSuffix = externalContext
+ .getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
+ String suffix = defaultSuffix != null ? defaultSuffix
+ : ViewHandler.DEFAULT_SUFFIX;
+ if (viewId != null) {
+ viewId += suffix;
+ }
+
+ if (viewId == null) {
+ if (!externalContext.getRequestServletPath().endsWith("/")) {
+ try {
+ externalContext.redirect(externalContext
+ .getRequestServletPath()
+ + "/");
+ facesContext.responseComplete();
+ return true;
+ } catch (IOException e) {
+ throw new FacesException("redirect failed", e);
+ }
+ }
+ }
+
+ Application application = facesContext.getApplication();
+ ViewHandler viewHandler = application.getViewHandler();
+
+ // boolean viewCreated = false;
+ UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewId);
+ if (viewRoot == null) {
+ viewRoot = viewHandler.createView(facesContext, viewId);
+ viewRoot.setViewId(viewId);
+ facesContext.renderResponse();
+ // viewCreated = true;
+ }
+
+ facesContext.setViewRoot(viewRoot);
+
+ /*
+ * This section has been disabled because it causes some bug. Be careful
+ * if you need to re-enable it. Furthermore, for an unknown reason, it
+ * seems that by default it is executed (i.e. log.isTraceEnabled() is
+ * true). Bug example : This traceView causes DebugUtil.printComponent
+ * to print all the attributes of the view components. And if you have a
+ * data table within an aliasBean, this causes the data table to
+ * initialize it's value attribute while the alias isn't set. So, the
+ * value initializes with an UIData.EMPTY_DATA_MODEL, and not with the
+ * aliased one. But as it's initialized, it will not try to get the
+ * value from the ValueBinding next time it needs to. I expect this to
+ * cause more similar bugs. TODO : Completely remove or be SURE by
+ * default it's not executed, and it has no more side-effects.
+ *
+ * if (log.isTraceEnabled()) { //Note: DebugUtils Logger must also be in
+ * trace level DebugUtils.traceView(viewCreated ? "Newly created view" :
+ * "Restored view"); }
+ */
+
+ if (facesContext.getExternalContext().getRequestParameterMap()
+ .isEmpty()) {
+ // no POST or query parameters --> set render response flag
+ facesContext.renderResponse();
+ }
+
+ recursivelyHandleComponentReferencesAndSetValid(facesContext, viewRoot);
+
+ informPhaseListenersAfter(facesContext, PhaseId.RESTORE_VIEW);
+
+ if (isResponseComplete(facesContext, "restoreView", false)
+ || shouldRenderResponse(facesContext, "restoreView", false)) {
+ // since this phase is completed we don't need to return right away
+ // even if the response is completed
+ skipFurtherProcessing = true;
+ }
+
+ if (!skipFurtherProcessing && log.isTraceEnabled())
+ log.trace("exiting restoreView ");
+ return skipFurtherProcessing;
+ }
+
+ /**
+ * Walk the component tree, executing any component-bindings to reattach
+ * components to their backing beans. Also, any UIInput component is marked
+ * as Valid.
+ * <p>
+ * Note that this method effectively breaks encapsulation; instead of asking
+ * each component to update itself and its children, this method just
+ * reaches into each component. That makes it impossible for any component
+ * to customise its behaviour at this point.
+ * <p>
+ * This has been filed as an issue against the spec. Until this issue is
+ * resolved, we'll add a new marker-interface for components to allow them
+ * to define their interest in handling children bindings themselves.
+ */
+ protected void recursivelyHandleComponentReferencesAndSetValid(
+ FacesContext facesContext, UIComponent parent) {
+ recursivelyHandleComponentReferencesAndSetValid(facesContext, parent,
+ false);
+ }
+
+ protected void recursivelyHandleComponentReferencesAndSetValid(
+ FacesContext facesContext, UIComponent parent, boolean forceHandle) {
+ Method handleBindingsMethod = getBindingMethod(parent);
+
+ if (handleBindingsMethod != null && !forceHandle) {
+ try {
+ handleBindingsMethod.invoke(parent, new Object[] {});
+ } catch (Throwable th) {
+ log.error(
+ "Exception while invoking handleBindings on component with client-id:"
+ + parent.getClientId(facesContext), th);
+ }
+ } else {
+ for (Iterator it = parent.getFacetsAndChildren(); it.hasNext();) {
+ UIComponent component = (UIComponent) it.next();
+
+ ValueBinding binding = component.getValueBinding("binding"); // TODO:
+ // constant
+ if (binding != null && !binding.isReadOnly(facesContext)) {
+ binding.setValue(facesContext, component);
+ }
+
+ if (component instanceof UIInput) {
+ ((UIInput) component).setValid(true);
+ }
+
+ recursivelyHandleComponentReferencesAndSetValid(facesContext,
+ component);
+ }
+ }
+ }
+
+ /**
+ * This is all a hack to work around a spec-bug which will be fixed in
+ * JSF2.0
+ *
+ * @param parent
+ * @return true if this component is bindingAware (e.g. aliasBean)
+ */
+ private static Method getBindingMethod(UIComponent parent) {
+ Class[] clazzes = parent.getClass().getInterfaces();
+
+ for (int i = 0; i < clazzes.length; i++) {
+ Class clazz = clazzes[i];
+
+ if (clazz.getName().indexOf("BindingAware") != -1) {
+ try {
+ return parent.getClass().getMethod("handleBindings",
+ new Class[] {});
+ } catch (NoSuchMethodException e) {
+ // return
+ }
+ }
+ }
+
+ return null;
+ }
+}
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsNavigationHandler.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsNavigationHandler.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsNavigationHandler.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsNavigationHandler.java Sat May 20 21:13:53 2006
@@ -0,0 +1,46 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import javax.faces.application.NavigationHandler;
+import javax.faces.context.FacesContext;
+
+import com.opensymphony.xwork.ActionContext;
+
+/**
+ * Overrides the JFS navigation by delegating the result to handling by the core
+ * result code lookup and execution.
+ */
+public class StrutsNavigationHandler extends NavigationHandler {
+
+ /**
+ * Stores any outcomes as the result code
+ *
+ * @param facesContext The faces context
+ * @param fromAction The action we are coming from
+ * @param outcome The String return code
+ */
+ @Override
+ public void handleNavigation(FacesContext facesContext, String fromAction, String outcome) {
+ ActionContext ctx = ActionContext.getContext();
+ if (outcome != null) {
+ ctx.getActionInvocation().setResultCode(outcome);
+ }
+ }
+
+}
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsVariableResolver.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsVariableResolver.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsVariableResolver.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/StrutsVariableResolver.java Sat May 20 21:13:53 2006
@@ -0,0 +1,70 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import javax.faces.context.FacesContext;
+import javax.faces.el.EvaluationException;
+import javax.faces.el.VariableResolver;
+
+import com.opensymphony.xwork.ActionContext;
+
+/**
+ * Adds the current Action instance to the variable lookups. All other requests
+ * delegate to underlying resolver.
+ */
+public class StrutsVariableResolver extends VariableResolver {
+
+ /** The original <code>VariableResolver</code> passed to our constructor. */
+ private VariableResolver original = null;
+
+ /** The variable name of our Struts action */
+ private static final String STRUTS_VARIABLE_NAME = "action";
+
+ /**
+ * Constructor
+ *
+ * @param original
+ * Original resolver to delegate to.
+ */
+ public StrutsVariableResolver(VariableResolver original) {
+
+ this.original = original;
+
+ }
+
+ /**
+ * <p>
+ * Resolve variable names known to this resolver; otherwise, delegate to the
+ * original resolver passed to our constructor.
+ * </p>
+ *
+ * @param name
+ * Variable name to be resolved
+ */
+ public Object resolveVariable(FacesContext context, String name)
+ throws EvaluationException {
+
+ if (STRUTS_VARIABLE_NAME.equals(name)) {
+ return ActionContext.getContext().getActionInvocation().getAction();
+ } else {
+ return original.resolveVariable(context, name);
+ }
+
+ }
+
+}
Added: struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java (added)
+++ struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java Sat May 20 21:13:53 2006
@@ -0,0 +1,70 @@
+/*
+ * $Id: TokenInterceptor.java 394468 2006-04-16 12:16:03Z tmjee $
+ *
+ * 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.struts.action2.jsf;
+
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Updates the model values from the component tree
+ */
+public class UpdateModelValuesInterceptor extends FacesInterceptor {
+
+ private static final long serialVersionUID = 4011504235094251077L;
+
+ /**
+ * Update Model Values (JSF.2.2.4)
+ *
+ * @param viewId The view id
+ * @param facesContext The faces context
+ * @return true, if response is complete
+ */
+ protected boolean executePhase(String viewId, FacesContext facesContext) throws FacesException
+ {
+ boolean skipFurtherProcessing = false;
+ if (log.isTraceEnabled()) log.trace("entering updateModelValues");
+
+ informPhaseListenersBefore(facesContext, PhaseId.UPDATE_MODEL_VALUES);
+
+ if(isResponseComplete(facesContext, "updateModelValues", true))
+ {
+ // have to return right away
+ return true;
+ }
+ if(shouldRenderResponse(facesContext, "updateModelValues", true))
+ {
+ skipFurtherProcessing = true;
+ }
+
+ facesContext.getViewRoot().processUpdates(facesContext);
+
+ informPhaseListenersAfter(facesContext, PhaseId.UPDATE_MODEL_VALUES);
+
+ if (isResponseComplete(facesContext, "updateModelValues", false)
+ || shouldRenderResponse(facesContext, "updateModelValues", false))
+ {
+ // since this phase is completed we don't need to return right away even if the response is completed
+ skipFurtherProcessing = true;
+ }
+
+ if (!skipFurtherProcessing && log.isTraceEnabled()) log.trace("exiting updateModelValues");
+
+ return skipFurtherProcessing;
+ }
+}
Added: struts/action2/trunk/core/src/main/resources/org/apache/struts/action2/jsf/package.html
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/resources/org/apache/struts/action2/jsf/package.html?rev=408129&view=auto
==============================================================================
--- struts/action2/trunk/core/src/main/resources/org/apache/struts/action2/jsf/package.html (added)
+++ struts/action2/trunk/core/src/main/resources/org/apache/struts/action2/jsf/package.html Sat May 20 21:13:53 2006
@@ -0,0 +1,9 @@
+<body>
+Integrates the JSF library into the Struts Action Framework. The overall approach
+ splits the JSF lifecycle into an Interceptor stack and Result, delegating
+ navigation and general controller functions to Struts.
+<p>
+ Most of this code was borrowed from MyFaces, and as such, will need to be synchronized
+ occassionally with the original code.
+</p>
+</body>
Modified: struts/action2/trunk/core/src/main/resources/struts-default.xml
URL: http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/resources/struts-default.xml?rev=408129&r1=408128&r2=408129&view=diff
==============================================================================
--- struts/action2/trunk/core/src/main/resources/struts-default.xml (original)
+++ struts/action2/trunk/core/src/main/resources/struts-default.xml Sat May 20 21:13:53 2006
@@ -13,6 +13,7 @@
<result-type name="velocity" class="org.apache.struts.action2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts.action2.views.xslt.XSLTResult"/>
<result-type name="plaintext" class="org.apache.struts.action2.dispatcher.PlainTextResult" />
+ <result-type name="jsf" class="org.apache.struts.action2.jsf.FacesResult" />
<!-- third party integration -->
<result-type name="jasper" class="org.apache.struts.action2.views.jasperreports.JasperReportsResult"/>
@@ -44,6 +45,14 @@
<interceptor name="token-session" class="org.apache.struts.action2.interceptor.TokenSessionStoreInterceptor"/>
<interceptor name="validation" class="com.opensymphony.xwork.validator.ValidationInterceptor"/>
<interceptor name="workflow" class="com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor"/>
+
+ <!-- JSF interceptors, one per lifecycle phase -->
+ <interceptor class="org.apache.struts.action2.jsf.FacesSetupInterceptor" name="jsfSetup" />
+ <interceptor class="org.apache.struts.action2.jsf.RestoreViewInterceptor" name="jsfRestore" />
+ <interceptor class="org.apache.struts.action2.jsf.ApplyRequestValuesInterceptor" name="jsfApply" />
+ <interceptor class="org.apache.struts.action2.jsf.ProcessValidationsInterceptor" name="jsfValidate" />
+ <interceptor class="org.apache.struts.action2.jsf.UpdateModelValuesInterceptor" name="jsfUpdate" />
+ <interceptor class="org.apache.struts.action2.jsf.InvokeApplicationInterceptor" name="jsfInvoke" />
<!-- Basic stack -->
<interceptor-stack name="basicStack">
@@ -176,6 +185,16 @@
<interceptor-ref name="execAndWait">
<param name="excludeMethods">input,back,cancel</param>
</interceptor-ref>
+ </interceptor-stack>
+
+ <!-- Sample JSF stack, can be combined with other stacks easily -->
+ <interceptor-stack name="jsfStack">
+ <interceptor-ref name="jsfSetup" />
+ <interceptor-ref name="jsfRestore" />
+ <interceptor-ref name="jsfApply" />
+ <interceptor-ref name="jsfValidate" />
+ <interceptor-ref name="jsfUpdate" />
+ <interceptor-ref name="jsfInvoke" />
</interceptor-stack>
</interceptors>