@Secure
.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- We need a doctype to allow us to use special characters like
We use a "strict" DTD to make IE follow the alignment rules. -->
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<body class="container">
<div id="page">
<div class="row" id="instructions">
Initially, the available login IDs are admin, secofr, and john, <br /> and the passwords are the same as the login
ID.
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<t:form t:id="login" class="form-signin">
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<h2 class="form-signin-heading">Log In</h2>
<div class="form-group">
<t:textfield t:id="loginId" class="input-medium" maxLength="15" t:validate="required, maxLength=15"
placeholder="Login ID" />
</div>
<div class="form-group">
<t:passwordfield t:id="password" class="input-medium" maxLength="15" t:validate="required, maxLength=15"
placeholder="Password" />
</div>
<div class="form-group">
<t:submit value="Login" class="btn btn-lg btn-primary" />
<t:eventlink event="GoHome" style="margin-left: 12px;">Home</t:eventlink>
</div>
<t:errors globalOnly="true" />
</div>
</div>
</t:form>
</div>
</div>
<div class="row" id="secure">
A page can be made secure, ie. accessible only by HTTPS, by annotating the page's class with
<code>@Secure</code>
.<br /> You will also have to enable HTTPS on your web server, which may require some configuration.<br />
References: <a href="http://tapestry.apache.org/https.html">Securing your application with HTTPS</a>, <a
href="http://roneiv.wordpress.com/2008/01/03/jboss-tutorial-how-to-enable-ssl-https-on-jboss-as-well-as-other-nice-to-know-configurations/">How
to enable SSL on JBoss</a>.
</div>
<div class="row" id="links">
<t:pagelink page="examples/state/displaysessioncontents">Display Session Contents</t:pagelink>
</div>
</div>
<t:tabgroup>
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/theapp/LogIn.tml" />
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/theapp/LogIn.java" />
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/commons/IIntermediatePage.java" />
<t:sourcecodetab src="/web/src/main/resources/META-INF/assets/css/theapp/login.css" />
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/state/theapp/Visit.java" />
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/base/theapp/SimpleBasePage.java" />
</t:tabgroup>
</body>
</html>
package jumpstart.web.pages.theapp;
import javax.ejb.EJB;
import jumpstart.business.commons.exception.BusinessException;
import jumpstart.business.domain.security.User;
import jumpstart.business.domain.security.iface.ISecurityFinderServiceLocal;
import jumpstart.util.ExceptionUtil;
import jumpstart.web.base.theapp.SimpleBasePage;
import jumpstart.web.commons.IIntermediatePage;
import jumpstart.web.pages.Index;
import jumpstart.web.state.theapp.Visit;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Link;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Form;
import org.apache.tapestry5.corelib.components.TextField;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.slf4j.Logger;
// To make this page accessible only by HTTPS, annotate it with @Secure and ensure your web server can deliver HTTPS.
// See http://tapestry.apache.org/secure.html .
// @Secure
@Import(stylesheet = "css/theapp/login.css")
public class LogIn extends SimpleBasePage implements IIntermediatePage {
// The activation context
@Property
private String loginId;
// Screen fields
@Property
private String password;
// Generally useful bits and pieces
@Persist
private Link nextPageLink;
@InjectComponent("login")
private Form form;
@InjectComponent("loginId")
private TextField loginIdField;
@Inject
private Logger logger;
@Inject
private ComponentResources componentResources;
@EJB
private ISecurityFinderServiceLocal securityFinderService;
@InjectPage
private UserView userViewPage;
// The code
@Override
public void setNextPageLink(Link nextPageLink) {
this.nextPageLink = nextPageLink;
}
void onActivate(String loginId) {
this.loginId = loginId;
}
String onPassivate() {
return loginId;
}
void onValidateFromLogin() {
if (form.getHasErrors()) {
// We get here only if a server-side validator detected an error.
return;
}
try {
// Authenticate the user
User user = securityFinderService.authenticateUser(loginId, password);
// Store the user in the Visit
setVisit(new Visit(user));
logger.info(user.getLoginId() + " has logged in.");
}
catch (BusinessException e) {
form.recordError(loginIdField, e.getLocalizedMessage());
}
catch (Exception e) {
logger.error("Could not log in. Stack trace follows...");
logger.error(ExceptionUtil.printStackTrace(e));
form.recordError(getMessages().get("login_problem"));
}
}
Object onSuccess() {
if (nextPageLink == null) {
// return Welcome.class;
userViewPage.set(getVisit().getMyUserId());
return userViewPage;
}
else {
componentResources.discardPersistentFieldChanges();
return nextPageLink;
}
}
Object onGoHome() {
componentResources.discardPersistentFieldChanges();
return Index.class;
}
}
package jumpstart.web.commons;
import org.apache.tapestry5.Link;
public interface IIntermediatePage {
void setNextPageLink(Link nextPageLink);
}
body {
Zpadding-top: 40px;
Zpadding-bottom: 40px;
Zbackground-color: #f5f5f5;
}
#page {
margin: 0 auto;
padding: 20px;
background-color: #ffffff;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4f4f4',
endColorstr='#ffffff'); /* for IE */
background: -webkit-gradient(linear, left top, left bottom, from(#eaeaea),
to(#ffffff)); /* for webkit browsers */
background: -moz-linear-gradient(top, #f2f2f2, #ffffff);
/* for firefox 3.6+ */;
}
#instructions {
padding: 40px 0 40px;
text-align: center;
color: #666;
}
.form-signin {
max-width: 300px;
padding: 19px 29px 29px;
margin: 0 auto;
background-color: #fff;
border: 1px solid #e5e5e5;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
}
.form-signin .form-signin-heading,.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin input[type="text"],.form-signin input[type="password"] {
font-size: 16px;
height: auto;
margin-bottom: 6px;
padding: 7px 9px;
}
#secure {
padding: 40px 0 40px;
text-align: center;
color: #666;
}
#links {
padding: 0px 0 40px;
text-align: center;
color: #666;
}
package jumpstart.web.state.theapp;
import java.io.Serializable;
import jumpstart.business.domain.security.User;
import jumpstart.business.domain.security.User.PageStyle;
@SuppressWarnings("serial")
public class Visit implements Serializable {
private Long myUserId = null;
private String myLoginId = null;
private PageStyle pageStyle = null;
private String dateInputPattern = null;
private String dateViewPattern = null;
private String dateListPattern = null;
public Visit(User user) {
myUserId = user.getId();
cacheUsefulStuff(user);
}
public void noteChanges(User user) {
if (user == null) {
throw new IllegalArgumentException();
}
else if (user.getId().equals(myUserId)) {
cacheUsefulStuff(user);
}
}
private void cacheUsefulStuff(User user) {
myLoginId = user.getLoginId();
pageStyle = user.getPageStyle();
dateInputPattern = user.getDateInputPattern();
dateViewPattern = user.getDateViewPattern();
dateListPattern = user.getDateListPattern();
}
public Long getMyUserId() {
return myUserId;
}
public String getMyLoginId() {
return myLoginId;
}
public PageStyle getPageStyle() {
return pageStyle;
}
public String getDateInputPattern() {
return dateInputPattern;
}
public String getDateViewPattern() {
return dateViewPattern;
}
public String getDateListPattern() {
return dateListPattern;
}
}
package jumpstart.web.base.theapp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import jumpstart.business.commons.exception.BusinessException;
import jumpstart.business.commons.exception.CannotDeleteIsReferencedException;
import jumpstart.business.commons.exception.DuplicateAlternateKeyException;
import jumpstart.business.commons.exception.DuplicatePrimaryKeyException;
import jumpstart.business.commons.exception.OptimisticLockException;
import jumpstart.business.commons.interpreter.BusinessServiceExceptionInterpreter;
import jumpstart.business.domain.security.User;
import jumpstart.web.state.theapp.Visit;
import org.apache.tapestry5.annotations.SessionState;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;
public class SimpleBasePage {
// @SessionState is explained in http://tapestry.apache.org/session-storage.html
@SessionState
private Visit visit;
private boolean visitExists;
private BusinessServiceExceptionInterpreter businessServiceExceptionInterpreter = new BusinessServiceExceptionInterpreter();
@Inject
private Messages messages;
protected Messages getMessages() {
return messages;
}
public Visit getVisit() {
return visit;
}
protected void setVisit(Visit visit) {
this.visit = visit;
}
public boolean isVisitExists() {
return visitExists;
}
public String getDateInputPattern() {
return visitExists ? visit.getDateInputPattern() : User.defaultDateInputPattern;
}
public String getDateViewPattern() {
return visitExists ? visit.getDateViewPattern() : User.defaultDateViewPattern;
}
public String getDateListPattern() {
return visitExists ? visit.getDateListPattern() : User.defaultDateListPattern;
}
public DateFormat getDateInputFormat() {
// If you want to make this static or move it into Visit, first read
// http://thread.gmane.org/gmane.comp.java.tapestry.user/20925
return new SimpleDateFormat(visit.getDateInputPattern());
}
public DateFormat getDateViewFormat() {
// If you want to make this static or move it into Visit, first read
// http://thread.gmane.org/gmane.comp.java.tapestry.user/20925
return new SimpleDateFormat(visit.getDateViewPattern());
}
public DateFormat getDateListFormat() {
// If you want to make this static or move it into Visit, first read
// http://thread.gmane.org/gmane.comp.java.tapestry.user/20925
return new SimpleDateFormat(visit.getDateListPattern());
}
protected String interpretBusinessServicesExceptionForCreate(Exception e) {
String message = "";
BusinessException x = businessServiceExceptionInterpreter.interpret(e);
if (x instanceof DuplicatePrimaryKeyException) {
message = getMessages().get("create_failed_duplicate_primary_key");
}
else if (x instanceof DuplicateAlternateKeyException) {
DuplicateAlternateKeyException d = (DuplicateAlternateKeyException) x;
message = getMessages().format("create_failed_duplicate_alternate_key", d.getTechnicalMessageText());
}
else {
message = x.getMessage();
}
return message;
}
protected BusinessException interpretBusinessServicesException(Exception e) {
return businessServiceExceptionInterpreter.interpret(e);
}
protected String interpretBusinessServicesExceptionForAdd(Exception e) {
String message = "";
BusinessException x = businessServiceExceptionInterpreter.interpret(e);
if (x instanceof OptimisticLockException) {
message = getMessages().get("add_failed_optimistic_lock");
}
else if (x instanceof DuplicatePrimaryKeyException) {
message = getMessages().get("add_failed_duplicate_primary_key");
}
else if (x instanceof DuplicateAlternateKeyException) {
DuplicateAlternateKeyException d = (DuplicateAlternateKeyException) x;
message = getMessages().format("add_failed_duplicate_alternate_key", d.getTechnicalMessageText());
}
else {
message = x.getMessage();
}
return message;
}
protected String interpretBusinessServicesExceptionForChange(Exception e) {
String message = "";
BusinessException x = businessServiceExceptionInterpreter.interpret(e);
if (x instanceof OptimisticLockException) {
message = getMessages().get("change_failed_optimistic_lock");
}
else if (x instanceof DuplicateAlternateKeyException) {
DuplicateAlternateKeyException d = (DuplicateAlternateKeyException) x;
message = getMessages().format("change_failed_duplicate_alternate_key", d.getTechnicalMessageText());
}
else {
message = x.getMessage();
}
return message;
}
protected String interpretBusinessServicesExceptionForRemove(Exception e) {
String message = "";
BusinessException x = businessServiceExceptionInterpreter.interpret(e);
if (x instanceof OptimisticLockException) {
message = getMessages().get("remove_failed_optimistic_lock");
}
else if (x instanceof CannotDeleteIsReferencedException) {
CannotDeleteIsReferencedException c = (CannotDeleteIsReferencedException) x;
message = getMessages().format("remove_failed_is_referenced",
new Object[] { c.getReferencedByEntityName() });
}
else {
message = x.getMessage();
}
return message;
}
protected String interpretBusinessServicesExceptionForDelete(Exception e) {
String message = "";
BusinessException x = businessServiceExceptionInterpreter.interpret(e);
if (x instanceof OptimisticLockException) {
message = getMessages().get("delete_failed_optimistic_lock");
}
else if (x instanceof CannotDeleteIsReferencedException) {
CannotDeleteIsReferencedException c = (CannotDeleteIsReferencedException) x;
message = getMessages().format("delete_failed_is_referenced",
new Object[] { c.getReferencedByEntityName() });
}
else {
message = x.getMessage();
}
return message;
}
}