-
1. RF 4 and SWF
andyn May 20, 2011 8:25 AM (in response to andyn)here is my configuration:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
...
<properties>
...
<spring.version>3.0.5.RELEASE</spring.version>
<org.richfaces.bom.version>4.0.0.Final</org.richfaces.bom.version>
<spring.webflow.version>2.3.0.RELEASE</spring.webflow.version>
...
</properties>
<!-- ====== JBoss RichFaces bom ========== -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>richfaces-bom</artifactId>
<version>${org.richfaces.bom.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
<!-- ====== Spring Libraries and Dependencies on Spring ========== -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>runtime</scope>
</dependency>
<!-- ====== JBoss RichFaces libraries ========== -->
<dependency>
<groupId>org.richfaces.ui</groupId>
<artifactId>richfaces-components-ui</artifactId>
</dependency>
<dependency>
<groupId>org.richfaces.core</groupId>
<artifactId>richfaces-core-impl</artifactId>
</dependency>
<dependency>
<groupId>org.richfaces.cdk</groupId>
<artifactId>annotations</artifactId>
<version>${org.richfaces.bom.version}</version>
<scope>provided</scope>
</dependency>
<!-- ====== RichFaces Libraries and Dependencies on RichFaces ========== -->
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.cssparser</groupId>
<artifactId>cssparser</artifactId>
</dependency>
<!-- ====== Spring Web Flow Libraries and Dependencies ========== -->
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-binding</artifactId>
<version>${spring.webflow.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-js</artifactId>
<version>${spring.webflow.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-webflow</artifactId>
<version>${spring.webflow.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-faces</artifactId>
<version>${spring.webflow.version}</version>
</dependency>
</dependencies>
...
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
...
<!-- Initializing JavaServer Faces, *NOT* used at runtime due to Spring Web Flow -->
<!-- FacesServlet -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<!-- The servlet is loaded on startup to be reachable for requests. -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Mapping for FacesServlet -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<!-- Initializing JBoss RichFaces -->
<!-- Plugging the "Blue Sky" skin into the project -->
<context-param>
<param-name>org.richfaces.skin</param-name>
<param-value>blueSky</param-value>
</context-param>
<!-- Making the RichFaces skin spread to standard HTML controls -->
<context-param>
<param-name>org.richfaces.enableControlSkinning</param-name>
<param-value>false</param-value>
</context-param>
<!-- Initializing Spring Web Flow -->
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/web-application-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all /spring requests to the Dispatcher Servlet for handling -->
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/swf/*</url-pattern>
</servlet-mapping>
</web-app>
web-application-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:faces="http://www.springframework.org/schema/faces"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- This activates post-processors for annotation-based config -->
<context:annotation-config/>
<context:component-scan base-package="de"/>
<!-- Imports the configurations of the different infrastructure systems of the application -->
<import resource="webmvc-config.xml" />
<import resource="webflow-config.xml" />
</beans>
webmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- Maps logical view names to JSF-Files (e.g. 'search' to '/search.jsp' -->
<bean id="jsfViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Maps request URIs to controllers -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/*-flow=flowController
/resource/**=resourceHandler
/javax.faces.resource/**=jsfResourceHandler
/rfRes/**=jsfResourceHandler
</value>
</property>
<property name="defaultHandler">
<!-- Selects view names to render based on the request URI: e.g. /main selects "main" -->
<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
</property>
</bean>
<bean id="messageSource" class="de.gui.MyResourceBundleMessageSource" />
<bean id="localeResolver" class="de.gui.MySessionLocaleResolver" />
<!-- Handler for requested resources -->
<bean id="resourceHandler" class="de.gui.MyResourceServlet"/>
<bean id="jsfResourceHandler" class="org.springframework.faces.webflow.JsfResourceRequestHandler"/>
</beans>
webflow-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:faces="http://www.springframework.org/schema/faces"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd
http://www.springframework.org/schema/faces
http://www.springframework.org/schema/faces/spring-faces-2.2.xsd">
<!-- Executes flows: the central entry point into the Spring Web Flow system -->
<webflow:flow-executor id="flowExecutor">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<!-- The registry of executable flow definitions -->
<webflow:flow-registry id="flowRegistry" flow-builder-services="facesFlowBuilderServices" base-path="/WEB-INF/flows">
<webflow:flow-location-pattern value="*-flow.xml" />
</webflow:flow-registry>
<!-- Handles requests mapped to the Spring Web Flow system -->
<bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
<property name="flowExecutor" ref="flowExecutor"/>
<!-- Integrates the ability to use RichFaces Ajax components -->
<property name="ajaxHandler">
<bean class="org.springframework.faces.webflow.JsfAjaxHandler"/>
</property>
</bean>
<!-- Configures the Spring Web Flow JSF integration -->
<faces:flow-builder-services id="facesFlowBuilderServices" />
<!-- A listener maintain one FacesContext instance per Web Flow request. -->
<bean id="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />
<bean id="MyWebflowExceptionHandler" class="de.gui.MyWebflowExceptionHandler" />
</beans>
MyResourceBundleMessageSource
public class MyResourceBundleMessageSource extends ResourceBundleMessageSource
{
public static final String BUNDLE_KEY_DELIMITER = "$";
public static final String MESSAGE_DELIMITER = "#~#";
private boolean isInitialized = false;
@Override
protected ResourceBundle doGetBundle(final String bundlename, final Locale targetLocale)
{
return ResourceBundle.getBundle(bundlename, targetLocale, new ResourceBundle.Control()
{
@Override
public ResourceBundle newBundle(final String baseName,
final Locale locale,
final String format,
final ClassLoader loader,
final boolean reload) throws IOException
{
return new MyResourceBundle(baseName, locale.getLanguage());
}
});
}
@Override
protected String resolveCodeWithoutArguments(final String code, final Locale locale)
{
if (!isInitialized)
{
setBasenames(TexteUtil.getAllLanguageFiles());
isInitialized = true;
}
String result = null;
ResourceBundle bundle = null;
String basename = "";
String key = code;
if (code.contains(MESSAGE_DELIMITER))
{
String[] codes = code.split(MESSAGE_DELIMITER);
result = "";
for (int i = 0; i < codes.length; i++)
{
result += " " + resolveCodeWithoutArguments(codes[i], locale);
}
}
else
{
if (code.contains(BUNDLE_KEY_DELIMITER))
{
basename = code.substring(0, code.indexOf(BUNDLE_KEY_DELIMITER));
key = code.substring(code.indexOf(BUNDLE_KEY_DELIMITER) + 1);
bundle = getResourceBundle(basename, locale);
}
if (bundle != null)
{
try
{
result = bundle.getString(key);
}
catch (MissingResourceException ex)
{
// Assume key not found
// -> do NOT throw the exception to allow for checking parent message source.
result = null;
}
}
if ((bundle == null) || (result == null))
{
result = super.resolveCodeWithoutArguments(key, locale);
}
}
return result;
}
@Override
protected MessageFormat resolveCode(final String code, final Locale locale)
{
if (!isInitialized)
{
setBasenames(TexteUtil.getAllLanguageFiles());
isInitialized = true;
}
MessageFormat result = null;
ResourceBundle bundle = null;
String basename = "";
String key = code;
if (code.contains(MESSAGE_DELIMITER))
{
String[] codes = code.split(MESSAGE_DELIMITER);
result = new MessageFormat("");
for (int i = 0; i < codes.length; i++)
{
result = new MessageFormat(result.toPattern() + " " + resolveCode(codes[i], locale).toPattern());
}
}
else
{
if (code.contains(BUNDLE_KEY_DELIMITER))
{
basename = code.substring(0, code.indexOf(BUNDLE_KEY_DELIMITER));
key = code.substring(code.indexOf(BUNDLE_KEY_DELIMITER) + 1);
bundle = getResourceBundle(basename, locale);
}
if (bundle != null)
{
result = getMessageFormat(bundle, key, locale);
}
if ((bundle == null) || (result == null))
{
result = super.resolveCode(key, locale);
}
}
return result;
}
private static class MyResourceBundle extends ResourceBundle
{
private final Properties props;
MyResourceBundle(final String baseName, final String locale) throws IOException
{
props = TexteUtil.getLanguageSupport(locale, baseName);
}
@Override
protected Object handleGetObject(final String key)
{
return props.getProperty(key);
}
@Override
public Enumeration<String> getKeys()
{
Vector<String> keys = new Vector<String>();
Enumeration<Object> keysEnum = props.keys();
while (keysEnum.hasMoreElements())
{
keys.add(keysEnum.nextElement().toString());
}
return keys.elements();
}
}
}
MySessionLocaleResolver
public class MySessionLocaleResolver extends SessionLocaleResolver
{public static final String LOCALE_SESSION_ATTRIBUTE_NAME = WebUtil.SELECTED_LANGUAGE;
public static final Locale DEFAULT_LOCALE = new Locale("en");
public MySessionLocaleResolver()
{
this.setDefaultLocale(DEFAULT_LOCALE);
}
@Override
public Locale resolveLocale(final HttpServletRequest request)
{
Object localeObject = WebUtils.getSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME);
if (localeObject == null)
{
return determineDefaultLocale(request);
}
Locale locale = new Locale(localeObject.toString());
if (locale == null)
{
return determineDefaultLocale(request);
}
return locale;
}
@Override
public void setLocale(final HttpServletRequest request, final HttpServletResponse response, final Locale locale)
{
WebUtils.setSessionAttribute(request, LOCALE_SESSION_ATTRIBUTE_NAME, locale);
}
}
MyResourceServlet
public class MyResourceServlet extends ResourceHttpRequestHandler
{
public MyResourceServlet()
{
super();
Vector<Resource> resources = new Vector<Resource>();
resources.add(new DefaultResourceLoader().getResource("../../"));
this.setLocations(resources);
}
}
MyWebflowExceptionHandler
public class MyWebflowExceptionHandler implements FlowExecutionExceptionHandler
{
@Override
public boolean canHandle(final FlowExecutionException exception)
{
return true;
}
@Override
public void handle(final FlowExecutionException exception, final RequestControlContext context)
{
exception.printStackTrace();
try
{
String exceptionMessage = exception.getCause().getCause().getMessage();
context.getMessageContext().addMessage(new MessageBuilder().error().code(exceptionMessage).build());
}
catch (Exception e)
{
context.getMessageContext().addMessage(new MessageBuilder().error().code("Allgemein"
+ MyResourceBundleMessageSource.BUNDLE_KEY_DELIMITER + "ERR_UNKNOWN").build());
}
context.getExternalContext().requestFlowExecutionRedirect();
}
}
test-flow.xml
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<on-start>
<set name="conversationScope.pageName" value="'Test'"/>
...
</on-start>
<decision-state id="FlowStart">
...
</decision-state>
<view-state id="Test" view="/WEB-INF/view/Test.xhtml" model="flowScope.testBean">
<on-entry>
...
</on-entry>
<transition on="SAVE" to="Test">
<evaluate expression="..."/>
</transition>
...
<transition on="AJAX_TEST">
<evaluate expression="..." result="flowScope.testVec"/>
...
</transition>
</view-state>
<end-state id="FlowError" view="/error.jsp"/>
<exception-handler bean="MyWebflowExceptionHandler"/>
</flow>
Test.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HTML xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:head>
<meta NAME="Author" content="..."/>
<TITLE>
<h:outputText value="#{resourceBundle....}" />
</TITLE>
...
</h:head>
<h:body>
<h:form id="form1">
...
<a4j:outputPanel id="showTest">
<h:commandButton action="SAVE" value="..." rendered="..." disabled="..." styleClass="..." />
<h:panelGroup>
<h:selectOneMenu id="selectTest" ...>
<f:selectItems value="..." ... />
<a4j:ajax event="valueChange" render="showTest" execute="someFunction" />
<a4j:jsFunction id="someFunction" name="someFunction" action="AJAX_TEST" ajaxsingle="true" />
</h:selectOneMenu>
</h:panelGroup>
...
</a4j:outputPanel>
</h:form>
</h:body>
</HTML>
-
2. Re: RF 4 and SWF
andyn May 24, 2011 7:27 AM (in response to andyn)Could nobody help me to solve this problem?
-
3. Re: RF 4 and SWF
lfryc May 24, 2011 10:37 AM (in response to andyn)Hi Andy,
Please take a look at https://issues.jboss.org/browse/RFPL-1430 and http://community.jboss.org/message/600290#600290 for information related to SWF integration.
-
4. Re: RF 4 and SWF
andyn May 25, 2011 2:52 AM (in response to lfryc)Hey Lukáš,
thanks a lot for your reply! I've already read these links and I've used this information to make my config work. So it works for me perfectly to send an ajax-request, if I use an a4j:commandButton or an a4j:commandLink. But if I use a4j:functions or the like to send an ajax-request, Spring Web Flow gets a request, but couldn't detect an (ajax)event and so no transition is triggerd! So I'm not able to use "non-action"-Components like a drop-down-box to trigger a transition in swf.
And if you take a look at the example on https://issues.jboss.org/browse/RFPL-1430, there is never used a "non-action"-Component, but always a a4j:commandButton or a4j:commandLink, and that works for me also.
-
5. Re: RF 4 and SWF
derkd Sep 12, 2011 4:50 PM (in response to andyn)I also have this same question? Can non-action components be used to load for example an selectOneMenu list? (partial page rendering)? And how?
-
-
7. Re: RF 4 and SWF
andrey.sisoyev Oct 13, 2011 1:25 AM (in response to andyn)this works (when migrating from RF3 to RF4):
<h:selectOneMenu id="authType"
value="#{formBean.data['authType']}" styleClass="medium">
<f:selectItems value="#{formBean.selectItems['authTypes']}" />
<a4j:support id="authTypeChangeListener" action="authTypeChanged"
event="onchange" />
</h:selectOneMenu>
\/ \/ \/ \/ \/ \/ \/ \/ \/ \/
<a4j:jsFunction name="authTypeChangeTransitionTrigger" action="authTypeChanged" render="authTypeRegion" />
<h:selectOneMenu id="authType"
value="#{formBean.data['authType']}" styleClass="medium"
onchange="authTypeChangeTransitionTrigger()">
<f:selectItems value="#{formBean.selectItems['authTypes']}" />
</h:selectOneMenu>