[jbossseam-issues] [JBoss JIRA] Updated: (JBSEAM-4411) jPDL re-installing its first seam object
Tony Herstell (JIRA)
jira-events at lists.jboss.org
Thu Sep 17 18:52:49 EDT 2009
[ https://jira.jboss.org/jira/browse/JBSEAM-4411?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Tony Herstell updated JBSEAM-4411:
----------------------------------
Workaround Description:
Since the original user just pops back every time (even if you forcibly set it to null) then you have to use the one provided regardless.
/**
* Copyright Software Factory - 2009
*/
package nz.co.softwarefactory.risingstars.controller.user;
import javax.ejb.Remove;
import javax.persistence.EntityManager;
import nz.co.softwarefactory.risingstars.mode.CrudsController;
import nz.co.softwarefactory.risingstars.mode.CRUDSMode.Mode;
import nz.co.softwarefactory.risingstars.model.User;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.Renderer;
import org.jboss.seam.international.StatusMessages;
import org.jboss.seam.international.StatusMessage.Severity;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Credentials;
import org.jboss.seam.security.Identity;
import org.jboss.seam.security.RunAsOperation;
import org.jboss.seam.security.management.IdentityManager;
/**
* @author Tony Herstell
*/
@SuppressWarnings("serial")
@Name("risingstars.registrationController")
@Scope(ScopeType.CONVERSATION)
public class RegistrationControllerImpl implements RegistrationController {
/**
* Inject and leverage the Seam Logger.
*/
@Logger
private Log log;
@In
private Identity identity;
@In
private IdentityManager identityManager;
@In
private EntityManager entityManager;
/**
* Inject the Renderer for Email purposes.
*/
@In(create=true)
private Renderer renderer;
@In
private Credentials credentials;
/**
* Outject a user for pages to act on.
*/
@In(create=true) @Out(required=true)
private User user;
/**
* Outject a mode of operation for pages to act on.
*/
// HACK HACK as for some reason we lose a Mode mode; but don't "lose" and injected bean that simply contains the Mode mode.
@In(create=true) @Out(required=true)
private CrudsController crudsController;
/**
* Inject the Status Messages component so that messages (errors and info)
* can be sent to the View
*/
@In(create = true)
private transient StatusMessages statusMessages;
private boolean isValidSuppliedDetails = false;
private boolean isUserCreated = false;
@Override
@Begin(pageflow="create_registration_details_pageflow")
public String createRegistrationDetails() {
log.info("> " + this.getClass().getName()+ " createRegistrationDetails ");
crudsController.setMode(Mode.CREATE);
log.info("< " + this.getClass().getName()+ " createRegistrationDetails ");
return "start";
}
@Override
@Begin(pageflow="update_registration_details_pageflow")
public String updateRegistrationDetails() {
log.info("> " + this.getClass().getName()+ " updateRegistrationDetails ");
crudsController.setMode(Mode.UPDATE);
log.info("< " + this.getClass().getName()+ " updateRegistrationDetails ");
return "start";
}
@Override
public void initUpdateRegistrationDetails() {
log.info("> " + this.getClass().getName()+ " initUpdateRegistrationDetails ");
// HACK HACK as cannot just point the User at the user just returned from the Datastore
User this_user = (User) entityManager.createQuery("from User u where u.email = :email").setParameter("email", credentials.getUsername()).getSingleResult();
updateUser(this_user, this.user);
log.info("< " + this.getClass().getName()+ " enter ");
}
// Hack
private void updateUser(User from, User to) {
to.setId(from.getId());
to.setVersion(from.getVersion());
to.setLastname(from.getLastname());
to.setFirstname(from.getFirstname());
to.setEmail(from.getEmail());
to.setPasswordHash(from.getPasswordHash());
to.setEnabled(from.isEnabled());
to.setRoles(from.getRoles());
}
@Override
public boolean isValidSuppliedDetails() {
boolean theResultToReturn = true;
log.info("> " + this.getClass().getName()+ " validSuppliedDetails ");
if (crudsController.getMode() == Mode.CREATE) {
new RunAsOperation() {
public void execute() {
setIsValidSuppliedDetails(!(identityManager.userExists(user.getEmail())));
}
}.addRole("admin")
.run();
if (getIsValidSuppliedDetails())
{
log.info ("Passed on unique user Check for email: " + user.getEmail());
} else {
log.info("Failed on unique user Check for email: " + user.getEmail());
statusMessages.addToControlFromResourceBundle("registration_email", Severity.ERROR, "user_email_already_exists_in_system");
}
theResultToReturn = getIsValidSuppliedDetails();
} else if (crudsController.getMode() == Mode.UPDATE) {
} else {
throw new IllegalArgumentException(this.getClass().getName() + "isValidSuppliedDetails called with disallowed Mode type");
}
log.info("< " + this.getClass().getName()+ " validSuppliedDetails ");
return theResultToReturn;
}
private void setIsValidSuppliedDetails(boolean isValid) {
this.isValidSuppliedDetails = isValid;
}
private boolean getIsValidSuppliedDetails() {
return this.isValidSuppliedDetails;
}
@Override
public void saveNewUser() {
log.info("> " + this.getClass().getName()+ " saveNewUser ");
if (crudsController.getMode() == Mode.CREATE) {
new RunAsOperation() {
public void execute() {
setIsUserCreated(identityManager.createUser(user.getEmail(), user.getPasswordHash(), user.getFirstname(), user.getLastname()));
identityManager.enableUser(user.getEmail());
}
}.addRole("admin")
.run();
if (getIsUserCreated()) {
credentials.setUsername(user.getEmail());
credentials.setPassword(user.getPasswordHash());
identity.login();
statusMessages.addFromResourceBundle(Severity.INFO, "registration_user_successfully_registered", user.getLastname() + "," + user.getFirstname());
try {
renderer.render("/WEB-INF/pages/user/registerSuccessfulEmailWrapper.xhtml");
log.info("Welcome Email sent!");
} catch (Exception e) {
log.info("Email sending failed: "+e);
}
} else {
log.error("failed to create new user " + user.getLastname() + ", " + user.getFirstname());
}
} else {
throw new IllegalArgumentException(this.getClass().getName() + "saveNewUser called with disallowed Mode type");
}
log.info("< " + this.getClass().getName()+ " saveNewUser ");
}
@Override
public void updateUser() {
log.info("> " + this.getClass().getName()+ " updateUser ");
if (crudsController.getMode() == Mode.UPDATE) {
// Update the user. HACK HACK
User this_user = (User) entityManager.createQuery("from User u where u.id = :id").setParameter("id", user.getId()).getSingleResult();
updateUser(this.user, this_user);
entityManager.persist(this_user);
final User final_user = this_user;
new RunAsOperation() {
public void execute() {
identityManager.changePassword(final_user.getEmail(), final_user.getPasswordHash());
}
}.addRole("admin")
.run();
Credentials credentials = identity.getCredentials();
credentials.setUsername(this_user.getEmail());
statusMessages.addFromResourceBundle(Severity.INFO, "registration_user_successfully_updated", user.getLastname() + "," + user.getFirstname());
} else {
throw new IllegalArgumentException(this.getClass().getName() + "updateUser called with disallowed Mode type");
}
log.info("< " + this.getClass().getName()+ " updateUser ");
}
private void setIsUserCreated(boolean isUserCreated) {
this.isUserCreated = isUserCreated;
}
private boolean getIsUserCreated() {
return this.isUserCreated;
}
@Remove
@Destroy
@Override
public void destroy() {
log.info("> destory");
log.info("< destory");
}
}
A really sub optimal solution as if the object is complex you have to do a deep copy (possibly linking to other objects) and then problem with merge/commit etc.
and Another one....
/**
* Outject a mode of operation for pages to act on.
*/
// HACK HACK as for some reason we lose a Mode mode; but don't "lose" and injected bean that simply contains the Mode mode.
@In(create=true) @Out(required=true)
private CrudsController crudsController;
@Local
public interface CrudsController extends Serializable {
public void setMode(Mode mode);
public Mode getMode();
public void destroy();
}
@SuppressWarnings("serial")
@Name("risingstars.crudsController")
@Stateful
public class CrudsControllerImpl implements CrudsController, Serializable {
/**
* Inject and leverage the Seam Logger.
*/
@Logger
private Log log;
public Mode mode;
public void setMode(Mode mode) {
this.mode = mode;
}
public Mode getMode() {
return this.mode;
}
@Remove
@Destroy
@Override
public void destroy() {
log.info("> destory");
log.info("< destory");
}
}
Finally.. Status Messages don't show up either.
:/
---
<pageflow-definition xmlns="http://jboss.com/products/seam/pageflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.com/products/seam/pageflow http://jboss.com/products/seam/pageflow-2.2.xsd"
name="create_registration_details_pageflow">
<start-state name="entry">
<transition name="start" to="getUsersDetails" />
</start-state>
<page name="getUsersDetails" view-id="/pages/user/createUserDetails.xhtml" redirect="true" no-conversation-view-id="/home.xhtml">
<description>Registering of new User</description>
<transition name="cancel" to="end" />
<transition name="next" to="evaluateDetails"/>
</page>
<decision name="evaluateDetails" expression="#{risingstars.registrationController.isValidSuppliedDetails()}">
<transition name="true" to="reviewDetails" />
<transition name="false" to="getUsersDetails" />
</decision>
<page name="reviewDetails" view-id="/pages/user/reviewCreateUserDetails.xhtml" redirect="true" no-conversation-view-id="/home.xhtml">
<description>Confirm details registering a new User (#{risingstars.user.lastname}, #{risingstars.user.firstname})</description>
<transition name="cancel" to="end" />
<transition name="back" to="getUsersDetails" />
<transition name="create" to="end">
<action expression="#{risingstars.registrationController.saveNewUser}"/>
</transition>
</page>
<page name="end" view-id="/home.xhtml" redirect="true">
<end-conversation before-redirect="true"/>
</page>
</pageflow-definition>
<pageflow-definition xmlns="http://jboss.com/products/seam/pageflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.com/products/seam/pageflow http://jboss.com/products/seam/pageflow-2.2.xsd"
name="update_registration_details_pageflow">
<start-state name="entry">
<transition name="start" to="getUsersDetails">
<action expression="#{risingstars.registrationController.initUpdateRegistrationDetails}"></action>
</transition>
</start-state>
<page name="getUsersDetails" view-id="/pages/user/updateUserDetails.xhtml" redirect="true" no-conversation-view-id="/home.xhtml">
<description>Updating of User (#{risingstars.user.lastname}, #{risingstars.user.firstname})</description>
<transition name="cancel" to="end" />
<transition name="next" to="evaluateDetails"/>
</page>
<decision name="evaluateDetails" expression="#{risingstars.registrationController.isValidSuppliedDetails()}">
<transition name="true" to="reviewDetails" />
<transition name="false" to="getUsersDetails" />
</decision>
<page name="reviewDetails" view-id="/pages/user/reviewUpdateUserDetails.xhtml" redirect="true" no-conversation-view-id="/home.xhtml">
<description>Confirm details updating (#{risingstars.user.lastname}, #{risingstars.user.firstname})</description>
<transition name="cancel" to="end" />
<transition name="back" to="getUsersDetails" />
<transition name="update" to="end">
<action expression="#{risingstars.registrationController.updateUser}"/>
</transition>
</page>
<page name="end" view-id="/home.xhtml" redirect="true">
<end-conversation before-redirect="true"/>
</page>
</pageflow-definition>
was:
Since the original user just pops back every time (even if you forcibly set it to null) then you have to use the one provided regardless.
/**
* Copyright Software Factory - 2009
*/
package nz.co.softwarefactory.risingstars.controller.user;
import javax.ejb.Remove;
import javax.persistence.EntityManager;
import nz.co.softwarefactory.risingstars.mode.CrudsController;
import nz.co.softwarefactory.risingstars.mode.CRUDSMode.Mode;
import nz.co.softwarefactory.risingstars.model.User;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.Renderer;
import org.jboss.seam.international.StatusMessages;
import org.jboss.seam.international.StatusMessage.Severity;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Credentials;
import org.jboss.seam.security.Identity;
import org.jboss.seam.security.RunAsOperation;
import org.jboss.seam.security.management.IdentityManager;
/**
* @author Tony Herstell
*/
@SuppressWarnings("serial")
@Name("risingstars.registrationController")
@Scope(ScopeType.CONVERSATION)
public class RegistrationControllerImpl implements RegistrationController {
/**
* Inject and leverage the Seam Logger.
*/
@Logger
private Log log;
@In
private Identity identity;
@In
private IdentityManager identityManager;
@In
private EntityManager entityManager;
/**
* Inject the Renderer for Email purposes.
*/
@In(create=true)
private Renderer renderer;
@In
private Credentials credentials;
/**
* Outject a user for pages to act on.
*/
@In(create=true) @Out(required=true)
private User user;
/**
* Outject a mode of operation for pages to act on.
*/
// HACK HACK as for some reason we lose a Mode mode; but don't "lose" and injected bean that simply contains the Mode mode.
@In(create=true) @Out(required=true)
private CrudsController crudsController;
/**
* Inject the Status Messages component so that messages (errors and info)
* can be sent to the View
*/
@In(create = true)
private transient StatusMessages statusMessages;
private boolean isValidSuppliedDetails = false;
private boolean isUserCreated = false;
@Override
@Begin(pageflow="create_registration_details_pageflow")
public String createRegistrationDetails() {
log.info("> " + this.getClass().getName()+ " createRegistrationDetails ");
crudsController.setMode(Mode.CREATE);
log.info("< " + this.getClass().getName()+ " createRegistrationDetails ");
return "start";
}
@Override
@Begin(pageflow="update_registration_details_pageflow")
public String updateRegistrationDetails() {
log.info("> " + this.getClass().getName()+ " updateRegistrationDetails ");
crudsController.setMode(Mode.UPDATE);
log.info("< " + this.getClass().getName()+ " updateRegistrationDetails ");
return "start";
}
@Override
public void initUpdateRegistrationDetails() {
log.info("> " + this.getClass().getName()+ " initUpdateRegistrationDetails ");
// HACK HACK as cannot just point the User at the user just returned from the Datastore
User this_user = (User) entityManager.createQuery("from User u where u.email = :email").setParameter("email", credentials.getUsername()).getSingleResult();
updateUser(this_user, this.user);
log.info("< " + this.getClass().getName()+ " enter ");
}
// Hack
private void updateUser(User from, User to) {
to.setId(from.getId());
to.setVersion(from.getVersion());
to.setLastname(from.getLastname());
to.setFirstname(from.getFirstname());
to.setEmail(from.getEmail());
to.setPasswordHash(from.getPasswordHash());
to.setEnabled(from.isEnabled());
to.setRoles(from.getRoles());
}
@Override
public boolean isValidSuppliedDetails() {
boolean theResultToReturn = true;
log.info("> " + this.getClass().getName()+ " validSuppliedDetails ");
if (crudsController.getMode() == Mode.CREATE) {
new RunAsOperation() {
public void execute() {
setIsValidSuppliedDetails(!(identityManager.userExists(user.getEmail())));
}
}.addRole("admin")
.run();
if (getIsValidSuppliedDetails())
{
log.info ("Passed on unique user Check for email: " + user.getEmail());
} else {
log.info("Failed on unique user Check for email: " + user.getEmail());
statusMessages.addToControlFromResourceBundle("registration_email", Severity.ERROR, "user_email_already_exists_in_system");
}
theResultToReturn = getIsValidSuppliedDetails();
} else if (crudsController.getMode() == Mode.UPDATE) {
} else {
throw new IllegalArgumentException(this.getClass().getName() + "isValidSuppliedDetails called with disallowed Mode type");
}
log.info("< " + this.getClass().getName()+ " validSuppliedDetails ");
return theResultToReturn;
}
private void setIsValidSuppliedDetails(boolean isValid) {
this.isValidSuppliedDetails = isValid;
}
private boolean getIsValidSuppliedDetails() {
return this.isValidSuppliedDetails;
}
@Override
public void saveNewUser() {
log.info("> " + this.getClass().getName()+ " saveNewUser ");
if (crudsController.getMode() == Mode.CREATE) {
new RunAsOperation() {
public void execute() {
setIsUserCreated(identityManager.createUser(user.getEmail(), user.getPasswordHash(), user.getFirstname(), user.getLastname()));
identityManager.enableUser(user.getEmail());
}
}.addRole("admin")
.run();
if (getIsUserCreated()) {
credentials.setUsername(user.getEmail());
credentials.setPassword(user.getPasswordHash());
identity.login();
statusMessages.addFromResourceBundle(Severity.INFO, "registration_user_successfully_registered", user.getLastname() + "," + user.getFirstname());
try {
renderer.render("/WEB-INF/pages/user/registerSuccessfulEmailWrapper.xhtml");
log.info("Welcome Email sent!");
} catch (Exception e) {
log.info("Email sending failed: "+e);
}
} else {
log.error("failed to create new user " + user.getLastname() + ", " + user.getFirstname());
}
} else {
throw new IllegalArgumentException(this.getClass().getName() + "saveNewUser called with disallowed Mode type");
}
log.info("< " + this.getClass().getName()+ " saveNewUser ");
}
@Override
public void updateUser() {
log.info("> " + this.getClass().getName()+ " updateUser ");
if (crudsController.getMode() == Mode.UPDATE) {
// Update the user. HACK HACK
User this_user = (User) entityManager.createQuery("from User u where u.id = :id").setParameter("id", user.getId()).getSingleResult();
updateUser(this.user, this_user);
entityManager.persist(this_user);
final User final_user = this_user;
new RunAsOperation() {
public void execute() {
identityManager.changePassword(final_user.getEmail(), final_user.getPasswordHash());
}
}.addRole("admin")
.run();
Credentials credentials = identity.getCredentials();
credentials.setUsername(this_user.getEmail());
statusMessages.addFromResourceBundle(Severity.INFO, "registration_user_successfully_updated", user.getLastname() + "," + user.getFirstname());
} else {
throw new IllegalArgumentException(this.getClass().getName() + "updateUser called with disallowed Mode type");
}
log.info("< " + this.getClass().getName()+ " updateUser ");
}
private void setIsUserCreated(boolean isUserCreated) {
this.isUserCreated = isUserCreated;
}
private boolean getIsUserCreated() {
return this.isUserCreated;
}
@Remove
@Destroy
@Override
public void destroy() {
log.info("> destory");
log.info("< destory");
}
}
A really sub optimal solution as if the object is complex you have to do a deep copy (possibly linking to other objects) and then problem with merge/commit etc.
and Another one....
/**
* Outject a mode of operation for pages to act on.
*/
// HACK HACK as for some reason we lose a Mode mode; but don't "lose" and injected bean that simply contains the Mode mode.
@In(create=true) @Out(required=true)
private CrudsController crudsController;
@Local
public interface CrudsController extends Serializable {
public void setMode(Mode mode);
public Mode getMode();
public void destroy();
}
@SuppressWarnings("serial")
@Name("risingstars.crudsController")
@Stateful
public class CrudsControllerImpl implements CrudsController, Serializable {
/**
* Inject and leverage the Seam Logger.
*/
@Logger
private Log log;
public Mode mode;
public void setMode(Mode mode) {
this.mode = mode;
}
public Mode getMode() {
return this.mode;
}
@Remove
@Destroy
@Override
public void destroy() {
log.info("> destory");
log.info("< destory");
}
}
Finally.. Status Messages don't show up either.
:/
added more info in workaround area.
> jPDL re-installing its first seam object
> ----------------------------------------
>
> Key: JBSEAM-4411
> URL: https://jira.jboss.org/jira/browse/JBSEAM-4411
> Project: Seam
> Issue Type: Bug
> Components: Core
> Affects Versions: 2.2.0.GA
> Environment: WinXP64 MyEclipse JBoss latest RF
> Reporter: Tony Herstell
> Priority: Critical
>
> Given this snippit
> <start-state name="entry">
> <transition name="start" to="getUsersDetails">
> <action expression="#{risingstars.registrationController.initUpdateRegistrationDetails}"></action>
> </transition>
> </start-state>
> <page name="getUsersDetails" view-id="/pages/user/updateUserDetails.xhtml" redirect="true" no-conversation-view-id="/home.xhtml">
> <description>Updating of User (#{risingstars.user.lastname}, #{risingstars.user.firstname})</description>
> <transition name="cancel" to="end" />
> <transition name="next" to="evaluateDetails"/>
> </page>
> I enter the jPDL and the bean has a User in scope... say (say id 123) auto created by
> @In(create=true) @Out(required=true)
> private User user;
> I then do this in initUpdateRegistrationDetails :
> this.user = (User) entityManager.createQuery("from User u where u.email = :email").setParameter("email", credentials.getUsername()).getSingleResult();
> Which forces the user in scope to now point to this new user (say id 456)
> What happens if by the time we get to the next page we have switched back to the original User (123).
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the seam-issues
mailing list