Code Monkey home page Code Monkey logo

spring-webflow's Introduction

Revved up by Develocity

Overview

Spring Web Flow facilitates building web applications that require guided navigation -- e.g. a shopping cart, flight check-in, a loan application, and many others. In contrast to stateless, free-form navigation such use cases have a clear start and end point, one or more screens to go through in a specific order, and a set of changes that are not finalized to the end.

A distinguishing feature is the ability to define a flow definition consisting of states, transitions, and data. For example, view states correspond to the individual screens of the flow while transitions are caused by events resulting from the click of a button or a link. Data may be stored in scopes such as flash, view, flow, and others. Scoped data is cleared when it is no longer in scope.

In REST terms a flow represents as a single resource. The same URL used to start the flow is also the URL used to step through the flow (there is also an execution key uniquely identifying the current flow instance). As a result of this approach navigation remains encapsulated in the flow definition.

Some key benefits of using Spring Web Flow:

  • A flow abstraction to model "long conversations" in web applications
  • Proper encapsulation for navigation rules
  • Multiple scopes in which to keep data
  • Automatic use of the POST/REDIRECT/GET pattern to avoid browser warnings
  • Impossible to return to completed flow sessions via browser back button
  • Rapid prototyping of flow requirements
  • Development mode in which flow definition changes are detected on the fly
  • IDE visualization for flow definitions
  • Much more...

Documentation

See the current Javadoc and Reference docs.

Samples

Samples can be found in the spring-webflow-samples repository.

Code of Conduct

This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected].

Downloading artifacts

Download instructions for Spring Web Flow artifacts via Maven and other build systems are available via the project wiki.

Getting support

Please, use the spring-webflow tag on StackOverflow. Commercial support is available too.

Building from source

Check out sources:

git clone git://github.com/spring-projects/spring-webflow.git

Compile and test, build all jars, distribution zips and docs:

./gradlew build

Install into your local Maven repository:

./gradlew install

Generate Eclipse settings and then manually import projects:

./import-into-eclipse.sh

The Spring Framework and Spring Web Flow use a very similar build system. For this reason the following Gradle build FAQ would be a very useful read.

Contributing

Pull requests are welcome. You'll be asked to sign our contributor license agreement (CLA). Trivial changes like typo fixes are especially appreciated (just fork and edit!). For larger changes, please search through JIRA for similiar issues, creating a new one if necessary, and discuss your ideas with the Spring Web Flow team.

License

Spring Web Flow is released under version 2.0 of the Apache License.

spring-webflow's People

Contributors

aemruli avatar bclozel avatar buzzardo avatar cbeams avatar dsyer avatar edysli avatar erichaagdev avatar habuma avatar iay avatar kryger avatar larsgrefer avatar nebhale avatar philwebb avatar rstoyanchev avatar scantor avatar spring-builds avatar spring-operator avatar sslavic avatar wilkinsona avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-webflow's Issues

Add configurable SWF property names [SWF-26]

Artur Karazniewicz opened SWF-26 and commented

It's good practice to hide as much details form the clinet as we can. Currently SWF forces to include well known named parameters like _flowExecutionId, _eventId - thus exposing underlying framework We use (It's easy to find pages using SWF, for instance). Would be nice when these parameter names could be configurable (more "cryptic") - like it's possible in SpringMVC.

Artur


No further details from SWF-26

Add class structure to allow auto assembly of object graph in a way that is independent from object retreival implementation. [SWF-9]

Keith Garry Boyce opened SWF-9 and commented

Objective:
I find in almost all situations that the bulk of work in building a web app is to collect data from varying locations and ultimately construct an object graph that you can then persist or use for querying. This is especially true if using hibernate or another ORM tool.

Conclusion:
The proposed code below accomplishes that so that by the time you get to the action the populated objects would already be pre-populated and waiting for you in the scope you specify. So the action code would then be very simple or non-existent.

Summary:
The current FormAction only allows the creation of one form object per action. My thought is that if using hibernate or another ORM tool what you want instead is multiple objects (one per each domain object) so that at the time you run the action the object graph will already be created and all you need to do is extract it from the context and use it to query or persist. This avoids the bulk of the work generally in actions to assemble domain objects.

So basically this is IoC for a scope object to either create object in scope and set properties, set property on object already in specified scope or add object to collection of an object already in specified scope.

Code:

<bean id="phoneBookInjector" class="spring.ContextInjector">
<property name="defaultAttributeSourceChain" value="parameter,request,flow,session,context"/>
<property name="defaultPopulation" value="true"/>
<property name="attributeResolvers">
<map>
<entry key="phoneNumber">
<bean class="spring.PortletAttributeResolver">
<property name="from" value="PHONE_NUMBER"/>
<property name="attributeSourceChain"
value="parameter,request,flow,session,context"/>
</bean>
</entry>
</map>
</property>
<property name="formObjectName">
<value>phoneBook</value>
</property>
<property name="formObjectClass">
<value>app.domain.PhoneBook</value>
</property>
<property name="formObjectScopeAsString">
<value>request</value>
</property>
<property name="validator">
<bean id="queryValidator" class="app.domain.PhoneBookValidator"/>
</property>
</bean>

<bean id="phoneBookAddressInjector" class="spring.ContextInjector">>
<property name="attributeResolvers">
<map>
<entry key="street">
<bean class="spring.PortletAttributeResolver">
<property name="from" value="STREET"/>
<property name="attributeSourceChain"
value="request"/>
</bean>
</entry>
</map>
</property>
<property name="formObjectName".
<value>phoneBook.addresses</value>
</property>
<property name="formObjectClass">
<value>app.domain.PhoneBookAddress</value>
</property>
<property name="formObjectScopeAsString">
<value>request</value>
</property>
<property name="validator">
<bean id="queryValidator" class="app.domain.PhoneBookValidator"/>
</property>
</bean>

<bean id="app.phone.SavePhone"
class="org.springframework.web.flow.action.InjectionAction">
<property name="injectors">
<list>
<ref bean="phoneBookInjector"/>
<ref bean="phoneBookAddressInjector"/>
</list>
</proerty>
</bean>

Basically an explanation of the intended implementation is as follows.

The functionality of InjectionAction class is as follows:

  1. extends AbstractAction
  2. It reads list of injectors in order and proccess them calling bindAndValidate

The functionality of ContextInjector class is as follows:

  1. extends from FormAction
  2. bindAndValidate of FormAction works as usual except that

a) property resolution is done with attributeResolvers instead of just using request parameters
b) These attributeResolvers support retrieval from nested properties
c) it has the ability to populate nested properties on objects already in scope
d) properties can be assigned from constant injected value instead of attributeResolvers. Value can be defined at the ContextInjector level in which case properties are resolved from object if property itself doesn't have a value assigned to it rather than an attribute resolver.
e) Something I haven't fully thought through, but it makes a lot of sense, is that AttributeResolver can be assigned at ContextInjector level to populate the object itself. This would allow developers to create a AttributeResolver that accepts a service layer method as an injection returning the object that could then be used to populate scope object. So you could basically set up the entire view without a line of code.
f) If property resolver is not an attributeResolver and it is a constant value instead. Property is automatically set to value.

  1. for each property in class find a property resolver in following precedence

a) an explicit PropertyResolver in propertyResolvers
b) a default PropertyResolver (which can be injected) if none specified and defaultPopulation is true

  1. for each property instantiate PropertyResolver and

a) inject defaultAttributeSourceChain if not already specified for the property resolver
b) inject property name as "to"

  1. Once instantiated object has been populated, validate if necessary and then set formObjectName to point to object in the scope formObjectScopeAsString specified

  2. If formObjectName in the form "phoneBook.addresses" and addresses is a collection then find phoneBook in the scope specified by formObjectScopeAsString and invoke add method to insert newly populated object in collection.

The functionality of PropertyResolver is as follows:

  1. For each scope specified in attributeSourceChain, search in that scope for "from" name or "to" name if "from" not specified.

To retreive the object PhoneBook you would simply call:

Code:
PhoneBook phoneBook = (PhoneBook)context.getRequestScope().getAttribute("phoneBook");

and save it since it is already populated (both the properties and the associated addresses).


Attachments:

Provide attribute mapping from sub-flow's flow-scope to request-scope of the super-flow [SWF-31]

Alex Wolfe opened SWF-31 and commented

As of PR5, mapping from a sub-flow's flow-scope to a super-flow's request-scope is a process that requires special handling in either the sub-flow or the super-flow.

There is a thread on the forums discussing this issue: http://forum.springframework.org/viewtopic.php?t=8121

Erwin mentioned that implementation isn't as clear-cut as it could be because certain situations such as the following must be avoided:
<output value="foo" as="${flowExecutionContext.activeSession.parent.scope.bar}"/>

While I'm certain there are less direct approaches, I suggest that the ParameterizableFlowAttributeMapper be modified to map against a new object called ScopeHolder which effectively limits references to the flowScope and requestScope during OGNL expression processing.

ParameterizableFlowAttributeMapper:
public void mapSubflowOutput(RequestContext context) {
if (this.outputMapper != null) {
// map from request context to parent flow scope
this.outputMapper.map(
context,
new ScopeHolder(
context.getFlowExecutionContext().getActiveSession().getParent().getScope(),
context
),
getMappingContext(context)
);
}
}

public class ScopeHolder {
private final Scope flowScope;
private final Scope requestScope;

public ScopeHolder(Scope flowScope, Scope requestScope) {
this.flowScope = flowScope;
this.requestScope = requestScope;
}

public Scope getFlowScope() {
return flowScope;
}

public Scope getRequestScope() {
return requestScope;
}
}


No further details from SWF-31

validator method requires formObjectType to be set [SWF-28]

Jim Newsham opened SWF-28 and commented

When trying to use a validator method, I was getting a pretty deeply nested NullPointerException:

org.springframework.webflow.ActionExecutionException: Exception thrown executing action 'com.commercepoint.superquote.webflow.action.VendorSignupActions@a010ba' in state 'page1' of flow 'vendorSignupFlow'; nested exception is java.lang.NullPointerException: null
java.lang.NullPointerException
at org.springframework.webflow.util.DispatchMethodInvoker.getParameterTypesString(DispatchMethodInvoker.java:168)
at org.springframework.webflow.util.DispatchMethodInvoker.getSignature(DispatchMethodInvoker.java:206)
at org.springframework.webflow.util.DispatchMethodInvoker$1.create(DispatchMethodInvoker.java:65)
at org.springframework.util.CachingMapDecorator.get(CachingMapDecorator.java:143)
at org.springframework.webflow.util.DispatchMethodInvoker.getDispatchMethod(DispatchMethodInvoker.java:217)
at org.springframework.webflow.util.DispatchMethodInvoker.dispatch(DispatchMethodInvoker.java:230)
at org.springframework.webflow.action.FormAction.invokeValidatorMethod(FormAction.java:729)
at org.springframework.webflow.action.FormAction.doValidate(FormAction.java:703)
at org.springframework.webflow.action.FormAction.bindAndValidate(FormAction.java:554)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.webflow.util.DispatchMethodInvoker.dispatch(DispatchMethodInvoker.java:231)
at org.springframework.webflow.action.MultiAction.doExecute(MultiAction.java:138)
at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:225)
at org.springframework.webflow.ActionExecutor.execute(ActionExecutor.java:65)
at org.springframework.webflow.AnnotatedAction.execute(AnnotatedAction.java:154)
at org.springframework.webflow.ActionExecutor.execute(ActionExecutor.java:65)
at org.springframework.webflow.support.ActionTransitionCriteria.test(ActionTransitionCriteria.java:87)
at org.springframework.webflow.support.TransitionCriteriaChain.test(TransitionCriteriaChain.java:65)
at org.springframework.webflow.Transition.canExecute(Transition.java:239)

[ETC ETC]

...which wasn't very descriptive of the problem, so I had to dig around in the source. It seems that since setFormObjectType was not invoked, the parameter types of the validator method invoker was not set. In my case, I wasn't setting formObjectType because I'm overriding loadFormObject.

At the very least, this issue report is asking for: (1) more descriptive error reporting in case of improper use; (2) better documentation as to how custom validator methods may be invoked, perhaps within FormAction.

However, you may also want to consider removing the requirement that formObjectType must be set. I see that it's now necessary since the validator method is typed to the form object type... but is this signature necessary? Why not just use the same signature as Validator.validate()?


No further details from SWF-28

View state controllers + added request context, flow scope and request scope to action bean invocation + added getErrors method on request context [SWF-33]

Steven Devijver opened SWF-33 and commented

This patch includes these improvements:

  • view state controllers: allow execution of controllers from a view state, ideal for AJAX actions.
  • make request context, flow scope and request scope available to action bean invocation
  • adds getErrors(String) to request context to retrieve bind exception for command name

Patch is attached.


Attachments:

FlowExecutionManager.setStorage broken assertion [SWF-18]

Steven Bazyl opened SWF-18 and commented

FlowExecutionManager.setStorage has a broken assertion - it's supposed to be checking that the supplied storage instance is not null, but it's checking against the member variable instead. This makes it impossible to initialize correctly. Easy fix... just change 'storage' to 'flowExecutionStorage'


No further details from SWF-18

Cannot override integration-repo location in common-build [SWF-147]

nebhale opened SWF-147 and commented

Using a project.properties file I cannot override the location of the 'integration.repo.dir' that the dist target publishes into. I can override the 'repository.dir' successfully from the project.properties file however. I've also tried using an ivyconf.properties in my project's root directory to no avail.


No further details from SWF-147

Use of Collections.addAll() in class org.springframework.webflow.action.bean.Arguments [SWF-29]

Roland Fรถrther opened SWF-29 and commented

Using Collections.addAll() in org.springframework.webflow.action.bean.Arguments (revision 1.2)
binds SWF to JDK 1.5, because this method is not available
in former JDK versions:

public void addAll(Argument[] arguments) {
Collections.addAll(this.arguments, arguments);
}

I would suggest an implementation like that:

public void addAll(Argument[] arguments) {
this.arguments.addAll(Arrays.asList(arguments));
}


No further details from SWF-29

Add explicit support for expiring flows and detecting flow expiry [SWF-10]

Markus Joschko opened SWF-10 and commented

Currently the flow is simply removed from the session by the cleanup filter without the possibility to do additional cleanup work itself.
It would be very helpful if the flowlistener is called before removing the flow from session.
Even better would be if this could somehow be coupled with a session listener (as the cleanup filter expects that the user performs an additional request).


Affects: 1.0 RC4

Issue Links:

  • #1088 Revise conversation package
    ("depends on")

3 votes, 3 watchers

State.addEntryAction and TransitionalState.addExitAction [SWF-48]

Chris Wood opened SWF-48 and commented

At the moment if you're building the flow using the java based flow builder it's difficult to add extra entry actions and exit actions since you have to test if there's any existing ones, and then wrap the pair in a CompositeAction.

This mod makes this easier by adding the methods State.addEntryAction and TransitionalState.addExitAction .

See attached for diff and files. Diff is against PR5


Attachments:

Enhace AbstractAction with common object scope management [SWF-22]

Cรจsar Ordiรฑana opened SWF-22 and commented

Most of the Action classes we are developing get or set an object from/to one of the two scopes, request or flow. Also, we like to be able to configure the name of the attribute and which scope to use, much like the FormAction.

As an example, I have attached a simple Action which can be used to remove an object from one of the scopes. The bean definition would be like this:

<bean id="RemoveAttributeAction"
class="com.disid.commons.webflow.action.RemoveAttributeAction">
<property name="attributeName">
<value>MyObject</value>
</property>
<property name="objectScopeAsString">
<value>flow</value>
</property>
</bean>

I think this functionality should be very common while developing Action classes, and maybe would be useful to enhace the AbstractAction class with it.

I've attached some files to show the idea, but it is mainly what the FormAction class does now with the form bean. Those files are:

  • ScopeObjectHelper: handles the retrieval and removal of objects from the configured scope and attribute name. We have created a separate class as we need to use it from Actions and MultiActions. Use examples:

    Object object = getScopeHelper().getScopeObject(context);

    getScopeHelper().storeScopeObject(object, context);

  • ScopeObjectAction: base action class to provide the scope object handling to child classes.

  • RemoveAttributeAction: example action.

  • WebflowUtils: scope handling utilities, mainly extracted from the FormAction class.


Attachments:

New extension point in FlowExecutionImpl [SWF-30]

Daniel Sendula opened SWF-30 and commented

FlowExecutionManager can be extended at createFlowExecution specialising FlowExecution (FlowExecutionImpl). FlowExecutionImpl has two ways of receiving Event: start and signalEvent methods. Both methods are preparing environment and 'entering' a state. It would be great if execution of methods State.enter and TransitionableState.onEvent can be controlled somehow.

Start and signalEvents can be refactored that two new protected methods invokeInitialState and invokeState are called.

protected ViewDescriptor invokeInitialState(State state, StateContext context) {
return state.enter(context);
}

protected ViewDescriptor invokeState(TransitionableState state, StateContext context) {
return state.onEvent(context.getSourceEvent(), context);
}

This will give more extensibility to FlowExecutionImpl: Classes that extend FlowExecutionManger would be able to introduce extention of FlowExecutionImpl and control invokation of states.


Attachments:

misleading NoMatchingTransitionException message on chained action-states [SWF-14]

Noa Resare opened SWF-14 and commented

When i execute two chained action states where the second action bean fires an event with id that is missing the message in the thrown NoMatchingTransitionException refers to the first action instead of the second one. Definitely a minor thing but still annoying.

Consider this:

<webflow id="applicationFlow" start-state="action0">
<action-state id="action0">
<action bean="applicationAction" method="returnNext"/>
<transition on="next" to="action1"/>
</action-state>
<action-state id="action1">
<action bean="applicationAction" method="returnNext"/>
<transition on="success" to="end"/>
</action-state>
<end-state id="end" view="end"/>
</webflow>

public Event returnNext(RequestContext ctx)
{
    return new Event(this, "next");
}

executing this flow gives this exception message:

org.springframework.webflow.NoMatchingTransitionException: No transition was matched to the event(s) signaled by the 1 action(s) that executed in this action state 'action0' of flow 'applicationFlow'; transitions must be defined to handle action result outcomes -- possible flow configuration error? Note: the eventIds signaled were: 'array<String>['next']', while the supported set of transitional criteria for this action state is 'array<TransitionCriteria>['next']'

The correct message should refer to satate 'action1' and the TransitionCriteria array printed at the end of the message should contain 'success'.


No further details from SWF-14

Event class javadoc [SWF-12]

Alex Greif opened SWF-12 and commented

The class org.springframework.webflow.Event has the following sentence in it's javadoc:
"Why is this class abstract and not an interface?"

AFAIK the class is not abstract, thus this point can be removed from the javadoc

Anyway it is a really trivial bug in the sources.


No further details from SWF-12

Variable resolution from subflow output params [SWF-44]

Doug Haber opened SWF-44 and commented

This improvement is related to:
http://forum.springframework.org/showthread.php?p=40042#post40042

The idea is that by specifing an output parameter from a subflow it can be automatically placed in the flow scope of the parent even if the variable name hasn't been defined by the parent before:

<attribute-mapper>
<output value="${flowScope.paymentMethod.creditCard}" as="creditCard"/>
</attribute-mapper>


No further details from SWF-44

ArrayIndexOutOfBoundsException on ActionState.doEnter() [SWF-20]

Enrique Ruiz (DiSiD) opened SWF-20 and commented

The next exception are throwed when match transition was not found:

java.lang.ArrayIndexOutOfBoundsException: 1
at org.springframework.web.flow.ActionState.doEnter(ActionState.java:372)
at org.springframework.web.flow.State.enter(State.java:164)
at org.springframework.web.flow.Transition.execute(Transition.java:248)

The problem is that this exception is throwed due to the log message construction and inside the catch block of NoMatchingTransitionException. Then the NoMatchingTransitionException isn't throwed.


No further details from SWF-20

XML Attribute Mapping [SWF-16]

Phil Kulak opened SWF-16 and commented

It would be really nice to use flow definitions to define parameter mappings into and out of subflows. For example:

<webflow id="mySubflow" start-state="setupForm">
<in-param name="city"/>
<in-param name="state"/>
...
</webflow>
<webflow id="myRootFlow" start-state="setupForm">
...
<subflow-state id="mySubflow" flow="mySubflow">
<param-mapping parent="homeCity" child="city"/>
<param-mapping parent="homeState" child="state"/>
</subflow-state>
...
</webflow>


No further details from SWF-16

Error creating action bean logs only FlowArtifactLookupException with "chain exhausted" message [SWF-39]

Colin Sampaleanu opened SWF-39 and commented

If Spring has a problem creating an action bean (bad property being set or whatever), a flow that tries to use that action will log only a FlowArtifactLookupException with the mesage "Chain exhausted looking for flow with id: XXX". This is because the chain lookup class doesn't make a distinction between erorrs when it tries to call the flow artifact locators in the chain. It just swallows and ingnores all errors. It should ignore only bean not found errors...


No further details from SWF-39

Assertions broken in AbstractFlowExecutionTests [SWF-24]

Steven Bazyl opened SWF-24 and commented

The two assertion functions in AbstractFlowExecutionTests seem to have broken recently (version 1.11?). There is a type mismatch now - the methods assertActiveFlowEquals and assertCurrentStateEquals expect IDs, but the implementations are now asserting against the flow and state objects directly. ...getFlow() should be ...getFlow().getId() and so on...


No further details from SWF-24

Put start/continue behaviour on the Flow class [SWF-15]

Erwin Vervaet opened SWF-15 and commented

Note to self:

At the moment we have:

  • A state can 'enter'
  • A transition can 'execute'
  • A flow can ???

There is no logic whatsoever in the Flow class. Probably we should have something like:

  • A flow can 'start' and 'continue'

Since all core concepts are pluggable (event from the flow XML), this would open up cool possibilities of plugging in a custom Flow subclass which for instance changes the 'start' behaviour. You can already plug-in a custom Flow subclass, but there is little use since it doesn't have any behaviour like the State or Transition classes do.


No further details from SWF-15

subflow form object with same name shadows main flow after returning [SWF-4]

Jim Newsham opened SWF-4 and commented

I'm attaching a sample test case (you'll need to change the package names from webflow to web.flow to test with PR3). This test case works fine in SWF PR3, and causes an error in the jsp page for SWF PR4 and also the current snapshot of SWF in cvs.

The scenario:

  • A main form submits to a sub form, which collects and validates information and returns to the main form; there is a main flow and a sub flow
  • The flows use different objects, but the form object names are the same (since flow scope is used, this should be okay, as far as I understand)
  • If the sub flow returns without doing anything, there is no problem
    • If the sub flow performs bindAndValidate before returning, the main form does not set a form object in the request, even when setupForm is first called; this results in an unexpected error on the page when trying to access non-existent fields on the named bean (in PR3, if setupForm is called, all is well, but if setupForm is not called, the same error occurs)

In the sample to be attached:

  • clicking "ok" in the main form, and "cancel" in the subform causes no problem.
  • clicking "ok" in the main form, and "ok" in the subform causes the following error:

org.springframework.beans.NotReadablePropertyException: Invalid property
'a' of bean class [SubBean]: Bean property 'a' is not readable or has an
invalid getter method: Does the return type of the getter match the parameter
type of the setter?
at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:652)
at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:644)
at org.springframework.validation.BindException.getFieldValue(BindException.java:333)
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:117)
at org.springframework.web.servlet.tags.BindTag.doStartTagInternal(BindTag.java:115)
at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:68)
at _jsp._WEB_22dINF._jsp._main__jsp._jspService(WEB-INF/jsp/main.jsp:11)
at com.caucho.jsp.JavaPage.service(JavaPage.java:63)
at com.caucho.jsp.Page.pageservice(Page.java:570)
at com.caucho.server.dispatch.PageFilterChain.doFilter(PageFilterChain.java:159)
at com.caucho.server.webapp.DispatchFilterChain.doFilter(DispatchFilterChain.java:115)
at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:208)
at com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:268)
at com.caucho.server.webapp.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:106)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:97)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:928)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:705)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:625)
at org.springframework.web.servlet.FrameworkServlet.serviceWrapper(FrameworkServlet.java:386)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:355)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:152)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:90)
at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:99)
at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:163)
at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:208)
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:259)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:341)
at com.caucho.util.ThreadPool.runTasks(ThreadPool.java:490)
at com.caucho.util.ThreadPool.run(ThreadPool.java:423)
at java.lang.Thread.run(Thread.java:595)


Attachments:

AbstractAction.afterPropertiesSet() does not throw Exception [SWF-37]

Rodney Chu opened SWF-37 and commented

AbstractAction.afterPropertiesSet() does not throw Exception thus making it impossible for subclasses to throw exceptions for bean misconfigurations.

I'm using afterPropertiesSet() in my Action (subclass of FormAction) to make sure that the properties are set properly. My convention is to throw an exception if there is a required property missing so that the container will complain. Now, when I try to declare a throws clause in the overriding method, the compiler complains.


No further details from SWF-37

incorrect error message when NoSuchTransition from subflow to parent [SWF-23]

Jim Newsham opened SWF-23 and commented

This is reported against SWF Preview 3.

When a subflow completes successfully and its returned event does not match up with the transitions defined in the <subflow-state> declaration of the parent, the error message accompanying the stack trace incorrectly states that the NSTE happened in the subflow. The error message is furthermore confusing because it contradictorily states that the transition doesn't exist, and goes on to list the signaled eventId and transitional criteria, which DO match up.

In this example, "submitForApprovalFlow" is the subflow (which has already completed successfully according to the debug log):

org.springframework.web.flow.NoMatchingTransitionException: No transition was matched to the event(s) signaled by the 1 action(s) that executed in this action state 'bind' of flow 'submitForApprovalFlow'; transitions must be defined to handle action result outcomes -- possible flow configuration error? Note: the eventIds signaled were: 'array['success']', while the supported set of transitional criteria for this action state is 'array['success', 'error']'
at org.springframework.web.flow.ActionState.doEnter(ActionState.java:382)
at org.springframework.web.flow.State.enter(State.java:164)
at org.springframework.web.flow.Transition.execute(Transition.java:269)
at org.springframework.web.flow.TransitionableState.onEvent(TransitionableState.java:202)
at org.springframework.web.flow.execution.impl.FlowExecutionImpl.signalEvent(FlowExecutionImpl.java:317)
at org.springframework.web.flow.execution.FlowExecutionManager.onEvent(FlowExecutionManager.java:289)
at org.springframework.web.flow.execution.FlowExecutionManager.onEvent(FlowExecutionManager.java:245)
at org.springframework.web.flow.execution.servlet.ServletFlowExecutionManager.handle(ServletFlowExecutionManager.java:77)
at org.springframework.web.flow.mvc.FlowController.handleRequestInternal(FlowController.java:137)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:128)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:44)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:684)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:625)
at org.springframework.web.servlet.FrameworkServlet.serviceWrapper(FrameworkServlet.java:386)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:355)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:152)


Attachments:

Make OGNL expression usage consistent [SWF-40]

Erwin Vervaet opened SWF-40 and commented

In PR5 it is not very clean and consistent when you can or can't use OGNL expressions. E.g.

<view-state id="..." view="redirect:${requestContext.viewName}">

Is supported, but

<view-state id="..." view="${requestContext.viewName}">

Is not.

Similar problems might exist in other areas: to be investigated.

Erwin


No further details from SWF-40

Decrease size of flow execution storage to improve performance and ability to use ClientContinuationFlowExecutionStorage in urls [SWF-36]

Mark White opened SWF-36 and commented

When using the ClientContinuationFlowExecutionStorage, the serialized FlowExecutionImpl has to go out over the wire to the client with every request. Given it's size (very easily 2k+) this adds a fair bit of overhead to the application and prevents it being stored in the url.

However the amount of actual data being serialized is often very small (unless there is a large amount of data in the FlowScope) and most of the overhead is from the Serialization itself. Using Externalization or a more custom serialization method would drastically reduce this size and improve the practicality of using ClientContinuationFlowExecutionStorage.


Affects: 1.0.4

Attachments:

Added simple listener support to webflow struts-adapter [SWF-3]

Markus Joschko opened SWF-3 and commented

I added a possibility to attach a listener to a struts configured FlowExecutor. The listener must be defined as bean in the web-context and can be used with the tag:

<set-property property="listenerId" value="exampleBeanId" />

Multiple listeners are not supported so far.

I made the changes against the following files:
org.springfamework.web.flow.struts.FlowAction 1.81
org.springframework.web.flow.struts.FlowActionMapping 1.13


Attachments:

Flow exception handling.. [SWF-7]

Keith Garry Boyce opened SWF-7 and commented

Quote:

  • Session expiration: consider setting up a HandlerExceptionResolver that maps the NoSuchFlowExecutionException to an error page, perhaps with a flow restart capability.

Is it possible or will it be possible to have this as part of the config xml rather than coding it explicitly. For instance something like:

Code:
<webflow id="contactUs" start-state="pre.select.topic.action">
<exception class="org.springframework.web.flow.NoSuchFlowExecutionException
" to="contactUs"/>


2 votes, 2 watchers

Enhance XML-defined action chains to support equivalent CompositeAction functionality [SWF-42]

Alex Antonov opened SWF-42 and commented

Right now when I specify the <entry> or <exit> behaviors during the state definition, they would execute an action, but regardless of its status continue on the execution of the state. When looking at the implementation, such a state gets an Entry/ExitAction set as a CompositeAction which takes inside the newly created AnnotatedAction object which is indeed being called to execute whatever it is you've specified.

Looking at the CompositeAction i see a property which indicates if it should stopOnError. But there is no way to indicate if the newly created CompositeAction object that wraps my entry/exit behaviors should stop if the <entry> action returns an error Event in response.

Could the change be made to the XmlFlowBuilder to accept a property element that would allow us to specify if we want an <entry> stopOnError and what that errorEventId should be instead of just doing a state.setEntryAction(new CompositeAction(parseAnnotatedActions(entryElement ))); call.

A proposed implementation would be to allow those two attributes to be part of the <entry>/<exit> tags
i.e. <entry stopOnError="true" errorEventId="failure">...</entry>
This way with very little overhead parcing during the building of the flow, we would allow this behavior to be controllable within the xml, thus reducing the need for in-code flow implementations. Also, due to the fact that you can not create a spring bean for the entry action and bind it via <entry bean="blah">...</entry> call, it makes it impossible to create a work around by defining a custom action class to handle such a behavior.


Affects: 1.0.4

Issue Links:

  • #206 Transition actions should optionally allow continuing running other actions after an action failure

Better ability to introspect flow transitions [SWF-43]

Chris Wood opened SWF-43 and commented

It would be handy if flow transitions had a bit more information available for introspecting.

This is my use case: In my view I run through the list of available transitions out of the particular view state. I'd like to render these as a list of links / submit buttons / whatever on the page, however there's no way to determine the eventId that the particular transition has as it's criteria, so I can't write the 'eventId' parameter easily.

A related issue is that it would be nice to have a canExecute method on the transition which takes a request context (for the current view state) and an eventId (for what view we're going to go to). Why is this useful? Again for the above case where we're running through the list of transitions and determining which ones are valid for this current view. The criteria list could then contain criteria based on security permissions ect.

I'd be happy to implement this bit of functionality and contribute it back if someone gives me the nod.


No further details from SWF-43

FlowExecutionManager.createFlow broken [SWF-21]

Steven Bazyl opened SWF-21 and commented

When using a single FlowExecutionManager for a web app, createFlowExecution is broken. The flow is supplied as a parameter, which is then ignored to get the preconfigure instance flow (which is null...)

protected FlowExecution createFlowExecution(Flow flow) {
return new FlowExecutionImpl(getFlow(),
getListeners(), getTransactionSynchronizer());
}

Should use the flow supplied as parameter instead of getFlow().

Hmmm....seems like the latest round of changes in preparation for PR3 introduced a lot of little bugs (this is my 3rd or 4th issue in the past day..all just little mistakes like this) I still love SWF of course and appreciate all the hard work, but I'd like to see a bit more stability in CVS :)


No further details from SWF-21

Webflow - FormAction improvements [SWF-1]

Jim Newsham opened SWF-1 and commented

We've subclassed FormAction to add a number of improvements that we need for our application. Some of these I believe could be useful to others and could be integrated into FormAction itself, so I'm contributing them below in case you agree.

(Yes, we did have a need to bind without validate, and to validate without bind, believe it or not.)

/**

  • Binds the request parameters to the form bean, but performs no validation.
  • Returns "success" if there are no binding errors, otherwise "error".
    */
    public Event bind(RequestContext context) {
    Object form = loadFormObject(context);
    DataBinder binder = createBinder(context, form);
    binder.bind(new MutablePropertyValues(
    context.getLastEvent().getParameters()));
    onBind(context, binder.getTarget(), binder.getErrors());
    exposeFormObjectAndErrors(context, form, binder.getErrors());
    return binder.getErrors().hasErrors() ? error() : success();
    }

/**

  • Validates the form bean, but performs no binding. Returns "success" if
  • validation succeeds, otherwise "error".
    */
    public Event validate(RequestContext context) throws Exception {
    Object form = loadFormObject(context);
    DataBinder binder = createBinder(context, form);
    BindException errors = binder.getErrors();
    if (getValidator() != null && validationEnabled(context)) {
    validate(context, form, errors);
    }
    exposeFormObjectAndErrors(context, form, errors);
    return errors.hasErrors() ? error() : success();
    }

/**

  • Removes the exposed form object and errors, so that it may be recreated or

  • reloaded. Returns "success".
    */
    public Event removeForm(RequestContext context) {
    // remove form object and its alias
    Scope scope = (getFormObjectScope() == ScopeType.FLOW)
    ? context.getFlowScope() : context.getRequestScope();
    scope.removeAttribute(getFormObjectName());
    scope.removeAttribute(FormObjectAccessor.FORM_OBJECT_ALIAS);

    // remove errors object and its alias
    scope = (getErrorsScope() == ScopeType.FLOW)
    ? context.getFlowScope() : context.getRequestScope();
    scope.removeAttribute(BindException.ERROR_KEY_PREFIX + getFormObjectName());
    scope.removeAttribute(BindException.ERROR_KEY_PREFIX +
    FormObjectAccessor.FORM_OBJECT_ALIAS);
    return success();

}

/**

  • Gets the request bean form object, which must already have been exposed
  • in the request or flow.
    */
    protected Object getForm(RequestContext context) {
    FormObjectAccessor accessor = new FormObjectAccessor(context);
    try {
    return accessor.getFormObject(getFormObjectName(), ScopeType.REQUEST);
    }
    catch (IllegalStateException e) {
    return accessor.getFormObject(getFormObjectName(), ScopeType.FLOW);
    }
    }

/**

  • Gets the errors object. If the errors object does not already exist, a
  • new one is created and added to the appropriate scope, but this requires
  • that the form object already be exposed in the request or flow.
    */
    protected Errors getFormErrors(RequestContext context) {
    FormObjectAccessor accessor = new FormObjectAccessor(context);
    try {
    return accessor.getFormErrors(getFormObjectName(), ScopeType.REQUEST);
    }
    catch (IllegalStateException ise) {
    try {
    return accessor.getFormErrors(getFormObjectName(), ScopeType.FLOW);
    }
    catch(IllegalStateException ise2) {
    Object form = getForm(context);
    System.err.println("creating new formErrors for form " + form +
    " and name " + getFormObjectName());
    Errors errors = new BindException(form, getFormObjectName());
    accessor.exposeErrors(errors, getErrorsScope());
    return errors;
    }
    }
    }

No further details from SWF-1

NPE in ExpiredFlowCleanupFilter. [SWF-41]

Alex Antonov opened SWF-41 and commented

java.lang.NullPointerException
org.springframework.webflow.execution.servlet.ExpiredFlowCleanupFilter.doCleanup(ExpiredFlowCleanupFilter.java:131)
org.springframework.webflow.execution.servlet.ExpiredFlowCleanupFilter.doFilterInternal(ExpiredFlowCleanupFilter.java:106)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

The problem is in the flowExecution.getActiveSession().getFlow().getId() call.

If you have an old flowExecutionId passed in for which there is no longer an entry in the session, it will come out to be expired, but there is no flow object, so getFlow() call returns null.

The way to reproduce the issue is to execute a flow, then bring down the tomcat, start it back up and just refresh the page. This will cause the NPE.


No further details from SWF-41

FlowExecutionImpl javadoc [SWF-13]

Alex Greif opened SWF-13 and commented

sorry for reporting such minor issues, but I am browsing the sources.

In the class FlowExecutionImpl the method javadocs of
activateSession() and
createFlowSession()
do not list all parameters.

@Erwin: drop me a comment if you are not interested in inconsistent javadoc issues.


No further details from SWF-13

Conversion: source class assignable to target class is incorrectly considered for conversion [SWF-32]

Steven Devijver opened SWF-32 and commented

For example, a java.util.HashMap instance that has to be assigned to a java.util.Map argument is incorrectly considered for conversion while the source type is assignable to the target type. To fix this a test has to be added to DefaultConversionService that returns a NoOpConvertor is the target type is assignable from the source type. A patch for spring-binding that implements this fix is attached.


Attachments:

add TilesBindingRequestProcessor [SWF-6]

Alex Burgel opened SWF-6 and commented

in webflow PR3, there is a BindingRequestProcessor, but no TilesBindingRequestProcessor.

it would be a useful addition, and very easy... same code except extends TilesRequestProcessor instead of RequestProcessor


No further details from SWF-6

FlowExecutionImpl.getFlowIdStack removed? [SWF-17]

Steven Bazyl opened SWF-17 and commented

Somewhere in the past week or two getFlowIdStack() was removed from FlowExecution (err, probably on impl class.) This was a very useful method for displaying bread crumbs. With the latest source I either have to iterate backwards through the parents (sucks, since I want root->child order) or use a FlowExecutionListener to track transitions and store them (sucks because I already have the history, just not in a very usable form.)

Please reintroduce this.


No further details from SWF-17

FlowAction should be able to work together with ContextLoaderPlugIn [SWF-2]

Thomas Dudziak opened SWF-2 and commented

In the current version of spring-webflow (pr3), it is not possible to have the (Xml)FlowFactoryBean and the flow actions defined in the spring context file that is loaded by the ContextLoaderPlugIn (for Spring-Struts integration). This however might be necessary in scenarios where the root context file is loaded early (eg. when Acegi is used) in order to prevent double creation of beans.

To remedy this, a simple fix can be applied to org.springframework.web.struts.TemplateAction that makes this class and its subclasses (eg. FlowAction) recognize the presence of the ContextLoaderPlugIn. The fix mainly consists of changing the base class of TemplateAction from Action to Spring-provided ActionSupport which already provides this functionality:

old TemplateAction:


public abstract class TemplateAction extends Action {

...

private WebApplicationContext webApplicationContext;

...

protected WebApplicationContext getWebApplicationContext() {
return this.webApplicationContext;
}

protected Object getBean(String beanName, Class requiredType) {
return this.webApplicationContext.getBean(beanName, requiredType);
}

public void setServlet(ActionServlet actionServlet) {
super.setServlet(actionServlet);
// ActionServlet may be null when an application is closed
// down before reload, especially in WebLogic
if (actionServlet != null) {
ServletContext servletContext = actionServlet.getServletContext();
this.webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
}
}
}

new TemplateAction:


public abstract class TemplateAction extends ActionSupport {

...

protected Object getBean(String beanName, Class requiredType) {
return getWebApplicationContext().getBean(beanName, requiredType);
}
}


No further details from SWF-2

Errors not bound to BindingActionForm on exception [SWF-8]

Alex Burgel opened SWF-8 and commented

i mentioned this in the forums, but i figure it should be filed as a bug.

http://forum.springframework.org/viewtopic.php?t=5848#23203

to summarize, if an exception is thrown in the flow, the spring Errors object is not bound to BindingActionForm which means that your views will throw an exception if they try to access the form.

this is a problem if you try to handle the exception through the struts exception handlers and then return back to the original form.

since the binding of Errors to BindingActionForm occurs in a FlowListener, some possible solutions might be:

  1. change this so the binding occurs in a finally block instead of in a listener

  2. add a new type of flow event that gets called regardless of whether an exception is thrown, like requestEnded or something... then having the Errors->BindingActionForm stuff listen for this type of event.

#2 might be generally useful


No further details from SWF-8

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.