Question on @In and Bijection
fsat.f_satyaputra.yahoo.co.uk Mar 28, 2008 2:38 PMHi All,
I'd like to understand more about how bijection works in Seam, as some of the objects which I have annotated with @In does not get injected under certain circumstances.
I have a link as such:
<s:link id="bjtest" view="/bjtest/start.xhtml" action="#{pageBean.prepare()}" value="Start Element Test"/>
Here's my page bean:
@Name("pageBean") @Scope(ScopeType.CONVERSATION) @AutoCreate public class PageBean implements Serializable { @In protected FormElementSet formElementSet; @Begin(join=true) @RaiseEvent("pageBean.prepare") public String prepare() { this.formElementSet.initialize(); return "prepare"; } public String save() { this.formElementSet.validateSave(); this.formElementSet.save(); return "prepare"; } public String submit() { this.formElementSet.validateSubmit(); this.formElementSet.save(); return "prepare"; } // snip...
The PageBean instance have runtime dependencies to the following 4 classes:
@Name("formElementSet") @Scope(ScopeType.CONVERSATION) @AutoCreate public class FormElementSet implements Serializable { private Set<FormElement> formElements = new TreeSet<FormElement>(); public void initialize() { this.formElements.clear(); } public void registerFormElement(FormElement... formElementsInput) { for (FormElement elem: formElementsInput) { this.formElements.add(elem); } } public boolean validateSave() { boolean result = true; for (FormElement elem: this.getFormElements()) { result = result & elem.validateSave(); } return result; } // snip...
public abstract class BaseFormElement implements FormElement, Serializable, Comparable<FormElement> { @In protected FormElementSet formElementSet; @Observer("pageBean.prepare") public abstract void register(); }
@Name("includeFormElementOne") @Scope(ScopeType.CONVERSATION) @AutoCreate public class IncludeFormElementOne extends BaseFormElement { @Override public void register() { System.out.println("@@@@@@@@@@@@@@@ [" + this + ".register()]"); this.formElementSet.registerFormElement(this); } public void save() { System.out.println("@@@@@@@@@@@@@@@ [" + this + ".save()]"); } public boolean validateSave() { System.out.println("@@@@@@@@@@@@@@@ [" + this + ".validateSave()]"); return true; } // snip....
@Name("includeFormElementTwo") @Scope(ScopeType.CONVERSATION) @AutoCreate public class IncludeFormElementTwo extends BaseFormElement { @In protected IncludeFormElementOne includeFormElementOne; @Override public void register() { System.out.println("@@@@@@@@@@@@@@@ [" + this + ".register()] w/ dependency [" + this.includeFormElementOne + "]"); this.formElementSet.registerFormElement(this); } public void save() { System.out.println("@@@@@@@@@@@@@@@ [" + this + ".save()] w/ dependency [" + this.includeFormElementOne + "]"); } public boolean validateSave() { System.out.println("@@@@@@@@@@@@@@@ [" + this + ".validateSave() w/ dependency [" + this.includeFormElementOne + "]"); return true; } // snip....
After clicking this s:link:
<s:link id="bjtest" view="/bjtest/start.xhtml" action="#{pageBean.prepare()}" value="Start Element Test"/>
The #{pageBean.prepare()} method is executed, which in turn raises the event and the event observer kicks in to register #{includeFormElementOne} and #{includeFormElementTwo}. This generates the following System.out, which shows the dependency between #{includeFormElementTwo} towards #{includeFormElementOne}:
@@@@@@@@@@@@@@@ [com.juggle.seam.bjtest.IncludeFormElementOne@60feaf.register()] @@@@@@@@@@@@@@@ [com.juggle.seam.bjtest.IncludeFormElementTwo@613422.register()] w/ dependency [com.juggle.seam.bjtest.IncludeFormElementOne@60feaf]
On the subsequent page, I have the button which prompts the save method:
<h:commandButton id="btnSave" action="#{pageBean.save()}" value="Save"> </h:commandButton>
This is the resulting System.out:
@@@@@@@@@@@@@@@ [com.juggle.seam.bjtest.IncludeFormElementOne@60feaf.validateSave()] @@@@@@@@@@@@@@@ [com.juggle.seam.bjtest.IncludeFormElementTwo@613422.validateSave() w/ dependency [null] @@@@@@@@@@@@@@@ [com.juggle.seam.bjtest.IncludeFormElementOne@60feaf.save()] @@@@@@@@@@@@@@@ [com.juggle.seam.bjtest.IncludeFormElementTwo@613422.save()] w/ dependency [null]
For some reason the reference from #{includeFormElementTwo} to #{includeFormElementOne} shows null, which indicates that the @In annotation fails to be picked up by the BijectionInterceptor.
My questions are as following:
- Is this an expected behaviour?
- Is #{includeFormElementTwo} intercepted by the BijectionInterceptor in when the #{pageBean.save()} method is called?
- Why would the reference #{includeFormElementTwo} to #{includeFormElementOne} becomes null?
Apologies if this letter becomes a mouthful, but I really want to understand how bijection works in Seam.
Thank you very much for your time and your help.
Regards,
Felix