Trying to answer that question has made me that a nested conversation is in fact not
necessary - inappropriate even.
I've now collapsed the conversations, but the following problem remains - here is the
code :)
The flow is as follows (relevant code in bold)
1. The Registration form conversation starts with the enterClaim method (first bit of
code)
2. The user clicks a link in the form (not shown) which calls the enterClaimant method on
the RegistrationEditorBean. This shows Tab 1 (JSF code below).
3. The user clicks the select link on that tab, which calls the selectClaimant method on
the RegistrationEditorBean. This method creates and installs a PartyFinderClient (more on
this soon) and displays the FindPerson Form (JSF code below).
4. The user searches and the results are shown using the Find Person Results Form (shown
below).
5. The user selects the link for the relevant person and this invokes the select method
of PartyFinder (code below)
6. PartyFinder.select looks up the PartyFinderClient and (i) passes it the selected party
so that it can handle the assignment and (ii) redirects to the page specified by that
PartyFinderClient. In this case, the PartyFinderClient assigns the party to a field in
RegistrationEditor.registrationData and returns to Tab 1.
(I use PartyFinderClient because there are a number of fields that require the same
selection process so the PartyFinderBean cannot know what to do with the data. I'd
love to know if there is a more elegant way to do this)
THE PROBLEM
When the user makes their selection it all works, except that the
RegistrationEditorBean's data field is now null. If I remove the @In(required=false)
tag from the setRegistrationData method then this problem disappears - but of course, I
need the injection because I might be editing, as opposed, to creating the
registrationData. Since I am outjecting the instance of the registrationData, why is that
outjected instance not being passed back in?
Hope you can make sense of all this!
Richard
(I'm using method injection as opposed to field injection because, as far as I can
see, there is no other way to ensure that nested objects (e.g. submissionInfo) are created
on demand)
RegistrationEditorBean
| ...
| @Name("registrationEditor")
| @Stateful
| @Scope(ScopeType.CONVERSATION)
| @Conversational
| public class RegistrationEditorBean implements RegistrationEditor {
|
| private RegistrationData data;
|
| @In
| private Session session;
|
| @Logger
| private Log log;
|
| @Out
| public RegistrationData getRegistrationData() {
| if (data == null) {data = new RegistrationData(); data.setSubmissionInfo(new
SubmissionInfo());}
| return data;
| }
|
| @In(required=false)
| public void setRegistrationData(RegistrationData data) {
| this.data = data;
| }
|
|
| @Begin(flushMode=FlushModeType.MANUAL, join=true)
| public String enterClaim() {
| return "/forms/registration/claim";
| }
|
| public String enterSubmission() {
| return "/forms/registration/submission";
| }
|
| public String enterClaimant() {
| return "/forms/registration/claimant";
| }
|
| public String selectClaimant() {
| PartyFinderClient client = new PartyFinderClient() {
|
| public String cancel() {
| return "/forms/registration/claimant";
| }
|
| public String select(Party party) {
| data.setClaimant(party);
| return "/forms/registration/claimant";
| }
|
| };
| client.install();
| return "/forms/party/find-person";
| }
| ...
|
| public void save() {
| session.save(data.getSubmissionInfo());
| session.save(data);
| session.flush();
| }
|
| ...
| @Destroy @Remove
| public void destroy() { }
|
| }
|
Registration Form JSF - Tab 1
| <?xml version="1.0" encoding="UTF-8"?>
| <!DOCTYPE html
| PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <html
xmlns:f="http://java.sun.com/jsf/core"
|
xmlns:h="http://java.sun.com/jsf/html"
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
xmlns:s="http://jboss.com/products/seam/taglib"
|
xmlns="http://www.w3.org/1999/xhtml">
| <head>
| <title>Registration</title>
| </head>
| <body>
| <ui:composition
xmlns:rich="http://richfaces.ajax4jsf.org/rich"
| template="registration.xhtml">
| <ui:define name="tab">
|
| <div name="tabset-actions" />
| <div name="tabset-links">
| <ul class="tabset" />
| </div>
| <div class="tab"><ui:insert name="tab"
/></div>
|
|
|
|
| <h:outputLabel value="Claimant" for="claimant" />
| <h:inputText id="claimant"
| value="#{registrationEditor.registrationData.claimant.lastName}"
| readonly="true" />
|
| <h:commandLink id="selectClaimant" value="Select"
| action="#{registrationEditor.selectClaimant}" />
|
|
| </ui:define>
| </ui:composition>
| </body>
| </html>
|
|
PartyFinderBean
| ...
| @Name("partyFinder")
| @Stateful
| public class PartyFinderBean implements PartyFinder {
|
| @SuppressWarnings("unused")
| @DataModel
| private List<Party> parties;
|
| @DataModelSelection
| private Party selectedParty;
|
| @In
| private Session session;
|
| @Logger
| private Log log;
|
| @SuppressWarnings("unchecked")
| public String find() {
| Party example = new Person();
| Example exampleParty =
Example.create(example).ignoreCase().enableLike(MatchMode.ANYWHERE);
| parties = session.createCriteria(Person.class)
| .add(exampleParty)
| .list();
| return "/forms/party/findPartyResults";
|
| }
|
| public String cancel() {
| PartyFinderClient client = PartyFinderClient.getInstalled();
| return (client == null ? null : client.cancel());
| }
|
| public String select() {
| PartyFinderClient client = PartyFinderClient.getInstalled();
| return (client == null ? null : client.select(selectedParty));
| }
|
| @Remove @Destroy
| public void destroy() { }
|
| }
|
PartyFinderClient
| ...
| public abstract class PartyFinderClient {
|
| public void install() {
| Contexts.getConversationContext().set("partyFinderClient", this);
| }
|
| public static PartyFinderClient getInstalled() {
|
| return (PartyFinderClient) Contexts.getConversationContext().
get("partyFinderClient");
| }
|
| public abstract String cancel();
| public abstract String select(Party party);
| }
|
|
Find Person Form JSF
| <?xml version="1.0" encoding="UTF-8"?>
| <!DOCTYPE html
| PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <html
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
xmlns:s="http://jboss.com/products/seam/taglib"
|
xmlns="http://www.w3.org/1999/xhtml">
| <head>
| <title>Find Person</title>
| </head>
| <body>
| <ui:composition
xmlns:rich="http://richfaces.ajax4jsf.org/rich"
template="/layout/template.xhtml">
| <ui:define name="body">
| <h:form id="form">
|
|
|
|
| <h:outputLabel value="Last Names"
for="lastName"/>
| <h:inputText id="lastName"
value="#{lastName}"/>
| <h:outputLabel value="First Name(s)"
for="firstNames"/>
| <h:inputText id="firstNames"
value="#{firstName}"/>
| <h:outputLabel value="Date of Birth"
for="dateOfBirth"/>
| <h:inputText id="dateOfBirth"
value="#{dateOfBirth}"/>
| <h:outputLabel value="Identity No."
for="identityNo"/>
| <h:inputText id="identityNo"
value="#{identityNo}"/>
| <h:outputLabel value="Passport No."
for="passportNo"/>
| <h:inputText id="passportNo"
value="#{passportNo}"/>
| <h:outputLabel value="Bank Account No."
for="bankAccountNo"/>
| <h:inputText id="bankAccountNo"
value="#{bankAccountNo}"/>
| <h:commandButton id="find" value="Find"
action="#{partyFinder.find}"/>
| <h:commandLink id="clear" value="Clear"
action="doClear"/>
|
|
| </h:form>
| </ui:define>
| </ui:composition>
| </body>
| </html>
|
Find Person Results
| <?xml version="1.0" encoding="UTF-8"?>
| <!DOCTYPE html
| PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <html
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
xmlns:s="http://jboss.com/products/seam/taglib"
|
xmlns="http://www.w3.org/1999/xhtml">
| <head>
| <title>Find Party Results</title>
| </head>
| <body>
| <ui:composition
xmlns:rich="http://richfaces.ajax4jsf.org/rich"
template="/layout/template.xhtml">
| <ui:define name="body">
| <h:form id="form">
|
|
|
|
| <h:dataTable value="#{parties}"
rendered="#{parties.rowCount>0}" var="party">
| <h:column>
| <f:facet name="header">
| <h:outputText value="Last Name"/>
| </f:facet>
| <s:link value="#{party.lastName}"
action="#{partyFinder.select}"/>
| </h:column>
| </h:dataTable>
|
|
| </h:form>
| </ui:define>
| </ui:composition>
| </body>
| </html>
|
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4053964#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...