Skip to content

Commit

Permalink
Tapestry 5 app for response time comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
kaosko committed Jun 7, 2011
1 parent 16ccd5e commit 3b9674a
Show file tree
Hide file tree
Showing 16 changed files with 609 additions and 0 deletions.
116 changes: 116 additions & 0 deletions tapestryapp/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>tapestryapp</groupId>
<artifactId>tapestryapp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>tapestryapp Tapestry 5 Application</name>
<dependencies>
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-core</artifactId>
<version>${tapestry-release-version}</version>
</dependency>
<!-- A dependency on either JUnit or TestNG is required, or the surefire plugin (which runs the tests)
will fail, preventing Maven from packaging the WAR. Tapestry includes a large number
of testing facilities designed for use with TestNG (http://testng.org/), so it's recommended. -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.12.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.5.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-test</artifactId>
<version>${tapestry-release-version}</version>
<scope>test</scope>
</dependency>

<!-- Provided by the servlet container, but sometimes referenced in the application
code. -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>

</dependencies>
<build>
<finalName>tapestryapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<optimize>true</optimize>
</configuration>
</plugin>

<!-- Run the application using "mvn jetty:run" -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.16</version>
<configuration>
<!-- Log to the console. -->
<requestLog implementation="org.mortbay.jetty.NCSARequestLog">
<!-- This doesn't do anything for Jetty, but is a workaround for a Maven bug
that prevents the requestLog from being set. -->
<append>true</append>
</requestLog>
</configuration>
</plugin>
</plugins>
</build>

<reporting>

<!-- Adds a report detailing the components, mixins and base classes defined by this module. -->
<plugins>
<plugin>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-component-report</artifactId>
<version>${tapestry-release-version}</version>
<configuration>
<rootPackage>tapestryapp</rootPackage>
</configuration>
</plugin>
</plugins>
</reporting>

<repositories>

<!-- This repository is only needed when the tapestry-release-version is a snapshot release. -->
<repository>
<id>apache-snapshots</id>
<url>http://repository.apache.org/snapshots/</url>
</repository>
</repositories>

<pluginRepositories>

<!-- As above, this can be commented out when access to the snapshot version
of a Tapestry Maven plugin is not required. -->
<pluginRepository>
<id>apache-snapshots</id>
<url>http://repository.apache.org/snapshots/</url>
</pluginRepository>

</pluginRepositories>

<properties>
<tapestry-release-version>5.2.5</tapestry-release-version>
</properties>
</project>
15 changes: 15 additions & 0 deletions tapestryapp/src/main/java/tapestryapp/Category.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package tapestryapp;

public class Category {
// Fields
private String name;

public String getName() {
return name;
}

public Category(String name) {
this.name = name;
}

}
33 changes: 33 additions & 0 deletions tapestryapp/src/main/java/tapestryapp/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package tapestryapp;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;


public class Product {
// Fields
private String name;
private Integer price;
private String description;
private Set<Category> categories = new HashSet<Category>();

// Getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getPrice() { return price; }
public void setPrice(Integer price) { this.price = price; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public Set<Category> getCategories() { return categories; }
public void setCategories(Set<Category> categories) { this.categories = categories; }

// ctor
public Product(String name, Integer price, String description, Category... categories) {
this.name = name;
this.price = price;
this.description = description;
this.categories = new HashSet<Category>(Arrays.asList(categories));
}

}
45 changes: 45 additions & 0 deletions tapestryapp/src/main/java/tapestryapp/components/Layout.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package tapestryapp.components;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.Block;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;

/**
* Layout component for pages of application tapestryapp.
*/
public class Layout
{
/** 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
@Parameter(defaultPrefix = BindingConstants.LITERAL)
private String sidebarTitle;

@Property
@Parameter(defaultPrefix = BindingConstants.LITERAL)
private Block sidebar;

@Inject
private ComponentResources resources;

public String getClassForPageName()
{
return resources.getPageName().equalsIgnoreCase(pageName)
? "current_page_item"
: null;
}

public String[] getPageNames()
{
return new String[] { "Index", "About", "Contact" };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package tapestryapp.components;

import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;

import tapestryapp.Product;

public class ProductDisplay {

@Parameter(required = true)
@Property
private Product product;

}
11 changes: 11 additions & 0 deletions tapestryapp/src/main/java/tapestryapp/pages/Index.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package tapestryapp.pages;

/**
* Start page of application tapestryapp.
*/
public class Index
{
public Object onActivate() {
return Products.class;
}
}
42 changes: 42 additions & 0 deletions tapestryapp/src/main/java/tapestryapp/pages/Products.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package tapestryapp.pages;

import java.util.List;
import java.util.Set;

import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;

import tapestryapp.Category;
import tapestryapp.Product;
import tapestryapp.services.DataService;

public class Products
{

@Inject
private DataService dataService;


@Property
private List<Product> products;

public void onActivate() {
if (products == null) {
products = dataService.getProducts();
}
}

@Property
private Product product;

public String getCategories() {
StringBuilder sb = new StringBuilder();
Set<Category> categories = product.getCategories();
for (Category category : categories) {
sb.append(category.getName());
sb.append(", ");
}
return sb.toString();
}

}
105 changes: 105 additions & 0 deletions tapestryapp/src/main/java/tapestryapp/services/AppModule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package tapestryapp.services;

import java.io.IOException;

import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ioc.Configuration;
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;

public class AppModule
{
public static void bind(ServiceBinder binder)
{
binder.bind(DataService.class, DataService.class);
}


public static void contributeApplicationDefaults(
MappedConfiguration<String, String> configuration)
{
configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
configuration.add(SymbolConstants.APPLICATION_VERSION, "1.0-SNAPSHOT");
configuration.add(SymbolConstants.DEFAULT_STYLESHEET, "context:default.css" );
configuration.add(SymbolConstants.DEFAULT_JAVASCRIPT, "" );
configuration.add(SymbolConstants.BLACKBIRD_ENABLED, "false");
configuration.add(SymbolConstants.COMBINE_SCRIPTS, "false" );
configuration.add(SymbolConstants.GZIP_COMPRESSION_ENABLED, "false");
}

public static void contributeIgnoredPathsFilter(Configuration<String> configuration)
{
configuration.add("/.*\\.jpg");
}

/**
* This is a service definition, the service will be named "TimingFilter". The interface,
* RequestFilter, is used within the RequestHandler service pipeline, which is built from the
* RequestHandler service configuration. Tapestry IoC is responsible for passing in an
* appropriate Logger instance. Requests for static resources are handled at a higher level, so
* this filter will only be invoked for Tapestry related requests.
*
* <p>
* Service builder methods are useful when the implementation is inline as an inner class
* (as here) or require some other kind of special initialization. In most cases,
* use the static bind() method instead.
*
* <p>
* If this method was named "build", then the service id would be taken from the
* service interface and would be "RequestFilter". Since Tapestry already defines
* 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 boolean service(Request request, Response response, RequestHandler handler)
throws IOException
{
long startTime = System.currentTimeMillis();

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
{
long elapsed = System.currentTimeMillis() - startTime;

log.info(String.format("Request time: %d ms", elapsed));
}
}
};
}

/**
* This is a contribution to the RequestHandler service configuration. This is how we extend
* Tapestry using the timing filter. A common use for this kind of filter is transaction
* management or security. The @Local annotation selects the desired service by type, but only
* from the same module. Without @Local, there would be an error due to the other service(s)
* that implement RequestFilter (defined in other modules).
*/
public void contributeRequestHandler(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.

configuration.add("Timing", filter);
}

}
Loading

0 comments on commit 3b9674a

Please sign in to comment.