Moved Spring Web Flow to a top level project
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Person implements Serializable {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String userId;
|
||||
|
||||
private String phone;
|
||||
|
||||
private List<Person> colleagues = new ArrayList<Person>();
|
||||
|
||||
public Person() {
|
||||
this(-1, "", "", "", "");
|
||||
}
|
||||
|
||||
public Person(long id, String firstName, String lastName, String userId, String phone) {
|
||||
this.id = new Long(id);
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.userId = userId;
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return this.firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return this.lastName;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return this.phone;
|
||||
}
|
||||
|
||||
public List getColleagues() {
|
||||
return this.colleagues;
|
||||
}
|
||||
|
||||
public int getColleagueCount() {
|
||||
return this.colleagues.size();
|
||||
}
|
||||
|
||||
public Person getColleague(int i) {
|
||||
return this.colleagues.get(i);
|
||||
}
|
||||
|
||||
public void addColleague(Person colleague) {
|
||||
this.colleagues.add(colleague);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Phonebook {
|
||||
|
||||
public List<Person> search(SearchCriteria criteria);
|
||||
|
||||
public Person getPerson(Long id);
|
||||
|
||||
public Person getPerson(String userId);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SearchCriteria implements Serializable {
|
||||
|
||||
private String firstName = "";
|
||||
|
||||
private String lastName = "";
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
public class SearchCriteriaValidator implements Validator {
|
||||
|
||||
public boolean supports(Class clazz) {
|
||||
return clazz.equals(SearchCriteria.class);
|
||||
}
|
||||
|
||||
public void validate(Object obj, Errors errors) {
|
||||
SearchCriteria query = (SearchCriteria)obj;
|
||||
if (!StringUtils.hasText(query.getFirstName()) && !StringUtils.hasText(query.getLastName())) {
|
||||
errors.reject("noCriteria", "Please provide some query criteria!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook.stub;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.webflow.samples.phonebook.Person;
|
||||
import org.springframework.webflow.samples.phonebook.Phonebook;
|
||||
import org.springframework.webflow.samples.phonebook.SearchCriteria;
|
||||
|
||||
public class StubPhonebook implements Phonebook {
|
||||
|
||||
private List<Person> persons = new ArrayList<Person>();
|
||||
|
||||
public StubPhonebook() {
|
||||
// setup some dummy test data
|
||||
Person kd = new Person(1, "Keith", "Donald", "kdonald", "11111");
|
||||
Person ev = new Person(2, "Erwin", "Vervaet", "klr8", "22222");
|
||||
Person cs = new Person(3, "Colin", "Sampaleanu", "sampa", "33333");
|
||||
Person jh = new Person(4, "Juergen", "Hoeller", "jhoeller", "44444");
|
||||
Person rj = new Person(5, "Rod", "Johnson", "rod", "55555");
|
||||
Person tr = new Person(6, "Thomas", "Risberg", "trisberg", "66666");
|
||||
Person aa = new Person(7, "Alef", "Arendsen", "alef", "77777");
|
||||
Person mp = new Person(8, "Mark", "Pollack", "mark", "88888");
|
||||
|
||||
kd.addColleague(ev);
|
||||
kd.addColleague(cs);
|
||||
kd.addColleague(jh);
|
||||
kd.addColleague(rj);
|
||||
kd.addColleague(tr);
|
||||
kd.addColleague(aa);
|
||||
kd.addColleague(mp);
|
||||
|
||||
ev.addColleague(kd);
|
||||
ev.addColleague(cs);
|
||||
ev.addColleague(jh);
|
||||
ev.addColleague(rj);
|
||||
|
||||
cs.addColleague(kd);
|
||||
cs.addColleague(ev);
|
||||
cs.addColleague(jh);
|
||||
cs.addColleague(rj);
|
||||
cs.addColleague(aa);
|
||||
cs.addColleague(mp);
|
||||
|
||||
rj.addColleague(cs);
|
||||
rj.addColleague(kd);
|
||||
rj.addColleague(ev);
|
||||
rj.addColleague(jh);
|
||||
rj.addColleague(tr);
|
||||
rj.addColleague(aa);
|
||||
rj.addColleague(mp);
|
||||
|
||||
jh.addColleague(cs);
|
||||
jh.addColleague(kd);
|
||||
jh.addColleague(ev);
|
||||
jh.addColleague(jh);
|
||||
jh.addColleague(tr);
|
||||
jh.addColleague(aa);
|
||||
|
||||
Person sa = new Person(9, "Shaun", "Alexander", "rolltide", "44444");
|
||||
Person dj = new Person(10, "Darell", "Jackson", "gatorcountry", "55555");
|
||||
sa.addColleague(dj);
|
||||
dj.addColleague(sa);
|
||||
|
||||
persons.add(kd);
|
||||
persons.add(ev);
|
||||
persons.add(cs);
|
||||
persons.add(jh);
|
||||
persons.add(rj);
|
||||
persons.add(tr);
|
||||
persons.add(aa);
|
||||
persons.add(mp);
|
||||
|
||||
persons.add(sa);
|
||||
persons.add(dj);
|
||||
}
|
||||
|
||||
public List<Person> search(SearchCriteria query) {
|
||||
List<Person> res = new ArrayList<Person>();
|
||||
for (Person person : persons) {
|
||||
if ((person.getFirstName().indexOf(query.getFirstName()) != -1)
|
||||
&& (person.getLastName().indexOf(query.getLastName()) != -1)) {
|
||||
res.add(person);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Person getPerson(Long id) {
|
||||
for (Person person : persons) {
|
||||
if (person.getId().equals(id)) {
|
||||
return person;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Person getPerson(String userId) {
|
||||
for (Person person : persons) {
|
||||
if (person.getUserId().equals(userId)) {
|
||||
return person;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?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-2.0.xsd">
|
||||
|
||||
<bean id="phonebook" class="org.springframework.webflow.samples.phonebook.stub.StubPhonebook"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook.webflow;
|
||||
|
||||
import org.springframework.binding.mapping.DefaultAttributeMapper;
|
||||
import org.springframework.binding.mapping.Mapping;
|
||||
import org.springframework.webflow.engine.Transition;
|
||||
import org.springframework.webflow.engine.builder.AbstractFlowBuilder;
|
||||
import org.springframework.webflow.engine.builder.FlowBuilderException;
|
||||
import org.springframework.webflow.engine.builder.FlowServiceLocator;
|
||||
import org.springframework.webflow.engine.support.ConfigurableFlowAttributeMapper;
|
||||
|
||||
/**
|
||||
* Java-based flow builder that builds the person details flow, exactly like it
|
||||
* is defined in the <code>detail-flow.xml</code> XML flow definition.
|
||||
* <p>
|
||||
* This encapsulates the page flow of viewing a person's details and their
|
||||
* collegues in a reusable, self-contained module.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
class PersonDetailFlowBuilder extends AbstractFlowBuilder {
|
||||
|
||||
public PersonDetailFlowBuilder(FlowServiceLocator flowServiceLocator) {
|
||||
super(flowServiceLocator);
|
||||
}
|
||||
|
||||
public void buildInputMapper() throws FlowBuilderException {
|
||||
Mapping idMapping = mapping().source("id").target("flowScope.id").value();
|
||||
getFlow().setInputMapper(new DefaultAttributeMapper().addMapping(idMapping));
|
||||
}
|
||||
|
||||
public void buildStates() throws FlowBuilderException {
|
||||
// get the person given a userid as input
|
||||
addActionState("getDetails", action("phonebook", method("getPerson(${flowScope.id})"), result("person")),
|
||||
transition(on(success()), to("displayDetails")));
|
||||
|
||||
// view the person details
|
||||
addViewState("displayDetails", "details", new Transition[] { transition(on(back()), to("finish")),
|
||||
transition(on(select()), to("browseColleagueDetails")) });
|
||||
|
||||
// view details for selected collegue
|
||||
ConfigurableFlowAttributeMapper idMapper = new ConfigurableFlowAttributeMapper();
|
||||
idMapper.addInputMapping(mapping().source("requestParameters.id").target("id").from(String.class)
|
||||
.to(Long.class).value());
|
||||
addSubflowState("browseColleagueDetails", getFlow(), idMapper, transition(on(finish()), to("getDetails")));
|
||||
|
||||
// end
|
||||
addEndState("finish");
|
||||
|
||||
// end error
|
||||
addEndState("error");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook.webflow;
|
||||
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionHolder;
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionRegistrar;
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
|
||||
import org.springframework.webflow.definition.registry.StaticFlowDefinitionHolder;
|
||||
import org.springframework.webflow.engine.builder.FlowAssembler;
|
||||
import org.springframework.webflow.engine.builder.FlowBuilder;
|
||||
import org.springframework.webflow.engine.builder.FlowServiceLocator;
|
||||
|
||||
/**
|
||||
* Demonstrates how to register flows programatically.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
class PhonebookFlowRegistrar implements FlowDefinitionRegistrar {
|
||||
|
||||
private FlowServiceLocator serviceLocator;
|
||||
|
||||
public PhonebookFlowRegistrar(FlowServiceLocator serviceLocator) {
|
||||
this.serviceLocator = serviceLocator;
|
||||
}
|
||||
|
||||
public void registerFlowDefinitions(FlowDefinitionRegistry registry) {
|
||||
registry.registerFlowDefinition(assemble("detail-flow", new PersonDetailFlowBuilder(serviceLocator)));
|
||||
registry.registerFlowDefinition(assemble("search-flow", new SearchPersonFlowBuilder(serviceLocator)));
|
||||
}
|
||||
|
||||
private FlowDefinitionHolder assemble(String flowId, FlowBuilder flowBuilder) {
|
||||
return new StaticFlowDefinitionHolder(new FlowAssembler(flowId, flowBuilder).assembleFlow());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook.webflow;
|
||||
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
|
||||
import org.springframework.webflow.engine.builder.AbstractFlowBuildingFlowRegistryFactoryBean;
|
||||
|
||||
/**
|
||||
* Demonstrates how to populate a flow registry programatically.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class PhonebookFlowRegistryFactoryBean extends AbstractFlowBuildingFlowRegistryFactoryBean {
|
||||
|
||||
protected void doPopulate(FlowDefinitionRegistry registry) {
|
||||
new PhonebookFlowRegistrar(getFlowServiceLocator()).registerFlowDefinitions(registry);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook.webflow;
|
||||
|
||||
import org.springframework.webflow.action.FormAction;
|
||||
import org.springframework.webflow.action.MultiAction;
|
||||
import org.springframework.webflow.engine.Transition;
|
||||
import org.springframework.webflow.engine.builder.AbstractFlowBuilder;
|
||||
import org.springframework.webflow.engine.builder.FlowBuilderException;
|
||||
import org.springframework.webflow.engine.builder.FlowServiceLocator;
|
||||
import org.springframework.webflow.engine.support.ConfigurableFlowAttributeMapper;
|
||||
import org.springframework.webflow.execution.ScopeType;
|
||||
import org.springframework.webflow.samples.phonebook.SearchCriteria;
|
||||
import org.springframework.webflow.samples.phonebook.SearchCriteriaValidator;
|
||||
|
||||
/**
|
||||
* Java-based flow builder that searches for people in the phonebook. The flow
|
||||
* defined by this class is exactly the same as that defined in the
|
||||
* <code>search-flow.xml</code> XML flow definition.
|
||||
* <p>
|
||||
* This encapsulates the page flow of searching for some people, selecting a
|
||||
* person you care about, and viewing their person's details and those of their
|
||||
* collegues in a reusable, self-contained module.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
class SearchPersonFlowBuilder extends AbstractFlowBuilder {
|
||||
|
||||
public SearchPersonFlowBuilder(FlowServiceLocator flowServiceLocator) {
|
||||
super(flowServiceLocator);
|
||||
}
|
||||
|
||||
public void buildStates() throws FlowBuilderException {
|
||||
// view search criteria
|
||||
MultiAction searchFormAction = createSearchFormAction();
|
||||
addViewState("enterCriteria", "searchCriteria", invoke("setupForm", searchFormAction),
|
||||
new Transition[] { transition(on("search"), to("executeSearch"), ifReturnedSuccess(invoke(
|
||||
"bindAndValidate", searchFormAction))) });
|
||||
|
||||
// execute query
|
||||
addActionState("executeSearch", action("phonebook", method("search(${flowScope.searchCriteria})"),
|
||||
result("results")), transition(on(success()), to("displayResults")));
|
||||
|
||||
// view results
|
||||
addViewState("displayResults", "searchResults", new Transition[] {
|
||||
transition(on("newSearch"), to("enterCriteria")), transition(on(select()), to("browseDetails")) });
|
||||
|
||||
// view details for selected user id
|
||||
ConfigurableFlowAttributeMapper idMapper = new ConfigurableFlowAttributeMapper();
|
||||
idMapper.addInputMapping(mapping().source("requestParameters.id").target("id").from(String.class)
|
||||
.to(Long.class).value());
|
||||
addSubflowState("browseDetails", flow("detail-flow"), idMapper, transition(on(finish()), to("executeSearch")));
|
||||
|
||||
// end - an error occured
|
||||
addEndState(error(), "error");
|
||||
}
|
||||
|
||||
protected FormAction createSearchFormAction() {
|
||||
FormAction action = new FormAction(SearchCriteria.class);
|
||||
action.setFormObjectScope(ScopeType.FLOW);
|
||||
action.setValidator(new SearchCriteriaValidator());
|
||||
return action;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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:flow="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd">
|
||||
|
||||
<!-- Launches new flow executions and resumes existing executions. -->
|
||||
<flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="continuation"/>
|
||||
|
||||
<!-- Creates the registry of Java-based flow definitions for this application -->
|
||||
<bean id="flowRegistry" class="org.springframework.webflow.samples.phonebook.webflow.PhonebookFlowRegistryFactoryBean"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,9 @@
|
||||
log4j.rootCategory=WARN, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
#Enable webflow debug logging
|
||||
log4j.category.org.springframework.webflow=DEBUG
|
||||
log4j.category.org.springframework.binding=DEBUG
|
||||
@@ -0,0 +1,37 @@
|
||||
<?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-1.0.xsd">
|
||||
|
||||
<input-mapper>
|
||||
<input-attribute name="id"/>
|
||||
</input-mapper>
|
||||
|
||||
<start-state idref="displayDetails" />
|
||||
|
||||
<view-state id="displayDetails" view="details">
|
||||
<render-actions>
|
||||
<bean-action bean="phonebook" method="getPerson">
|
||||
<method-arguments>
|
||||
<argument expression="flowScope.id" />
|
||||
</method-arguments>
|
||||
<method-result name="person" />
|
||||
</bean-action>
|
||||
</render-actions>
|
||||
<transition on="back" to="finish" />
|
||||
<transition on="select" to="browseColleagueDetails" />
|
||||
</view-state>
|
||||
|
||||
<subflow-state id="browseColleagueDetails" flow="detail-flow">
|
||||
<attribute-mapper>
|
||||
<input-mapper>
|
||||
<mapping source="requestParameters.id" target="id" from="string" to="long" />
|
||||
</input-mapper>
|
||||
</attribute-mapper>
|
||||
<transition on="finish" to="displayDetails" />
|
||||
</subflow-state>
|
||||
|
||||
<end-state id="finish" />
|
||||
|
||||
</flow>
|
||||
@@ -0,0 +1,14 @@
|
||||
<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.xsd">
|
||||
|
||||
<!-- Search form action that setups the form and processes form submissions -->
|
||||
<bean id="formAction" class="org.springframework.webflow.action.FormAction">
|
||||
<property name="formObjectClass" value="org.springframework.webflow.samples.phonebook.SearchCriteria"/>
|
||||
<property name="validator">
|
||||
<bean class="org.springframework.webflow.samples.phonebook.SearchCriteriaValidator"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?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-1.0.xsd">
|
||||
|
||||
<start-state idref="enterCriteria"/>
|
||||
|
||||
<view-state id="enterCriteria" view="searchCriteria">
|
||||
<render-actions>
|
||||
<action bean="formAction" method="setupForm"/>
|
||||
</render-actions>
|
||||
<transition on="search" to="displayResults">
|
||||
<action bean="formAction" method="bindAndValidate"/>
|
||||
</transition>
|
||||
</view-state>
|
||||
|
||||
<view-state id="displayResults" view="searchResults">
|
||||
<render-actions>
|
||||
<bean-action bean="phonebook" method="search">
|
||||
<method-arguments>
|
||||
<argument expression="flowScope.searchCriteria"/>
|
||||
</method-arguments>
|
||||
<method-result name="results"/>
|
||||
</bean-action>
|
||||
</render-actions>
|
||||
<transition on="newSearch" to="enterCriteria"/>
|
||||
<transition on="select" to="browseDetails"/>
|
||||
</view-state>
|
||||
|
||||
<subflow-state id="browseDetails" flow="detail-flow">
|
||||
<attribute-mapper>
|
||||
<input-mapper>
|
||||
<mapping source="requestParameters.id" target="id" from="string" to="long"/>
|
||||
</input-mapper>
|
||||
</attribute-mapper>
|
||||
<transition on="finish" to="displayResults"/>
|
||||
</subflow-state>
|
||||
|
||||
<import resource="search-flow-beans.xml"/>
|
||||
|
||||
</flow>
|
||||
@@ -0,0 +1,51 @@
|
||||
<%@ include file="includeTop.jsp" %>
|
||||
|
||||
<div id="content">
|
||||
<div id="insert">
|
||||
<img src="images/webflow-logo.jpg"/>
|
||||
</div>
|
||||
<form action="phonebook.htm" method="post">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Person Details</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colpan="2"><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>First Name</b></td>
|
||||
<td>${person.firstName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Last Name</b></td>
|
||||
<td>${person.lastName}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>User Id</B></td>
|
||||
<td>${person.userId}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Phone</b></td>
|
||||
<td>${person.phone}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<br>
|
||||
<b>Colleagues:</b>
|
||||
<br>
|
||||
<c:forEach var="colleague" items="${person.colleagues}">
|
||||
<a href="phonebook.htm?_flowExecutionKey=${flowExecutionKey}&_eventId=select&id=${colleague.id}">
|
||||
${colleague.firstName} ${colleague.lastName}<br>
|
||||
</a>
|
||||
</c:forEach>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="buttonBar">
|
||||
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}">
|
||||
<input type="submit" class="button" name="_eventId_back" value="Back">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</DIV>
|
||||
@@ -0,0 +1,18 @@
|
||||
<%@ page session="false" %>
|
||||
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<DIV align="left">Error</DIV>
|
||||
<HR>
|
||||
<DIV align="left">
|
||||
<P>
|
||||
An error has occured!
|
||||
</P>
|
||||
</DIV>
|
||||
<HR>
|
||||
<DIV align="right"></DIV>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,5 @@
|
||||
<div id="copyright">
|
||||
<p>© Copyright 2002-2006, <a href="http://www.springframework.org">www.springframework.org</a>, under the terms of the Apache 2.0 software license.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,21 @@
|
||||
<%@ page contentType="text/html" %>
|
||||
<%@ page session="false" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
|
||||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Search the Phonebook</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="logo">
|
||||
<img src="images/spring-logo.jpg" height="73" alt="Logo" border="0">
|
||||
</div>
|
||||
|
||||
<div id="navigation">
|
||||
</div>
|
||||
@@ -0,0 +1,51 @@
|
||||
<%@ include file="includeTop.jsp" %>
|
||||
|
||||
<div id="content">
|
||||
<div id="insert">
|
||||
<img src="images/webflow-logo.jpg"/>
|
||||
</div>
|
||||
<form:form commandName="searchCriteria" method="post">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Search Criteria</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<hr>
|
||||
</td>
|
||||
</tr>
|
||||
<spring:hasBindErrors name="searchCriteria">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="error">Please provide valid search criteria</div>
|
||||
</td>
|
||||
</tr>
|
||||
</spring:hasBindErrors>
|
||||
<tr>
|
||||
<td>First Name</td>
|
||||
<td>
|
||||
<form:input path="firstName" />
|
||||
</td>
|
||||
</tr>
|
||||
<TR>
|
||||
<td>Last Name</td>
|
||||
<td>
|
||||
<form:input path="lastName" />
|
||||
</td>
|
||||
</TR>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<hr>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="buttonBar">
|
||||
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}">
|
||||
<input type="submit" class="button" name="_eventId_search" value="Search">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form:form>
|
||||
</div>
|
||||
|
||||
<%@ include file="includeBottom.jsp" %>
|
||||
@@ -0,0 +1,53 @@
|
||||
<%@ include file="includeTop.jsp" %>
|
||||
|
||||
<div id="content">
|
||||
<div id="insert">
|
||||
<img src="images/webflow-logo.jpg"/>
|
||||
</div>
|
||||
<form action="phonebook.htm" method="post">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
Search Results
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<hr>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table border="1">
|
||||
<tr>
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>User Id</th>
|
||||
<th>Phone</th>
|
||||
</tr>
|
||||
<c:forEach var="person" items="${results}">
|
||||
<tr>
|
||||
<td>${person.firstName}</td>
|
||||
<td>${person.lastName}</td>
|
||||
<td>
|
||||
<a href="phonebook.htm?_flowExecutionKey=${flowExecutionKey}&_eventId=select&id=${person.id}">
|
||||
${person.userId}
|
||||
</a>
|
||||
</td>
|
||||
<td>${person.phone}</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="buttonBar">
|
||||
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}">
|
||||
<input type="submit" class="button" name="_eventId_newSearch" value="New Search">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<%@ include file="includeBottom.jsp" %>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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-2.0.xsd">
|
||||
|
||||
<!--
|
||||
Exposes web flows for execution at a single request URL.
|
||||
The id of a flow to launch should be passed in by clients using
|
||||
the "_flowId" request parameter:
|
||||
e.g. /phonebook.htm?_flowId=search
|
||||
-->
|
||||
<bean name="/phonebook.htm" class="org.springframework.webflow.executor.mvc.FlowController">
|
||||
<property name="flowExecutor" ref="flowExecutor"/>
|
||||
<property name="cacheSeconds" value="5"/>
|
||||
</bean>
|
||||
|
||||
<!-- Resolves flow view names to .jsp templates -->
|
||||
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
|
||||
<property name="prefix" value="/WEB-INF/jsp/"/>
|
||||
<property name="suffix" value=".jsp"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?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:flow="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd">
|
||||
|
||||
<!-- Launches new flow executions and resumes existing executions. -->
|
||||
<flow:executor id="flowExecutor" registry-ref="flowRegistry"/>
|
||||
|
||||
<!-- Creates the registry of flow definitions for this application -->
|
||||
<flow:registry id="flowRegistry">
|
||||
<flow:location path="/WEB-INF/flows/**-flow.xml"/>
|
||||
</flow:registry>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
|
||||
version="2.4">
|
||||
|
||||
<context-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>
|
||||
classpath:org/springframework/webflow/samples/phonebook/stub/services-config.xml
|
||||
</param-value>
|
||||
</context-param>
|
||||
|
||||
<listener>
|
||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>phonebook</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>
|
||||
/WEB-INF/phonebook-servlet-config.xml
|
||||
/WEB-INF/phonebook-webflow-config.xml
|
||||
<!-- Comment out to use alternative Java-based Flow Builders
|
||||
classpath:org/springframework/webflow/samples/phonebook/webflow/phonebook-webflow-config.xml
|
||||
-->
|
||||
</param-value>
|
||||
</init-param>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>phonebook</servlet-name>
|
||||
<url-pattern>*.htm</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.jsp</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
</web-app>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
21
spring-webflow-samples/phonebook/src/main/webapp/index.jsp
Normal file
21
spring-webflow-samples/phonebook/src/main/webapp/index.jsp
Normal file
@@ -0,0 +1,21 @@
|
||||
<%@ page session="true" %> <%-- make sure we have a session --%>
|
||||
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<DIV align="left">Phonebook - A Spring Web Flow Sample</DIV>
|
||||
<HR>
|
||||
<DIV align="left">
|
||||
<P>
|
||||
<A href="phonebook.htm?_flowId=search-flow">Phonebook</A>
|
||||
</P>
|
||||
<P>
|
||||
This sample application illustrates core features of the web flow system.
|
||||
</P>
|
||||
</DIV>
|
||||
<HR>
|
||||
<DIV align="right"></DIV>
|
||||
</BODY>
|
||||
</HTML>
|
||||
58
spring-webflow-samples/phonebook/src/main/webapp/style.css
Normal file
58
spring-webflow-samples/phonebook/src/main/webapp/style.css
Normal file
@@ -0,0 +1,58 @@
|
||||
body {
|
||||
width: 720px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
div#logo {
|
||||
width: 720px;
|
||||
height: 73px;
|
||||
background: #86AEA5;
|
||||
}
|
||||
|
||||
div#navigation {
|
||||
width: 720px;
|
||||
height: 15px;
|
||||
background: #E2F3B8;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div#content {
|
||||
width: 720px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div#insert {
|
||||
width: 120;
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.buttonBar {
|
||||
height: 1.5em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div#copyright {
|
||||
width: 720px;
|
||||
}
|
||||
|
||||
div#copyright p {
|
||||
text-align: center;
|
||||
font-family: Tahoma, sans-serif;
|
||||
font-size: 75%;
|
||||
color: div#336633;
|
||||
margin-left: 5px;
|
||||
font-weight: bold;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.readOnly {
|
||||
color: rgb(192, 192, 192);
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
log4j.rootCategory=WARN, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
# Enable web flow logging
|
||||
log4j.category.org.springframework.webflow=DEBUG
|
||||
log4j.category.org.springframework.binding=DEBUG
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* 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.springframework.webflow.samples.phonebook.webflow;
|
||||
|
||||
import org.springframework.binding.mapping.AttributeMapper;
|
||||
import org.springframework.binding.mapping.MappingContext;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionResource;
|
||||
import org.springframework.webflow.engine.EndState;
|
||||
import org.springframework.webflow.engine.Flow;
|
||||
import org.springframework.webflow.execution.support.ApplicationView;
|
||||
import org.springframework.webflow.samples.phonebook.stub.StubPhonebook;
|
||||
import org.springframework.webflow.test.MockFlowServiceLocator;
|
||||
import org.springframework.webflow.test.MockParameterMap;
|
||||
import org.springframework.webflow.test.execution.AbstractXmlFlowExecutionTests;
|
||||
|
||||
public class SearchFlowExecutionTests extends AbstractXmlFlowExecutionTests {
|
||||
|
||||
public void testStartFlow() {
|
||||
ApplicationView view = applicationView(startFlow());
|
||||
assertCurrentStateEquals("enterCriteria");
|
||||
assertViewNameEquals("searchCriteria", view);
|
||||
assertModelAttributeNotNull("searchCriteria", view);
|
||||
}
|
||||
|
||||
public void testCriteriaSubmitSuccess() {
|
||||
startFlow();
|
||||
MockParameterMap parameters = new MockParameterMap();
|
||||
parameters.put("firstName", "Keith");
|
||||
parameters.put("lastName", "Donald");
|
||||
ApplicationView view = applicationView(signalEvent("search", parameters));
|
||||
assertCurrentStateEquals("displayResults");
|
||||
assertViewNameEquals("searchResults", view);
|
||||
assertModelAttributeCollectionSize(1, "results", view);
|
||||
}
|
||||
|
||||
public void testCriteriaSubmitError() {
|
||||
startFlow();
|
||||
signalEvent("search");
|
||||
assertCurrentStateEquals("enterCriteria");
|
||||
}
|
||||
|
||||
public void testNewSearch() {
|
||||
testCriteriaSubmitSuccess();
|
||||
ApplicationView view = applicationView(signalEvent("newSearch"));
|
||||
assertCurrentStateEquals("enterCriteria");
|
||||
assertViewNameEquals("searchCriteria", view);
|
||||
}
|
||||
|
||||
public void testSelectValidResult() {
|
||||
testCriteriaSubmitSuccess();
|
||||
MockParameterMap parameters = new MockParameterMap();
|
||||
parameters.put("id", "1");
|
||||
ApplicationView view = applicationView(signalEvent("select", parameters));
|
||||
assertCurrentStateEquals("displayResults");
|
||||
assertViewNameEquals("searchResults", view);
|
||||
assertModelAttributeCollectionSize(1, "results", view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FlowDefinitionResource getFlowDefinitionResource() {
|
||||
return createFlowDefinitionResource("src/main/webapp/WEB-INF/flows/search-flow.xml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerMockServices(MockFlowServiceLocator serviceRegistry) {
|
||||
Flow mockDetailFlow = new Flow("detail-flow");
|
||||
mockDetailFlow.setInputMapper(new AttributeMapper() {
|
||||
public void map(Object source, Object target, MappingContext context) {
|
||||
assertEquals("id of value 1 not provided as input by calling search flow", new Long(1), ((AttributeMap)source).get("id"));
|
||||
}
|
||||
});
|
||||
// test responding to finish result
|
||||
new EndState(mockDetailFlow, "finish");
|
||||
|
||||
serviceRegistry.registerSubflow(mockDetailFlow);
|
||||
serviceRegistry.registerBean("phonebook", new StubPhonebook());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user