PDA

View Full Version : Cannot get back a command in a flow ..



yfmoan
Jun 21st, 2005, 09:46 PM
Hi ,
l cannot get back a command that put in a flow scope , according to Keith , it suppose to "stay there for the life of the flow".

l wish to do the following ,

l first search a list of publishers for edit , after a successful search , l pick a publisher for edit , show the edit page then edit and submit . After a successful edit , l wish to immediately display back the original search for user experience ...so l need the original command --> googleSortCommand for my case , but l cannot get it , may be my code problem .... below is my codes snippet ,


public class BookRelatedActions extends AbstractLibraryFormAction {

private static final String GOOGLE_SORT_COMMAND = "googleSortCommand";

public BookRelatedActions() {

setFormObjectName(GOOGLE_SORT_COMMAND);
setFormObjectClass(GoogleSortCommand.class);
//l set <property name="formObjectScopeAsString" value="flow"/> in xxx.servlet.xml
&#125;

...
public Event SearchPublisher&#40;RequestContext context&#41; throws Exception &#123;

GoogleSortCommand googleSortCommand = &#40;GoogleSortCommand&#41;context.getFlowScope&#40;&#41;.get&#40;GOOG LE_SORT_COMMAND&#41;;

String publisherName = googleSortCommand.getKeyword&#40;&#41;;
String sortColumn = googleSortCommand.getSortColumn&#40;&#41;;

System.out.println&#40;"-------"+publisherName+"--------"&#41;;
System.out.println&#40;"^^^^^^^^"+sortColumn+"^^^^^^^^"&#41;;

if&#40;publisherName != null&#41;&#123;

Map model = getLibrary&#40;&#41;.findPublishersByNameWithTotal&#40;googleS ortCommand&#41;;
ArrayList publishers = &#40;ArrayList&#41;model.get&#40;"_resultset"&#41;;

if &#40;publishers.size&#40;&#41; < 1&#41; &#123;
// no item found
writeMessage&#40;context,"NoPublihserFound","no.publisher.found"&#41;;

return success&#40;&#41;;
&#125;
// multiple items found
context.getRequestScope&#40;&#41;.setAttribute&#40;"Publishers", model&#41;;

return success&#40;&#41;;
&#125;

return success&#40;&#41;;
&#125;

&#125;


System.out.println&#40;"-------"+publisherName+"--------"&#41;;
System.out.println&#40;"^^^^^^^^"+sortColumn+"^^^^^^^^"&#41;;
show nulls ... no original form object return.

bookRelated-flow.xml,

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE webflow PUBLIC "-//SPRING//DTD WEBFLOW//EN"
"http&#58;//www.springframework.org/dtd/spring-webflow.dtd">

<webflow id="bookRelated.Flow" start-state="bookRelated.start">

<view-state id="bookRelated.start" view="bookRelated.view">
<transition on="showPublisherForm" to="AddPublisherForm"/>
<transition on="searchPublisherById" to="publisher.Update.Flow"/>
<transition on="deletePublisher" to="DeletePublisher"/>

<transition on="searchAuthor" to="SearchAuthor">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchPublisher" to="SearchPublisher">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchSubject" to="SearchSubject">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchOtherTitle" to="SearchOtherTitle">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchSeries" to="SearchSeries">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchNote" to="SearchNote">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
</view-state>

<view-state id="AddPublisherForm" view="publisher.Create">
<transition on="add" to="bindAndValidate.SaveForm"/>

<transition on="searchAuthor" to="SearchAuthor">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchPublisher" to="SearchPublisher">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchSubject" to="SearchSubject">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchOtherTitle" to="SearchOtherTitle">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchSeries" to="SearchSeries">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchNote" to="SearchNote">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
</view-state>

<action-state id="bindAndValidate.SaveForm">
<action bean="publisherActions" method="bindAndValidate"/>
<transition on="success" to="SavePublisher"/>
<transition on="error" to="AddPublisherForm"/>
</action-state>

<action-state id="SavePublisher">
<action name="Save" bean="publisherActions"/>
<transition on="Save.success" to="AddPublisherForm"/>
<transition on="Save.error" to="AddPublisherForm"/>
</action-state>

<subflow-state id="publisher.Update.Flow" flow="publisher.Update.Flow">
<attribute-mapper>
<input value="$&#123;sourceEvent.parameters.id&#125;" as="id" type="long"/>
</attribute-mapper>
<transition on="finish" to="bookRelated.start"/>
<transition on="finish.edit.publisher" to="SearchPublisher">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="_SearchAuthor" to="SearchAuthor"/>
<transition on="_SearchPublisher" to="SearchPublisher"/>
<transition on="_SearchSubject" to="SearchSubject"/>
<transition on="_SearchOtherTitle" to="SearchOtherTitle"/>
<transition on="_SearchSeries" to="SearchSeries"/>
<transition on="_SearchNote" to="SearchNote"/>
<transition on="error" to="bookRelated.start"/>
</subflow-state>

<action-state id="DeletePublisher">
<action bean="publisherActions"/>
<transition on="success" to="bookRelated.start"/>
<transition on="error" to="bookRelated.start"/>
</action-state>

<action-state id="SearchAuthor">
<action bean="bookRelatedActions"/>
<transition on="success" to="bookRelated.start"/>
</action-state>

<action-state id="SearchPublisher">
<action bean="bookRelatedActions"/>
<transition on="success" to="bookRelated.start"/>
</action-state>

<action-state id="SearchSubject">
<action bean="bookRelatedActions"/>
<transition on="success" to="bookRelated.start"/>
</action-state>

<action-state id="SearchOtherTitle">
<action bean="bookRelatedActions"/>
<transition on="success" to="bookRelated.start"/>
</action-state>

<action-state id="SearchSeries">
<action bean="bookRelatedActions"/>
<transition on="success" to="bookRelated.start"/>
</action-state>

<action-state id="SearchNote">
<action bean="bookRelatedActions"/>
<transition on="success" to="bookRelated.start"/>
</action-state>

</webflow>
subflow - publisher.Update-flow.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE webflow PUBLIC "-//SPRING//DTD WEBFLOW//EN"
"http&#58;//www.springframework.org/dtd/spring-webflow.dtd">

<webflow id="publisher.Update.Flow" start-state="SearchPublisherById">

<action-state id="SearchPublisherById">
<action bean="publisherActions"/>
<transition on="success" to="publisher.edit"/>
<transition on="error" to="finish"/>
</action-state>

<view-state id="publisher.edit" view="publisher.Update">
<transition on="edit" to="bindAndValidate.EditForm"/>
<transition on="back" to="finish"/>
<transition on="searchAuthor" to="_SearchAuthor">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchPublisher" to="_SearchPublisher">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchSubject" to="_SearchSubject">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchOtherTitle" to="_SearchOtherTitle">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchSeries" to="_SearchSeries">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
<transition on="searchNote" to="_SearchNote">
<action bean="bookRelatedActions" method="bindAndValidate"/>
</transition>
</view-state>

<action-state id="bindAndValidate.EditForm">
<action bean="publisherActions" method="bindAndValidate"/>
<transition on="success" to="EditPublisher"/>
<transition on="error" to="publisher.edit"/>
</action-state>

<action-state id="EditPublisher">
<action bean="publisherActions"/>
<transition on="success" to="finish.edit.publisher"/>
<transition on="error" to="publisher.edit"/>
</action-state>

<end-state id="finish"/>
<end-state id="finish.edit.publisher"/>
<end-state id="_SearchAuthor"/>
<end-state id="_SearchPublisher"/>
<end-state id="_SearchSubject"/>
<end-state id="_SearchOtherTitle"/>
<end-state id="_SearchSeries"/>
<end-state id="_SearchNote"/>
</webflow>

moon

klr8
Jun 22nd, 2005, 04:20 AM
As far as I can see, it seems to be working since you actually get something back from "context.getFlowScope().get(GOOGLE_SORT_COMMAND)", otherwise you would have gotten a NPE on "googleSortCommand.getKeyword();".

Erwin.

yfmoan
Jun 22nd, 2005, 04:36 AM
Nope , it was filtered by if(publisherName != null) ... and display an successView ( l direct all success or error to successView for convenient ..hihi )
Some of my print out ,


l did the printout&#58;
System.out.println&#40;googleSortCommand&#41;;
System.out.println&#40;"-------"+subjectName+"--------"&#41;;
System.out.println&#40;"^^^^^^^^"+sortColumn+"^^^^^^^^"&#41;;
results&#58;

&#40;first search&#41;

org.yourschool.library.domain.command.GoogleSortCo mmand@1debcf3

-------%--------

^^^^^^^^publisherName^^^^^^^^

&#40;after success edit&#41;

org.yourschool.library.domain.command.GoogleSortCo mmand@152e7a4

-------null--------

^^^^^^^^null^^^^^^^^
it seem to be two different instances for the commands.

moon

klr8
Jun 22nd, 2005, 05:51 AM
Look at your code:

1) First you do "GoogleSortCommand googleSortCommand = (GoogleSortCommand)context.getFlowScope().get(GOOG LE_SORT_COMMAND);"

2) Next you do "String publisherName = googleSortCommand.getKeyword();"

Since that is not throwing a NPE, it means that googleSortCommand is present in the flow scope. The fact that you have different form objects in your flow scope is probably because you're doing 'setupForm' multiple times.

Erwin

yfmoan
Jun 22nd, 2005, 07:54 AM
Yes , l don't know why there is another command too , l got a new empty content command.

l don't have any setupForm , what you see in BookRelatedActions is all , actually l have just one method now - SearchPublisher (just for testing) , you can also see it in my bookRelated-flow.xml too .... , another object - PublisherActions , just a CRUD actions for Publisher that you can see in another thread post ..:)

moon

yfmoan
Jun 22nd, 2005, 10:26 AM
If l remove the line ,
<action bean="bookRelatedActions" method="bindAndValidate"/>

<subflow-state id="publisher.Update.Flow" flow="publisher.Update.Flow">
<attribute-mapper>
<input value="$&#123;sourceEvent.parameters.id&#125;" as="id" type="long"/>
</attribute-mapper>
<transition on="finish" to="bookRelated.start"/>
<transition on="finish.edit.publisher" to="SearchPublisher"/>
*********** remove the code here *************
<transition on="_SearchAuthor" to="SearchAuthor"/>
<transition on="_SearchPublisher" to="SearchPublisher"/>
<transition on="_SearchSubject" to="SearchSubject"/>
<transition on="_SearchOtherTitle" to="SearchOtherTitle"/>
<transition on="_SearchSeries" to="SearchSeries"/>
<transition on="_SearchNote" to="SearchNote"/>
<transition on="error" to="bookRelated.start"/>
</subflow-state>
then l got a NPE ...

The code above is so simple that l don't know where to find the error ....hihi .... l am dying ....

moon

yfmoan
Jun 22nd, 2005, 08:43 PM
Hi , Erwin
l found the answer , my original xxx-library.xml was using

<bean id="flowExecutionManager"
class="org.springframework.web.flow.execution.servlet.Ser vletFlowExecutionManager">
<property name="storage">
<bean class="org.springframework.web.flow.execution.
servlet.HttpSessionContinuationFlowExecutionStorag e"/>
</property>
</bean>

after l change it to

<bean id="flowExecutionManager"
class="org.springframework.web.flow.execution.servlet.Ser vletFlowExecutionManager">
<property name="storage">
<bean class="org.springframework.web.flow.execution.servlet.Htt pSessionFlowExecutionStorage"/>
</property>
</bean>
it is return the same form object now , l got the original command object.
but now the question , why there is a different between HttpSessionContinuationFlowExecutionStorage and HttpSessionFlowExecutionStorage ? , if this is the case , that means we cannot use HttpSessionContinuationFlowExecutionStorage if we want to get back the original command ?

moon

yfmoan
Jun 22nd, 2005, 09:13 PM
Immediately there is another problem (may be mine)
l do paging using own make tag , refer to http://forum.springframework.org/showthread.php?t=14458 , the mechanism l was using to retrieve the page , pageSize , sortColumn ,...are simply using,

public void initProperties(){

HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
this.parameters = RequestUtil.getRequestParameterMap(request);

String Page = (String)parameters.get(PAGE);
this.page = Integer.parseInt(Page);

String PageSize = (String)parameters.get(PAGE_SIZE);
this.pageSize = Integer.parseInt(PageSize);

this.listSize = ((List)((Map)request.getAttribute(modelName)).get("_resultset")).size();
this.totalElements = ((Integer)((Map)request.getAttribute(modelName)).g et("_totalElements")).intValue();

this.previousPageLink = UrlEncoder.encode(makePreviousPageParameters(param eters));
this.nextPageLink = UrlEncoder.encode(makeNextPageParameters(parameter s));

}
although l found the problem above , l got another exception immediately ,

java.lang.NumberFormatException: null
java.lang.Integer.parseInt(Unknown Source)
java.lang.Integer.parseInt(Unknown Source)
org.simplePage.web.tags.GoogleTag.initProperties(G oogleTag.java:60)
....l cannot get those parameter back to feed the GoogleTag .... l guess because of those parameters are in the flow scope not the request scope , if my guess is true , than l have to modify my codes to retrieve those parameters from SWF , this will make my paging codes depend on SWF API , how to solve this problem ?

l think one of the SWF's ability is chaining actions , because it can store the "history" inside a flow (what ever it store in RequestContext , Event ,.....) , but if you put something (parameters for example) inside a flow , then you must have a way to let something out (parameters for example..:)) after few chaining steps to show results ....

what do you think ?

moon

yfmoan
Jun 23rd, 2005, 09:07 PM
Guess 1.
l think other paging tag like displaytag or valuelist will subject to the same problem if they are using similar retrieving method ... how they know where to get those parameters ?

Q1.
Even though l pass those parameters to my paging tag manually by the help of the action (BookRelatedActions) ,

Map parameters = context.getSourceEvent&#40;&#41;.getParameters&#40;&#41;;
context.getRequestScope&#40;&#41;.setAttribute&#40;"_parameters", parameter&#41;;
context.getRequestScope&#40;&#41;.setAttribute&#40;"Publishers", model&#41;;
it still fail my paging tag , because the parameters from SourceEvent is an UnmodifiableMap , then how can we do paging using SWF ?

moon