BAEL-1112 - Apache Tapestry

This commit is contained in:
Anshul BANSAL 2019-11-14 18:49:35 +02:00
parent 6804dc9b19
commit 90da38847e
15 changed files with 157 additions and 289 deletions

View File

@ -1,45 +1,16 @@
package com.baeldung.tapestry.components;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.Symbol;
/**
* Layout component for pages of application test-project.
* Layout component for pages of application.
*/
@Import(module = "bootstrap/collapse")
public class Layout {
@Inject
private ComponentResources resources;
/**
* The page title, for the <title> element and the
* <h1>element.
*/
@Property
@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
private String title;
@Property
private String pageName;
@Property
@Inject
@Symbol(SymbolConstants.APPLICATION_VERSION)
private String appVersion;
public String getClassForPageName() {
return resources.getPageName().equalsIgnoreCase(pageName) ? "active" : null;
}
public String[] getPageNames() {
return new String[] { "Index", "About", "Contact" };
}
@Property
@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
private String title;
}

View File

@ -1,18 +0,0 @@
package com.baeldung.tapestry.pages;
import org.apache.tapestry5.annotations.PageActivationContext;
public class About {
@PageActivationContext
private String learn;
public String getLearn() {
return learn;
}
public void setLearn(String learn) {
this.learn = learn;
}
}

View File

@ -1,5 +0,0 @@
package com.baeldung.tapestry.pages;
public class Contact {
}

View File

@ -0,0 +1,36 @@
package com.baeldung.tapestry.pages;
import java.util.Date;
import org.apache.tapestry5.Block;
import org.apache.tapestry5.annotations.Log;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
import org.slf4j.Logger;
public class Home {
@Property
private String appName = "apache-tapestry";
public Date getCurrentTime() {
return new Date();
}
@Inject
private Logger logger;
@Inject
private AjaxResponseRenderer ajaxResponseRenderer;
@Inject
private Block ajaxBlock;
@Log
void onCallAjax() {
logger.info("Ajax call");
ajaxResponseRenderer.addRender("ajaxZone", ajaxBlock);
}
}

View File

@ -19,50 +19,41 @@ import java.util.Date;
* Start page of application apache-tapestry.
*/
public class Index {
@Inject
private Logger logger;
@Inject
private Logger logger;
@Inject
private AjaxResponseRenderer ajaxResponseRenderer;
@Inject
private AjaxResponseRenderer ajaxResponseRenderer;
@Property
@Inject
@Symbol(SymbolConstants.TAPESTRY_VERSION)
private String tapestryVersion;
@Property
@Inject
@Symbol(SymbolConstants.TAPESTRY_VERSION)
private String tapestryVersion;
@InjectPage
private About about;
@Inject
private Block block;
@Inject
private Block block;
// Handle call with an unwanted context
Object onActivate(EventContext eventContext) {
return eventContext.getCount() > 0 ?
new HttpError(404, "Resource not found") :
null;
}
// Handle call with an unwanted context
Object onActivate(EventContext eventContext) {
return eventContext.getCount() > 0 ?
new HttpError(404, "Resource not found") :
null;
}
@Log
void onComplete() {
logger.info("Complete call on Index page");
}
Object onActionFromLearnMore() {
about.setLearn("LearnMore");
@Log
void onAjax() {
logger.info("Ajax call on Index page");
return about;
}
ajaxResponseRenderer.addRender("middlezone", block);
}
@Log
void onComplete() {
logger.info("Complete call on Index page");
}
@Log
void onAjax() {
logger.info("Ajax call on Index page");
ajaxResponseRenderer.addRender("middlezone", block);
}
public Date getCurrentTime() {
return new Date();
}
public Date getCurrentTime() {
return new Date();
}
}

View File

@ -4,51 +4,39 @@ import org.apache.tapestry5.alerts.AlertManager;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Form;
import org.apache.tapestry5.corelib.components.PasswordField;
import org.apache.tapestry5.corelib.components.TextField;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.slf4j.Logger;
public class Login {
@Inject
private Logger logger;
@Inject
private Logger logger;
@Inject
private AlertManager alertManager;
@Inject
private AlertManager alertManager;
@InjectComponent
private Form login;
@InjectComponent
private Form login;
@InjectComponent("email")
private TextField emailField;
@Property
private String email;
@InjectComponent("password")
private PasswordField passwordField;
@Property
private String password;
@Property
private String email;
void onValidateFromLogin() {
if(email == null || password == null) {
alertManager.error("Email/Password is null");
login.recordError("Validation failed");
}
}
@Property
private String password;
Object onSuccessFromLogin() {
alertManager.success("Welcome! Login Successful");
return Home.class;
}
void onValidateFromLogin() {
if (!email.equals("users@tapestry.apache.org"))
login.recordError(emailField, "Try with user: users@tapestry.apache.org");
if ( !password.equals("Tapestry5"))
login.recordError(passwordField, "Try with password: Tapestry5");
}
Object onSuccessFromLogin() {
logger.info("Login successful!");
alertManager.success("Welcome aboard!");
return Index.class;
}
void onFailureFromLogin() {
logger.warn("Login error!");
alertManager.error("I'm sorry but I can't log you in!");
}
void onFailureFromLogin() {
alertManager.error("Please try again with correct credentials");
}
}

View File

@ -2,7 +2,7 @@ package com.baeldung.tapestry.services;
import java.io.IOException;
import org.apache.tapestry5.*;
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
@ -10,20 +10,18 @@ import org.apache.tapestry5.ioc.annotations.Contribute;
import org.apache.tapestry5.ioc.annotations.Local;
import org.apache.tapestry5.ioc.services.ApplicationDefaults;
import org.apache.tapestry5.ioc.services.SymbolProvider;
import org.apache.tapestry5.services.*;
import org.apache.tapestry5.services.javascript.JavaScriptStack;
import org.apache.tapestry5.services.javascript.StackExtension;
import org.apache.tapestry5.services.javascript.StackExtensionType;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestFilter;
import org.apache.tapestry5.services.RequestHandler;
import org.apache.tapestry5.services.Response;
import org.slf4j.Logger;
/**
* This module is automatically included as part of the Tapestry IoC Registry, it's a good place to
* configure and extend Tapestry, or to place your own service definitions.
*/
public class AppModule
{
public static void bind(ServiceBinder binder)
{
public class AppModule {
public static void bind(ServiceBinder binder) {
// binder.bind(MyServiceInterface.class, MyServiceImpl.class);
// Make bind() calls on the binder object to define most IoC services.
@ -33,8 +31,7 @@ public class AppModule
}
public static void contributeFactoryDefaults(
MappedConfiguration<String, Object> configuration)
{
MappedConfiguration<String, Object> configuration) {
// The values defined here (as factory default overrides) are themselves
// overridden with application defaults by DevelopmentModule and QaModule.
@ -48,8 +45,7 @@ public class AppModule
}
public static void contributeApplicationDefaults(
MappedConfiguration<String, Object> configuration)
{
MappedConfiguration<String, Object> configuration) {
// Contributions to ApplicationDefaults will override any contributions to
// FactoryDefaults (with the same key). Here we're restricting the supported
// locales to just "en" (English). As you add localised message catalogs and other assets,
@ -57,23 +53,22 @@ public class AppModule
// the first locale name is the default when there's no reasonable match).
configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
// You should change the passphrase immediately; the HMAC passphrase is used to secure
// You should change the passphrase immediately; the HMAC passphrase is used to secure
// the hidden field data stored in forms to encrypt and digitally sign client-side data.
configuration.add(SymbolConstants.HMAC_PASSPHRASE, "change this immediately");
}
/**
* Use annotation or method naming convention: <code>contributeApplicationDefaults</code>
*/
@Contribute(SymbolProvider.class)
@ApplicationDefaults
public static void setupEnvironment(MappedConfiguration<String, Object> configuration)
{
/**
* Use annotation or method naming convention: <code>contributeApplicationDefaults</code>
*/
@Contribute(SymbolProvider.class)
@ApplicationDefaults
public static void setupEnvironment(MappedConfiguration<String, Object> configuration) {
// Support for jQuery is new in Tapestry 5.4 and will become the only supported
// option in 5.5.
configuration.add(SymbolConstants.JAVASCRIPT_INFRASTRUCTURE_PROVIDER, "jquery");
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "context:mybootstrap");
}
configuration.add(SymbolConstants.JAVASCRIPT_INFRASTRUCTURE_PROVIDER, "jquery");
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "context:mybootstrap");
}
/**
@ -94,24 +89,19 @@ public class AppModule
* a service named "RequestFilter" we use an explicit service id that we can reference
* inside the contribution method.
*/
public RequestFilter buildTimingFilter(final Logger log)
{
return new RequestFilter()
{
public RequestFilter buildTimingFilter(final Logger log) {
return new RequestFilter() {
public boolean service(Request request, Response response, RequestHandler handler)
throws IOException
{
throws IOException {
long startTime = System.currentTimeMillis();
try
{
try {
// The responsibility of a filter is to invoke the corresponding method
// in the handler. When you chain multiple filters together, each filter
// received a handler that is a bridge to the next filter.
return handler.service(request, response);
} finally
{
} finally {
long elapsed = System.currentTimeMillis() - startTime;
log.info("Request time: {} ms", elapsed);
@ -128,10 +118,7 @@ public class AppModule
* that implement RequestFilter (defined in other modules).
*/
@Contribute(RequestHandler.class)
public void addTimingFilter(OrderedConfiguration<RequestFilter> configuration,
@Local
RequestFilter filter)
{
public void addTimingFilter(OrderedConfiguration<RequestFilter> configuration, @Local RequestFilter filter) {
// Each contribution to an ordered configuration has a name, When necessary, you may
// set constraints to precisely control the invocation order of the contributed filter
// within the pipeline.

View File

@ -1,27 +1,15 @@
package com.baeldung.tapestry.services;
import java.io.IOException;
import org.apache.tapestry5.*;
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Local;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestFilter;
import org.apache.tapestry5.services.RequestHandler;
import org.apache.tapestry5.services.Response;
import org.slf4j.Logger;
/**
* This module is automatically included as part of the Tapestry IoC Registry if <em>tapestry.execution-mode</em>
* includes <code>development</code>.
*/
public class DevelopmentModule
{
public class DevelopmentModule {
public static void contributeApplicationDefaults(
MappedConfiguration<String, Object> configuration)
{
MappedConfiguration<String, Object> configuration) {
// The factory default is true but during the early stages of an application
// overriding to false is a good idea. In addition, this is often overridden
// on the command line as -Dtapestry.production-mode=false

View File

@ -1,17 +1,8 @@
package com.baeldung.tapestry.services;
import java.io.IOException;
import org.apache.tapestry5.*;
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Local;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestFilter;
import org.apache.tapestry5.services.RequestHandler;
import org.apache.tapestry5.services.Response;
import org.slf4j.Logger;
/**
* This module is automatically included as part of the Tapestry IoC Registry if <em>tapestry.execution-mode</em>

View File

@ -1,67 +1,21 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
>
<head>
<meta charset="utf-8"/>
<title>${title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content=""/>
<meta name="author" content=""/>
<!-- Fav and touch icons -->
<link rel="shortcut icon" href="${asset:context:/favicon.ico}"/>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<t:pagelink page="index" class="navbar-brand">app</t:pagelink>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<t:loop source="pageNames" value="pageName">
<t:any element="li" class="prop:classForPageName">
<t:pagelink page="prop:pageName">${pageName}</t:pagelink>
</t:any>
</t:loop>
</ul>
<span class="navbar-right">
<li>
<t:pagelink page="login" class="btn btn-default navbar-btn">Sign in</t:pagelink>
</li>
</span>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container">
<div class="row">
<div class="span12">
<t:alerts/>
</div>
</div>
</div>
<div class="container">
<t:body />
<hr />
<footer>
<p>&copy; Your Company 2015</p>
</footer>
</div> <!-- /container -->
</body>
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<title>${title}</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="span12">
<t:alerts/>
</div>
</div>
</div>
<div class="container">
<t:body />
<hr />
<footer>
<p>&copy; Your Company 2015</p>
</footer>
</div>
</body>
</html>

View File

@ -1,23 +0,0 @@
<html t:type="layout" title="About apache-tapestry"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p="tapestry:parameter">
<div class="row">
<div class="span12">
<p>About apache-tapestry application ...</p>
</div>
</div>
<t:if test="learn">
<div class="row">
<div class="span12">
<p>
To learn more go to
<a href="http://tapestry.apache.org">Tapestry home</a>
and start typing...
</p>
</div>
</div>
</t:if>
</html>

View File

@ -1,7 +0,0 @@
<html t:type="layout" title="Contact com.baeldung"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p="tapestry:parameter">
<p>Contact com.baeldung ...</p>
</html>

View File

@ -0,0 +1 @@
introMsg=Welcome to the Apache Tapestry Tutorial

View File

@ -0,0 +1,14 @@
<html t:type="layout" title="apache-tapestry Home" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<h1>Home! ${appName}</h1>
<h2>${message:introMsg}</h2>
<h3>${currentTime}</h3>
<p><t:eventlink event="callAjax" zone="ajaxZone" class="btn btn-default">Call Ajax</t:eventlink></p>
<t:zone t:id="ajaxZone" class="span4"></t:zone>
<t:block t:id="ajaxBlock">
<hr/>
<h2>Rendered through Ajax</h2>
<p>The current time is: <strong>${currentTime}</strong></p>
</t:block>
</html>

View File

@ -6,8 +6,8 @@
<div class="span4 offset3">
<t:form t:id="login">
<h2>Please sign in</h2>
<t:textfield t:id="email" class="input-block-level" validate="required" placeholder="Email address"/>
<t:passwordfield t:id="password" class="input-block-level" validate="required" placeholder="Password"/>
<t:textfield t:id="email" class="input-block-level" placeholder="Email address"/>
<t:passwordfield t:id="password" class="input-block-level" placeholder="Password"/>
<t:submit class="btn btn-large btn-primary" value="Sign in"/>
</t:form>
</div>