Clone wiki

santa-exchange / Home

Note: As of June 2018, this code is unmaintained. It was originally written starting in 2011, which is an eternity ago in user-interface terms. Today, GWT is basically dead as a user interface development framework, making this code mostly irrelevant. Besides that, the Santa Exchange backend no longer works with the most recent Java 8 API for Google AppEngine, so as of January 2019, there won't even be any infrastructure on which it will run. I don't have the time or the motivation to fix it, so it remains here as a historical example.

Santa Exchange GWT Demonstration Project

Project Goals

A "Secret Santa" exchange is a party where people get together to exchange surprise gifts. The gift assignments are secret, and the gifts are usually fairly small. was a Java-based Google Web Toolkit (GWT v2) web site built using the Mvp4g framework. It runs on Google AppEngine (GAE). The web site lets users manage a gift exchange and send invitations via email. The project was originally maintained at Google Code, but moved here to BitBucket when Google announced retirement of the Google Code service.

This project is intended to provide a solid foundation for use in building other web sites, and I've used it for that purpose myself in both personal and professional projects.

Although the application is pretty small from an end-user perspective, all of the important underlying frameworks have been implemented and thoroughly tested. My goal was to demonstrate all of the features needed in an enterprise-quality software project. I chose to implement Secret Santa functionality because I am comfortable with the problem domain, which is limited in scope. This allowed me to focus on the design patterns and frameworks rather than the problem domain.

A major result of this effort was the CedarCommon project, a library of common Java functionality. Between the two of them, CedarCommon and SantaExchange provide a good example of how to build a solid GWT application using Mvp4g.

Available Documentation

See the Table of Contents at the bottom of this page for a list of other wiki pages related to SantaExchange.

Revision Control

The code is managed in a Mercurial repository hosted on BitBucket:

Project Mercurial URL Description
SantaExchange Java source code for the GWT web site

Shared functionality tied to CedarCommon is kept in a separate Mercurial repository.

System Architecture

The source code is divided into two projects: CedarCommon provides common functionality shared with other web applications. SantaExchange (code, javadoc) implements the actual GWT web site.

Both CedarCommon and SantaExchange are Eclipse projects, targeted at Java 6 and Eclipse 4. Both projects are managed using Gradle 2 and Maven. It's easier to work with SantaExchange using the Google Plugin for Eclipse, but it's not necessary to have the plugin (or even Eclipse, for that matter).

Note: SantaExchange is designed to be used with Java 6 and sets a Java 6 source and target compatibility level. However, recent versions of the AppEngine runtime only work with Java 7. So, although the code is compatible with Java 6, you'll need a Java 7 JDK to build or test the code.

The GWT portion of the web site uses the Model-View-Presenter (Passive View) pattern, implemented by the Mvp4g framework. The back-end is designed around Spring 3.2.

GAE supports two standard roles: user and administrator. For SantaExchange, role-level authorization is implemented both at the UI layer and at the back-end.

At the UI layer, users log into the site using a Google account. Originally, login via OpenId was supported -- including AOL, Yahoo, and MySpace logins in addition to Google. However, as of sometime in 2014, Google apparently made the decision to begin phasing out support for the federated authentication mechanism in AppEngine, so I formally moved away from OpenId as of February 1, 2015.

Mvp4g modules and filters are configured to divide the site into 3 regions: external, internal, and administrative. The external region is visible to the public, the internal region is visible to any authenticated user, and the administrative region is visible only to authenticated administrators.

All GWT remote procedure calls (RPCs) are implemented as Spring services using GWT-SL. Spring security is integrated into the RPC layer. Service interfaces or method calls can be annotated with @Secured("ROLE_ADMIN") or @Secured("ROLE_USER"). The Spring security framework will make sure that only authenticated users of the proper type are allowed to invoke the RPCs. A third role, ROLE_ENABLED, can be used to restrict locked users from calling RPCs.

The back-end DAO (data access object) layer is implemented using Objectify 3. CedarCommon provides an abstract DAO layer and includes an efficient, generalized pagination framework.

The back-end email implementation uses Velocity templates. Email is sent via the usual GAE infrastructure, but CedarCommon provides access to the infrastructure via a Spring service.

The user-visible portions of the implementation are fully localized, although I have not yet found time to have the site translated into any language other than English.

Build System

The SantaExchange and CedarCommon code is managed using the Gradle 2 build system. Underneath, dependencies are managed using Maven, mostly from Maven Central.

When I originally wrote SantaExchange, I checked dependency jars into revision control, because this is what the Google Plugin for Eclipse encourages you to do. This was less than ideal: the Mercurial repository eventually grew very large due to the frequent AppEngine upgrade cycle. Upgrades in general were painful, and I also had to manually track the source and version of each jar, etc. in my own documentation.

Using Gradle has simplified the whole process, even if it does add an extra setup step for anyone who wants to work with the code. There are notes in the wiki under DevelopmentEnvironment and SourceCode that will walk you through the process.

Test Coverage

There is a substantial unit test suite, with over 90% code coverage and nearly 700 test cases implemented as of this writing. Many unit tests rely on StubbedTestRunner, a JUnit4 test runner that allows much (but not all) of the GWT client code to be tested using standard JUnit 4 unit tests and Mockito mocks. Presenters and certain portions of the view layer code can be tested with JUnit 4. Code that deals directly with user interface widgets must still be tested using the slower and less-flexible GWT client-side unit tests.

Besides the unit test suite, there is also a functional acceptance test suite implemented using Cucumber and Capybara. Cucumber tests are written in a business-readable domain-specific language. Test bindings are written in Ruby, and then Capybara drives a browser session using Selenium. Acceptance test coverage is not as complete as unit test coverage, but the acceptance test suite still provides a good smoke test to prove that the application is working normally.

Table of Contents