java

  • submit to reddit

Getting Started with Oracle Berkeley DB

By Masoud Kalali

8,495 Downloads · Refcard 68 of 151 (see them all)

Download
FREE PDF


The Essential Berkeley DB Cheat Sheet

The Oracle Berkeley DB (BDB) family consists of three open source data persistence products that provide developers with fast, reliable, high performance, enterprise ready local databases implemented in the ANSI C and Java programming languages. This DZone Refcard provides a brief introduction to the Oracle Berkeley DB family. The author, Masoud Kalali, then moves on to discuss in depth the Oracle Berkeley DB Java Edition, including the following topics: Transaction Support, Performance Tuning, Backup, and Recovery. This DZone Refcard is perfect for anyone interested in learning more about the Oracle Berkeley DB family and its capabilities.
HTML Preview
Getting Started with Oracle Berkeley DB

Getting Started with Oracle Berkeley DB

By Masoud Kalali

About Oracle Berkeley DB

The Oracle Berkeley DB (BDB) family consists of three open source data persistence products which provide developers with fast, reliable, high performance, enterprise ready local databases implemented in the ANSI C and Java programming languages. The BDB family typically stores key-value pairs but is also flexible enough to store complex data models. BDB and BDB Java Edition share the same base API, making it possible to easily switch between the two.

We will review the most important aspects of Oracle BDB family briefly. Then we will dig deep into Oracle BDB Java Edition and see what its exclusive features are. We discuss Based API and Data Persistence Layer API. We will see how we can manage transactions DPL and Base API in addition to persisting complex objects graph using DPL will form the overall development subjects. Backup recovery, tuning, and data migration utilities to migrate data between different editions and installations forms the administrations issues which we will discuss in this Refcard.

The BDB Family

Oracle BDB Core Edition

Berkeley DB is written in ANSI C and can be used as a library to access the persisted information from within the parent application address space. Oracle BDB provides multiple interfaces for different programming languages including ANSI C, the Java API through JNI in addition to Perl, PHP, and Python.

Oracle BDB XML Edition

Built on top of the BDB, the BDB XML edition allows us to easily store and retrieve indexed XML documents and to use XQuery to access stored XML documents. It also supports accessing data through the same channels that BDB supports.

BDB Java Edition

BDB Java Edition is a pure Java, high performance, and flexible embeddable database for storing data in a key-value format. It supports transactions, direct persistence of Java objects using EJB 3.0-style annotations, and provides a low level key-value retrieval API as well as an “access as collection” API.

Key Features

Each of the BDB family members supports different feature sets. BDB XML edition enjoys a similar set of base features as the Core BDB. BDB Java edition on the other hand is implemented in a completely different environment with an entirely different set of features and characteristics (See Table 4). The base feature sets are shown in Table 1.

Table 1: Family Feature Sets
Feature Set Description
Data Store (DS) Single writer, multiple reader
Concurrent Data Store (CDS) Multiple writers, multiple snapshot readers
Transactional Data Store (TDS) Full ACID support on top of CDS
High Availability (HA) Replication for fault tolerance. Fail over recovery support

Table 2 shows how these features are distributed between the different BDB family members.

Table 2: Different Editions’ Feature Sets DS CDS TS HA
BDB/BDB XML Edition

model_binder

model_binder

model_binder

model_binder

BDB Java Edition

model_binder

model_binder

Additional Features

The BDB family of products has several special features and offers a range of unique benefits which are listed in Table 3.

Table 3: Family Features and Benefits
Feature Benefit
Locking High concurrency
Data stored in application-native format Performance, no translation required
Programmatic API, no SQL Performance, flexibility/control
In process, not client-server Performance, no IPC required
Zero administration Low cost of ownership
ACID transactions and recovery Reliability, data integrity
Dual License Open/Closed source distributions
In memory or on disk operation Transacted caching/ persisted data store
Similar data access API Easy switch between JE and BDB
Just a set of library Easy to deploy and use
Very large databases Virtually no limit on database size

Features unique to BDB Java Edition are listed in Table 4.

Table 4: BDB Java Edition Exclusive Features
Feature Benefit
Fast, indexed, BTree Ultra fast data retrieval
Java EE JTA and JCA support Integration with Java EE application servers
Efficient Direct Persistence Layer EJB 3.0 like annotation to store Java Objects graph
Easy Java Collections API Transactional manipulation of Base API through enhanced Java Collections
Low Level Base API Work with dynamic data schema
JMX Support Monitor able from within parent application

These features, along with a common set of features, make the Java edition a potential candidate for use cases that require caching, application data repositories, POJO persistence, queuing/buffering, Web services, SOA, and Integration.

Introducin g Berkeley DB java Edition

Installation

You can download BDB JE from http//bit.ly/APfJ5. After extracting the archive you’ll see several directories with selfdescribing names. The only file which is required to be in the class path to compile and run the included code snippet is je- 3.3.75.jar (the exact file name may vary) which is placed inside the lib directory. Notice that BDB JE requires J2SE JDK version 1.5.0_10 or later.

Hot Tip

All editions of Berkeley DB are freely available for download and can be used in open source products which are not distributed to third parties. A commercial license is necessary for using any of the BDB editions in a closed source and packaged product. For more information about licensing visit: http://bit.ly/17pMwZ

Access APIs

BDB JE provides three APIs for accessing persisted data. The Base API provides a simple key-value model for storing and retrieving data. The Direct Persistence Layer (DPL) API lets you persist any Java class with a default constructor into the database and retrieve it using a rich set of data retrieval APIs. And finally the Collections API which extends the well known Java Collections API with data persistence and transaction support over data access.

Base API sample

The Base API is the simplest way to access data. It stores a key and a value which can be any serializable Java object.


EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
Environment dbEnv = new Environment(new File(“/home/masoud/dben”),
envConfig);
DatabaseConfig dbconf = new DatabaseConfig();
dbconf.setAllowCreate(true);
dbconf.setSortedDuplicates(false);//allow update
Database db = dbEnv.openDatabase(null, “SampleDB “, dbconf);
DatabaseEntry searchEntry = new DatabaseEntry();
DatabaseEntry dataValue = new DatabaseEntry(“ data content”.
getBytes(“UTF-8”));
DatabaseEntry keyValue = new DatabaseEntry(“key content”.
getBytes(“UTF-8”));
db.put(null, keyValue, dataValue);//inserting an entry


db.get(null, keyValue, searchEntry, LockMode.DEFAULT);//retrieving
record
String foundData = new String(searchEntry.getData(), “UTF-8”);
dataValue = new DatabaseEntry(“updated data content”.
getBytes(“UTF-8”));
db.put(null, keyValue, dataValue);//updating an entry
db.delete(null, keyValue);//delete operation
db.close();
dbEnv.close();

There are multiple overrides for the Database.put method to prevent duplicate records from being inserted and to prevent record overwrites.

DPL Sample

DPL sample consists of two parts, the entity class and the entity management class which handle CRUD over the entity class.

Entity Class


@Entity
public class Employee {
  @PrimaryKey
  public String empID;
  public String lastname;
  @SecondaryKey(relate = Relationship.MANY_TO_MANY,
  relatedEntity = Project.class,onRelatedEntityDelete =
DeleteAction.NULLIFY)
  public Set<Long> projects;
  public Employee() { }
  public Employee(String empID, String lastname, Set<Long> projects)
{
   this.empID = empID;
   this.lastname = lastname;
   this.projects = projects;
    }
  }}

This is a simple POJO with few annotations to mark it as an entity with a String primary key. For now ignore the @Secondarykey annotation, we will discuss it later.

The data management Class


EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
Environment dbEnv = new Environment(new File(“/home/masoud/dbendpl”),
envConfig);
StoreConfig stConf = new StoreConfig();
stConf.setAllowCreate(true);
EntityStore store = new EntityStore(dbEnv, “DPLSample”, stConf);
PrimaryIndex userIndex;
userIndex = store.getPrimaryIndex(String.class, Employee.class);
userIndex.putNoReturn(new Employee(“u180”, “Doe”, null));//insert
Employee user = userIndex.get(“u180”);//retrieve
userIndex.putNoReturn(new Employee(“u180”, “Locke”, null));//
Update
userIndex.delete(“u180”);//delete
store.close();
dbEnv.close();

These two code snippets show the simplest from of performing CRUD operation without using transaction or complex object relationships.

Sample code description

An Environment provides a unit of encapsulation for one or more databases. Environments correspond to a directory on disk. The Environment is also used to manage and configure resources such as transactions. EnvironmentConfig is used to configure the Environment, with options such as transaction configuration, locking, caching, getting different types of statistics including database, locks and transaction statistics, etc.

One level closer to our application is DatabaseConfig and Database object when we use Base API. When we use DPL these objects are replaced by StoreConfig and EntityStore.

In Base API DatabaseConfig and Database objects provide access to the database and how the database can be accessed.

Configurations like read-only access, record duplication handling, creating in-memory databases, transaction support, etc. are provided through DatabaseConfig.

In DPL StoreConfig and EntityStore objects provide access to object storage and how the object storage can be accessed. Configurations such as read only access, data model mutation, creating in-memory databases, transaction support, etc. are provided through StoreConfig.

The PrimaryIndex class provides the primary storage and access methods for the instances of a particular entity class. There are multiple overrides for the PrimaryIndex.put method to prevent duplicate entity insertion and provide entity overwrite prevention.

Hot Tip

When closing an Environment or Database or when we commit a Transaction in a multi thread application we should ensure that no thread still has in-progress tasks.

BDB Java edition environment anatomy

A BDB JE database consists of one or more log files which are placed inside the environment directory.

The log files are named NNNNNNNN.jdb where NNNNNNNN is an 8-digit hexadecimal number that increases by 1 (starting from 00000000) for each log file written to disk. BDB JE rolls to next file when the current file size reaches the predefined configurable size. The predefined size is 10MB.

A BDB database can be considered like a relational table in an RDBMS. In Base API we directly use the database we need to access, while in DPL we use an EntityStore which may interact with multiple databases under the hood.

Each BDB environment can contain tens of databases and all of these databases will be stored in a single row of log files. (No separate log files per-database). Figure 1 shows the concept visually.

Hot Tip

To create in-memory database we can use DatabaseConfig. setTemporary(true) and StoreConfig.setTemporary(true) to get an in-memory instance with no data persisted beyond the current session.

Figure1

Figure 1: BDB JE environment and log files.

Hot Tip

The environment path should point to an already existing directory, otherwise the application will face and exception. When we create an environmnt object for the first time, necessary files are created inside that direcory.

BDB Java edition environment anatomy

Table 5 shows Base API characteristics and benefits. The keyvalue access model provides the most flexibility.

Table 5: Base API Features
Key value store retrieval, value can be anything
Cursor API to traverse in a dataset forward and backward
JCA (Java Connectivity Architecture) support
JMX (Java Management eXtension) support
Table 6: DPL API Features
Type Safe access to persisted objects
Updating classes with adding new fields is supported
Persistent class fields can be private, package-private, protected or public
Automatic and extendable data binding between Objects and underlying storage
Index fields can be accessed using a standard java.util collection.
Java annotations are used to define metadata like relations between objects
Field refactoring is supported without changing the stored date.(Called mutation)

Table 6 and Table 7 list the features that mostly determine when we should use which API. Table 7 lists possible use cases for each API.

Table 7: Which API is suitable for your case
Use case characteristics Suitable API
Data model is highly dynamic and changing Base API
Data model has complex object model and relationships DPL
Need application portability between Java Edition and Core Edition DPL, Base API

Transaction Support

Transaction Support is an inseparable part of enterprise software development. BDB JE supports transaction and provides concurrency and record level locking. To add transaction support to DPL in our DPL sample code we can introduce the following changes:


...
envConfig.setTransactional(true);
stConf.setTransactional(true);
TransactionConfig txConf = new TransactionConfig();
stConf.setTransactional(true);
txConf.setReadCommitted(true);
Transaction tx= dbEnv.getThreadTransaction();
dbEnv.beginTransaction(tx, txConf);
...
userIndex.putNoReturn(tx, new Employee(“u180”, “Doe”, null));//
insert
...
tx.commit();
...

The simplicity of BDB JE Transaction Support makes it very suitable for transactional cache systems. The isolation level, deferrable and manual synchronization of transactional data with hard disk (Durability), replication policy, and transaction lock request and transaction lifetime timeout can be configured using the Transaction and TransactionConfig objects.

Hot Tip

Environment, Database, and EntityStore are thread safe meaning that we can use them in multiple threads without manual synchronization

Transaction support in Base API is a bit different, as in Base API we directly deal with databases while in DPL we deal with environment and EntityStore objects. The following changes will allow transaction support in Base API.


...
envConfig.setTransactional(true);
dbconf.setTransactional(true);
TransactionConfig txConf = new TransactionConfig();
txConf.setSerializableIsolation(true);
txConf.setNoSync(true);
Transaction tx = dbEnv.getThreadTransaction();
tx.setLockTimeout(1000);
tx.setTxnTimeout(5000);
Database db = dbEnv.openDatabase(tx, «SmpleDB», dbconf);
dbEnv.beginTransaction(tx, txConf);
...
db.put(tx, keyValue, dataValue);//inserting an entry
...
tx.commit();

More transaction related supported features are demonstrated in this snippet. Environment, Database, EntityStore, etc. configuration is omitted from these snippet for sake of simplicity.

Hot Tip

Once a transaction is committed, the transaction handle is no longer valid and a new transaction object is required for further transactional activities.

Persisting Complex Object Graph using DPL

For this section we leave Base API alone and focus on using DPL for complex object graphs. We continue with introducing secondary index and many-to-many mapping.

Let’s look at some important annotations that we have for defining the object model.

Table 8: BDB JE annotations
Annotation Description
@Entity Declares an entity class; that is, a class with a primary index and optionally one or more indices.
@PrimaryKey Defines the class primary key and must be used one and only one time for every entity class.
@SecondaryKey Declares a specific data member in an entity class to be a secondary key for that object. This annotation is optional, and can be used multiple times for an entity class.
@Persistent Declares a persistent class which lives in relation to an entity class.
@NotTransient Defines a field as being persistent even when it is declared with the transient keyword.
@NotPersistent Defines a field as being non-persistent even when it is not declared with the transient keyword.
@KeyField Indicates the sorting position of a key field in a composite key class when the Comparable interface is not implemented. The KeyField integer element specifies the sort order of this field within the set of fields in the composite key.

We used two of these annotations in practice and you saw @SecondaryKey in the Employee class. Now we are going to see how the @SecondaryKey annotation can be used. Let’s create the Project entity which the Employee class has a many-to-many relation with.


@Entity
public class Project {
	public String projName;
	@PrimaryKey(sequence = «ID»)
	public long projID;
	public Project() {
	}
	public Project(String projName) {
	this.projName = projName;
	}
}

The @PrimaryKey annotation has a string element to define the name of a sequence from which we can assign primary key values automatically. The primary key field type must be numerical and a named sequence can be used for multiple entities.

Now let’s see how we can store and retrieve an employee with its related project objects.


...
PrimaryIndex<String, Employee> empByID;
PrimaryIndex<Long, Project> projByID;
empByID = store.getPrimaryIndex(String.class, Employee.class);
projByID = store.getPrimaryIndex(Long.class, Project.class);
SecondaryIndex<Long, String, Employee> empsByProject;
empsByProject = store.getSecondaryIndex(empByID, Long.class,
“projects”);
Set<Long> projects = new HashSet<Long>();
Project proj = null;
proj = new Project(“Develop FX”);
projByID.putNoReturn(proj);
projects.add(proj.projID);
proj = new Project(“Develop WS”);
projByID.putNoReturn(proj);
projects.add(proj.projID);
empByID.putNoReturn(new Employee(“u146”, “Shephard”, projects));//
insert
empByID.putNoReturn(new Employee(“u144”, “Locke”, projects));//
insert
EntityIndex projs = empsByProject.subIndex(proj.
projID);
EntityCursor<Employee> pcur = projs.entities();
for (Employee entity : pcur) {
   //process the employees
}
EntityCursor<Employee> emplRange = empByID.entities(“e146”, true,
“u148”, true);
for (Employee entity : emplRange) {
   //process the employees
}
emplRange.close();
pcur.close();
store.close();
dbEnv.close();

The Environment and EntityStore definitions are omitted. The SecondaryIndex provides primary methods for retrieving objects related to the Secondary Key of a particular object. The SecondaryIndex can be used to retrieve the related objects through a traversable cursor. We can also use SecondaryIndex to query for a specific range of objects in a given range for its primary key.

Table 9: Supported Object Relation
Relation Description
ONE_TO_ONE A single entity is related to a single secondary key value.
ONE_TO_MANY A single entity is related to one or more secondary key values.
MANY_TO_ONE One or more entities are related to a single secondary key value.
MANY_TO_MANYOne or more entities are related to one or more secondary key values.

A SecondaryIndex can be used to traverse over the collection of secondary key’s values to retrieve the secondary objects.

Hot Tip

Multiple processes can open a database as long as only one process opens it in read-write mode and other processes open the database in read-only mode. The readonly processes get an open-time snapshot of the database and won’t see any changes coming from other process.

BDB JE Collections API

The only different between using BDB JE collections API and classic collections is the fact that when we use BDB JE Collections API we are accessing persisted objects instead of in-memory objects which we usually access in classic collection APIs.

The Collections API Characteristics
An implementation Map, SortedMap, Set, SortedSet, and Iterator.
To stay compatible with Java Collections, Transaction is supported using TransactionWorker and TransactionRunner which the former one is the interface which we can implement to execute our code in a transaction and later one process the transaction.
Keys and values are represented as Java objects. Custom binding can be defined to bind the stored bytes to any type or format like XML, for example.
Data binding should be defined to instruct the Collections API about how keys and values are represented as stored data and how stored data is converted to and from Java objects. We can use one of the two (SerialBinding, TupleBinding) default data bindings or a custom data binding.
Environment, EnvironmentConfig, Database and DatabaseConfig stay the same as it was for Base API.
Collections API extends Java serialization to store class description separately to make data records much more compact.

To get a real sense about BDB JE Collections API think of it as we can persist and retrieve objects using a collection class like SortedMap’s methods like tailMap, subMap or put, putall, get, and so on.

But before we use the SortedMap object to access the stored data, we need to initialize the base objects like Database and Environment; we should create the ClassCatalog object, and finally we should define bindings for our key and value types.

Collections API sample

Now let’s see how we can store and retrieve our our objects using Collections API. In this sample we are persisting a pair of Integer key and String value using SortedMap.

First lets analyze the TransactionWorker implementation.


public class TransWorker implements TransactionWorker {
	private ClassCatalog catalog;
	private Database db;
	private SortedMap map;
	public TransWorker(Environment env) throws Exception {
	   DatabaseConfig dbConfig = new DatabaseConfig();
	   dbConfig.setTransactional(true);
	   dbConfig.setAllowCreate(true);
   Database catalogDb = env.openDatabase(null, “catalog”, dbConfig);
	   catalog = new StoredClassCatalog(catalogDb);
	   // use Integer tuple binding for key entries
	   TupleBinding keyBinding =
              TupleBinding.getPrimitiveBinding(Integer.class);
	   // use String serial binding for data entries
	 SerialBinding dataBinding = new SerialBinding(catalog,
String.class);
	 db = env.openDatabase(null, “dben-col”, dbConfig);
	 map = new StoredSortedMap(db, keyBinding, dataBinding,
true);
    }
    /** Performs work within a transaction. */
    public void doWork() throws Exception {
	   // check for existing data and writing
	   Integer key = new Integer(0);
	   String val = (String) map.get(key);
	   if (val == null) {
           map.put(new Integer(10), “Second”);
     }
     //Reading Data
    Iterator iter = map.entrySet().iterator();
       while (iter.hasNext()) {
          Map.Entry entry = (Map.Entry) iter.next();
          //Process the entry
    }
  }
}

TransWorker implements TransactionWorker which makes it necessary to implement the doWork method. This method is called by TransactionRunner when we pass an object of TransWorker to its run method. The TransWorker constructor simply receive an Environment object and construct other required objects . Then it opens the database in Collection mode, creates the required binding for the key and values we want to store in the database and finally it creates the SortedMap object which we can use to put and retrieve objects using it. Now let’s see the driver code which put this class in action.


public class CollectionSample {
   public static void main(String[] argv)
		throws Exception {
		// Creating the environment
		EnvironmentConfig envConfig = new EnvironmentConfig();
		envConfig.setTransactional(true);
		envConfig.setAllowCreate(true);
		Environment dbEnv = new Environment(new File(“/home/
masoud/dben-col”), envConfig);
		// creating an instance of our TransactionWorker
		TransWorker worker = new TransWorker(dbEnv);
		TransactionRunner runner = new TransactionRunner(dbEnv);
           runner.run(worker);
	}
}

The steps demonstrated in the CollectionSample are self describing. The only new object in this snippet is the TransactionRunner object which we used to run the TransWorker object. I omit many of the safe programming portions to keep the code simple and conscious. we need exception handling and properly closure of all BDB JE objects to ensure data integrity

BDB JE Backup/Recovery and Tuning

Backup and Recovery

We can simply backup the BDB databases by creating an operating system level copy of all jdb files. When required we can put the archived files back into the environment directory to get a database back to the state it was at. The best option is to make sure all transactions and the write process are finished to have a consistent backup of the database.

The BDB JE provides a helper class located at com.sleepycat. je.util.DbBackup to perform the backup process from within a Java application. This utility class can create an incremental backup of a database and later on can restore from that backup. The helper class ideally freezes the BDB JE activities during the backup to ensure that the created backup exactly represents the database state when the backup process started.

Tuning

Berkeley DB JE has 3 daemon threads and configuring these threads affects the overall application performance and behavior. These 3 threads are as follow:

Cleaner Thread Responsible for cleaning and deleting unused log files. This thread is run only if the environment is opened for write access.
Checkpointer Thread Basically keeps the BTree shape consistent. Checkpointer thread is triggered when environment opens, environment closes, and database log file grows by some certain amount.
Compressor Thread For cleaning the BTree structure from unused nodes.

These threads can be configured through a properties file named je.properties or by using the EnvironmentConfig and EnvironmentMutableConfig objects. The je.properties file, which is a simple key-value file, should be placed inside the environment directory and override any further configuration which we may make using the EnvironmentConfig and EnvironmentMutableConfig in the Java code.

The other performance effective factor is cache size. For ondisk instances cache size determines how often the application needs to refer to permanent storage in order to retrieve some data bucket. When we use in-memory instances cache size determines whether our database information will be paged into swap space or it will stay in the main memory.

je.cleaner.minUtilization Ensures that a minimum amount of space is occupied by live records by removing obsolete records. Default occupied percentage is 50%.
je.cleaner.expunge Determines the cleaner behavior in the event that it is able to remove an entire log file. If “true” the log file will be deleted, otherwise it will be renamed to nnnnnnnn.del
je.checkpointer.bytesInterval Determines how often the Checkpointer should check the BTree structure. If it performs the checks little by little it will ensure a faster application startup but will consume more resources specially IO.
je.maxMemory Percent Determines what percentage of JVM maximum memory size can be used for BDB JE cache. To determine the ideal cache size we should put the application in the production environment and monitor its behavior.

A complete list of all configurable properties, with explanations, is available in EnvironmentConfig Javadoc. The list is comprehensive and allows us to configure the BDB JE at granular level.

All of these parameters can be set from Java code using the EnvironmentConfig object. The properties file overrides the values set by using EnvironmentConfig object.

Helper Utilities

Three command line utilities are provided to facilitate dumping the databases from one environment, verifying the database structure, and loading the dump into another environment.

DbDump Dumps a database to a user-readable format.
DbLoad Loads a database from the DbDump output.
DbVerify Verifies the structure of a database.

To run each of these utilities, switch to BDB JE directory, switch to lib directory and execute as shown in the following command:


java -cp je-3.3.75.jar com.sleepycat.je.util.DbVerify

The JAR file name may differ depending on your version of BDB JE. These commands can also be used to port a BDB JE database to BDB Core Edition.

Hot Tip

A very good set of tutorials for different set of BDB JE APIs are available inside the docs folder of BDB JE package. Several examples for different set of functionalities are provided inside the examples directory of the BDB JE package.

About The Author

Photo of Masoud Kalali

Masoud Kalali

Masoud Kalali holds a software engineering degree and has been working on software development projects since 1998. He has experience with a variety of technologies (.Net, J2EE, CORBA, and COM+) on diverse platforms (Solaris, Linux, and Windows). His experience is in software architecture, design and server side development. Masoud has several articles in Java.net. He is one of founder members of NetBeans Dream Team. Masoud’s main area of research and interest includes Web Services and Service Oriented Architecture along with large scale and high throughput systems' development and deployment.

Blog: http://weblogs.java.net/blog/kalali/

Contact: Kalali@gmail.com

Recommended Book

Oracle Berkeley DB

The Berkeley DB Book is a practical guide to the intricacies of the Berkeley DB. This book covers in-depth the complex design issues that are mostly only touched on in terse footnotes within the dense Berkeley DB reference manual. It explains the technology at a higher level and also covers the internals, providing generous code and design examples.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

JavaServer Faces 2.0

By Cay Horstmann

28,367 Downloads · Refcard 58 of 151 (see them all)

Download
FREE PDF


The Essential JavaServer Faces 2.0 Cheat Sheet

JavaServer Faces (JSF) is the “official” component-based view technology in the Java EE web tier. This JSF 2.0 DZone Refcard is perfect for both new and seasoned JSF developers. JSF 2.0, the long-awaited successor to JSF 1.x, brings exciting new features: less boilerplate code, better error handling, built-in Ajax, and more. This Refcard also provides updated summaries of the tags and attributes needed for JSF programming, along with a summary of the JSF expression language and a list of code snippets for common operations.
HTML Preview
JavaServer Faces 2.0

JavaServer Faces 2.0

By Cay Horstmann

JSF Overview

JavaServer Faces (JSF) is the “official” component-based view technology in the Java EE web tier. JSF includes a set of predefined UI components, an event-driven programming model, and the ability to add third-party components. JSF is designed to be extensible, easy to use, and toolable. This refcard describes JSF 2.0.

Development Process

A developer specifies JSF components in JSF pages, combining JSF component tags with HTML and CSS for styling. Components are linked with managed beans—Java classes that contain presentation logic and connect to business logic and persistence backends.

JSF framework

In JSF 2.0, it is recommended that you use the facelets format for your pages:


<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”
  “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”
  xmlns:f=”http://java.sun.com/jsf/core”
  xmlns:h=”http://java.sun.com/jsf/html”
  xmlns:ui=”http://java.sun.com/jsf/facelets”>
  <h:head>...</h:head>
  <h:body>
   <h:form>
       ...
   </h:form>
  </h:body>
</html>

These common tasks give you a crash course into using JSF.

Text Field

Code 1

page.xhtml


<h:inputText value=”#{bean1.luckyNumber}”>

WEB-INF/classes/com/corejsf/SampleBean.java


@ManagedBean(name=”bean1”)
@SessionScoped
public class SampleBean {
   public int getLuckyNumber() { ... }
   public void setLuckyNumber(int value) { ... }
   ...
}

Button

Press Button

page.xhtml


<h:commandButton value=”press me” action=”#{bean1.login}”/>

WEB-INF/classes/com/corejsf/SampleBean.java


@ManagedBean(name=”bean1”)
@SessionScoped
public class SampleBean {
   public String login() {
     if (...) return “success”; else return “error”;
   }
...
}


The outcomes success and error can be mapped to pages in faces-config.xml. if no mapping is specified, the page /success.xhtml or /error.xhtml is displayed.

Radio Buttons

Radio Button

page.xhtml


<h:selectOneRadio value=”#{form.condiment}>
<f:selectItems value=”#{form.items}”/>
</h:selectOneRadio>

WEB-INF/classes/com/corejsf/SampleBean.java


public class SampleBean {
  private static Map<String, Object> items;
  static {
    items = new LinkedHashMap<String, Object>();
    items.put(“Cheese”, 1); // label, value
    items.put(“Pickle”, 2);
    ...
  }
  public Map<String, Object> getItems() { return items; }
  public int getCondiment() { ... }
  public void setCondiment(int value) { ... }
  ...
}

JBoss Studio2.0_5.jpg

Validation and Conversion

Page-level validation and conversion:


<h:inputText value=”#{bean1.amount}” required=”true”>
  <f:validateDoubleRange maximum=”1000”/>
</h:inputText>
<h:outputText value=”#{bean1.amount}”>
  <f:convertNumber type=”currency”/>
</h:outputText>

The number is displayed with currency symbol and group separator: $1,000.00

Using the Bean Validation Framework (JSR 303) 2.0


public class SampleBean {
  @Max(1000) private BigDecimal amount;
}

Error Messages

Error Message


<h:outputText value=”Amount”/>
<h:inputText id=”amount” label=”Amount” value=”#{payment.amount}”/>
<h:message for=”amount”/>

Resources and Styles

page.xhtml


<h:outputStylesheet library=”css” name=”styles.css” target=”head”/>
...
<h:outputText value=”#{msgs.goodbye}!” styleClass=”greeting”>

faces-config.xml


<application>
  <resource-bundle>
    <base-name>com.corejsf.messages</base-name>
    <var>msgs</var>
  </resource-bundle>
</application>

WEB-INF/classes/com/corejsf/messages.properties


goodbye=Goodbye

WEB-INF/classes/com/corejsf/messages_de.properties


goodbye=Auf Wiedersehen

resources/css/styles.css


.greeting {
  font-style: italic;
  font-size: 1.5em;
  color: #eee;
}

Table with links

Table With Links


<h:dataTable value=”#{bean1.entries}” var=”row” styleClass=”table”
  rowClasses=”even,odd”>
  lt;h:column>
    <f:facet name=”header”>
      <h:outputText value=”Name”/>
    </f:facet>
    <h:outputText value=”#{row.name}”/>
  </h:column>
  <h:column>
    <h:commandLink value=”Delete” action=”#{bean1.deleteAction}”
      immediate=”true”>
      <f:setPropertyActionListener target=”#{bean1.idToDelete}”
        value=”#{row.id}”/>
    </h:commandLink>
  </h:column>
</h:dataTable>

WEB-INF/classes/com/corejsf/SampleBean.java


public class SampleBean {
  private int idToDelete;
  public void setIdToDelete(int value) { idToDelete = value; }
  public String deleteAction() {
    // delete the entry whose id is idToDelete
    return null;
  }
  public List<Entry> getEntries() { ... }
  ...
}

Ajax 2.0


<h:commandButton value=”Update”>
  <f:ajax execute=”
</h:commandButton>

lifecycle

lifecycle

The jsf expression language

An EL expression is a sequence of literal strings and expressions of the form base[expr1][expr2]... As in JavaScript, you can write base.identifier instead of base[‘identifier’] or base[“identifier”]. The base is one of the names in the table below or a bean name.

header A Map of HTTP header parameters, containing only the first value for each name
headerValues A Map of HTTP header parameters, yielding a String[] array of all values for a given name
param A Map of HTTP request parameters, containing only the first value for each name
paramValues A Map of HTTP request parameters, yielding a String[] array of all values for a given name
cookie A Map of the cookie names and values of the current request
initParam A Map of the initialization parameters of this web application
requestScope,
sessionScope,
applicationScope,
viewScope 2.0
A map of all attributes in the given scope
facesContext The FacesContext instance of this request
view The UIViewRoot instance of this request
component 2.0 The current component
cc 2.0
resource 2.0 Use resource[‘library:name’] to access a resource

Value expression: a reference to a bean property or an entry in a map, list or array. Examples:

userBean.name calls getName or setName on the userBean object pizza.choices[var] calls pizza.getChoices().get(var) or pizza.getChoices().put(var, ...)

Method expression: a reference to a method and the object on which it is to be invoked. Example:
userBean.login calls the login method on the userBean object when it is invoked. 2.0: Method expressions can contain parameters: userBean.login(‘order page’)

In JSF, EL expressions are enclosed in #{...} to indicate deferred evaluation. The expression is stored as a string and evaluated when needed. In contrast, JSP uses immediate evaluation, indicated by ${...} delimiters.

2.0: EL expressions can contain JSTL functions

fn:contains(str, substr),
fn:containsIgnoreCase(str, substr)
fn:startsWith(str, substr)
fn:endsWith(str, substr)
fn:length(str)
fn:indexOf(str)
fn:join(strArray, separator)
fn:split(str, separator)
fn:substring(str, start, pastEnd)
fn:substringAfter(str, separator)
fn:substringBefore(str, separator)
fn:replace(str, substr,
replacement)
fn:toLowerCase(str)
fn:toUpperCase(str)
fn:trim()
fn:escapeXml()

JSF Core Tags

Tag Description/Attributes
f:facet Adds a facet to a component - name: the name of this facet
f:attribute Adds an attribute to a component - name, value: the name and value of the attribute to set
f:param
Constructs a parameter child component
- name: An optional name for this parameter component.
- value:The value stored in this component.
f:actionListener f:valueChangeListener
Adds an action listener or value change listener to a component
- type: The name of the listener class
f:propertyAction Listener 1.2
Adds an action listener to a component that sets a bean property
to a given value
- target: The bean property to set when the action event occurs
- value: The value to set it to
f:phaseListener 1.2
Adds a phase listener to this page
- type: The name of the listener class
f:event 2.0
Adds a system event listener to a component
- name: One of preRenderComponent, postAddToView,
  preValidate, postValidate
- listenter: A method expression of the type
  void (ComponentSystemEvent) throws
  AbortProcessingException
f:converter
Adds an arbitrary converter to a component
- convertedId: The ID of the converter
f:convertDateTime
Adds a datetime converter to a component
- type: date (default), time, or both
- dateStyle, timeStyle: default, short, medium, long or full
- pattern: Formatting pattern, as defined in java.text.
  SimpleDateFormat
- locale: Locale whose preferences are to be used for parsing
  and formatting
- timeZone: Time zone to use for parsing and formatting
  (Default: UTC)
f:convertNumber
Adds a number converter to a component
- type: number (default), currency , or percent
- pattern: Formatting pattern, as defined in java.text.
  DecimalFormat
- minIntegerDigits, maxIntegerDigits,
  minFractionDigits, maxFractionDigits: Minimum,
  maximum number of digits in the integer and fractional part
- integerOnly: True if only the integer part is parsed (default:
  false)
- groupingUsed: True if grouping separators are used (default:
  true)
- locale: Locale whose preferences are to be used for parsing
  and formatting
- currencyCode: ISO 4217 currency code to use when
  converting currency values
- currencySymbol: Currency symbol to use when converting
  currency values
f:validator
Adds a validator to a component
- validatorID: The ID of the validator
f:validateDoubleRange,
f:validateLongRange,
f:validateLength
Validates a double or long value, or the length of a string
- minimum, maximum: the minimum and maximum of the valid
  range
f:validateRequired 2.0 Sets the required attribute of the enclosing component
f:validateBean 2.0
Specify validation groups for the Bean Validation Framework
(JSR 303)
f:loadBundle
Loads a resource bundle, stores properties as a Map
- basename: the resource bundle name
- value: The name of the variable that is bound to the bundle map
f:selectItem
Specifies an item for a select one or select many component
- binding, id: Basic attributes
- itemDescription: Description used by tools only
- itemDisabled: false (default) to show the value
- itemLabel: Text shown by the item
- itemValue: Item’s value, which is passed to the server as a
  request parameter
- value: Value expression that points to a SelectItem instance
- escape: true (default) if special characters should be converted
  to HTML entities
- noSelectionOption 2.0: true if this item is the “no selection
  option”
f:selectItems
Specifies items for a select one or select many component
- value: Value expression that points to a SelectItem, an array
  or Collection, or a Map mapping labels to values.
- var 2.0: Variable name used in value expressions when
  traversing an array or collection of non-SelectItem elements
- itemLabel 2.0, itemValue 2.0, itemDescription 2.0,
  itemDisabled 2.0, itemLabelEscaped 2.0: Item label,
  value, description, disabled and escaped flags for each item in
  an array or collection of non-SelectItem elements. Use the
  variable name defined in var.
- noSelectionOption 2.0: Value expression that yields the “no
  selection option” item or string that equals the value of the “no
  selection option” item
f:ajax 2.0
Enables Ajax behavior
- execute, render: Lists of component IDs for processing in the
  “execute” and “render” lifecycle phases
- event: JavaScript event that triggers behavior. Default: click
  for buttons and links, change for input components
- immediate: If true, generated events are broadcast during
  “Apply Request Values” phase instead of “Invoke Application”
- listener: Method binding of type void (AjaxBehaviorEvent)
- onevent, onerror: JavaScript handlers for events/errors
f:viewParam 2.0 Defines a “view parameter” that can be initialized with a request
parameter
-name, value: the name of the parameter to set
-binding, converter, id, required, value, validator,
valueChangeListener: basic attributes
f:metadata 2.0 Holds view parameters. May hold other metadata in the future

JSF HTML Tags

Tag Description
h:head 2.0,h:body 2.0,
h:form
HTML head, body, form
h:outputStylesheet 2.0,
h:outputScript 2.0
Produces a style sheet or script
h:inputText Single-line text input control.

code8.1

h:inputTextArea Multiline text input control.

code8.1

h:inputSecret Password input control. inputTextArea
h:inputHidden Hidden field
h:outputLabel Label for another
component for
accessibility
h:outputLink HTML anchor. code8.2
h:outputFormat Like outputText, but
formats compound
messages
h:outputText Single-line text output.
h:commandButton,
h:button 2.0
Button: submit, reset, or pushbutton. press me
h:commandLink, h:link 2.0 Link that acts like a
pushbutton.
register
h:message Displays the most recent
message for a component
Recent Message
h:messages Displays all messages
h:grapicImage Displays an image Image Display
h:selectOneListbox Single-select listbox Listbox
h:selectOneMenu Single-select menu Menu Select
h:selectOneRadio Set of radio buttons Radio Button Select
h:selectBooleanCheckbox Checkbox Checkbox
h:selectManyCheckbox Set of checkboxes Checkboxes
h:selectManyListbox Multiselect listbox Multiselect Listbox
h:selectManyMenu Multiselect menu Multiselect Menu
h:panelGrid HTML table
h:panelGroup Two or more components
that are laid out as one
h:dataTable A feature-rich table
component
h:column Column in a data table

Basic Attributes

id Identifier for a component
binding Reference to the component that can be used in a backing bean
rendered A boolean; false suppresses rendering
value A component’s value, typically a value binding
valueVhangeListener A method expression of the type void (ValueChangeEvent)
converter, validator Converter or validator class name
required A boolean; if true, requires a value to be entered in the associated field

Attributes for h:body and h:form

Attribute Description
binding, id, rendered Basic attributes
dir, lang, style, styleClass, target, title
h:form only: accept, acceptcharset, enctype
HTML 4.0 attributes
(acceptcharset corresponds
to HTML accept-charset,
styleClass corresponds to
HTML class)
onclick, ondblclick, onkeydown, onkeypress,
onkeyup, onmousedown, onmousemove, onmouseout,
onmouseover
h:body only: onload, onunload
h:form only: onblur, onchange, onfocus,
onreset, onsubmit
DHTML events

Attributes for h:inputText, h:inputSecret,
h:inputTextarea, and h:inputHidden

Code Attribute Description cols For h:inputTextarea only—number of columns immediate Process validation early in the life cycle redisplay For h:inputSecret only—when true, the input field’s value is redisplayed when the web page is reloaded required Require input in the component when the form is submitted rows For h:inputTextarea only—number of rows binding, converter, id, rendered, required, value, validator, valueChangeListener Basic attributes accesskey, alt, dir,
disabled, lang, maxlength,
readonly, size, style,
styleClasstabindex, title HTML 4.0 pass-through attributes—alt, maxlength, and size do not apply to h:inputTextarea. None apply to h:inputHidden onblur, onchange, onclick,
ondblclick, onfocus,
onkeydown, onkeypress,
onkeyup, onmousedown,
onmousemove, onmouseout,
onmouseover, onselect DHTML events. None apply to h:inputHidden

Attributes for h:outputText and h:outputFormat

Attribute Description
escape If set to true, escapes <, >, and & characters. Default value is true
Basic attributes
style, title HTML 4.0

Attributes for h:outputLabel

Attribute Description
for The ID of the component to be labeled.
binding, converter, id, rendered, value Basic attributes

Attributes for h:graphicImage

cloud Attribute Description library 2.0, name 2.0 The resource library (subdirectory of resources) and file name (in that subdirectory) binding, id, rendered, value Basic attributes alt, dir, height, ismap, lang,
longdesc, style, styleClass, title,
url, usemap, width HTML 4.0 onblur, onchange, onclick,
ondblclick, onfocus, onkeydown,
onkeypress, onkeyup, onmousedown,
onmousemove, onmouseout,
onmouseover, onmouseup DHTML events

Attributes for h:commandButton and h:commandLink

press me Attribute Description action (command tags) Navigation outcome string or method expression of type String () outcome 2.0 (non-command tags) Value expression yielding the navigation outcome fragment 2.0 (non-command tags) Fragment to be appended to URL. Don’t include the # separator actionListener Method expression of type void (ActionEvent) charset For h:commandLink only—The character encoding of the linked reference image (button tags) For h:commandButton only—A context-relative path to an image displayed in a button. If you specify this attribute, the HTML input’s type will be image immediate A boolean. If false (the default), actions and action listeners are invoked at the end of the request life cycle; if true, actions and action listeners are invoked at the beginning of the life cycle type For h:commandButton: The type of the generated input element: button, submit, or reset. The default, unless you specify the image attribute, is submit. For h:commandLink and h:link: The content type of the linked resource; for example, text/html, image/gif, or audio/basic value The label displayed by the button or link binding, id, rendered Basic attributes accesskey, dir, disabled (h:commandButton only), lang, readonly, style, styleClass, tabindex, title
link tags only: charset, coords, hreflang, rel, rev, shape, target HTML 4.0 onblur, onclick, ondblclick,
onfocus, onkeydown, onkeypress,
onkeyup, onmousedown, onmousemove,
onmouseout, onmouseover,
onmouseup DHTML events

Attributes for h:outputLink

Java Anchor Attribute Description accesskey, binding, converter, id, lang, rendered, value Basic attributes charset, coords, dir, hreflang, lang, rel, rev, shape, style, styleClass, tabindex, target, title, type HTML 4.0 onblur, onchange, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup DHTML events

Attributes for: h:selectBooleanCheckbox,
h:selectManyCheckbox, h:selectOneRadio,
h:selectOneListbox, h:selectManyListbox,
h:selectOneMenu, h:selectManyMenu

Boolean Checkbox Attribute Description enabledClass, disabledClass CSS class for enabled/disabled elements— h:selectOneRadio and h:selectManyCheckbox only selectedClass 2.0,
unselectedClass 2.0 CSS class for selected/unselected elements— h:selectManyCheckbox only layout Specification for how elements are laid out: lineDirection (horizontal) or pageDirection (vertical)—h:selectOneRadio and h:selectManyCheckbox only collectionType 2.0 selectMany tags only: the name of a collection class such as java.util.TreeSet hideNoSelectionOption 2.0 Hide item marked as “no selection option” binding, converter, id, immediate, required, rendered, validator, value, valueChangeListener Basic attributes accesskey, border, dir, disabled, lang, readonly, style, styleClass, size, tabindex, title HTML 4.0—border only for h:selectOneRadio and h:selectManyCheckbox, size only for h:selectOneListbox and h:selectManyListbox. onblur, onchange, onclick,
ondblclick, onfocus, onkeydown,
onkeypress, onkeyup, onmousedown,
onmousemove, onmouseout,
onmouseover, onmouseup, onselect DHTML events

Attributes for h:message and h:messages

Boolean Checkbox Attribute Description for The ID of the component whose message is displayed— applicable only to h:message errorClass, fatalClass, infoClass, warnClass CSS class applied to error/fatal/information/warning messages errorStyle, fatalStyle, infoStyle, warnStyle CSS style applied to error/fatal/information/warning messages globalOnly Instruction to display only global messages—h:messages only. Default: false layout Specification for message layout: table or list— h:messages only showDetail A boolean that determines whether message details are shown. Defaults are false for h:messages, true for h:message. showSummary A boolean that determines whether message summaries are shown. Defaults are true for h:messages, false for h:message. tooltip A boolean that determines whether message details are rendered in a tooltip; the tooltip is only rendered if showDetail and showSummary are true binding, id, rendered Basic attributes style, styleClass, title HTML 4.0

Attributes for h:panelGrid

Attribute Description
bgcolor Background color for the table
border Width of the table’s border
cellpadding Padding around table cells
cellspacing Spacing between table cells
columns Number of columns in the table
frame frame Specification for sides of the frame surrounding
the table that are to be drawn; valid values: none,
above, below, hsides, vsides, lhs, rhs, box, border
headerClass, footerClass CSS class for the table header/footer
rowClasses, columnClasses Comma-separated list of CSS classes for rows/columns
rules Specification for lines drawn between cells; valid values: groups, rows, columns, all
summary Summary of the table’s purpose and structure used for non-visual feedback such as speech
binding, id, rendered, value Basic attributes
dir, lang, style, styleClass, title, width HTML 4.0
onclick, ondblclick,
onkeydown, onkeypress,
onkeyup, onmousedown,
onmousemove, onmouseout,
onmouseover, onmouseup
DHTML events

Attributes for h:panelGroup

Attribute Description
binding, id, rendered Basic attributes
style, styleClass HTML 4.0

Attributes for h:dataTable

Attribute Description
bgcolor Background color for the table
border Width of the table’s border
cellpadding Padding around table cells
cellspacing Spacing between table cells
first index of the first row shown in the table
frame Specification for sides of the frame surrounding the table should be drawn; valid values: none, above, below, hsides, vsides, lhs, rhs, box, border
headerClass, footerClass CSS class for the table header/footer
rowClasses, columnClasses comma-separated list of CSS classes for rows/columns
rules Specification for lines drawn between cells; valid values: groups, rows, columns, all
summary summary of the table’s purpose and structure used for non-visual feedback such as speech
var The name of the variable created by the data table that represents the current item in the value
binding, id, rendered,
value
Basic attributes
dir, lang, style, styleClass, title, width HTML 4.0
onclick, ondblclick,
onkeydown, onkeypress,
onkeyup, onmousedown,
onmousemove, onmouseout,
onmouseover, onmouseup
DHTML events

Attributes for h:column

Attribute Description
headerClass 1.2,
footerClass 1.2
CSS class for the column’s header/footer
binding, id, rendered Basic attributes
Attribute Description
ui:define Give a name to content for use in a template
-name: the name of the content
ui:insert If a name is given, insert named content if defined or use the child elements otherwise. If no name is given, insert the content of the tag invoking the template -name: the name of the content
ui:composition Produces content from a template after processing child elements (typically ui:define tags) Everything outside the ui:composition tag is ignored -template: the template file, relative to the current page
ui:component Like ui:composition, but makes a JSF component -binding, id: basic attributes
ui:decorate, ui:fragment Like ui:composition, ui:
ui:include Include plain XHTML, or a file with a ui:composition or ui:component tag -src: the file to include, relative to the current page
ui:param Define a parameter to be used in an included file or template -name: parameter name -value: a value expression (can yield an arbitrary object)
ui:repeat Repeats the enclosed elements
  • value: a List, array, ResultSet, or object
  • offset, step, size: starting intex, step size, ending index of the iteration
  • var: variable name to access the current element
  • varStatus: variable name to access the iteration status, with integer properties begin, end, index, step and Boolean properties even, odd, first, last
ui:debug Shows debug info when CTRL+SHIFT+a key is pressed
  • hotkey: the key to press (default d)
  • rendered: true (default) to activate
ui:remove Do not include the contents (useful for comments or temporarily deactivating a part of a page)

About The Author

Photo of Cay S Horstmann

Cay S. Horstmann

has written many books on C++, Java and object-oriented development, is the series editor for Core Books at Prentice-Hall and a frequent speaker at computer industry conferences. For four years, Cay was VP and CTO of an Internet startup that went from 3 people in a tiny office to a public company. He is now a computer science professor at San Jose State University. He was elected Java Champion in 2005.

Cay Horstmann’s Java Blog

http://weblogs.java.net/blog/cayhorstmann/

Cay Horstmann’s Website-

http://www.horstmann.com/

Recommended Book

Maven

Core JavaServer Faces delves into all facets of JSF development, offering systematic best practices for building robust applications and maximizing developer productivity.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Getting Started with JavaFX

By Stephen Chin

17,506 Downloads · Refcard 56 of 151 (see them all)

Download
FREE PDF


The Essential JavaFX Cheat Sheet

JavaFX makes it easier to build better RIAs with graphics, animation, and media. Built on Java, this platform uses existing Java libraries and is capable of running in your browser, on your desktop, and on your phone. This DZone Refcard is ideal for the beginner, and will help you get started programming with JavaFX Script. It will also serve as a convenient reference once you have mastered the language. The instructions in this Refcard assume that you are using an IDE, but it is also possible to do everything from the command line as well.
HTML Preview
JavaFX

Getting Started with JavaFX

By Stephen Chin

About JavaFX

JavaFX is an exciting new platform for building Rich Internet Applications with graphics, animation, and media. It is built on Java technology, so it is interoperable with existing Java libraries, and is designed to be portable across different embedded devices including mobile phones and set-top boxes. This Refcard will help you get started programming with JavaFX Script and also serve as a convenient reference once you have mastered the language.

To get started, you will have to download the latest JavaFX SDK from the JavaFX website here: http://javafx.com/.

The instructions in the following tutorial assume that you are using an IDE, such as NetBeans. However, it is possible to do everything from the command line as well.

JFXPoetry, a si mple exa mple

To illustrate how easy it is to build an application that melds graphics, text, animation, and media, we will start with a simple tutorial. The goal will be to write an application that:

  • Loads and displays an image from the internet
  • Displays and animates a verse of poetry
  • Declaratively mixes in graphic effects
  • Plays media asynchronously

For the JFXPoetry theme, we will use “Pippa’s Song,” a wellknown excerpt from Robert Browning’s Pippa Passes.

Loading an Image on the Stage

Stage and Scene are the building blocks of almost every JavaFX program. A Stage can either be represented as a Frame for desktop applications, a rectangle for applets, or the entire screen for mobile devices. The visual content of a Stage is called a Scene, which contains a sequence of content Nodes that will be displayed in stacked order. The following program creates a basic Stage and Scene which is used to display an image:


var scene:Scene;
Stage {
  title: “Pippa’s Song by Robert Browning”
  scene: scene = Scene {
    content: [
      ImageView {
        image: bind Image {
	 height: scene.height
	 preserveRatio: true
	 url: “http://farm1.static.flickr.com/39/
	    121693644_75491b23b0.jpg”
        }
      }
    ]
  }
}

Notice that that JavaFX syntax makes it simple to express nested UI structures. The curly braces “{}” are used for object instantiation, and allow inline initialization of variables where the value follows the colon “:”. This is used to instantiate an ImageView with an Image inside that loads its content from the given URL. To ensure the image resizes with the window, we set preserveRatio to true and bind the Image. Binding is a very powerful facility in JavaFX that makes it easy to update values without heavyweight event handlers. Compiling and running this application will display a picture of a misty morning in Burns Lake, BC, Canada taken by Duane Conlon as shown in Figure 1.1 2

Figure 1.1 2

Figure 1: A JavaFX Stage containing an image loaded from the network

Displaying Text With Effects

Displaying text in JavaFX is as simple as instantiating a Text Node and setting the content to a String. There are many variables available on Text, but for this example we will set the font, fill color, and also add a Drop Shadow effect to make the text stand out on the background.


1 Creative Commons Attribution 2.0 License: http://creativecommons.org/licenses/by/2.0/

2 Duane Conlon’s Photostream: http://www.flickr.com/photos/duaneconlon/


var text:Text;
Stage {
	  ...
	  ImageView {
        ...
	  },
	  text = Text {
		effect: DropShadow {}
		font: bind Font.font(“Serif”, FontWeight.BOLD,
					  scene.height / 12.5)
	    fill: Color.GOLDENROD
	    x: 10
	    y: bind scene.height / 6
	    content: “The year’s at the spring,\n”
				 “And day’s at the morn;\n”
				 “Morning’s at seven;\n”
				 “The hill-side’s dew-pearled;\n”
				 “The lark’s on the wing;\n”
				 “The snail’s on the thorn;\n”
				 “God’s in His heaven--\n”
				 “All’s right with the world!”
        }

Notice that rather than specifying the whole poem text on one line we have split it across several lines, which will automatically get concatenated. Also, we have used the bind operator to set both the font size and y offset, which will update their values automatically when the scene height changes. Figure 2 shows the updated example with text overlaid on the Image.

Figure 2

Figure 2: Updated example with a Text overlay

JavaFX offers a large set of graphics effects that you can easily apply to Nodes to create rich visual effects. Table 1 lists all the available effects you can choose from.

Table 1. Graphics effects available in JavaFX

Effect Description
Blend Blends two inputs together using a pre-defined BlendMode
Bloom Makes brighter portions of the Node appear to glow
BoxBlur Fast blur with a configurable quality threshold
ColorAdjust Per-pixel adjustments of hue, saturation, brightness, and contrast
DisplacementMap Shifts each pixel by the amount specified in a DisplacementMap
DropShadow Displays an offset shadow underneath the node
Flood Fills a rectangular region with the given Color
GaussianBlur Blurs the Node with a configurable radius
Glow Makes the Node appear to glow with a given intensity level
Identity Passes an image through to a chained effect
InnerShadow Draws a shadow on the inner edges of the Node
InvertMask Returns a mask that is the inverse of the input
Lighting Simulates a light source to give Nodes a 3D effect
MotionBlur Blurs the image at a given angle to create a motion effect
PerspectiveTransform Maps a Node to an arbitrary quadrilateral for a perspective effect
Reflection Displays an inverted view of the Node to create a reflected effect
SepiaTone Creates a sepia tone effect to mimic aged photographs
Shadow Similar to a DropShadow, but without the overlaid image

Animated Transitions

Animations in JavaFX can be accomplished either by setting up a Timeline from scratch, or using one of the pre-fabricated Transitions. To animate the Text rising onto the screen, we will use a TranslateTransition, which adjusts the position of a Node in a straight line for the specified duration:


var animation = TranslateTransition {
  duration: 24s
  node: text
  fromY: scene.height
  toY: 0
  interpolator: Interpolator.EASEOUT
}
animation.play();

By setting an interpolator of EASEOUT, the text will start at full speed and gradually deaccelerate as it approaches its destination. Animations and Transitions can also be configured to repeat, run at a specific rate, or reverse. To run the transition, all you need to do is call the play() function, which will animate the text as shown in Figure 3.

Figure 3

Figure 3: Animated Text Scrolling Into View

Table 2 lists all of the available transitions that are part of the JavaFX API. To get a feel for how the different transitions work, try adding a FadeTransition that will gradually fade the background in over a 5 second duration.

Table 2. Transitions Supported by JavaFX

Transition Description
FadeTransition Changes the opacity of a node over time
ParallelTransition Plays a sequence of transitions in parallel
PathTransition Animates nodes along a Shape or Path
PauseTransition Executes an action after the specified delay
RotateTransition Changes the rotation of a node over time
ScaleTransition Changes the size of a node over time
SequentialTransition Plays a sequence of transitions in series
TranslateTransition Changes the position of a node over time

Interacting With Controls

The JavaFX 1.2 release features a new library of skinnable controls written in pure JavaFX. Table 3 lists some of the new controls and what they can be used for.

Table 3. Controls Available in JavaFX 1.2

Control Description
Button Button that can contain graphics and text
CheckBox Selectable box that can be checked, unchecked, or undefined
Hyperlink HTML-like clickable text link
Label Text that can be associated with anther control
ListView Scrollable list that can contain text or Nodes
ProgressBar Progress bar that can show percentage complete or be indeterminate
RadioButton Selectable button that can belong to a group
ScrollBar Scroll control typically used for paging
Slider Draggable selector of a number or percent
TextBox Text input control

The simplest control to use is a Button, which can easily be scripted to play the animation sequence again from the beginning.


var button:Button;
Stage {
...
text = Text {
...
    },
    button = Button {
        translateX: bind (scene.width - button.width) / 2
        translateY: bind (scene.height - button.height) / 2
        text: “Play Again”
      visible: bind not animation.running
      action: function() {
        animation.playFromStart();
      }
    }
  ]

Ths bind operator is used to both hide the button while the animation is playing and also center the button in the window. Initially the button is invisible, but we added a new SequentialTransition that plays a FadeTransition to show the button after the translation is complete. Clicking the button shown in Figure 4 will hide it and play the animation from the beginning.

Figure 4

Figure 4: Button Control to Play the Animation Again

Panning With Layouts

JavaFX 1.2 comes with several new layouts that make it easy to design complex UIs. One of these is the ClipView, which we will use to support dragging of the poem text. ClipView takes a single Node as the input and allows the content to be panned using the mouse:


 content: [
...
    ClipView {
	 width: bind scene.width
	 height: bind scene.height
	 override var maxClipX = 0
	 node: text = Text {
...
     }
   }

To ensue the ClipView takes the full window, its width and height are bound to the scene. Also, we have overridden the maxClipX variable with a value of 0 to restrict panning to the vertical direction. The text can now be dragged using the mouse as shown in Figure 5.

Figure 5

Figure 5: Panning the Text using a ClipView

Table 4 lists all of the available layouts that come JavaFX comes with. HBox and VBox have been around since the 1.0 release, but all the other layouts are new in JavaFX 1.2.

Table 4. Layouts Available in JavaFX 1.2

Layout Description
HBox Lays out its contents in a single, horizontal row
VBox Lays out its contents in a single, vertical column
ClipView Clips its content Node to the bounds, optionally allowing panning
Flow Lays out its contents either vertically or horizontally with wrapping
Stack Layers its contents on top of each other from back to front
Tile Arranges its contents in a grid of evenly sized tiles

Finishing with Media

JavaFX has built-in media classes that make it very simple to play audio or video either from the local files or streaming off the network. To complete the example we will add in a public domain clip of Indigo Bunting birds chirping in the background. Adding in the audio is as simple as appending a MediaPlayer with autoPlay set to true that contains a Media object pointing to the URL.


MediaPlayer {
  autoPlay: true
  media: Media {
    source: “http://video.fws.gov/sounds/35indigobunting.mp3”
  }
}

In this example we are using an mp3 file, which is supported across platforms by JavaFX. Table 5 lists some of the common media formats supported by JavaFX, including all the crossplatform formats.

Table 5. Common Media Formats Supported by JavaFX

Type Platform Format File Extension
Audio Cross-platform MPEG-1 Audio Layer 3 mp3
Audio Cross-platform Waveform Audio Format wav
Audio Macintosh Advanced Audio Coding m4a, aac
Audio Macintosh Audio Interchange File Format aif, aiff
Video Platform Format File Extension
Video Cross-platform Flash Video flv, f4v
Video Cross-platform JavaFX Multimedia fxm
Video Windows Windows Media Video wmv, avi
Video Macintosh QuickTime mov
Video Macintosh MPEG-4 mp4

To try the completed example complete with animation and audio, you can click on the following url:

http://jfxtras.org/samples/jfxpoetry/JFXPoetry.jnlp

The full source code for this application is available on the JFXtras Samples website: http://jfxtras.org/portal/samples

Running on Mobile

To run the sample in the Mobile Emulator all you have to do is pass in the MOBILE profile to the javafxpackager program or switch the run mode in your IDE project properties. JavaFX Mobile applications are restricted to the Common Profile, which does not include all the features of desktop applications. The full list of restrictions is shown in Table 5.

Table 5. Functionality Not Available in the Common Profile

Class(es) Affected Variables and Methods
javafx.ext.swing.* All
javafx.reflect.* All
javafx.scene.Node effect, style
javafx.scene.Scene stylesheets
javafx.scene.effect.* All
javafx.scene.effect.light.* All
javafx.scene.shape.ShapeIntersect All
javafx.scene.shape.ShapeSubtract All
javafx.scene.text.Font autoKern, embolden, letterSpacing, ligatures, oblique, position
javafx.stage.AppletStageExtension All
javafx.util.FXEvaluator All
javafx.util.StringLocalizer All

Over 80% of the JavaFX API is represented in the Common Profile, so it is not hard to build applications that are portable. In this example we used a DropShadow on the text that, once removed, will let us run the example in the Mobile Emulator as shown in Figure 6.

Figure 6

Figure 6: JFXPoetry application running in the Mobile Emulator

Running as a Desktop Widget

You can deploy your application as a desktop widget using the WidgetFX open-source framework. Any JavaFX application can be converted to a widget by including the WidgetFX-API.jar and making some small updates to the code.

The Following code fragment highlights the code changes required:


var widget:Widget = Widget {
  resizable: false
  width: 500
  height: 375
  content: [
...
      height: widget.height
...
    font: bind Font.font(“Serif”, FontWeight.BOLD,
              widget.height / 12.5)
...
    y: bind widget.height / 6
...
  ]
}


...
    fromY: widget.height
...
widget;

The updates to the code include the following three changes:

  • Wrap your application in a Widget class. The Widget class extends javafx.scene.layout.Panel, which makes it easy to extend.
  • Set the initial widget width/height and modify references from scene to widget.
  • Return the widget at the end of the script.

To run the widget, simply change your project properties to run the application using Web Start Excecution. This will automatically create a JNLP file compatible with WidgetFX and launch the Widget Runner, which allows you to test your widget as shown in the Figure 7.

Figure 7

Figure 7: JFXPoetry running as a desktop widget

For more information about WidgetFX, including SDK download, documentation, and additional tutorials, check out the project website: http://widgetfx.org/

JavaFX Reference

Language Reference

JavaFX supports all the Java datatypes plus a new Duration type that simplifies writing animationed UIs.

Data Types:

DataType Java Equivalent Range Examples
Boolean boolean true or false true,false
Integer int -2147483648 to 2147483647 2009, 03731, 0x07d9
Number float 1.40×10 45 and 3.40×1038 3.14, 3e8, 1.380E-23
String String N/A “java’s”, ‘in”side”er’
Duration <None> -263 to 263-1 milliseconds 1h, 5m, 30s, 500ms
Character char 0 to 65535 0,20,32
Byte byte -128 to 127 -5, 0,5
Short short -32768 to 32767 -300, 0, 521
Long long -263 to 263-1 2009, 03731,0x07d9
Float float 1.40x10 45 and 3.40x1038 3.14, 3e8, 1.380E-23
Double double 4.94x10 324 and 1.80x10308 3.14, 3e8, 1.380E-123

JavaFX Characters cannot accept literals like ‘a’ or ‘0’, because they are treated as Strings. The primary way of getting Characters will be by calling a Java API that returns a char primitive, although you can create a new character by assigning a numeric constant

Operators:

The following table lists all the mathematical, conditional, and boolean operators along with their precedence (1 being the highest).

Operator Meaning Precedence Examples
++ Pre/post increment 1 ++i, i++
-- Pre/post decrement 1 --i, i--
not Boolean negation 2 not (cond)
* Multiply 3 2 * 5, 1h * 4
/ Divide 3 9 / 3, 1m / 3
mod Modulo 3 20 mod 3
+ Add 4 0 + 2, 1m + 20s
- Subtract (or negate) 4 (2) -2, 32 - 3, 1h - 5m
== Equal 5 value1 == value2, 4 == 4
!= Not equal 5 value1 != value2, 5 != 4
< Less than 5 value1 < value2, 4 < 5
<= Less than or equal 5 value1 <= value2, 5 <= 5
< Greater than 5 value1 > value2, 6 > 5
>= Greater than or equal 5 value1 >= value2, 6 >= 6
instanceof Is instance of class 6 node instanceof Text
as Typecast to class 6 node as Text
and Boolean and 7 cond1 and cond2
or Boolean or 8 cond1 or cond2
+= Add and assign 9 value += 5
-= Subtract and assign 9 value -= 3
*= Multiply and assign 9 value *= 2
/= Divide and assign 9 value /=4
= Assign 9 value = 7
  • Multiplication and division of two durations is allowed, but not meaningful
  • Underflows/Overflows will fail silently, producing inaccurate results
  • Divide by zero will throw a runtime exception

Sequences:

JavaFX sequences provide a powerful resizable and bindable list capability under a simple array-like syntax. All of the sequence operators (sizeof, reverse, indexof) have a relative precedence of 2.

Operation Syntax Examples
Construct

[x,y,z]
[y..z]
[y..<z]
[y..z step w]


var nums = [1, 2, 3, 4]; var letters = [“a”, “b”, “c”];
[1..5] = [1, 2, 3, 4, 5]
[1..>5] = [1, 2, 3, 4]
[1..9 step 2] = [1, 3, 5, 7, 9]

Size sizeof seq sizeof nums; // = 4
Index indexof variable

for(x in seq) {
indexof x;
}

Element seq[i] letters[2]; // = “c”
Slice

eq[x..y]
seq[x..<y]


nums[1..2]; // = [2, 3]
letters[0..<2]; // = [“a”, “b”]

Predicate seq[x|boolean] nums[n|n mod 2 == 0]; // = [2, 4]
Reverse reverse seq reverse letters; // = [“c”, “b”, “a”]
Insert

insert x into seq
insert x before seq[i]
insert x after seq[i]


insert 5 into nums; // = [1, 2, 3, 4, 5]
insert “gamma” before letters[2]; // = [“a”, “b”,
“gamma”, “c”]
insert “2.3” after nums[1]; // = [1, 2, 2.3, 3, 4]

Delete

delete seq[i]
delete seq[x..y]
delete x from seq
delete seq


delete letters[1]; // = [“a”, “c”]
delete nums[1..2]; // = [1, 4]
delete “c” from letters; // = [“a”, “b”]
delete letters; // = []

  • The javafx.util.Sequences class provides additional functions, which allow you to manipulate sequences, such as min, max, search, shuffle, and short.
  • Nested sequences are automatically flattened, so [[1,2], [3,4]] is equivalent to [1,2,3,4].
  • Sequences require commas after all elements except close braces; however it is recommended to always use commas
  • You can declare a sequence as a nativearray. This is an optimization so that arrays returned from a Java method don’t need to be converted to a sequence.

Access Modifiers:

The JavaFX access modifiers are based upon Java with the addition of extra variable-only modifiers.

Modifier Name Description
<Default> Script only access Only accessible within the same script file
package Package access Only accessible within the same package
protected Protected access Only accessible within the same package or by subclasses
public Public access Can be accessed anywhere
publicread

Read access
modifier

Var/def modifier to allow a variable to be read anywhere
public-init Init access modifier Var/def modifier to allow a variable to be initialized or read anywhere
  • Unlike Java the default permission in JavaFX is script-only rather than package.
  • The var/def access modifiers can be stacked with other modifiers, such as public-read protected

Expressions:

JavaFX supports many of the same expressions as Java, but adds in powerful inline functions and for loop extensions.

Expression Syntax Example
if

if (cond) expr1 else expr2
if (cond) then expr1 else expr2


if (grass.green) {
  grass.mow();
} else {
  grass.water();
}
var water = if (grass.color ==
BLACK) aLot else aLittle;

for

for (x in seq) expr
for (x in seq where cond) expr
for (x in seq, y in x) expr


var loans = for (b in borrowers
where b.pulse > 0)
{
  b.createLoan();
}
for (loan in loans) {
  loan.approve();
}

while while (bool) expr

while (swimming) {
  paddle();
  breathe();
}


try/catch/
finally


try {expr1} catch(exception)
{expr2} finally {expr3}


try {
  Bailout();
} catch(e:FinancialCrisis) {
  massiveBailout();
} finally {
  increaseTaxes();
}

function function(params):returnType{}

function(e:MouseEvent):Void {
     e.source.toFront();
}

Just like in Java programs:

  • continue can be used to skip a for or while loop iteration
  • break can be used to exit a for or while loop
  • return can be used to exite from a function event if inside a loop

Magic Variables:

JavaFX provides some built-in variables that can be accessed from any code running inside a script.

Name Description
__DIR__ Directory the current classfile is contained in
__FILE__ Full path to the current classfile
__PROFILE__ The current profile, which can be ‘desktop’ or ‘mobile’

API Reference

In the short span of a few pages you have already seen quite a bit of the JavaFX platform. Some other functionality that JavaFX offers includes:

Package Description
javafx.animation Animation and Interpolation
javafx.async Asynchronous Tasks and Futures
javafx.data.feed RSS/Atom Feed support
javafx.data.pull XML and JSON Pull Parsers
javafx.ext.swing Additional Swing-based Widgets
javafx.fxd Production Suite (FXD)
javafx.io Local Data Storage
javafx.reflect JavaFX Reflection Classes
javafx.chart Charting and Graphing
javafx.scene.media Media (Audio and Video) Playback
javafx.scene.shape Vector Shapes

An easy way to view and navigate the full JavaFX API is using the JFXplorer application. The following URL will launch it in as a web start application that you can use to start exploring the JavaFX API today:

http://jfxtras.org/samples/jfxplorer/JFXplorer.jnlp

Additional Resources

About The Author

Photo of Stephen Chin

Open-Source Developer and Agile Manager, Stephen Chin is founder of numerous opensource projects including WidgetFX and JFXtras and Senior Manager at Inovis in Emeryville, CA. He has been working with Java desktop and enterprise technologies for over a decade, and has a passion for improving development technologies and process. Stephen’s interest in Java technologies has lead him to start a Java and JavaFX focused blog and coauthor the upcoming Pro JavaFX Platform book together with Jim Weaver, Weiqi Gao, and Dean Iverson.

Stephen’s Blog:

http://steveonjava.com/

Jim Weaver’s JavaFX Learning Blog:

http://learnjavafx.typepad.com/

Recommended Book

ProJavaFX

Learn from bestselling JavaFX author Jim Weaver and expert JavaFX developers Weiqi Gao, Stephen Chin, and Dean Iverson to discover the highly anticipated JavaFX technology and platform that enables developers and designers to create RIAs that can run across diverse devices. Covering the JavaFX Script language, JavaFX Mobile, and development tools, Pro JavaFX™ Platform: Script, Desktop and Mobile RIA with Java™ Technology provides code examples that cover virtually every language and API feature.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Getting Started with BIRT

By Virgil Dodson

12,390 Downloads · Refcard 49 of 151 (see them all)

Download
FREE PDF


The Essential BIRT Cheat Sheet

Eclipse Business Intelligence and Reporting Tools (BIRT) is an open source, Eclipse-based reporting system that integrates with your Java/J2EE application to produce compelling reports. BIRT is the only top-level Eclipse project focused on business intelligence.This DZone Refcard provides an overview of the BIRT components focusing on a few key capabilities of the BIRT Designer, BIRT Runtime APIs, and BIRT Web Viewer. This Refcard should be interesting to report designers as well as developers or architects involved in integrating BIRT reports into applications.
HTML Preview
BIRT

Getting Started with BIRT

By Virgil Dodson

What Is Birt?

Eclipse Business Intelligence and Reporting Tools (BIRT) is an open source, Eclipse-based reporting system that integrates with your Java/J2EE application to produce compelling reports. BIRT is the only top-level Eclipse project focused on business intelligence. BIRT provides core reporting features such as report layout, data access and scripting. This Refcard provides an overview of the BIRT components focusing on a few key capabilities of the BIRT Designer, BIRT Runtime APIs, and BIRT Web Viewer. This Refcard should be interesting to report designers as well as developers or architects involved in integrating BIRT reports into applications.

Design and Runtime components

BIRT has two main components: a report designer based on Eclipse, and a runtime component that you can add to your application. The charting engine within BIRT can also be used by itself, allowing you to add charts to your application.

Birt Components

Getting birt

Open Source BIRT can be downloaded from http://download. eclipse.org/birt/downloads/ or http://www.birt-exchange. com. There are several different packages containing BIRT depending on your needs.

BIRT All-In-One
Download
The fastest way to get started designing BIRT reports on Windows.
Includes everything you need to start designing BIRT Reports,
including the full Eclipse SDK.
BIRT Framework This download allows you to add the BIRT plug-in to your existing
Eclipse environment. (Make sure you check the dependencies and
update those too.)
RCP Designer Simple to use rich client version of the BIRT Report Designer
dedicated to creating reports without the rest of the Eclipse
development environment.
BIRT Runtime Deployment components of the BIRT project including a command
line example, API examples, and example web viewer.
BIRT Web Tools Integration Contains the plug-ins required to use the BIRT Web Project Wizard
and the BIRT Viewer JSP tag library.

Hot Tip

You can also get BIRT into your existing Eclipse environment through the Eclipse Update Manager. Be sure to also select the Data Tools Project when using this approach.

BIRT report designers

BirtReport

The BIRT report designers are easy-to-use, visual report development tools that meet a comprehensive range of reporting requirements. The report designers include taskspecific editors, builders, and wizards that make it easy to create reports that can be integrated into web applications. All BIRT report designers support:

  • Component-based model for reuse
  • Ease of use features
  • Support for a wide range of reports, layouts and formatting
  • Programmatic control
  • Data access across multiple data sources

BIRT FILE TYPES

Design File
(*.rptdesign)
An XML file that contains the data connection infromation, report layout and instructions. Created when making a report in the BIRT Designer.
Template File
(*.rpttemplate)
Ensures all reports you create start with some common elements such as a company header or predefined syles. The starting point for a BIRT report.
Library File
(*.rtplibrary)
Stores commonly used report elements, such as a company logo, so they are managed in one place for all reports.
Report Document
(*.rtpdocument)
The completed report including layout instructions and data. Can be transformed into final report output, such as HTML, PDF, and XLS.

BIRT Data Sources

BIRT supports a variety of data sources and can be extended to support any data to which you have access. In addition to the list below, BIRT also ships with a connection to the ClassicModels sample database and can be easily extended to connect to your custom data source. BIRT also includes a Joint Data Set which allows you to join data across data sources.

Flat File Data Source Supports tab, comma, semicolon, and pipe delimited data
JDBC Data Source Supports connections to relational databases
Scripted Data Source Allows you to communicate with Java objects or to any data you can get from you application.
Web Services Data
Source
Supports connections to a web service. A wizard helps you point at a service through a WSDL and select the data
XML Data Source Supports data from XML

Palette of report items

label Use to include static (or localized) text within a report. Typically for report titles, column headers or any other report text.
text Use to include richly formatted text to your report, including the ability to integrate HTML formatting with your dynamic data.
DynamicText Use to integrate your static text with dynamic or conditional data.
data Use to include data from your connection in the report.
image Use to include images from various embedded sources or dynamic locations.
grid Use to define the layout of a report. Can be nested within other grids to support complex layouts.
list Use to display Data elements from your data source that repeat and creates a new report row for each daata set row. Can contain multiple levels of grouping.
table Use to display repeating data elements within your report and has support for multiple columns and multiple levels of grouping.
chart Use to add rich, interactive charting to your BIRT report.
Cross Tab Use to display grouped and dynamic data by both the row and column level.
aggregation Use to build totals for tables and groups. Includes over 30 built-in functions like COUNT, SUM, MAX, MIN, AVE, RUNNINGSUM, COUNTDISTINCT, and RANK.

Chart types

Bar Chart1 Side-by-Side Bar Charts show bars from each series
one beside the other. These bars are arranged so that
they each have the same width. The width of the bars
depends on the number of series being plotted.
Stacked Bar Charts show bars stacked one above the
other. The positive and negative values are stacked
separately above and below the origin.
Percent Stacked Bar Charts show bars stacked one
over the other in such a way that the total height of the
stacked bar (from its lowest to its highest) is 100%
Line Chart2 Overlay Line Charts show lines from each series
independent of the others. The lines are shown joining
the values for the series.
Stacked Line Charts show lines stacked one above
the other. The positive and negative values are stacked
separately above and below the origin.
Percent Stacked Line Charts show lines stacked one
over the other in such a way that the total height of the
stacked lines (from the lowest point to the highest in
each unit) is 100%
Area Chart3 Overlay Area Charts show areas from each series
independent of the others. The areas are shown
joining the values for the series.
Stacked Area Charts show areas stacked one above
the other. The positive and negative values are stacked
separately above and below the origin.
Percent Stacked Area Charts show areas stacked one
over the other in such a way that the total height of the
stacked areas (from the lowest point to the highest in
each unit) is 100%
Pie Chart4 Pie Charts show values as slices of a pie. The size of
each slice is proportional to the value it represents. Pie
charts for multiple series are plotted as multiple pies,
one for each series.
Meter Chart5 Standard Meter Charts contain a single dial with
region(s). The background of the dial can be divided
into regions with different colors.
Superimposed Meter Charts contain multiple dials
with identical regions. The dials overlap together so
that it can represent multiple needles within a single
region.
Scatter Chart6 Scatter Charts show the values arranged on the plot
using the category and value data as coordinates. Each
data value is indicated by a marker.
Stock Chart7 A Candlestick Stock Chart contains a box with lines
extending up and down from the ends. The upper and
lower edges of the box are the stock open and close
values. The upper and lower points of the line are the
high and low values.
A Bar-Stick Stock Chart contains a vertical line with
two horizontal lines sticking to it. The upper and lower
points of the vertical line are the stock open and close
values. The two horizontal lines are the high and low
values.
Bubble Chart8 Bubble Charts show the values arranged on the plot
using the category and value data as coordinates. Each
data value is indicated by a marker.
Difference Chart9 Difference Charts use two fills to represent the
positive and negative areas
Gantt Chart10 Standard Gantt Charts contain a connection line with
start and end markers.
Tube Chart1 Side-by-Side Tube Charts show tubes from each
series one beside the other. These tubes are arranged
so that they each have the same width. The width of
the tubes depends on the number of series being
plotted.
Stacked Tube Charts show tubes stacked one above
the other. The positive and negative values are stacked
separately above and below the origin.
Percent Stacked Tube Charts show tubes stacked
one over the other in such a way that the total height
of the stacked tube (from its lowest point to its highest)
is 100%
Cone Chart11 Side-by-Side Cone Charts show cones from each
series one beside the other. These cones are arranged
so that they each have the same width. The width of
the cones depends on the number of series being
plotted.
Stacked Cone Charts show cones stacked one above
the other. The positive and negative values are stacked
separately above and below the origin.
Percent Stacked Cone Charts show cones stacked
one over the other in such a way that the total height
of the stacked cone (from its lowest point to its highest)
is 100%
Pyramid Chart12 Side-by-Side Pyramid Charts show pyramids from
each series one beside the other. These pyramids are
arranged so that they each have the same width. The
width of the pyramids depends on the number of
series being plotted.
Stacked Pyramid Charts show pyramids stacked one
above the other. The positive and negative values are
stacked separately above and below the origin.
Percent Stacked Pyramid Charts show pyramids
stacked one over the other in such a way that the total
height of the stacked pyramid (from its lowest point to
its highest) is 100%

Hot Tip

Creating your first report:
  • Create a new Report Project from the category of Business Intelligence of Reporting Tools. Change to the Report Design perspective.
  • File -> New ->Report. Select the template called “My First Report” which launches a cheat sheet containing a step-by-step tutorial assisting you with connecting to data sources, creating data sets, and laying out your report.

Localization

BIRT supports internationalization of report data including support for bidirectional text. BIRT also supports the localization of static report elements within a report allowing you to replace report labels, table headers, and chart titles with localized text. BIRT uses resources files with name/value pairs and a *.properties file extension. For example, a file called MyLocalizedText_de.properties can include a line that says “welcomeMessage=Willkommen”. To use these files within a BIRT report:

Assign Resource File to entire report Report -> Properties -> Resources -> Resource File
Assign individual keys to a label Label -> Properties -> Localization -> Text key

Styles

Reports designed with the BIRT report designer can be richly formatted with styles that match your existing web application

Built-in Styles Built-in styles can be shared in a report library for managing style across multiple reports.
CSS Style Sheet BIRT can import CSS files at design time or reference existing CSS files at run time.

Report Parameters

A BIRT report can contain parameters that effect the report. Parameters can be supplied by the user or passed in programmatically from the application. Parameters can be bound to a data set query effectively filtering the report data. Parameters can also be used in expressions and scripting. For example, a parameter can be used with a visibility expression to hide a column or entire table. Available report parameter values can be supplied from a static list, dynamically created from a data set, or even cascading dynamic parameters. For example, selecting a Country presents the available States, and selecting a State presents the available Cities. Related parameters can be grouped for easier user navigation.

Parameter collection from the user can be in several forms:

Text Box Empty text area where the user can type the values desired
Combo/List Box A list of values is presented to the user. This list can be provided as a
static list or dynamically generated based on a data set query. multiple
values can be accepted.
Radio Button Provides boolean Yes/No, True/False, On/Off of parameters
Custom Parameters can be passed in programmatically so you can creae your
own web front end to collect the parameters from the user.

Customization wi th expressions, scripting and Events

BIRT includes out-of-the-box functionality that is available through drag-and-drop or by setting some properties, but also supports more advanced customizations through expressions, scripting, and events. The expression builder in BIRT allows you to do conditional report processing just about anywhere you need to instead of hard coding values. For example, the expression below will display the shipped date for orders that have already shipped, otherwise, it will display the order date.


if (dataSetRow[“STATUS”] == “Shipped”) {
  dataSetRow[“SHIPPEDDATE”];
} else {
  dataSetRow[“ORDERDATE”];
}

Scripting of a BIRT report can be done in either JavaScript or Java depending on your skill set and needs. Scripting allows you to circumvent the traditional event processing of the BIRT report. You can add scripting to report object, data source, and data element event types. Each of these event types has several events that you can overwrite.

For example, you can use scripting to navigate your Java objects and add them to a BIRT Data Set.


favoritesClass = new Packages.SimpleClass();
favorites = favoritesClass.readData();
…
var favrow = favorites.get(currentrow);
var Customer = favrow[0];
var Favorite = favrow[1];
var Color = favrow[2];
row[“Customer”]=Customer;
row[“Favorite”]=Favorite;
row[“Color”]=Color;

Use scripting to change bar colors on a chart based on plotted data.


if (dph.getOrthogonalValue() < 1000) {
  fill.set(255,0,0); //red
} else if (dph.getOrthogonalValue() < 5000) {
  fill.set(255,255,0); //yellow
} else {
  fill.set(0,255,0); //green
}

Use scripting to add or drop a report table based on a user parameter.


if (params[“showOrders”] == false){
  reportContext.getReportRunnable().designHandle.getDesignHandle()
    .findElement(“table1”).drop();
}

Or use scripting to include dynamic images that are based on the report data.


if (row[“CREDITLIMIT”] <= 0) {
“down.jpg”
} else {
“up.jpg”
}

Report deployment options

Once you create your report designs, there are several different ways to generate the report output. Obviously, you can run these reports directly from the BIRT Designer, but you can also run BIRT reports from the command line, generate BIRT reports from you Java application using the BIRT APIs, integrate and customize the example web viewer, or deploy your reports with third-party components and report servers.

APIs

BIRT supplies several APIs and an example J2EE application for generating and viewing reports. The major APIs are the Design Engine API(DE API), Report Engine API(RE API) and the Chart Engine API (CE API). In addition to the APIs, BIRT supports scripting using either Java or JavaScript within report designs.

Design Engine API(DE API) Use the Design Engine API (DE API) to create a custom report designer tool, or to explore or modify BIRT report designs. The BIRT Designer uses this API. You can call this API within a BIRT script to modify the currently running report design.
Report Engine API(RE API) Use the Report Engine API to run BIRT reports directly from Java code or to create a custom web application front end for BIRT.
Chart Engine API(CE API) Use the Chart Engine API to create and render charts apart from BIRT.

Birt report engine tasks

There are several tasks supplied by the Report Engine API that can be used to generate report output. A few key tasks are listed below.

IRunAndRenderTask Use this task to run a report and create the output directly to one of the supported output formats. This task does not create a report document.
IRunTask Use this task to run a report and generate a report document, which is saved to disk.
IGetParameterDefinitionTask Use this task to obtain information about parameters and their default values.
IDataExtractionTask Use this task to extract data from a report document. The BIRT viewer uses this class to extract report data into CSV format.

World ’s Simplest birt engine example


static void executeReport() throws EngineException
{
  IReportEngine engine=null;
  EngineConfig config = null;
try{
  // start up Platform
  config = new EngineConfig( );
  config.setBIRTHome(“C:\\BIRT_231\\birt-runtime-2_3_1\\
  ReportEngine”);
  config.setLogConfig(“C:\\BIRT_231\\logs”, java.util.logging.Level.
  FINEST);
  Platform.startup( config );
  // create new Report Engine
  IReportEngineFactory factory = (IReportEngineFactory) Platform
  .createFactoryObject( IReportEngineFactory.EXTENSION_REPORT_
  ENGINE_FACTORY );
  engine = factory.createReportEngine( config );
  // open the report design
  IReportRunnable design = null;
  design = engine.openReportDesign(“C:\\BIRT_231\\designs\\param
  .rptdesign”);
  // create RunandRender Task
  IRunAndRenderTask task = engine.createRunAndRenderTask(design);
  // pass necessary parameters
  task.setParameterValue(“ordParam”, (new Integer(10101)));
  task.validateParameters();
  // set render options including output type
  PDFRenderOption options = new PDFRenderOption();
  options.setOutputFileName(“my_report.pdf”);
  options.setOutputFormat(“pdf”);
  task.setRenderOption(options);
  // run task
  task.run();
  task.close();
  engine.destroy();
}catch( Exception ex){
	ex.printStackTrace();
}
finally
{
  Platform.shutdown( );
}


Hot Tip

If you are deploying the BIRT Engine within an RCP application you should NOT set the BIRT Home variable or execute the Platform.startup() method.

WEb Viewer

Web Viewer

The BIRT WebViewer is an example application that illustrates generating and rendering BIRT report output in a web application. This viewer demonstrates report pagination, an integrated table of contents, report export to several formats, and printing to local and server side printers.

The BIRT Web Viewer can be used in a variety of ways:

Stand-alone Use as a pre-built web application for running and viewing reports.
Modify Viewer Source Use as a starter web application that you can customize to your needs.
RCP Application Use as a plug-in for your existing RCP application.
Integrated with existing web application The viewer can be integrated with URLs or BIRT JSP tag library.

The BIRT Web Viewer consists of two main Servlets, the ViewerServlet and the BirtEngineServlet. These Servlets handle three mappings: (/frameset, /run, and /preview).

/frameset Renders the report in the full AJAX viewer, complete with toolbar, navigation bar
and table of contents features. This mapping also generates an intermediate
report document from the report design file to support the AJAX based features.
For example.
http://localhost:8080viewer/frameset?_report=myreport .rptdesign&parm1=value
/run Runs and renders the report but does not create a report document. This
mapping does not supply HTML pagination, TOC or toolbar features, but does
use the AJAX framework to collect parameters, support report cancelling and
retrieve the report output in HTML format. For example.
http://localhost:8080/viewer/run?_report=myreport.rptdesign&parm1=value)
/preview Runs and renders the report but does not generate a report document, although
an existing report document can be used; in this case, just the render operation
occurs. The output from the run and render operation is sent directly to the
browser. For example
http://localhost:8080/viewer/prevew?_report=myreport.rptdesign&parm1=value)

Viewer URL Parameters

Below are a few of the key URL parameters available for the viewer. These parameters can be used along with the Servlet mappings, such as, run, frameset, and preview, listed in the Web Viewer section.

Attribute Description
__id Unique identifier for the viewer.
__title Sets the report file.
__showtitle Determines if the report title is shown in the frameset viewer. Defaults to true. Valid values are true and false.
__toolbar Determines if the report toolbar is shown in the frameset viewer. Defaults to true. Valid values are true and false.
__navigationbar Determines if the navigation bar is shown in the framset viewer. Defaults to true. Valid values are true and false.
__parameterpage Determines if the parameter page is displayed. By default, the frameset, run, and preview mappings automatically determine if the parameter page is required. This setting overrides this behavior. Valid values are true and false.
__report Sets the name of the report design to process. This setting can be absolute path or relative to the working folder.
__document Sets the name for the rptdocument. The document is created when the report engine separates run and render tasks, and is used to support features like table of contents and pagination. This setting can be an absolute path or relative to the working folder.
__format Specifies the desired output format, such as pdf, html, doc, ppt, or xls.
__Locale Specifies the locale for the specific operation. Note that this setting overrides the default locale.
__page Specifies page to render.
__pagerange Specifies page range to render such as, 1-4, 7.
__bookmark Specifies a bookmark in the report to load. The viewer automatically loads the appropriate page.

Viewer Web.xml settings

The BIRT Web Viewer has several configuration options. These settings can be configured by modifying the web.xml file located in the WebViewerExample/WEB-INF folder. Below are a few of the key settings available for the viewer.

Attribute Description
BIRT_VIEWER
_LOCALE
This setting sets the default locale for the Web Viewer.
BIRT_VIEWER
_WORKING
_FOLDER
This is the default location for report designs. If the report design specified
in a URL parameter is relative, this path is pre-pended to the report name.
BIRT_VIEWER
_DOCUMENT
_FOLDER
If the __document parameter is not used, a report document is generated
in this location. If this setting is left blank, the default value, webapp/
documents, is used. If the__document URL parameter is used and the value
is relative, the report document is created in the working folder.
BIRT_VIEWER
_IMAGE_DIR
Specifies the default location to store temporary images generated by the
report engine. If this setting is left blank, the default location of webapp/
report/images is used.
BIRT_VIEWER
_LOG_DIR
Specifies the default location to store report engine log files. If this setting
is left blank, the default location of webapp/logs is used.
BIRT_VIEWER
_LOG_LEVEL
Sets the report engine log level. Valid values are:
OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, and FINEST.
BIRT_VIEWER
_SCRIPTLIB_DIR
Specifies the default location to place JAR files used by the script engine
or JARs containing Java event handlers. These JARs are appended to the
classpath. If this setting is left blank the default value of webapp/scriptlib
will be used.
BIRT_
RESOURCE_
PATH
This setting specifies the resource path used by report engine. The
resource path is used to search for libraries, images, and properties files
used by a report. If this setting is left blank, resources are searched for in
BIRT_VIEWER
_MAX_ROWS
Specifies the maximum number of rows to retrieve from a dataset
BIRT_VIEWER
_PRINT
_SERVERSIDE
This setting specifies whether server side printing is supported. If
set to OFF the toolbar icon used for server side printing is removed
automatically. Valid values are ON and OFF.

Viewer JSP Tag library

The BIRT Web Viewer includes a set of tags to make it easy to integrate BIRT reports into browser pages. These tags are available from the BIRT Web Tools Integration download. Below are a few the key JSP tags and a description of their usage.

Tag Description
viewer Displays the complete Viewer inside an IFRAME. This tag allows you to use frameset and run Servlet mappings. The AJAX Framework is used.
report Displays the report inside an IFRAME or DIV tag without the Viewer. This tag allows you to use preview mapping and does not create an rptdocument. The AJAX Framework is not used.
param Used to set parameter values when using the viewer or report tags. This tag must be nested within the viewer or report tag.
value Used to specify multiple values for a given param tag.
parameterPage Used to launch the BIRT parameter dialog or to create a customized parameter entry page. This tag can be used with the frameset, run, or preview mappings to launch the viewer after the parameters are entered.
paramDef Used within a parameterPage tag to retrieve pre-generated HTML for specific parameter control types such as radio, checkbox, dynamic or cascaded parameters

Simple viewer jsp tag example


<%@ taglib uri=”/birt.tld” prefix=”birt” %>
…
<birt:viewer
id=”birtViewer” pattern=”preview”
reportDesign=”TopNPercent.rptdesign”
height=”600” width=”800”
format=”html”
title=”My Viewer Tag”
isHostPage=”false”
showTitle=”true” showToolBar=”true”
showNavigationBar=”true”
showParameterPage=”true”>
</birt:viewer> 

BIRT REPORT OUTPUT FORMATS

In addition to delivering paginated report content to a web browser, BIRT also supports several other output formats. These formats listed below are support by both the Report Engine API as well as the BIRT Web Viewer.

Paginated web output An example web viewer is included with BIRT allowing for on demand paginated web output.
DOC Microsoft Word Document.
HTML Suitable for creating HTML pages of report data deployable to any server.
PDF Adobe PDF output suitable for emailing or printing.
Postscript Output can be directed to a printer that supports postscript.
PPT Powerpoint output.
XLS Excel file output.

Birt extension points

The APIs in BIRT define extension points that let the developer add custom functionality to the BIRT framework. These extensions can be in the form of custom data sources, report items, chart types, output formats, and functions. Once implemented, these custom extensions will show along with the built-in types. For example, you can create a custom report item, like a rotated text label, that will show up in the BIRT Palette along with the existing items.

Data Sources BIRT supports the Open Data Access (ODA) architecture, which means it can be extended to support custom data sources.
Functions BIRT allows you to create custom functions that extend those available in BIRT Expressions.
Report Items Report Items can be extended, allowing you to create your own custom report item.
Chart Types Additional chart types can be added to BIRT as plug-ins.
Output Emitters BIRT can be extended to include your own custom output type. For example, a simple CSV emitter exists and can be added to BIRT.

Additional Birt resources

Eclipse BIRT Project Site http://www.eclipse.org/birt
BIRT Exchange Community Site http://www.birt-exchange.com
Submitting/Searching BIRT Bugs http://bugs.eclipse.org/bugs/enter_bug.cgi?product=BIRT
Online BIRT Documentation http://www.birt-exchange.com/modules/documentation/

About The Author

Photo of author Virgil Dodson

Virgil Dodson

Virgil Dodson is a Developer Evangelist at Actuate Corporation and blogger/forum moderator at the BIRT Exchange community site. Virgil has over 13 years experience as a software developer. For the past 6 years he has helped Java developers get started with Actuate’s embedded reporting products. He holds a Bachelor of Science degree in Computer Information Systems from DeVry.

Recommended Book

Birt

Topics Discussed Include: Installing and deploying BIRT Deploying a BIRT report to an application server Understanding BIRT architecture Scripting in a BIRT report design Integrating BIRT functionality in applications Working with the BIRT extension framework


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Flex & Spring Integration

By Jon Rose and James Ward

14,378 Downloads · Refcard 48 of 151 (see them all)

Download
FREE PDF


The Essential Flex & Spring Integration Cheat Sheet

Adobe Flex Software is a popular framework for building Rich Internet Applications (RIAs). The Flex framework is used to create SWF files that run inside Flash Player. This DZone Refcard shows you how to integrate Flex and Spring to create a powerful platform for building robust RIAs. It starts off by showing you how to set up a server-side Java project with BlazeDS and the Spring Framework. After configuring your project with a basic Spring bean for use in BlazeDS, you’ll write your Flex application to use the Spring/BlazeDS service.
HTML Preview
Flex & Spring Integration

Flex & Spring Integration

By Jon Rose and James Ward

ABOUT Adobe Flex

Adobe Flex Software is a popular framework for building Rich Internet Applications (RIAs). The Flex framework is used to create SWF files that run inside Flash® Player. The framework was built for use by developers and follows traditional application development paradigms rather than the timelinebased development found in the Flash Professional authoring tools. Applications are built using the Flex Builder IDE™ - an Eclipse-based development environment. ActionScript® 3 is used to access data and build user interface components for web and desktop applications that run inside Flash Player or Adobe AIR® Software. The Flex Framework also uses a declarative XML language called MXML to simplify Flex development and layout.

ABOUT Spring

The Spring Framework is one of the most popular ways to build enterprise Java applications. Unlike traditional Java EE development, Spring provides developers a full featured “lightweight container,” that makes applications easy to test and develop. Although Spring is best known for its dependency injection features, it also provides features for implementing typical server-side enterprise applications, such as declarative security and transaction management.

WHy Flex and Spring?

Adobe Flex has strong ties to Java, which include an Eclipsebased IDE and BlazeDS, its open source server-based Java remoting and web messaging technology. In addition, most enterprise projects that use Flex build on a Java back end. With Flex and Java so often married together, it is only natural to want to integrate Flex with Spring-based Java back ends. Beyond greenfield development, many organizations want to revamp or replace the user interface of existing enterprise Spring applications using Flex. In late 2008, the Spring community recognized these cases and began working on the Spring BlazeDS Integration project to add support for Flex development with Java and Spring.

By default BlazeDS creates instances of server-side Java objects and uses them to fulfill remote object requests. This approach doesn’t work with Spring, as the framework is built around injecting the service beans through the Spring container. The Spring integration with BlazeDS allows you to configure Spring beans as BlazeDS destinations for use as remote objects in Flex.

Integrating Flex and spring

This Refcard assumes that you are already familiar with Spring and Flex. If you need an introduction or refresher to either, check out the Very First Steps in Flex and/or Spring Configuration DZone Refcardz.

To use BlazeDS, the server-side application could be any Java application that deploys as a WAR file. This Refcard uses the Eclipse IDE to create and edit the Java project. This Refcard walks you through the following steps:

  • Set up a server-side Java project with BlazeDS and the Spring Framework
  • Configure the Java project with a basic Spring bean for use in BlazeDS
  • Write Flex application to use the Spring/BlazeDS service

Hot Tip

BlazeDS provides simple two-way communication with Java back-ends. Adobe Flash Player supports a serialization protocol called AMF that alleviates the bottlenecks of text-based protocols and provides a simpler way to communicate with servers. AMF is a binary protocol for exchanging data that can be used over HTTP in place of text-based protocols that transmit XML. Applications using AMF can eliminate an unnecessary data abstraction layer and communicate more efficiently with servers. To see a demonstration of the performance advantages of AMF, see the Census RIA Benchmark at: http://www.jamesward.org/census.The specification for AMF is publicly available, and numerous implementations of AMF exist in a variety of technologies including Java, .Net, PHP, Python, and Ruby.

Hot Tip

The open source BlazeDS project includes a Java implementation of AMF that is used for remotely communicating with server-side Java objects as well as for a publish/subscribe messaging system. The BlazeDS remoting technology allows developers to easily call methods on Plain Old Java Objects (POJOs), Spring services, or EJBs. Developers can use the messaging system to send messages from the client to the server, or from the server to the client. BlazeDS can also be linked to other messaging systems such as JMS or ActiveMQ. Because the remoting and messaging technologies use AMF over HTTP, they gain the performance benefits of AMF as well as the simplicity of fewer data abstraction layers. BlazeDS works with a wide range of Javabased application servers, including Tomcat, WebSphere, WebLogic, JBoss, and ColdFusion.

To follow along with this tutorial you will need:

First, set up the server-side Java web project in Eclipse by creating a web application from the blazeds.war file (found inside the blazeds zip file).

  • Import the Blazeds.war file to create the project:
    • Choose File > Import
    • Select the WAR file option. Specify the location of the blazeds.war file. For the name of the web project, type dzone-server
    • Click Finish

Now you can create a server that will run the application:

  • Select File > New > Other
  • Select Server > Server
  • Click Next
  • Select Apache > Tomcat v6.0Server
  • Click Next
  • Specify the location where Tomcat is installed and select the JRE (version 5 or higher) to use
  • Click Next
  • Select dzone-server in the Available Projects list
  • Click Add to add it to the Configured Projects list
  • Click Finish

Next, in the dzone-server project create the basic Java classes to be used by BlazeDS and Spring:


public class MyEntity {
  private String firstName;
  private String lastName;
  private String emailAddress;
  public String getFirstName() {
   return firstName;
  }
public void setFirstName(String firstName) {
  this.firstName = firstName;
  }
public String getLastName() {
  return lastName;
  }
public void setLastName(String lastName) {
  this.lastName = lastName;
  }
public String getEmailAddress() {
  return emailAddress;
  }
public void setEmailAddress(String emailAddress) {
  this.emailAddress = emailAddress;
  }
}

Listing 1: Java entity to be passed between Java and Flex


import java.util.List;
public interface MyService {
  public List<MyEntity> getMyEntities();
}

Listing 2: Java Service Interface


import java.util.ArrayList;
import java.util.List;
public class MyServiceImpl implements MyService {
  public List<MyEntity> getMyEntities() {
   List<MyEntity> list = new ArrayList<MyEntity>();
   MyEntity entity = new MyEntity();
   entity.setFirstName(“Hello”);
   entity.setLastName(“World”);
   entity.setEmailAddress(“hello@world.com”);
   list.add(entity);
   MyEntity entity2 = new MyEntity();
   entity2.setFirstName(“Hello”);
   entity2.setLastName(“Space”);
   entity2.setEmailAddress(“hello@space.com”);
   list.add(entity2);
   MyEntity entity3 = new MyEntity();
   entity3.setFirstName(“Hello”);
   entity3.setLastName(“Neighbor”);
   entity3.setEmailAddress(“hello@neighbor.com”);
   list.add(entity3);
   return list;
  }
}

Listing 3: Java Example Service Implementation

Listings 1, 2, and 3 are very basic Java classes that you’ll use as examples for this tutorial. In a real-world application, the service implementation would likely connect to one or more enterprise services for data, such as a relational database. In this case, it simply returns a hard-coded set of entities as an ArrayList.

The basic Java web project with the BlazeDS dependencies is now complete.

Next, configure the Java project with a basic Spring bean for the MyService interface:

  • Copy the Spring libraries, the Spring BlazeDS Integration Library, and the ANTLR library to the project dzoneserver/ WebContent/WEB-INF/lib directory
  • Create a basic Spring Configuration File:
    • Right Click WebContent/WEB-INF and then choose New > File
    • For the file name, type application-config.xml
    • Click Finish
    • Copy and paste the text from Listing 4 into the file

<?xml version=”1.0” encoding=”UTF-8”?>
 <beans xmlns=”http://www.springframework.org/schema/beans”
 xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
 xsi:schemaLocation=”
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd”>
 <!-- Spring Beans’s -->
 <bean id=”myService” class=”MyServiceImpl” />
</beans>

Listing 4: Basic Spring Configuration

Those familiar with Spring should recognize this as a basic Spring configuration for creating a simple bean from the MyServiceImpl class. Later in this tutorial you will be using this bean through BlazeDS.

At this point, you have a basic Java web project with a default BlazeDS configuration. Now, you’ll change the default BlazeDS configuration to use the newly created Spring bean.

To begin configuring Spring BlazeDS Integration, update the web.xml file by removing the default BlazeDS configuration and replacing it with the code from Listing 5.


<>?xml version=”1.0” encoding=”UTF-8”?>
<>web-app>
 <>display-name>dzone-server<>/display-name>
 <>servlet>
   <>servlet-name>Spring MVC Dispatcher Servlet<>/servlet-name>
   <>servlet-class>
   org.springframework.web.servlet.DispatcherServlet
   <>/servlet-class>
   <>init-param>
    <>param-name>contextConfigLocation<>/param-name>
    <>param-value>/WEB-INF/application-config.xml<>/param-value>
   <>/init-param>
   <>load-on-startup>1<>/load-on-startup>
  <>/servlet>
  <>!-- Map /spring/* requests to the DispatcherServlet -->
  <>servlet-mapping>
   <>servlet-name>Spring MVC Dispatcher Servlet<>/servlet-name>
   <>url-pattern>/spring/*<>/url-pattern>
  <>/servlet-mapping>
<>/web-app>

Listing 5: web.xml

The web.xml contents in Listing 5 create a servlet filter from Spring that will process all BlazeDS requests at: http://localhost:8080/dzone-server/spring This will be the base URL for accessing the BlazeDS endpoint. Also, you should notice that this is a standard DispatcherServlet for Spring.

Now that you have Spring wired into the Java web application, you will update the basic Spring configuration from Listing 4 so that it will work with BlazeDS. Add the highlighted section from Listing 6 to your application-config.xml file.


<?xml version=”1.0” encoding=”UTF-8”?>
<beans xmlns=”http://www.springframework.org/schema/beans”
 xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
 xmlns:flex=”http://www.springframework.org/schema/flex”
 xsi:schemaLocation=”
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/flex
 http://www.springframework.org/schema/flex/spring-flex-1.0.xsd”>
 <!-- Spring Beans’s -->
 <bean id=”myService” class=”MyServiceImpl” />
 <!-- Simplest possible message broker -->
 <flex:message-broker />


 <!-- exposes myService as BlazeDS destination -->
 <flex:remote-service ref=”myService” />
</beans>

Listing 6: Advanced Spring Configuration for BlazeDS

Listing 6 exposes the MyServiceImpl class as a BlazeDS destination. First, the Flex® namespace is added to the configuration. Note that the XSD will not be published from Spring until the final 1.0 release, and until then you will have to add it manually to your XML catalog. With the Flex namespace added, the configuration uses the messagebroker tag to create the MessageBrokerFactoryBean. Since there is no additional configuration information provided, the MessageBroker will be created with “sensible defaults,” assuming that the service-config.xml is in WEB-INF/flex/ services-config.xml. The remote-service tag creates a destination from existing Spring beans.

Hot Tip

In Spring BlazeDS Integration release 1.0.0M2, the standard BlazeDS configuration file (servicesconfig. xml) is still used for configuration of the communication channels.

Next, update the default BlazeDS services-config.xml file (found in the WebContent/WEB-INF/flex folder) to reflect the Spring URL defined in the web.xml file. Replace the contents of the file with the code in Listing 7.


<?xml version=”1.0” encoding=”UTF-8”?>
  <services-config>
   <services>
    <default-channels>
     <channel ref=”my-amf”/>
   </default-channels>
  </services>
 <channels>
<channel-definition id=”my-amf”
class=”mx.messaging.channels.AMFChannel”>
  <endpoint
   url=”http://{server.name}:{server.port}/{context.root}/spring/
    messagebroker/amf”
   class=”flex.messaging.endpoints.AMFEndpoint”/>
  </channel-definition>
 <channel-definition id=”my-polling-amf”
class=”mx.messaging.channels.AMFChannel”>
<endpoint
  url=”http://{server.name}:{server.port}/{context.root}/spring/
   messagebroker/amfpolling”
    class=”flex.messaging.endpoints.AMFEndpoint”/>
     <properties>
    <polling-enabled>true</polling-enabled>
  <polling-interval-seconds>4</polling-interval-seconds>
 </properties>
</channel-definition>
</channels>
</services-config>

Listing 7: Update channel definition in services-config.xml

Note that the endpoint URL for the my-amf and my-polling-amf channels in Listing 7 include “spring” after the context.root parameter. This is the only configuration change you need to make in the BlazeDS default configuration files. All the remote destinations are configured in the Spring application-config. xml file.

You are now done configuring the server-side Spring / BlazeDS Java application. You may want to start up the Tomcat server to verify that your configuration is correct.

Now you can build the Flex application to use the Spring service remotely. Follow these steps to create the Flex project:

  • Select File > New > Other
  • In the Select A Wizard dialog box, select Flex Project
  • In the New Flex Project box, type in a project name: dzone-flex
  • Use the default location (which will already be checked)
  • Select Web Application (Runs In Flash Player)
  • Select None as the Application Server Type
  • Click Next
  • Specify the Output folder to be the location of the dzoneserver’s WebContent directory such as: C:\workspace\dzone-server\WebContent\
  • Click Finish

Your project will open in the MXML code editor and you’ll see a file titled main.mxml. Open the file and add the Flex® application code from Listing 8. This code accesses the MyServiceImpl class in Java and returns the results to Flex.


<?xml version=”1.0” encoding=”utf-8”?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
   creationComplete=”srv.getMyEntities()”>
  <mx:AMFChannel id=”myamf”
uri=”/dzone-server/spring/messagebroker/amf”/>
  <mx:ChannelSet id=”channelSet” channels=”{[myamf]}”/>
 <mx:RemoteObject id=”srv”
  destination=”myService” channelSet=”{channelSet}”/>
 <mx:DataGrid dataProvider=”{srv.getMyEntities.lastResult}”/>
</mx:Application>

Listing 8: Final main.mxml source file for accessing the Spring service

The code in Listing 8 sets up the AMFChannel for accessing the Spring service. Note that the destination “flexMyService” is the same as the bean you defined in the application-config. xml Spring configuration file. Also, you might have noticed that none of the Flex code contains anything specific to Spring. The Flex code doesn’t have to change, as the client code has no knowledge of the fact that Spring is being used on the server.

To get the dzone-server to update the deployed web application you may need to right-click the dzone-server project and select Refresh.

With all steps of the tutorial completed, you can start the Tomcat server in Eclipse and access the application at the following URL: http://localhost:8080/dzone-server/main.html

Running Application

Figure 1: The running application

To allow the Flex application to be launched in Run or Debug mode from Eclipse:

  • Right-click the dzone-flex project
  • Select Properties, then Flex Build Path
  • For the Output Folder URL, type http://localhost:8080/dzone-server/
  • Click OK to update the project properties

Now you can right-click the main.mxml file and select Run As > Flex Application or Debug As > Flex Application.

The running application displays the data that was hard coded in the MyServiceImpl Java class, as seen in Figure 1. Now you have a complete sample application using Spring, BlazeDS, and Flex

User Authentication

One of the benefits of using Spring is that it provides support for many common enterprise requirements, including security. In this section, you’ll expand on the basic application by using Spring Security to protect the service channel with role-based authentication.

To add security to the application you will need to download the following dependencies:

Then add the following files to the WEB-INF/lib directory in the dzone-server project:

  • cglib-2.2.jar
  • aspectjrt.jar (located in the aspectj.jar file)
  • asm-3.1.jar
  • asm-commons-3.1.jar
  • spring-security-acl-2.0.4.jar
  • spring-security-core-2.0.4.jar
  • spring-security-core-tiger-2.0.4.jar

<beans:beans xmlns=”http://www.springframework.org/schema/security”
 xmlns:beans=”http://www.springframework.org/schema/beans”
 xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
 xsi:schemaLocation=”
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
 http://www.springframework.org/schema/security
 http://www.springframework.org/schema/security/spring-security-
 2.0.4.xsd”>
<http auto-config=”true” session-fixation-protection=”none”/>
 <authentication-provider>
  <user-service>
   <user name=”jeremy” password=”atlanta”
  authorities=”ROLE_USER, ROLE_ADMIN” />
 <user name=”keith” password=”melbourne”
authorities=”ROLE_USER” />
</user-service>
</authentication-provider>
</beans:beans>

Listing 9: application-Context-security.xml Spring Security Configuration File

The first step is to create a very basic Spring Security configuration file. This example will use hard-coded credentials, however in a real application a database or LDAP server will likely be the source of the credentials. These methods of authentication can be easily configured with Spring Security. To learn more about Spring Security and how to add more advanced configurations, see the project home page at: http://static.springframework.org/spring-security/site/

To create a basic Spring Security Configuration File:

  • Right-click WebContent/WEB-INF and then choose New > File
  • For the file name, type applicationContext-security.xml
  • Click Finish
  • Copy the code from Listing 9 to the file

This configuration allows the user to authenticate through the Blaze DZ channel. Add the security configuration to the Spring configuration in the web.xml by updating the contextConfigLocation param-value as shown in Listing 10.


<servlet>
 <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</
  servlet-class>
 <init-param>
  <param-name>contextConfigLocation
  <param-value>
     /WEB-INF/application-config.xml
     /WEB-INF/applicationContext-security.xml
   </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

Listing 10: web.xml File with Security Configuration Added

At this point, you need to update the Spring configuration file to secure the getMyEntities method on myService. To do this update the application-config.xml file with the code in Listing 11.


<?xml version=”1.0” encoding=”UTF-8”?>
<beans xmlns=”http://www.springframework.org/schema/beans”
  xmlns:flex=”http://www.springframework.org/schema/flex”
  xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  xmlns:security=”http://www.springframework.org/schema/security”
  xsi:schemaLocation=”
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/flex
  http://www.springframework.org/schema/flex/spring-flex-1.0.xsd
  http://www.springframework.org/schema/security
  http://www.springframework.org/schema/security/spring-security-
2.0.4.xsd
  “>
  <flex:message-broker>
   <flex:secured />
  </flex:message-broker>
  <bean id=”myService” class=”MyServiceImpl”>
   <flex:remote-service/>
   <security:intercept-methods>
   <security:protect method=”getMyEntities” access=”ROLE_USER” />
  </security:intercept-methods>
 </bean>
</beans>

Listing 11: Updated application-config.xml Spring configuration file

If you run the Flex® application at this point, the getMyEntities service call will fail because the user is not authenticated.

Now that the server is configured to protect the service, you will update the Flex application to require the user to authenticate before loading data from the getMyEntities service method. The updated code shown in Listing 12 presents users with a login form (See Figure 2) until they are successfully authenticated. Once the user is authenticated, the view state is updated showing the DataGrid bound to the service results, and the service method is called.

Update the main.mxml page with the code in Listing 12. You can then run the application and login with one of the hard-coded username and password combinations from the applicationContext-security.xml configuration file.


<?xml version=”1.0” encoding=”utf-8”?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”>
<mx:Script>
  import mx.rpc.events.ResultEvent;
  import mx.rpc.events.FaultEvent;
  import mx.rpc.AsyncToken;
  import mx.rpc.AsyncResponder;
private function login():void {
var token:AsyncToken = channelSet.login(username.text, password.
text);
token.addResponder(new AsyncResponder(loginResult, loginFault));
}
private function loginResult(event:ResultEvent,
token:AsyncToken):void {
   //get data
   srv.getMyEntities();
   //change state
   currentState = “userAuthenticated”;
 }
 private function loginFault(event:FaultEvent, token:AsyncToken):void
{
invalidLogin = true;
}
</mx:Script>
<mx:AMFChannel id=”myamf”
uri=”/dzone-server/spring/messagebroker/amf”/>
<mx:ChannelSet id=”channelSet” channels=”{[myamf]}”/>
<mx:RemoteObject id=”srv”
destination=”myService” channelSet=”{channelSet}”/>
<mx:Boolean id=”invalidLogin”>false
<!-- Login Form -->
<mx:Panel id=”loginPanel” title=”Login Form”>
<mx:Label text=”Invalid username or password”
includeInLayout=”{invalidLogin}” visible=”{invalidLogin}” />
  <mx:Form defaultButton=”{loginButton}”>
   <mx:FormItem width=”100%” label=”Username”>
    <mx:TextInput id=”username”/>
   </mx:FormItem>
  <mx:FormItem width=”100%” label=”Password”>
 <mx:TextInput id=”password” displayAsPassword=”true” />
  </mx:FormItem>
    </mx:Form>
     <mx:ControlBar>
    <mx:Button id=”loginButton” label=”Login” click=”login()”/>
   </mx:ControlBar>
  </mx:Panel>
<mx:states>
 <mx:State name=”userAuthenticated”>
   <mx:RemoveChild target=”{loginPanel}” />
    <mx:AddChild>
   <mx:DataGrid dataProvider=”{srv.getMyEntities.lastResult}” />
  </mx:AddChild>
</mx:State>
</mx:states>
</mx:Application>

Listing 12: Update Flex Application

The Flex code in Listing 12 is very basic. It presents the user with the loginPanel until loginResult() is invoked by a successful login. The username and password parameters come from a login form and are passed to the channelSet’s login() method. On a successful login, the loginResult() handler function is called, and the post-login logic is invoked. In this case, the currentState is updated to userAuthenticated, which removes the login form and adds the DataGrid bound to the service call’s results. In addition, the getMyEntities service method is called to load the data.

Login Form

Now, you have a basic Flex®, Spring, and BlazeDS application protected with authentication.

Conclusion

In this Refcard, you first created a Spring bean that was exposed to the Flex client through BlazeDS using Spring BlazeDS Integration. Next, you secured your service by adding Spring Security, and basic Flex authentication. As you can see, the new Spring BlazeDS Integration project makes integrating Flex and Spring easy and straightforward. The combination of the two technologies creates a powerful platform for building robust RIAs. You can learn more about integrating Flex and Spring on the Spring BlazeDS Integration project site: http://www.adobe.com/devnet/flex/flex_java.html

About The Author

Photo of author Jon Rose

Jon Rose

Jon Rose is the Flex Practice Director for Gorilla Logic, an enterprise software consulting company located in Boulder, Colorado. He is an editor and contributor to InfoQ.com, an enterprise software community. Visit his website at: www.ectropic.com

Gorilla Logic, Inc. provides enterprise Flex and Java consulting services tailored to businesses in all industries. www.gorillalogic.com

Photo of author James Ward

James Ward

James Ward is a Technical Evangelist for Flex at Adobe. He travels the globe speaking at conferences and teaching developers how to build better software with Flex. Visit his websit at: www.jamesward.com

First Steps in Flex, co-authored by James, will give you just enough information, and just the right information, to get you started learning Flex--enough so that you feel confident in taking you own steps once you finish the book. For more information visit: http://www.firststepsinflex.com

Recommended Book

First Steps in Flex

First Steps in Flex will take you through your first steps on your way to becoming a powerful user interface programmer.

We’ve gone to great lengths to show you the world of Flex without burying you in information you don’t need right now. At the same time, we give pointers to places where you can go to explore more.

First Steps in Flex is the ideal starting point for any programmer who wants to quickly become proficient in Flex 3.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Vaadin

A Familiar Way to Build Web Apps with Java

By Marko Grönroos

12,585 Downloads · Refcard 85 of 151 (see them all)

Download
FREE PDF


The Essential Vaadin Cheat Sheet

Vaadin is a server-side Ajax web application development framework that allows you to build web applications just as you would with traditional desktop frameworks, such as AWT or Swing. An application is built from user interface components contained hierarchically in layout components. In the server-driven model, the application code runs on a server, which the actual user interaction is handled by a client-side engine running in the browser. This DZone Refcard will cover how to create an application, components, themes, data binding, and more.
HTML Preview
Getting Started with Vaadin

Vaadin: A Familiar Way to Build Web Apps with Java

By Marko Grnroos

ABOUT VAADIN

Vaadin is a server-side Ajax web application development framework that allows you to build web applications just like with traditional desktop frameworks, such as AWT or Swing. An application is built from user interface components contained hierarchically in layout components.

In the server-driven model, the application code runs on a server, while the actual user interaction is handled by a client-side engine running in the browser. The client-server communications and any client-side technologies, such as HTML and JavaScript, are invisible to the developer. As the client-side engine runs as JavaScript in the browser, there is no need to install plug-ins. Vaadin is released under the Apache License 2.0.

Client-Server Architecture

Figure 1: Vaadin Client-Server Architecture

If the built-in selection of components is not enough, you can develop new components with the Google Web Toolkit (GWT) in Java.

CREATING AN APPLICATION

An application that uses the Vaadin framework needs to inherit the com.vaadin.Application class and implement the init() method.


import com.vaadin.ui.*;

public class HelloWorld extends com.vaadin.Application {
	public void init() {
		Window main = new Window(“Hello window”);
		setMainWindow(main);
		main.addComponent(new Label(“Hello World!”));
	}
}

The basic tasks in writing an application class and the initialization method are:

  • inherit the Application class
  • create and set a main window
  • populate the window with initial components
  • define event listeners to implement the UI logic

Optionally, you can also:

  • set a custom theme for the window
  • bind components to data
  • bind components to resources

The application can change the components and the layout dynamically according to the user input.

Architecture for Vaadin Applications

Figure 2: Architecture for Vaadin Applications


You can get a reference to the application object from any component attached to the application with getApplication()

Event Listeners

In the event-driven model, user interaction with user interface components triggers server-side events, which you can handle with event listeners.

In the example below, we handle click events for a button with an anonymous class:


Button button = new Button(“Click Me!”);
button.addListener(new Button.ClickListener() {
	public void buttonClick(ClickEvent event) {
		getWindow().showNotification(“Thank You!”);
	}
});

Download Vaadin

Below is a list of the most important event interfaces; their corresponding listener interfaces are named -Listener.

Event Interface Description
Property.ValueChangeEvent Field components except Button
Button.ClickEvent Button click
Window.CloseEvent A sub-window or an application-level window has been closed

Unless the immediate property (see below) is set, value change events are not communicated immediately to the server-side when the user changes the values, but are delayed until the first immediate interaction. Certain events, such as button clicks, are immediate by default.

Deployment

To deploy an application as a servlet, you must define a WEB-INF/web.xml deployment descriptor. The application class must be defined in the application parameter.


<web-app>
	<display-name>myproject
	
	<servlet>
		<servlet-name>Myproject Application
		<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet
		</servlet-class>
		<init-param>
			<description>Vaadin application class to start
			<param-name>application
			<param-value>com.example.myproject.HelloWorld
		</init-param>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>Myproject Application
		<url-pattern>/*
	</servlet-mapping>
</web-app>

COMPONENTS

Vaadin components include field, layout, and other components. The component classes and their inheritance hierarchy are illustrated in Figure 4 (page 3).

Component Properties

Common component properties are defined in the Component interface and the AbstractComponent base class for all components.

Property Description
caption A label that identifies the component for the user, usually shown above, left of, or inside a component, depending on the component and the containing layout.
description A longer description usually displayed as a tooltip when mouse hovers over the component.
enabled If false, the user can not interact with the component. The component is shown as grayed. (Default: true)
icon An icon for the component, usually shown left of the caption.
immediate If true, value changes are communicated immediately to the server-side, usually when the selection changes or (a text field) loses input focus. The default is false for most components, but true for Button.
locale The current country and/or language for the component. Meaning and use are application-specific for most components. (Default: application locale)
readOnly If true, the user can not change the value. (Default: false)
visible Whether the component is actually visible or not. (Default: true)

Field Properties

Field properties are defined in the Field interface and the AbstractField base class for fields.

Property Description
required Boolean value stating whether a value for the field is required. (Default: false)
requiredError Error message to be displayed if the field is required but empty. Setting the error message is highly recommended for providing user feedback about a failure.

Sizing

The size of components is defined in the Sizeable interface.

Method Description
setWidth()
setHeight()
Set the component size in either fixed units (px, pt, pc, cm, mm, in, or em) or as a relative percentage (%) of the containing layout. The value "-1" means undefined size (see below).
setSizeFull() Sets both dimensions to 100% relative size of the space given by the containing layout.
setSizeUndefined() Sets both dimensions as undefined, causing the component to shrink to fit the content.

Notice that a layout with an undefined size must not contain a component with a relative (percentual) size.

Validation

All components implementing the Validatable interface, such as all fields, can be validated with validate() or isValid(). You need to implement a Validator and its validate() and isValid() methods, and add the validator to the field with addValidator().

Built-in validators are defined in the com.vaadin.data.validator package and include:

Validator Description
DoubleValidator A floating-point value
EmailValidator An email address
IntegerValidator An integer value
RegexpValidator String that matches a regular expression
StringLengthValidator Length of string is within a range

Resources

Icons, embedded images, hyperlinks, and downloadable files are referenced as resources.


Button button = new Button("Button with an icon");
button.setIcon(new ThemeResource("img/myimage.png"));

The external and theme resources are usually static resources. Application resources are served by the Vaadin application servlet, or by the user application itself.

Resource classes and interfaces

Figure 3: Resource classes and interfaces

Class Name Description
ExternalResource Any URL
ThemeResource A static resource served by the application server from the current theme. The path is relative to the theme folder.
FileResource Loaded from the file system
ClassResource Loaded from the class path
StreamResource Provided dynamically by the application

User Component Classes Class Diagram

Figure 4: The Class Diagram presents all user interface component classes and the most important interfaces, relationships, and methods.

LAYOUT COMPONENTS

The layout of an application is built hierarchically from layout components, or more generally component containers, with the actual interaction components as the leaf nodes of the component tree.

You start by creating a root layout for the main window and set it with setContent(), unless you use the default, and then add the other layout components hierarchically with addComponent().

Margins

The margin of layout components is controlled with the margin property, which you can set with setMargin(). Once enabled, the HTML element of the layout will contain an inner element with <layoutclass>-margin style, for example, v-verticallayoutmargin for a VerticalLayout. You can use the padding property in CSS in a custom theme to set the width of the margin:


.v-verticallayout-margin {
	padding-right: 20px;
	padding-top: 30px;
	padding-bottom: 40px;
}

Spacing

Some layout components allow spacing between the elements. You first need to enable spacing with setSpacing(true), which enables the <layoutclass>-spacing-on style for the layout, for example, v-gridlayout-spacing-on for GridLayout. You can then set the amount of spacing in CSS in a custom theme with the padding-top property for vertical and padding-left for horizontal spacing, for example as follows:


.v-gridlayout-spacing-on {
	padding-left: 50px; /* Horizontal spacing */
	padding-top: 100px; /* Vertical spacing */
}

Alignment

When a layout cell is larger than a contained component, the component can be aligned within the cell with the setComponentAlignment() method as in the example below:


VerticalLayout layout = new VerticalLayout();
Button button = new Button("My Button");
layout.addComponent(button);
layout.setComponentAlignment(button, Alignment.MIDDLE_CENTER);

Custom Layout

The CustomLayout component allows the use of a HTML template that contains location tags for components, such as <div location="hello">. The components are inserted in the location elements with the addComponent() method as shown below:


CustomLayout layout = new CustomLayout("mylayout");
layout.addComponent(new Button("Hello"), "hello");

The layout name in the constructor refers to a corresponding .html file in the layouts subfolder in the theme folder, in the above example layouts/mylayout.html. See Figure 5 for the location of the layout template.

THEMES

Vaadin allows customization of appearance of the user interface with themes. Themes can include CSS style sheets, custom layout HTML templates, and any graphics.

Custom themes are placed under the WebContent/VAADIN/ themes/ folder of the web application. This location is fixed the VAADIN folder specifies that these are static resources specific to Vaadin.

The name of a theme folder defines the name of the theme, to be used for the setTheme() method:


public void init() {
	setTheme("mytheme");
	...

The theme folder must contain the styles.css style sheet and custom layouts must be placed in the layouts sub-folder, but other contents may be named freely.

Custom themes need to inherit a base theme in the beginning of the styles.css file. The default theme for Vaadin 6 is reindeer


@import url(../reindeer/styles.css);

Theme contents

Figure 5: Theme contents

Hot Tip

During development, you can let the built-in themes and the default widget set be loaded dynamically from the Vaadin JAR. For production, it is more efficient to let them be served statically by the web server. You just need to extract the VAADIN folder from the JAR.

DATA BINDING

Vaadin allows binding components directly to data. The data model, illustrated in Figure 4, is based on interfaces on three levels of containment: properties, items, and containers.

Properties

The Property interface provides access to a value of a specific class with the setValue() and getValue() methods.

All field components provide access to their value through the Property interface, and the ability to listen for value changes with a Property.ValueChangeListener. The field components hold their value in an internal data source by default, but you can bind them to any data source with setPropertyDataSource().

For selection components, the property value points to the item identifier of the current selection, or a collection of item identifiers in the multiSelect mode.

The ObjectProperty is a wrapper that allows binding any object to a component as a property.

Items

An item is an ordered collection of properties. The Item interface also associates a name with each property. Common uses of items include Form data and Table rows. You can set the data source of a Form with setItemDataSource().

The BeanItem is a special adapter that allows accessing any Java bean (or POJO with proper setters and getters) through the Item interface. This is especially useful for binding a Form or a Table to beans.

Containers

A container is a collection of items. It allows accessing the items with an item identifier associated with each item.

Common uses of containers include selection components, as defined in the AbstractSelect class, especially the Table and Tree components. (The current selection is indicated by the property of the field, which points to the item identifier of the selected item.) You can set the container data source of a field with setContainerDataSource().

Vaadin includes the following built-in container implementations:

Container Class Description
IndexedContainer Container with integer index keys
BeanItemContainer Container for BeanItems
HierarchicalContainer Tree-like container, used especially by the Tree component
FilesystemContainer Direct access to the file system

Buffering

All field components implement the Buffered interface that allows buffering user input before it is written to the data source. Buffering is enabled by default.

Method Description
commit() Writes the buffered data to the data source
discard() Discards the buffered data and re-reads the data from the data source
set-/getWriteThrough() When the writeThrough property is true, write buffering is disabled
set-/getReadThrough() When the readThrough property is true, read buffering is disabled

CREATING NEW COMPONENTS

Creating a Client-Side Widget

The basic tasks of a client-side component are:

  • Implement the Paintable interface
  • Maintain a reference to the ApplicationConnection object
  • Implement updateFromUIDL() to deserialize state changes from server-side
  • Serialize state changes to server-side with calls to updateVariable()

Creating a Server-Side Component

The basic tasks of a server-side component are:

  • Use @ClientWidget annotation for the server-side component class to bind the component to the client-side counterpart
  • Implement paintContent() to serialize state changes to client-side with addVariable() and addAttribute() calls
  • Implement changeVariables() to deserialize state changes from client-side

TWidget integration

Figure 6: Widget integration within the Vaadin client-server communication architecture

Defining a Widget Set

A widget set is a collection of widgets that, together with the communication framework, form the Client-Side Engine of Vaadin, when compiled with the GWT Compiler into JavaScript.

A widget set is defined in a .gwt.xml GWT Module Descriptor. You need to specify at least one inherited base widget set, typically the DefaultWidgetSet or a custom set.


<module>
	<inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />
</module>

The client-side source files must be located in the client subpackage under the package of the descriptor.

You can associate a stylesheet with a widget set with the <stylesheet> element in the .gwt.xml descriptor:


<stylesheet src="/sites/all/modules/dzone/assets/refcardz/085/colorpicker/styles.css"/>

Widget Project Structure

Widget set source structure

Figure 7: Widget set source structure.

Figure 7 illustrates the source code structure of a widget project (for the Color Picker example).

Using Widget Sets

You can generate the descriptor of a combining widget set automatically with the com.vaadin.terminal.gwt.widgetsetutils. WidgetSetBuilder application. It searches the class path to find all widget sets, including ones packaged in JARs, and generates the required <inherit> elements.

  • Give the full name (including the package name) of the widget set as a parameter. This is the name of the .gwt.xml file without the extension.
  • Give path to the top-level source directory as the first element of the class path

For more information on Vaadin, visit the Vaadin Blog at http://vaadin.com/blog or the Forum at http://vaadin.com/forum

About The Author

Photo of Marko Grnroos

Marko Grnroos

CMarko Grnroos is a professional writer and software developer working at IT Mill Ltd, the company behind Vaadin. He has been involved in web application development since 1994 and has worked on several application development frameworks in C, C++, and Java. He has been active in many open source software projects and holds an M.Sc. degree in Computer Science from the University of Turku. He lives in Turku, Finland.

Website: http://iki.fi/magi

Blog: http://markogronroos.blogspot.com/

Recommended Book

Book of Vaadin

Book of Vaadin is a comprehensive documentation of Vaadin. It shows how to get started, gives a good overview of the features, and tutors you through advanced aspects of the framework.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Java Enterprise Edition 6

The Most Elegant Enterprise Java yet

By Andrew Lee Rubinger

17,711 Downloads · Refcard 150 of 151 (see them all)

Download
FREE PDF


The Essential Java EE 6 Cheat Sheet

This Java Enterprise Edition 6 cheat sheet covers the very best parts of the public APIs with descriptions, code examples, and class names. Enterprise software development is inherently complex. Multi-user systems open the door to concerns such as transactional integrity, security, persistence integration, and interaction between components. Simply put, the mission of Java Enterprise Edition is to enable an out-of-the-box set of configurable services that allows the programmer to write less and focus on delivering clean business logic.
HTML Preview
Java Enterprise Edition 6 The Most Elegant Enterprise Java Yet

Java Enterprise Edition 6The Most Elegant Enterprise Java Yet

By Andrew Lee Rubinger

ABOUT THE PLATFORM

Enterprise software development is inherently complex, and multi-user systems open the door to concerns such as transactional integrity, security, persistence integration, and interaction between components. Very simply put, the mission of the Java Enterprise Edition is to enable an out-of-the-box set of configurable services that allows the programmer to write less and focus on delivering clean business logic.

To this end, Java EE 6 is an aggregate of many interoperable technologies designed to deliver a unified experience. Application Servers that are certified to the standards defined by the Java Community Process are intended to service applications written to the specifications within the platform.

For the sake of brevity, this reference card will focus on the key APIs of Java EE 6 that are most relevant to modern development.

JAVA PLATFORM, ENTERPRISE EDITION 6 (JAVA EE 6)

JSR-316

This umbrella specification ties together the various subsystems that comprise the platform and provides additional integration support.

Profiles

New to Java EE 6 is the notion of the “Web Profile”, a subset of the full specification that is targeted to cater to more specialized and minimal webbased application requirements. It is guaranteed to support the platform common annotations for injection and lifecycle (JSR-250), JNDI Naming standards, and the Java Transaction API. Additionally, the Web Profile focuses on Servlet and closely related technologies such as persistence, view presentation (JavaServer Faces and JavaServer Pages), and the business logic elements of EJB Lite.

Code Example

The simple class below is all it takes in Java EE 6 to define a POJO-based managed component capable of lifecycle callbacks, interceptors, and resource injection.

/** * Interceptor logging that an invocation has been received */ public class LoggingInterceptor { @AroundInvoke public Object intercept(InvocationContext context) throws Exception { System.out.println(“Been intercepted: “ + context); return context.proceed(); } } /** * Defines a simple managed bean able to receive an injection */ @ManagedBean @Interceptors({LoggingInterceptor.class}) // Invocations will be // intercepted public class ComponentResourceInjection { @Resource private UserTransaction userTransaction; // ... business methods will be intercepted // by LoggingInterceptor
Reference

The full JavaDoc for the Java EE 6 API is located at: http://download.oracle.com/javaee/6/api/

COMMON ANNOTATIONS FOR THE JAVA PLATFORM

JSR-250

he common annotations for Java EE are a shared package used throughout the platform specifications that generally focus on shared services like lifecycle, injection, and security.

Class Name Description
Generated Marks generated code
ManagedBean Defines a class as a Java EE 6 Managed Bean
PostConstruct Lifecycle callback after an instance has been created but before it is put into service
PreDestroy Lifecycle callback before an instance is to be removed from service
Resource Defines an injection point, marks that this is to be provided by t he container
Resources Allows for injection of N resources
DeclareRoles Class-level target defining valid security roles
DenyAll Marks that no roles are allowed to access this method
PermitAll Marks that all roles are allowed to access this method (or all methods if applied to a class)
RolesAllowed Specifies list of roles permitted to access this method (or all methods if applied to a class)
RunAs Defines the identity context when run in the container

JAVA SERVLET 3.0

JSR-315

Servlet technology models the request/response programming model and is commonly used to extend HTTP servers to tie into server-side business logic. In Servlet 3.0, the specification has been expanded to include support for annotations, asynchronous processing, pluggability, and general ease-of-configuration.

Code Example

Because Servlet 3.0 includes annotations to define servlets, the descriptor web.xml is no longer required in most of the common cases; below is an example of all that’s needed to create a simple servlet.


/**
	* Simple Servlet which welcomes the user by name specified
	* by the request parameter “name”.
	*/
@WebServlet(urlPatterns =
{“/welcome”}) // Will service requests to the path “/welcome”
public class WelcomeServlet extends HttpServlet
{
	/**
	 * Inject a reference to an EJB
	 */
	@EJB
	private WelcomeBean bean;
/**
* Service HTTP GET Requests
*/
  @Override
  protected void doGet(final HttpServletRequest request, final HttpServletResponse
response) throws ServletException,
IOException
{
	// Get the name from the request
	final String name = request.getParameter(“name”);
	// Precondition checks
	if (name == null)
	{
	response.sendError(HttpServletResponse.SC_BAD_REQUEST, “Request
parameter \”name\” is required”);
	}
	// Set content type
	response.setContentType(“text/plain”);
	// Get the welcome message
	final String welcomeMessage = bean.welcome(name);
	// Write out
	response.getWriter().write(welcomeMessage);
}
}

Public API from javax.servlet.annotation:

Class Name Description
HttpConstraint Defines security constraints for all HTTP-servicing methods in a secured servlet
HttpMethodConstraint Defines security constraints for an HTTP-servicing method in a servlet
MultipartConfig Indicates the servlet is to service requests for multipart/form-data MIME type
ServletSecurity Secures a servlet class for HTTP-servicing methods
WebFilter Defines a class as a servlet filter
WebInitParam Specificies an initialization parameter on a servlet or filter
WebListener Defines a class as a web listener
WebServlet Defines a class as a servlet
PermitAll Marks that all roles are allowed to access this method (or all method if applied to a class)
RolesAllowed Specifies list of roles permitted to access this method (or all methods if applied to a class)
RunAs Defines the identity context when run in the container

JAVA API FOR RESTFUL WEB SERVICES (JAX-RS)

JSR-311

New to Java EE, the JAX-RS specification allows for standard development adhering to the Representational State Transfer (REST) paradigm. These applications are packaged as a Servlet inside a web application archive.


/**
* JAXB Model of a Name
*/
@XmlRootElement
public class Name {
	private String name;
	
	public Name(String name) {
	this.name = name;
	}
	public Name() {}
	public String getName() {return this.name;}
	
	public void setName(String name) {
	this.name = name;
	}
}

/**
  * Services requests for the path “/name”
  * returning the JAXB-formed Name XML
  */
@Path(“/name”)
@Produces({“application/xml”})
public class NamedResource extends javax.ws.rs.core.Application {
	@GET
	public Name get(@QueryParam(“name”) String name) {
		return new Name(name);
}
}

...and HTTP GET requests to “{baseUrl}/myapp/name?name=andrew” will return the XML form for the Name.

Public API Annotation Selection from javax.ws.rs:

Class Name Description
Consumes Defines the media types that may be accepted
CookieParam Injects the value of an HTTP cookie to a method param or bean/class field
DefaultValue Defines default values for cookies and other parameters
DELETE Flags that a method is to service HTTP DELETE requests
Encoded Disables automatic decoding of parameter values
FormParam Injects the value of a form parameter to a resource method parameter
GET Flags that a method is to service HTTP GET requests
HEAD Flags that a method is to service HTTP HEAD requests
HeaderParam Injects the value of a header parameter
HttpMethod Draws an association between an HTTP method with an annotation
MatrixParam Injects the value of a URI matrix parameter
Path Designates the URI path that a resource class or resource method will serve
PathParam Injects the value of a URI path parameter
POST Flags that a method is to service HTTP POST requests
Produces Signals the media type(s) to be served by this resource
PUT Flags that a method is to service HTTP PUT requests
QueryParam Injects the value of a query parameter

CONTEXTS AND DEPENDENCY INJECTION FOR JAVA

JSR-299

The Java Contexts and Dependency Injection (CDI) specification introduces a standard set of application component management services to the Java EE platform. CDI manages the lifecycle and interactions of stateful components bound to well defined contexts. CDI provides typesafe dependency injection between components. CDI also provides interceptors and decorators to extend the behavior of components, an event model for loosely coupled components and an SPI allowing portable extensions to integrate cleanly with the Java EE environment. Additionally, CDI provides for easy integration with view layers such as JavaServer Faces 2.0 (JSR-314).

Code Example

Below is a simple example of a CDI Bean that is placed in scope alongside the HTTP session, given a String-based name binding (such that it may be used in JSF view components, for example) and injects the FacesContext such that it may be used in business methods.



	@SessionScoped // Bind to the web session
	@Named // To be used in view components by name
	public class GreeterBean implements Serializable {
	
		@Inject // Used to integrate w/ JSF
		private FacesContext context;
		
		public GreeterBean() {}
		
		// ... business methods
	
	}

Class Name Description
javax.decorator.Decorator Declares the class as a Decorator
javax.decorator.Delegate Specifies the injection point of a Decorator
javax.enterprise.context.ApplicationScoped Specifies the bean has application scope
javax.enterprise.context.ConversationScoped Specifies the bean has conversation scope
javax.enterprise.context.Dependent Specifies the bean belongs to dependent pseudo-scope
javax.enterprise.context.NormalScope Specifies the bean is normallyscoped
javax.enterprise.context.RequestScoped Specifies the bean is request-scoped
javax.enterprise.context.SessionScoped Specifies the bean is session-scoped
javax.enterprise.event.Observes Identifies an event parameter of an observer method
javax.enterprise.inject.Alternative Specifies that the bean is an Alternative
javax.enterprise.inject.Any Built-in qualifier type
javax.enterprise.inject.Default Default qualifier type
javax.enterprise.inject.Disposes Identifies the disposed parameter of a disposer method
javax.enterprise.inject.Model Built-in stereotype for beans defining the model layer of an MVC webapp (ie. JSF)
javax.enterprise.inject.New Built-in qualifier type
javax.enterprise.inject.Produces Identifies a Producer method or field
javax.enterprise.inject.Specializes Indicates that a bean specializes another bean
javax.enterprise.inject.Stereotype Specifies that an annotation is a stereotype
javax.enterprise.inject.Typed Restricts the types of a bean

Relevent Public Annotation API from JSR-330, Dependency Injection for Java in package javax.inject:

Class Name Description
Inject Identifies injectable constructors, methods, and fields
Named String-based qualifier
Qualifier Identifies qualifier annotations
Scope Identifies scope annotations
Singleton Identifies a type that the injector only instantiates once

For a deeper dive into CDI, check out DZone’s CDI Refcard: http://refcardz.dzone.com/refcardz/contexts-and-depencency

BEAN VALIDATION 1.0

BEAN VALIDATION 1.0

New to Java EE 6, the Bean Validation Specification provides for unified declaration of validation constraints upon bean data. It may be used to maintain the integrity of an object at all levels of an application: from user form input in the presentation tier all the way to the persistence layer.

Code Example

Here is an example of how to apply Bean Validation constraints in a declarative fashion to ensure the integrity of a User object.


public class User {
		@NotNull
		@Size(min=1, max=15)
		private String firstname;
		
		@NotNull
		@Size(min=1, max=30)
		private String lastname;
		
		@Pattern(regexp=”\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b”)
		public String email;
	}

Public Annotation API for javax.validation

Class Name Description
Constraint Link between a constraint annotation and its constraint validation implementations
GroupSequence Defines a group sequence
OverridesAttribute Mark an attribute as overriding the attribute of a composing constraint
OverridesAttribute.List Defines several @OverridesAttribute annotations on the same element
ReportAsSingleViolation A constraint annotation hosting this annotation will return the composed annotation error report if any of the composing annotations fail.
Valid Mark an association as cascaded

JAVASERVER FACES 2.0

JSR-314

JavaServer Faces is a user interface (UI) framework for the development of Java web applications. Its primary function is to provide a componentbased toolset for easily displaying dynamic data to the user. It also integrates a rich set of tools to help manage state and promote code reuse.

Additionally, JSF is an extensible specification that encourages the authoring of custom user views. It’s designed with tooling in mind such that integrated development environments (IDEs) can intelligently assist with design.

Code Example

Here we’ll show a simple example of a JSF managed bean whose state is scope to the HTTP request, and is registered to a bean name that may be accessed by the view layer.


	/**
  * This class defines a bean to live bound to the HTTP
  * request scope, and may be accessed by the view layer
  * under the name “hitchhikersGuide”.
  */
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.ProjectStage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;

@RequestScoped
@ManagedBean(name = “hitchhikersGuide”)
public class HitchhikersGuide {
private String ultimateAnswer;

	@ManagedProperty(value = “#{facesContext.application.projectStage}”)
	private ProjectStage journeyStage;
	public String getUltimateAnswer() {
	  return ultimateAnswer;
	}
	public void setUltimateAnswer(String ultimateAnswer) {
	  this.ultimateAnswer = ultimateAnswer;
	}
	public ProjectStage getJourneyStage() {
	  return journeyStage;
	}
	public void setJourneyStage(ProjectStage journeyStage) {
	  this.journeyStage = journeyStage;
	}
	@PostConstruct
	public void findUltimateAnswerToUltimateQuestion() {
	  ultimateAnswer = “42”;
	}
	
}

index.xhtml View:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
 	 “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”
	xmlns:h=”http://java.sun.com/jsf/html”
	xmlns:f=”http://java.sun.com/jsf/core”>
	<head>
		<title>Sample JSF Page</title>
	</head>
	<body>
	<f:view>
		<h2><h:outputText value=”Test Managed Bean Annotations”/></h2>
		<p><h:outputText value=”hitchhikersGuide.ultimateAnswer =
#{hitchhikersGuide.ultimateAnswer}”/></p>
		<h2><h:outputText value=”Test Project Stage”/></h2>
		<p><h:outputText value=”project stage = #{hitchhikersGuide.
journeyStage}”/></p>
	</f:view>
	</body>
</html>

Public API from javax.faces.bean:

Class Name Description
ApplicationScoped Denotes a ManagedBean is to be in application scope
CustomScoped Denotes a ManagedBean is to be in a custom-defined scope of the specified value
ManagedBean Defines a class as a ManagedBean type
ManagedProperty Injection point for fields in ManagedBean classes
NoneScoped Denotes a ManagedBean is to be in the “none” scope
ReferencedBean Denotes the class as a referenced bean
RequestScoped Denotes a ManagedBean is to be in request scope
SessionScoped Denotes a ManagedBean is to be in session scope
ViewScoped Denotes a ManagedBean is to be in view scope
Class Name Description
Application Singleton scoped per web application to provide configuration for things like validators, components and converters
ApplicationFactory Creates (if required) and returns Application instances
ApplicationWrapper Application type which may be used by developers to add to an existing ResourceHandler
ConfigurableNavigation-Handler Extends NavidationHandler to provide runtime inspection of the NavigationCase which defines the rule base for navigation
FacesMessage A single validation message
NavigationCase A single navigation case in the navigation rule base
NavigationHandler Handles navigation from a given action and outcome
Resource Models a client resource request
ResourceHandler API by which UIComponent and Renderer instances can reference Resource instances
ResourceWrapper Simple base implementation of Resource to be extended by developers looking to add custom behaviors
StateManager Coordinates the process of saving and restoring the view between client requests
StateManagerWrapper Base implementation of a StateManager which may be subclasses by developers looking to add custom behaviors
ViewHandler Pluggable point for the render response and restore view phases of the request lifecycle.
ViewHandlerWrapper Base implementation of a ViewHandler which may be subclasses by developers looking to add custom behaviors.

ENTERPRISE JAVABEANS 3.1

JSR-318

Enterprise JavaBeans provide a component model to encapsulate business logic. As such, they provide a few bean types:

  • Session Beans
  • Stateless
  • No conversational state between requests
  • Stateful
  • Same bean instance used to service each client/session
  • Singleton
  • One shared bean instance for all users
  • Message-Driven
  • Event Listener
  • JCA endpoint
  • Asynchronous
  • Entity
  • Integration point w/ Java Persistence
Code Example

It’s simple to define an EJB capable of greeting a user.


/**
 * Stateless Session EJB
 */
@Stateless // Defines a Stateless Session Bean
@LocalBean // No-interface view
public class GreeterBean {
	@Override
	public String greet(String name) {
		return “Hi, “ + name + “!”;
	}
}

Other components, such as Servlets, may now inject a proxy to the above EJB:

@EJB private GreeterBean greeterEjb;

Public API Annotation Selection from javax.ejb:

Class Name Description
AccessTimeout Designates the amount of time a concurrent method should block before timing out
ActivationConfig-Property Used to configure Message-Driven Beans
AfterBegin Defines a Tx callback method for the “after begin” event
AfterCompletion Defines a Tx callback method for the “after completion” event
ApplicationException Defines a user exception which should not be wrapped
Asynchronous Defines methods to be executed asynchronously.
BeforeCompletion Defines a Tx callback method for the “before completion” event
ConcurrencyManagement Configures the concurrency management mode for a singleton session bean
DependsOn Designates initialization order for Singleton Session Beans
EJB Defines an injection point and dependency upon an EJB component
EJBs Plural injection point and dependency for EJB components, to be applied at the class-level
Local Defines a local business interface view
LocalBean Defines a no-interface view
Lock Defines a concurrency lock for Singleton Session Beans using container-managed concurrency
MessageDriven Defines a Message-Driven Bean
PostActivate
Defines an event callback after a Stateful Session Bean has been activated
PrePassivate Defines an event callback before a Stateful Session Bean is to be passivated
Remote Defines a remote business interface view
Remove Defines a business method that should trigger the removal of a Stateful Session Bean instance (i.e., destroy the session
Schedule Defines a new timer to be created with a specified schedule
Schedules Plural of Schedule
Singleton Defines a Singleton Session Bean
Startup Denotes that a Singleton Session Bean should eagerly load
Stateful Defines a Stateful Session Bean
StatefulTimeout Defines a Stateful Session Bean
Stateless Defines a Stateless Session Bean
Timeout Defines a timer expiration method
TransactionAttribute Configures the transactional context under which business methods should execute
TransactionManagement Configures transactional management for a Session or Message-Driven Bean (container or bean provided)

JAVA PERSISTENCE 2.0

JSR-317

Most enterprise applications will need to deal with persistent data, and interaction with relational databases can be a tedious and difficult endeavor. The Java Persistence specification aims to provide an object view of backend storage in a transactionally aware manner. By dealing with POJOs, JPA enables developers to perform database operations without the need for manually tuning SQL.

Code Example

A JPA entity is simply a POJO with some annotations to provide additional mapping metadata. For instance:


@Entity
	public class SimpleEmployee {
		@Id @Auto
		private Long id;
		private String name;
		public Long getId(){ return id; }
		public void setId(final Long id) { this.id = id; }
		public String getName() { return name; }
		public void setName(final String name) { this.name = name; }
}

Now a managed component such as an EJB or CDI bean can interact with the database through our entity by associating it with an EntityManager


@PersistenceContext
private EntityManager em;
public void createUser(){
	final SimpleEmployee andrew = new SimpleEmployee();
	andrew.setId(100L);
	andrew.setName(“Andrew Lee Rubinger”);
	em.persist(andrew); // Store in the DB
	// Now any state changes done to this managed object will be
	// reflected in the database when the Tx completes
}

Public API Annotation Selection from javax.persistence:

Class Name Description
Basic Describes mapping for a database column
Column Specifies column mapping for a persistent property
DiscriminatorColumn Notes the discriminator column used for SINGLE_TABLE and JOINED inheritance strategies
DiscriminatorValue Specifies the value of the discriminator column for entities of this type
ElementCollection Defines a collection of instances
Embeddable Defines a class whose instances are stored as part of the owning entity
Embedded Specifies a persistent property whose value is an instance of an embeddable class
EmbeddedId Denotes composite primary key of an embeddable class
Entity Defines a POJO as a persistent entity
EntityListeners Specifies callback listeners
Enumerated Specifies that a persistent property should be persisted as an enumeration
GeneratedValue Specifies generation strategies for primary keys
Id Denotes a primary key field
IdClass Denotes a composite primary key class
Inheritance Denotes the inheritance strategy for this given entity
JoinColumn Specifies a column for joining an entity association or element collection.
JoinColumns Plural of JoinColumn
JoinTable Maps associations
Lob Denotes a binary large object persistent property
ManyToMany Defines an N:N relationship
ManyToOne Defines an N:1 relationship
NamedQuery Defines a static query in JPAQL
OneToMany Defines a 1:N relationship
OneToOne Defines a 1:1 relationship
OrderBy Specifies ordering of elements when a Collection is retrieved
PersistenceContext Used for injecting EntityManager instances
PersistenceUnit Used for injecting EntityManagerFactory instances
PostLoad Define an event callback method
PostPersist Define an event callback method
PostRemove Define an event callback method
PostUpdate Define an event callback method
PrePersist Define an event callback method
PreRemove Define an event callback method
PreUpdate Define an event callback method
Table Specifies the primary table for this entity
Temporal Denotes persistence of Date and Calendar field types
Transient Denotes that a property is not persistent
Version Specifies the persistent property used as the optimistic lock

About The Authors

Andrew Lee Rubinger

Andrew Lee Rubinger

Open Source Software Engineer and Author

Advocate for and speaker on testable enterprise Java development, author of “Enterprise JavaBeans 3.1” from O’Reilly Media. Member of the JBoss Application Server development team and technical lead of the ShrinkWrap project. Proudly employed by JBoss / Red Hat.

Recommended Book

Enterprise JavaBeans

Learn how to code, package, deploy, and test functional Enterprise JavaBeans with the latest edition of bestselling guide. Written by the developers of the JBoss EJB 3.1 implementation, this book brings you up to speed on each of the component types and container services in this technology, while the workbook in the second section provides several hands-on examples for putting the concepts into practice. Enterprise JavaBeans 3.1 is the most complete reference you’ll find on this specification.

Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Daily Dose: Java SE7 To Arrive At End Of July

On Monday, The Java Community Process completed voting on the final approval ballots for Java SE7, and all JSRs were given the green light. This completes the JCP's work on Java 7, but there's a few more steps to finishing the product, according to Mark...

0 replies - 15416 views - 07/20/11 by Jim Moscater in Daily Dose

NetBeans IDE 7

Programming in Java 7

By Geertjan Wielenga

18,842 Downloads · Refcard 14 of 151 (see them all)

Download
FREE PDF


The Essential NetBeans 7 Cheat Sheet

NetBeans IDE 7: Programming in Java 7- Developers from the Java Development Kit team worked closely with developers from the NetBeans team to create a well aligned JDK 7 development experience with support for new language features, such as the diamond operator, strings in switch, and multicatch. When you use these constructs in your code, NetBeans IDE recognizes them, offers correct classes in code completion, correctly highlights errors, and lets you automatically fix old syntax. You’ll find this DZone Refcard helpful if you want to get as much out of JDK 7 and NetBeans IDE 7 as their creators intended.
HTML Preview
Netbeans Java Editor

Netbeans Java Editor

By Geertjan Wielenga and Patrick Keegan

About Netbeans IDE

The NetBeans IDE has seen adoption snowballing over the past years and now comes to you with deep Java EE 6 support in NetBeans IDE 6.8. You’ll find this reference card helpful if you want to get as much out of the Java editor (and related tools) as its authors intended when creating it. It lists all the keyboard shortcuts in carefully thought out categories and it provides a thorough exposition of optimal handling of Java code in the editor, covering viewing, navigation, source handling, and refactoring. Go to http://www.netbeans.org/downloads/ to get NetBeans IDE.

Java Editor Overview

What's New For Java In Netbeans IDE 6.8

The following features are new in NetBeans IDE 6.8 and can be of particular use to you in the context of creating Java-based applications:

Java EE 6 Support The IDE provides tools for developing applications complying with the new Java Enterpise Edition 6, specifically web, EJB, web service, and JPA support. The Java EE 6 compliant server bundled with the IDE is GlassFish v3.
Facelets Editor For Facelets (JavaServer Faces 2.0), a complete editor with coloring, code completion, namespace support, component palette, code folding, error checking, and code templates is provided.
Maven Java EE 6 archetype support, new archetype catalogs, Groovy & Scala support, dependency exclusion support in visual dependency graph, as well as several other performance and usability improvements.
Other Related Enhancements JavaFX editor, JIRA support, instant messaging, new UI for Kenai projects, and code completion enhancements in SQL editor.

Netbeans IDE Java Quick Start Tutorial

This tutorial provides a very simple and quick introduction to the NetBeans IDE workflow by walking you through the creation of a simple “Hello World” Java console application.

  1. Start NetBeans IDE. In the IDE, choose File > New Project (Ctrl-Shift-N).
  2. In the New Project wizard, expand the Java category and select Java Application. Then click Next.
  3. In the Name and Location page of the wizard, type "HelloWorld" in Project Name. Then click Finish.
  4. Because you have left the Create Main Class checkbox selected in the New Project wizard, the IDE has created a skeleton class for you. You can add the "Hello World!" message to the skeleton code by replacing the line:
    // TODO code application logic here
    with the line:
    System.out.println("Hello World!");
  5. From the IDE’s menu bar, choose Run > Run Main Project (F6). The Output window should show you the "Hello World!" message.

Keyboard Shortcuts And Code Templates

Finding, Searching, and Replacing

Ctrl-F3 Search word at insert point
F3/Shift-F3 Find next/previous in file
Ctrl-F/H Find/Replace in file
Alt-F7 Find usages
Ctrl-Shift-F/H Find/replace in projects
Alt-Shift-U Find usages results
Alt-Shift-H Turn off search result highlights
Ctrl-R Inplace Rename
Ctrl-U, then U Convert selection to uppercase
Ctrl-U, then L Convert selection to lowercase
Ctrl-U, then S Toggle case of selection
Alt-Shift-V Paste formatted

Opening and Toggling Between Views

Ctrl-Tab (Ctrl-`) Toggle between open documents
Shift-Escape Maximize window (toggle)
Ctrl-F4/Ctrl-W Close currently selected window
Ctrl-Shift-F4/Ctrl-Shift-W Close all windows
Shift-F10 Open contextual menu
Alt-Shift-D Undock window
Ctrl-4 Open Output window
Ctrl-8 Open Kenai Dashboard

Navigating through Source Code

Ctrl-O/Alt-Shift-O Go to type/file
Ctrl-Shift-T Go to related JUnit test, if any
Alt-O Go to source
Ctrl-B Go to declaration
Ctrl-G Go to line
Ctrl-Shift-M Toggle add/remove bookmark
Ctrl-Shift-Period/Comma Next/previous bookmark
Ctrl-Period/Comma Next/previous usage/compile error
Ctrl-Shift-1/2/3 Select in Projects/Files/Favorites
Ctrl-[ Move caret to matching bracket
Ctrl-K/Ctrl-Shift K Next/previous word match
Alt-Left/Alt-Right/Ctrl-Q Go backward/forward/to last edit

Compiling, Testing, and Running

F9 Compile package/ file
F11 Build main project
Shift-F11 Clean & build main project
Ctrl-Q Set request parameters
Ctrl-Shift-U Create JUnit test
Ctrl-F6/Alt-F6 Run JUnit test on file/project
F6/Shift-F6 Run main project/file

Debugging

Ctrl-F5 Start debugging main project
Ctrl-Shift-F5 Start debugging current file
Ctrl-Shift-F6 Start debugging test for file (JUnit)
Shift-F5/F5 Stop/Continue debugging session
F4 Run to cursor location in file
F7/F8 Step into/over
Ctrl-F7 Step out
Ctrl-Alt-Up Go to called method
Ctrl-Alt-Down Go to calling method
Ctrl-F9 Evaluate expression
Ctrl-F8 Toggle breakpoint
Ctrl-Shift-F8 New breakpoint
Ctrl-Shift-F7 New watch

Coding In Java

Alt-Insert Generate code
Ctrl-Shift-I Fix all class imports
Alt-Shift-I Fix selected class’s import
Alt-Shift-F Format selection
Alt-Shift Left/Right/Up/Down Shift lines left/right/up/down
Ctrl-Shift-Up/Down Copy lines up/down
Ctrl/Alt-F12 Inspect members/hierarchy
Ctrl-/ Add/remove comment lines
Ctrl-E Delete current line

Refactoring

This table provides short descriptions of the refactoring operations that are available in the IDE, mostly from under the Refactoring menu and within the Java editor itself, when you right-click within it.

Refactoring Operation Description
Rename Enables you to change the name of a class, variable, or method to something more meaningful. In addition, it updates all source code in your project to reference the element by its new name.
Introduce Variable, Constant, Field, or Method Enables you to generate a statement based on the selected code and replace that block of code with a call to the statement.
Change Method Parameters Enables you to add parameters to a method and change the access modifier.
Encapsulate Fields Generates a getter method and and a setter method for a field and optionally updates all referencing code to access the field using the getter and setter methods.
Pull Up Moves methods and fields to the superclass.
Push Down Moves inner classes, methods, and fields to all subclasses of their current class.
Move Class Moves a class to another package or into another class. In addition, all source code in your project is updated to reference the class in its new location.
Copy Class Copies a class to the same or a different package.
Move Inner to Outer Level Moves an inner class one level up in hierarchy.
Convert Anonymous Class to Inner Converts an anonymous class to an inner class that contains a name and constructor. The anonymous inner class is replaced with a call to the new inner class.
Extract Interface Creates a new interface from the selected public non-static methods in a class or interface.
Extract Superclass Creates a new abstract class, changes the current class to extend the new class, and moves the selected methods and fields to the new class.
Use Supertype Where Possible Changes code that references the selected class (or other type) to instead use a supertype of that type.
Safely Delete Checks for references to a code element and then automatically deletes that element if no other code references it.

When typing in the Source Editor, you can generate the text in the right-column of the following list by typing the abbreviation that is listed in the left-column and then pressing Tab.

Java Editor Code Templates

En Enumeration
Ex Exception
Ob Object
Psf public static final
Psfb public static final boolean
Psfi public static final int
Psfs public static final String
St String
ab abstract
bo boolean
br break
ca catch (
cl class
cn continue
df default:
dowhile do { } while (condition);
eq equals
ex extends
fa false
fi final
fl float
forc for (Iterator it = collection.iterator(); it.hasNext( );) { Object elem = (Object) it.next( ); }
fore for (Object elem : iterable) { }
fori for (int i = 0; i < arr.length; i++) { }
fy finally
ie interface
ifelse if (condition){ }else { }
im implements
iof instanceof
ir import
le length
newo Object name = new Object(args);
pe protected
pr private
psf private static final
psfb private static final boolean
psfi private static final int
psfs private static final String
pst printStackTrace();
psvm public static void main(String[ ] args){ }
pu public
re return
serr System.err.println ("|");
sout System.out.println ("|");
st static
sw switch (
sy synchronized
tds Thread.dumpStack();
th throws
trycatch try {} catch (Exception e) {}
tw throw
twn throw new
wh while (
whileit while (it.hasNext()) { Object elem = (Object) it.next(); }

JSP Code Templates

ag application.getAttribute(“|”)
ap application.putAttribute(“|”,)
ar application.removeAttribute(“|”)
cfgi config.getInitParameter(“|”)
jspf <jsp:forward page=”|”/>
jspg <jsp:getProperty name=”|” property=”” />
jspi <jsp:include page=”|”/>
jspp <jsp:plugin type=”|” code=”” codebase=””></jsp:plugin>
jsps <jsp:setProperty name=”|” property=””/>
jspu <jsp:useBean id=”I” type=””/>
oup out.print(“|”)
oupl out.println(“|”)
pcg pageContext.getAttribute(“|”)
pcgn pageContext.getAttributeNamesInScope(“|”)
pcgs pageContext.getAttributesScope(“|”)
pcr pageContext.removeAttribute(“|”)
pcs pageContext.setAttribute(“|”,)
pg <%@page |%>
pga <%@page autoFlush=”false”%>
pgb <%@page buffer=”|kb”%>
pgc <%@page contentType=”|”%>
pgerr <%@page errorPage=”|”%>
pgex <%@page extends=”|”%>
pgie <%@page isErrorPage=”true”%>
pgim <%@page import=”|”%>
pgin <%@page info=”|”%>
pgit <%@page isThreadSafe=”false”%>
pgl <%@page language=”java”%>
pgs <%@page session=”false”%>
rg request.getParameter(“|”)
sg session.getAttribute(“|”)
sp session.setAttribute(“|”, )
sr session.removeAttribute(“|”)
tglb <%@taglib uri=”|”%>

Mac OS Keyboard Shortcuts

In most cases, working with the IDE on the Mac is no different from working on other operating systems. Two significant differences do exist, however. Firstly, the Options window on the Mac is found under NetBeans > Preferences. Secondly, the About box is under NetBeans > About.

Scrolling and Selecting

Keys Action
Cmd-[ Moves the insertion point to the highlighted matching bracket. Note that this shortcut only works when the insertion point is located immediately after the opening bracket.
Cmd-Shift-[ Selects the block between a pair of brackets. Note that this shortcut only works when the insertion point is located immediately after either the opening or closing bracket.
Ctrl-G Jumps to any specified line.
Cmd-A Selects all text in the file.

Code Folding

Keys Action
Cmd-Minus (-) Collapses the block of code in which the insertion point is currently located.
Cmd-Plus (+) Expands the block of code which is adjacent to the insertion point.
Cmd-Shift-Minus (-) Collapses all blocks of code in the current file.
Cmd-Shift-Plus (+) Expands all blocks of code in the current file.

Cutting, Copying, Pasting, and Deleting Text

Keys Action
Cmd-Z Undo. Reverses a series of editor actions one at a time (excluding Save).
Cmd-Y Redo. Reverses a series of Undo commands one at a time.
Cmd-X Cut. Deletes the current selection and places it on the clipboard.
Cmd-C Copy. Copies the current selection to the clipboard.
Cmd-V Paste. Pastes the contents of the clipbard at the insert point.
Backspace Delete Deletes the current selection.
Cmd-E Deletes the current line.
Cmd-K Copies the word preceding the insertion point and then pastes it after the insertion point (the insertion point must be in the whitespace preceeding or following a word). Press K multiple times to cycle through preceding words in succession.
Cmd-Shift-K Copies the word following the insertion point and pastes it at the insertion point (the insertion point must be located in the whitespace preceeding or following a word.) Press L multiple times to cycle through consecutive following words.

To Change Default Settings:

  1. Choose Tools > Options from the main menu.
  2. For code templates, select Editor and click the Code Templates tab. Here you can also change the expansion key, from Tab to something ese.
  3. For keyboard shortcuts, select Keymap and choose a profile from the Profile drop-down list.

10 Handy Editor Shortcuts

  1. Move/copy up/down. Press Ctrl-Shift-Up and the current selection is copied to the lines right above the current selection. Press Alt instead of Ctrl and it is moved instead of copied. Press Down instead of Up and the lines of code will be copied below the current selection, as below:

  2. Capture inner/outer syntactic element. Each time you press Alt-Shift-Period, the selection expands to a successively wider syntactic element.

    For example, below one statement was selected, the key combination Alt-Shift-Period was pressed, and then the complete content of the surrounding block statement was shown to be selected.

    The selection expands from the current statement to sur rounding block statements to the surrounding method and, from there, to the surrounding class and further. To successively narrow the selection, press Alt-Shift-Comma, instead of Alt-Shift-Period

  3. Generate code skeletons. Whenever you want to generate commonly needed pieces of code, such as constructors, getters, and setters, simply click Alt-Insert, and a small popup appears with a list of items from which you can select: 10 Handy Editor Shortcuts in NetBeans IDE 6.0 as constructors, getters, and setters, simply

  4. Inplace rename. If you want to change a variable, method, or other item, of which more than one are used in your code, press Ctrl-R, and you will see that all instances of the item turn blue at the same time, as shown below. Now, when you change the selected item, all the other instances change at the same time, until you press Escape, at which point the inplace rename mode comes to an end.

  5. Add/Remove comment lines. Select one or more lines, press Ctrl-/ and then the selected lines are commented out, as shown below. Press the same keys again and the commented lines will no longer be commented.

  6. Inspect members/hierarchy. Both the members of the current class as well as its hierarchy can be displayed and then filtered. Press Alt-F12 and the ancestors of the current file are shown. On the other hand, if you press Ctrl-F12, the current file’s members are displayed, as shown here:

  7. Switch between documents. When you have multiple documents open at the same time, press Ctrl and Tab, and then a small popup appears. You can scroll through the popup, which displays all the open documents, and then choose the document that you want to open:

  8. Jump to last edit. Often, you find yourself in a situation where you have edited in one document, while you currently find yourself in a completely different document. How do you get back to the place where you were last editing your code? That is likely to be the place where you want to get back to, in order to do some more editing. Now, whenever you click Ctrl-Q, the last edited document is found, and the cursor lands on the line where the last edit took place. Alternatively, you can click the button shown below, in the top left corner of the Source Editor:

  9. Bookmarks. When you press Ctrl-Shift-M, the current line is “bookmarked”. What this means is that you can later quickly cycle back/forward to it (with Ctrl-Shift-Period and Ctrl-Shift-Comma). The bookmarked line gets a small icon in the left sidebar, as shown below, until you press Ctrl-Shift-M on the line again, to remove the bookmark:

  10. Highlight exit points. Place the cursor on the return type and you will immediately see all exit points highlighted:

Quick Options Window Overview

General Sets the IDE-wide browser and proxy settings
  • Web Browser
  • Proxy Settings
Editor Sets the editor-specific options, specifically those relating to code folding, code completion, camel case behavior, indentation, code templates, and macros.
  • Code Folding
  • Code Completion
  • Camel Case Behavior
  • Indentation
  • Code Templates
  • Macros
Fonts & Colors Sets the fonts and colors for syntax, highlighting, annotations, and diff viewer.
  • Syntax
  • Highlighting
  • Annotations
  • Diff
Keymap Sets the keyboard profile to be used throughout the IDE. By default, profiles are provided for NetBeans, Eclipse, and Emacs. A legacy profile is also provided, for NetBeans 5.5 keyboard shortcuts, which were radically rewritten in NetBeans IDE 6.0.
  • NetBeans Profile
  • Eclipse Profile
  • Idea Profile
  • Emacs Profile
  • Netbeans 5.5 Profile
Miscellaneous Sets the options for Ant processing, appearance, diffing, files, the Matisse GUI Builder, issue tracking, Java Debugger, JavaScript, Maven, Profiler, ToDo Tasks, and Versioning.
  • Ant
  • Appearance
  • Diff
  • Files
  • GUI Builder
  • Issue Tracking
  • Java Debugger
  • JavaScript
  • Maven
  • Profiler
  • Tasks
  • Versioning

Resources

Resource URL
NetBeans DZone Community http://netbeans.dzone.com/
NetBeans Tutorials http://www.netbeans.org/kb/index.html
NetBeans Video Tutorials http://www.netbeans.org/kb/60/screencasts.html
NetBeans Blogs http://planetnetbeans.org/
NetBeans TV http://netbeans.tv/
NetBeans Weekly Newsletter http://www.netbeans.org/community/news/newsletter/latest.html

Thanks to the following people who kindly gave of their time and expertise in reviewing this refcard: Adam Bien, Tonny Kohar, Varun Nischal, Kristian Rink, and Tom Wheeler.

Geertjan Wielenga

Photo of author Geertjan Wielenga

Geertjan Wielenga is the NetBeans technical writer responsible for documentation related to the NetBeans Java editor. He is co-author of the book Rich Client Programming: Plugging into the NetBeans Platform. He is known for his popular blog at http://blogs.sun.com/geertjan, as well as for his role as a Zone Leader at Javalobby.

Patrick Keegan

Photo of author Patrick Keegan

Patrick Keegan has been writing about the NetBeans IDE for over 9 years. In addition to writing help and tutorials, he is co-author of the NetBeans IDE Field Guide and has contributed to other books on NetBeans and Java.

Recommended Book

Book cover of Pro Netbeans IDE 6

Pro NetBeans IDE 6 Rich Client Platform Edition focuses on the new features of NetBeans 6 as well as what has changed since NetBeans 5.5, empowering you to be a more effective and productive developer.

Book cover of Definitife Guide to the Netbeans Platform

The Definitive Guide to NetBeans™ Platform is a thorough and definitive introduction to the NetBeans Platform, covering all its major APIs in detail, with relevant code examples used throughout.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Daily Dose: CloudBees Extends Java PaaS to Private Cloud

CloudBees now supports OpenStack and vSphere. This new move will extend CloudBees' Java PaaS support to the private cloud environment, i.e. behind company firewalls.  Until now, Run@cloud service has traditionally been implemented publicly using Amazon's EC2...

0 replies - 18266 views - 04/26/11 by Katie Mckinsey in Daily Dose

Spring Roo

Making Java Fun Again

By Stefan Schmidt

16,376 Downloads · Refcard 139 of 151 (see them all)

Download
FREE PDF


The Essential Spring Roo Cheat Sheet

Spring Roo is a popular open-source rapid application development (RAD) tool for Java developers. It enables the developer to build best-practice, high-quality, lock-in-free enterprise applications in minutes. Roo is also highly modular: it allows developers to extend its functionality by installing new add-ons in a secure way. This DZone Refcard will show you how to get started with your first project and will introduce you to the key features of Spring Roo. You’ll be guided through the source code, common commands, dynamic finders, remoting support, incremental database reverse engineering, and removing Spring Roo.
HTML Preview
Spring Roo: Open-Source Rapid Application Development for Java

Spring Roo:Open-Source Rapid Application Development for Java

By Stefan Schmidt

ABOUT SPRING ROO

Spring Roo is a popular open-source rapid application development (RAD) tool for Java developers. It enables the developer to build best-practice, high-quality, lock-in-free enterprise applications in minutes – a task that would otherwise take days if not weeks. Developers using Roo can fundamentally and sustainably improve their productivity without compromising engineering integrity or flexibility. Roo is highly modular: it allows developers to extend its functionality by installing new add-ons in a secure and trusted way.

You can load the Spring Roo shell in the background and let it monitor your project or directly interact with it by issuing shell commands. The shell offers many usability features such as tab completion, context awareness, help and hinting support and automatic roll-back. Roo even keeps a log of your shell commands so you can easily replay them if desired.

ARCHITECTURAL OVERVIEW

Projects created with Spring Roo are standard Java enterprise applications using the Spring Framework. This means you’ll find all the typical artifacts such as Java source files, XML configuration files, properties files and view artifacts such as jspx files in your project. Besides automatic configuration of Maven build artifacts, logging and dependency injection, Roo allows you to connect to or transparently create new backend databases. It achieves that by automatically configuring the Spring application context for your database and object relational mapping (ORM) tool through the Java Persistence API (JPA) standard. Transaction management is also configured out of the box. Furthermore, it can take care of maintaining your JUnit integration tests, Web front-ends and other common project layers.

Image 1

Spring Roo’s unique approach

One of the major benefits of using Spring Roo is its deep integration of AspectJ’s inter-type declaration (ITD) features. This allows Roo to automatically produce and maintain boiler-plate code such as getter and setter methods in a different compilation unit (the .aj file). AspectJ ITD files are kept separate from the normal .java code you’d write as a developer so Roo can maintain the file’s lifecycle and contents completely independently of whatever you are doing to the .java files. Your .java files do not need to do anything unnatural like reference the generated ITD file and the whole process is completely transparent.

Spring Roo selectively merges the best of the passive and active code generation models. Roo will passively ‘watch’ (i.e., read and monitor) any activity in your project’s .java sources and automatically adjust the AspectJ ITDs in the background to support your activities. For example, typical domain classes only contain field definitions that are either added through Roo shell commands (passive generation – the user asks for it) or manually added by the developer in the IDE. Boilerplate code like toString(), accessors and mutators for the fields as well as many other functionalities are then transparently added and managed in the ITDs. Roo will actively make adjustments in the ITDs when the developer renames or deletes the field from his Person.java file. Note that source code members like the toString() or getName() and setName() methods in a separate file (.aj) are fully available for code completion in modern IDEs such as STS and IntelliJ thanks to fully integrated support for AspectJ Eclipse.

Image 2

Since the ITDs are not expected to be edited by the developer, Roo can manage the contents of an ITD actively. This allows Roo to integrate new features in Spring Framework once they become available or make the code more efficient simply by updating the ITD sources when upgrading to a new version of Spring Roo.

A development-time only tool

The ITD files are automatically managed by the Spring Roo shell, which is kept running in the background while developing your project. The contents of the ITDs can be controlled and customized by Java annotations placed in your .java source files. These annotations always start with @Roo and are sourcelevel retention only: hence, they are not compiled in your .class files. This means that Roo-managed applications deployed to production environments have absolutely no dependency on Roo itself. You can observe this by taking a look at your application runtime classpath; for example, in Web applications, your WEBINF/ lib directory will contain no Roo-related JARs.

The use of Spring Roo as a productivity RAD tool that is present only at development time brings many advantages; you avoid lock-in, keep full flexibility for future extensions and gain better performance due to the absence of additional runtime dependencies. Furthermore, there is no scope for possible Roo bugs to affect your project, and there is no risk of upgrading to a later version of Roo due to the lack of executable code anywhere in your project classpath.

Roo’s default architecture

Depending on the requirements of the application, there are a number of approaches to designing and subsequently layering a Java enterprise application. Persistence logic is often encapsulated in a Data Access Object (DAO) layer in combination with an additional repository layer. In front of these persistence layers, developers frequently use a façade or service layer, which can contain business logic that applies to multiple domain types. In MVC-style Web applications, there is a controller layer and finally there is a domain layer. There are ,of course, any number of alternative approaches to architecting enterprise Java applications.

In a typical Roo application, you’ll only use an entity layer (which is similar to a domain layer) and a web layer. An optional services layer might be added if your application requires it, although a DAO layer is rarely added. The domain entity approach taken by Roo is conceptually related to the active record pattern employed by many modern RAD frameworks. Through the use of separate ITDs for adding different functionalities to a target type, Roo applications still adheres to the separation of concerns principle.

For more information on high-level features and concepts employed by Spring Roo, refer to the first sections of the reference documentation.

FIRST HOPS

Spring Roo is easy to install as standalone tool and runs on Windows, Mac OSX and Linux alike. Integrated development environments (IDEs) for Java such as the SpringSource Tool Suite (STS), Eclipse (+ AJDT) and JetBrains IntelliJ also integrate Spring Roo directly into their toolset.

The only prerequisites for running the Spring Roo shell are a working Java 6 SDK and Apache Maven (2.0.9+) installation. Once these two are installed, you can go ahead and download and unpack the Spring Roo distribution. You can find the ~7MB download for the latest release of Spring Roo at http://www.springsource.com/ download/community?project=Spring%20Roo. Once downloaded, simply unpack it into and add it to your path. Windows users can add %ROO_HOME%\bin to their path and *nix users can create a symbolic link to $ROO_HOME/bin/roo.sh.

Alternatively, you can install STS, which includes an integrated version of the Spring Roo shell without any need for further configuration.

Once this is complete, you can simply start your Spring Roo shell in a fresh directory:

Image 3

The Spring Roo shell

The Spring Roo shell offers hinting support for newcomers. This way you can learn about the suggested steps beginning with the creation of a new project, followed by configuration of persistence features to the creation of your first domain classes.

Tab completion plays a central role when using the Spring Roo shell. By simply hitting the Tab key, the Roo shell will offer commands, command attributes or even brief comments about the functionality offered by a command or a command attribute. Typing the first letters of a command followed by Tab will complete the command. Subsequent uses of Tab will complete mandatory command attributes until a user selection or input is required. Note, the integrated Roo shell in STS uses the Ctrl + Space key combination familiar to Eclipse users in lieu of the Tab completion in the standalone Roo shell.

The Roo shell will automatically hide commands, which are not applicable in the current context. For example, the ‘persistence setup’ command will not be shown when using Tab before a new project has been created using the ‘project’ command. Roo also offers help for any of the commands it offers. To see help details for the ‘persistence setup’ command, simply type ‘help persistence’ and Roo will present a short description and also all mandatory and optional command attributes along with a brief description for each. Finally, the Roo shell will automatically rollback changed files in case a problem is encountered.

Your first Roo project

The first action to take in a new Spring Roo managed project is to create a new project:


roo> project –topLevelPackage net.addressbook
Created /home/sschmidt/AddressBook/pom.xml
Created SRC_MAIN_JAVA
Created SRC_MAIN_RESOURCES
Created SRC_TEST_JAVA
Created SRC_TEST_RESOURCES
Created SRC_MAIN_WEBAPP
Created SRC_MAIN_RESOURCES/META-INF/spring
Created SRC_MAIN_RESOURCES/META-INF/spring/applicationContext.xml
Created SRC_MAIN_RESOURCES/log4j.properties

As you can see, Roo has created a standard Maven project layout with a Spring application context and a Log4J configuration. After the creation of the project, you can type ‘hint’ and follow the suggestions for your next steps. Note, the integrated ‘hinting’ support is context sensitive. This means that the ‘hint’ command is aware of state of your project and adjusts its suggestions accordingly. For example, after the creation of a new project, the ‘hint’ command will suggest to configure your persistence setup.

code img

Then in the same fashion, you can create your first domain entity (along with a JUnit integration test) and create a few fields for it:


roo> entity --class ~.domain.Person --testAutomatically
~.domain.Person roo> field string --fieldName name
~.domain.Person roo> field date --fieldName birthDay --type java.util.Date

Of course, you can refine your domain model through the Spring Roo shell or directly in your .java source code, create new types, fields, references, etc.

Once your work is complete, you may want to test the integrity of your domain model by running the Roo generated integration tests. You can do that by running ‘perform tests’ in the Roo shell, ‘mvn test’ in your normal shell or through your IDE. The integration tests will execute against your configured database and the test data will be cleaned up automatically after the tests have completed.

Taking a look at the source code

A quick look at Person.java reveals the advantage of using
AspectJ ITDs:


package net.addressbook.domain;

import org.springframework.roo.addon.entity.RooEntity;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.tostring.RooToString;
import java.util.Date;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.format.annotation.DateTimeFormat;

@RooJavaBean
@RooToString
@RooEntity
public class Person {

	private String name;
	
	@Temporal(TemporalType.TIMESTAMP)
	@DateTimeFormat(style = “S-”)
	private Date birthDay;

}

As mentioned before, the repetitive boilerplate code for things like the toString() method, mutators and accessors are managed by Spring Roo in separate AspectJ ITDs in the background, leaving you with a more concise code artifact that is much easier to manage and comprehend. Roo has also taken care of correctly configured JPA annotations (such as @Temporal) and Spring annotations (such as @DateTimeFormat) to your fields where appropriate to provide correct persistence and conversion behavior. You’ll notice the @RooToString annotation has also been added automatically that triggers Roo to produce the following ITD:


package net.addressbook.domain;

import java.lang.String;

privileged aspect Person_Roo_ToString {

	public String Person.toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(“Name: “).append(getName()).append(“, “);
		sb.append(“BirthDay: “).append(getBirthDay());
		return sb.toString();
	}
}

You will notice that the toString() method looks just like a normal Java method with the only difference of the AspectJ target type definition in front of the method name. Furthermore, AspectJ type definitions use the ‘privileged aspect’ definition instead of ‘public class’ you would see in typical Java sources.

As discussed in the previous section, Spring Roo integrates all persistence related functionality through an ITD into the target type. This allows for a lean architecture without compromising on functionality or flexibility. Take a look into the Person_Roo_Entity.aj ITD to see the code generated and maintained by Roo. By default Roo will generate the following methods to support persisting your Person domain entity (listing contains the most relevant methods only):

Method Name Purpose
void persist() Save a new person record.
Person merge() Update an existing person record.
void remove() Remove an existing person record.
Person findPerson(ID) Find a person record by ID.
List<Person> findAllPeople() Retrieve a list of all persistent Person records.
List<Person> findPersonEntries(from, to) Retrieve a list of persistent Person records for a given range.
long countPeople() Return a count of all Person records.

roo> controller all --package ~.web

This command will automatically scaffold a complete Spring MVC Web UI which features:

  • Best-practice Spring MVC out of the box
  • REST support (JSON integration optional)
  • Round tripping of view artifacts (jspx)
  • Customizable tag library (tagx)
  • Integrated templating support (Tiles)
  • Theming support (Spring MVC & CSS)
  • Pagination support
  • i18n & i11n built-in
  • Form validation based on JSR 303
  • Rich Dojo UI widgets for data selectors, etc

You can easily deploy your Web application to the configured Tomcat or Jetty Web containers in your project by issuing ‘mvn tomcat:run’ or ‘mvn jetty:run’ respectively and then navigate to your Web application in a Web browser:

Web Browser

If you prefer a UI scaffolded using Google Web Toolkit (GWT), you can issue the following command:


roo> gwt setup

This command will provide a complete GWT-based UI with similar features to the MVC UI shown above:

Data Browser

Common commands

Let’s recap what you have done so far by issuing just a few commands. You have created a fully configured and working enterprise Java application using Maven, Spring Framework with features such as dependency injection, transaction support, MVC, JSP, Tiles, CSS, Dojo, JPA, AspectJ, Java Bean Validation (server and client side), JUnit, Log4J and more.

The following table summarizes some of the common commands you should know about to get started with a new Spring Roo project:

Command Purpose
project --topLevelPackage [..] Creates a new Spring Roo managed project.
persistence setup --provider
[..] --database [..]
Installs or update a persistence provider and a database connection for your project.
entity --class [..] Creates a new persistent entity in your project.
field string | number |
boolean | date | set | [..]
Inserts a private field into the specified java file.
enum type | constant [..] Inserts enum types and constants into your project.
test integration | mock | stub Creates a new integration | mock | stub tests for the specified entity.
controller all | scaffold [..] Creates a Spring MVC UI for your domain model.
gwt setup Creates a GWT UI for your domain model.
security setup Installs a Spring Security configuration for your project.
logging setup --level [..] Configures logging in your project.

For a more complete reference of all available commands (and command options), refer to the command index at:
http://static.springsource.org/spring-roo/reference/html-single/ index.html#command-index

BUT WAIT... THERE’S MORE!

As you have guessed, so far we have barely scratched the surface of Spring Roo. There are many more features offered by Roo.

Incremental database reverse engineering

With the Roo 1.1.x release, a new add-on called ‘incremental database reverse engineering’ (DBRE) was added to Roo’s toolset. DBRE allows you to create a complete JPA-based domain entity layer based on the introspection of tables in your database. In addition, DBRE can maintain your domain entity model incrementally to synchronize all changes to the data model.

For example, data model changes such as adding, removing or renaming tables or columns in your database will be detected by DBRE. DBRE has been designed to enable developers to repeatedly re-introspect a database schema and synchronize all changes with the application domain model on demand. This approach is different to traditional JPA reverse engineering tools, which introspect a database schema and produce a Java application tier only once.

DBRE setup

The typical workflow when using the DBRE feature for the first time is to create a new project with the Spring Roo shell:


roo> project --topLevelPackage net.addressbook.dbre

This is then followed by setting up your persistence configuration:


roo> persistence setup --provider HIBERNATE --database POSTGRES
--databaseName addressbook --userName rootest --password rootest

If you have not previously installed the database driver, add-on you need to do so (this is a one-off operation):


roo> addon search postgres /* search for the postgres jdbc add-on */
roo> addon install id 2 /* install search result #2 for postgres addon,
assuming the author is trusted */

You can now try out the DBRE add-on by using the ‘database introspect’ command, which displays the database structure, or schema, in XML format. This can be used to preview the domain model structure which DBRE will create based on your data schema.

Finally, you can use the database reverse engineer command to create your domain entity model based on the database schema:


roo> database reverse engineer --schema addressbook

Once the domain model has been created, you can scaffold a Web UI of your choice (see previous section).

Dynamic finders

Another popular Spring Roo add-on is the dynamic finder add-on. This add-on allows you to define search query methods for your entity domain model based on method names. The dynamic finder add-on can suggest any number of these names using the ‘finder list’ command and you can then select an appropriate finder, name to let the dynamic finder add-on take care of code generating the appropriate query:

Search1

You can also combine fields and subsequently filter search results as follows:

Search 2

Once you have found the appropriate finder you can install it with the ‘finder add’ command:

Search 3

Note, the finder add-on creates a new AspectJ ITD, which introduces the findPeopleByBirthDayBetweenAndNameLike(Date minBirthDay, Date maxBirthDay, String name) method to the Person.java target type.

Furthermore, the Spring MVC scaffolding can automatically scaffold a search form for your finders:

Search Finder

Remoting support

Java Message Service (JMS)

Spring Roo offers an add-on to integrate JMS functionality into your application. Specifically, this add-on allows you to define a message sender, a message listener and even the configuration of an in-memory message queue service (based on Apache ActiveMQ). Optionally, to support asynchronous execution of the message sending functionality you can easily add the new @Async feature introduced in Spring Framework v3.

To get started, the Roo JMS add-on offers the ‘jms setup’ command:


roo> jms setup --provider ACTIVEMQ_IN_MEMORY

The add-on will take care of adding all necessary configurations and dependencies to your application.

The ‘field jms template’ command allows you to configure a JMS sender in an arbitrary target type in your application:


roo> field jms template --class ~.domain.Person --async

This will create a dependency injected field of type JmsTemplate and also a sendMessage(Object message) method in the target type.

Finally, you can use the ‘jms listener class’ command to create a new class in your application, which will receive messages from the queue:


roo> jms listener class --class ~.jms.MyListener

Email support

The Spring Roo email add-on offers commands to configure Spring Framework email support in your application context. For example, it offers the ‘email sender setup’ command:


roo> email sender setup --hostServer smtp.gmail.com --port 587
--protocol SMTP --username foo --password foo

Similar to the JMS add-on, the email add-on also offers a field command which offers an optional asynchronous configuration:


roo> field email template --class ~.domain.Person --async

This will create a dependency injected field of type MailSender and also a sendMessage(String mailFrom, String subject, String mailTo, String message) method in the target type.

JSON serialization support

The JSON add-on offers JSON support in the domain layer as well as the Spring MVC scaffolding. A number of methods are provided to facilitate serialization and deserialization of JSON documents into domain objects. To install JSON integration, you can use ‘json all’ command:


roo> json all

This will install a number of methods in each discovered domain type:

Method Function
String toJson() Serializes Person to a JSON representation.
Person fromJsonToPerson(String json) Creates a Person instance from a JSON document.
String toJsonArray (Collection<Person> collection) Serializes a collection of people to a JSON array representation.
Collection<Owner> fromJsonArrayToOwners(String json) Creates a Person collection from a JSON document.

TIPS & TRICKS

Taking control

Sometimes, the developer may want to customize the way a certain member is implemented that is provided through a Roo ITD. Since code changes to the Roo managed ITDs are not preserved, the developer needs a way to take control over the member without loosing Roo’s benefits of maintaining the rest of the members provided in the ITDs.

Spring Roo offers a convenient approach to this called ‘push-in refactoring’. Push-in refactoring is achieved by simply moving the member that needs customization from the ITD to the associated .java source file. You can do this manually in a text editor by simply copying the code from the ITD and pasting it into the target .java file (and removing the AspectJ target type definition from the member signature) or by leveraging the ‘pushin refactoring’ support in Eclipse / STS.

Refactoring Support

Roo will automatically detect if a member (i.e., a method or field), which it could code-generate in an ITD, is present in the target .java source file and refrain from adding it to the ITD (or remove it if it is currently present). Due to its passive approach with regards to any code found in .java source files, Roo will simply read your member and make adjustments to the ITDs if appropriate. This will allow you to customize the member in your .java sources without any interference by Roo.

Removing Roo in three easy steps

As mentioned in the first section of this Refcard, Spring Roo does not lock the developer in. Due to its nature of being a development-time only RAD tool, it is almost trivial to remove all Roo artifacts from your project.

Hot Tip

Before removing Spring Roo from your project, we recommend to back up your project by simply using the ‘backup’ command.
Step 1: Push-in refactor

As discussed in the previous section, Eclipse / STS offer push-in refactoring of individual members. In fact, it does not only offer this for individual members but also for complete types, packages or even your complete project. So a push-in refactoring of your project will move all source code from the Spring Roo managed AspectJ ITDs into their respective Java source targets.

Step 2: Remove all @Roo annotations from source code

While your project is now free of AspectJ ITDs, your .java files will still have @Roo annotations within them. In addition, there will be import directives at the top of your .java files to import those @Roo annotations. You can easily remove these unwanted members by clicking Search > Search > File Search in Eclipse / STS, containing text “\n.*[@\.]Roo[^t_]+?.*$” (without the quotes), file name pattern “*.java” (without the quotes), ticking the “Regular expression” check-box and clicking “Replace”. When the following window appears and asks you for a replacement pattern, leave it blank and continue.

Search Window 1
Step 3: Annotation JAR Removal

Now that all references to annotations contained in your org.springframework.roo.annotations-*.jar library are removed from your Java sources, you can open your project pom.xml and search for the following dependency:


<!-- ROO dependencies -->
<dependency>
	<groupId>org.springframework.roo</groupId>
	<artifactId>org.springframework.roo.annotations</artifactId>
	<version>${roo.version}</version>
	<scope>provided</scope>
</dependency>

You can delete (or comment out) the entire <dependency> element. If you’re running STS or Eclipse with m2Eclipse installed, there is no need to do anything further. If you used the command-line mvn command to create your Eclipse .classpath file, you’ll need to execute mvn eclipse:clean eclipse:eclipse to rebuild the .classpath file.

Roo has now been entirely removed from your project and you should rerun your tests and user interface for verification of expected operation.

Re-enabling Roo ITDs

If you wish to re-enable support for Roo ITDs in your project, you need to add/enable the Roo annotations jar dependency in the project pom.xml, annotate the relevant java sources with the @Roo annotations and then use the Eclipse / STS Refactor > Pull Out ITD feature to move the source code out of your java sources. This is required because Roo takes a passive approach to managing your java source files. This means it would not touch any code in your java source files unless you explicitly tell it to.

CONCLUSION

Spring Roo delivers serious productivity gains to Java developers. It offers integration with popular, proven Java technologies you already know. It is easy to learn, easy to use and easy to extend. It builds on Java’s strengths. It supports the developers to create best-practice enterprise Java applications with excellent performance while maintaining engineering flexibility with no runtime, no lock-in and no risk.

Spring Roo Resources

Website: http://www.springsource.org/roo
Twitter: http://twitter.com/springroo

About The Authors

Dr Stefan Schmidt

Dr Stefan Schmidt has been a Software Engineer with SpringSource since early 2008. He is currently based in the Sydney, Australia office, where he has been a key Roo developer since the project began. Stefan’s work on Roo focuses on many of the most popular add-ons, including those which provide web, search and messaging features. Stefan has been developing Java enterprise applications since 2003. Prior to his work at SpringSource, Stefan has been teaching various Enterprise Java subjects at the University of Technology in Sydney. He mentored hundreds of students in the design of enterprise software architectures with focus on scalability, separation of concerns and design patterns using enterprise Java technologies.

Recommended Book

Roo in Action

Roo in Action is a unique book that teaches you how to code Java in Roo, with a particular focus on Spring-based applications. It starts by getting you into the Roo mindset, covering Aspect Oriented Programming and annotations within a don’t-repeat-yourself, convention-overconfiguration framework. Through hands-on examples, you’ll learn how Roo creates well formed application structures and supports best practices and tools. Plus, you’ll get a quick-and-dirty guide to setting up Roo effectively in your environment

Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

Daily Dose: FuseSource IDE for Camel

Fuse IDE for Camel, the new integrated development environment for Camel, is now available through FuseSource's Fuse Mediation Router subscription.  Thanks to Eclipse-based tooling, the new IDE has a more user-friendly GUI.  Using the Eclipse-based GUI...

0 replies - 15137 views - 04/12/11 by Katie Mckinsey in Daily Dose

Daily Dose : Java 7 Developer Preview Builds Finally Available!

Oracle's new Java 7 JDK, or JDK7, is now available for download by developers. This version of JDK7 has been officially feature complete since the beginning of the year. Users are encouraged to report bugs between now and the end of March.  Just remember...

1 replies - 21355 views - 02/24/11 by Katie Mckinsey in Daily Dose

Mastering Portals with a Portlet Bridge

By Wesley Hales

6,755 Downloads · Refcard 132 of 151 (see them all)

Download
FREE PDF


The Essential JBoss Portlet Bridge Cheat Sheet

Portals have long been a thorn in the side of many developers who want to stay cutting edge, but most focus on the needs of the enterprise. About 99% of the time, a portal is the only answer for aggregating many applications into a single UI. A portlet bridge allows you to run application frameworks like JSF in a portal environment without worrying about the underlying portlet API or portlet concepts. Portlet bridge is a must-have mediator when working with portals, and it allows developers to learn a new technology painlessly. This Refcard provides specific configurations for the JBoss Portlet Bridge.
HTML Preview
Mastering Portals with a Portlet Bridge

Mastering Portals with a Portlet Bridge

By Wesley Hales

ABOUT PORTLET BRIDGES

Portals have long been a thorn in the side of many developers who want to stay cutting edge—but must focus on the needs of the enterprise. And 99% of the time, a portal is the only answer for aggregating many applications into one UI.

A portlet bridge allows you to run application frameworks like JSF in a portal environment without worrying about the underlying portlet API or portlet concepts.

The JSR-301/329 portlet bridge boasts ease of transition, ease of initiation, and seamless mappings from JSF to the portal environment. Overall, a portlet bridge is a must-have mediator when working with portals, and it allows developers to learn a new technology painlessly.

ABOUT THE JBOSS PORTLET BRIDGE

This refcard shows specific configurations for the JBoss Portlet Bridge. The JBoss Portlet Bridge is a non-final draft implementation of the JSR-329 specification which supports the JSF 1.2 and 2.0 runtime within a JSR 168 or 286 portlet and with added enhancements to support other web frameworks (such as Seam and RichFaces).

The project follows the spec from JSR-301 to JSR-329 and now maintains an alpha version (3.0) compatible with JSF 2.0 and RichFaces 4.0.

Versions

Since this portlet bridge spans four different JSRs and supports two additional JSF frameworks, understanding versions can be a little daunting. i.e. Just because the portlet bridge is versioned at 2.0 does not mean it covers the JSF 2.0 specification.

JBoss Portlet Bridge Latest Versions Compatible Frameworks
2.1.0.FINAL JSR-286 Portlets, JSF 1.2, RichFaces 3.3.3.FINAL,Seam 2.2.1.CR2
3.0.0.ALPHA SR-286 Portlets, JSF 2.0, RichFaces 4.0

IN THE BEGINNING, THERE WERE PORTLETS

It would only be fair (and cruel in some states) if I gave you a brief primer on portal and portlet technologies. There will come a day when you will need to understand what an ActionRequest is and what you can pull from your FacesContext.ExternalContext() while running as a JSF portlet.

Portal Terminology

Portal

Hosts the presentation layer for personalization, single sign on and content aggregation.

Portlet Container

A portal can host multiple portlet containers, and each portlet container has its own runtime environment.

Portal Page: Aggregation of portlets, organized and displayed on a single page.

Portlet: A portlet is a Java technology-based web component, managed by a portlet container, that processes requests and generates dynamic content.

Portlet Instance: A portlet instance can be placed on multiple pages and will show the same state in regards to the current mode.

Portlets vs. Servlets

Most rookie portlet developers have their roots in the servlet world. So it’s important to know the key differences in what you’re about to dive into from what you’ve been dealing with. Portlets generate a portion or “fragment” of the HTML page they’re being displayed upon. This is the first big bullet point in understanding differences between servlets and portlets. UI wise, they cannot make use of the same html (for instance the standard <html> <head> <title> and <body> are forbidden in the portlet markup). The job of writing these tags belongs to the Portal Page and not you, the developer.

Points To Remember
  • Portlet URLs, which are used as links to other pages within your Portlet window, are dynamically pre-generated by the Portlet code and passed into the markup.
  • Although servlets and portlets are in some respects similar, their containers and lifecycles differ.
  • On the front end, portlets are HTML fragments that compose a larger page which they are unaware of. Servlets provide the entire page.
  • Portlets cannot be accessed by use of a single URL, the way in which servlets are accessed. Instead, the URL points to the page where many portlets may be contained.
  • The portal request paradigm is completely different. There are two requests instead of one. This is talked about in the next section.
  • You now have mode and state buttons that allow you to “minimize” or “maximize” the portlet window or enter “help” mode.
  • Portlets support two scopes within the session (PORTLET_SCOPE and APPLICATION_SCOPE). This allows for cases like sharing data from one portlet to another.
  • Portlets are not allowed to set character encoding on the response, set HTTP headers, or manipulate the URL of the client request to the portal.
Portlet Lifecycle

Once you wrap your head around the fact that there are two requests and the Portal sends them for you, the rest is a piece of cake. What I’m about to explain makes total sense, but it’s a huge change from the way things are done in a Servlet-based web app. In the Servlet world, a Servlet owns the process of receiving an entire web request and rendering output at the same time in one big response. In the Portlet world, the Portal receives the web request then makes separate calls to individual portlets. This separation allows for a different lifecycle method to be introduced in Portlets. The two requests are called Action and Render, and each have their own request and response. You must first keep in mind that when you click a link or submit button in the portlet window, it has been generated by the portal API. Thus, the portal needs to control/remember things like which window is sending the request, modes, parameters, window states, etc. So when an Action link is clicked, the portal will get this information and run processAction() along with a few other methods in your portlet. You are guaranteed that this action will be complete before the rendering phase starts. Once this is done, the portal now needs to re-render the page along with all the other portlets on that page. The best thing to keep in mind is portlets may be asked to render, even when the user is not interacting with them. Conceptually, this makes sense to have the two requests. However, developers have been naturally forced to do both of these things at the same time in the servlet world.

In most cases, when converting an existing servlet based application to a portlet, you must use a portlet bridge so that URLs are generated for the portlet world—along with other framework functionality.

GIVING PORTLETS A SECOND CHANCE

If You Skipped The First Page...

It’s okay because the portlet bridge is created to mask all of those hairy details from the developer so you only have to worry about your web application. You can now take your existing JSF-based application and plug it into a portal painlessly.

Getting Started

Use the following maven archetype command:


mvn archetype:generate
-DarchetypeCatalog=http://bit.ly/jbossportletbridge

frame 1

Choose from the available projects and you will have everything you need to start developing a new portlet. If you are moving an existing application to a portlet, this will serve as a reference point for configuration.

Archetype Options

You will also see other configuration options like “makeremotable” and “richfaces-javascript-namespace” in the archetype generate phase.

Option Purpose
make-remotable Boolean property that will create the configuration for running this portlet remotely over WSRP
richfaces-javascriptnamespace Boolean property that allows for namespacing dynamically generated RichFaces javascript.

CONFIGURATION

The portlet bridge is a mediator between your web application and the portal worlds. It is not a portlet. So here we will review the changes you must make to convert your current JSF application into a portlet.

Core JSF Portlet Setup

portlet.xml

The following config is the backbone of your portlet. It shows where the supplied GenericFacesPortlet is and which JSF pages to render when clicking on the mode buttons (i.e. help, edit, etc...).


<portlet>
<portlet-name>yourPortletName</portlet-name>
<portlet-class>
	javax.portlet.faces.GenericFacesPortlet
</portlet-class>
<init-param>
	<name>javax.portlet.faces.defaultViewId.view</name>
	<value>/welcome.xhtml</value>
</init-param>
<init-param>
	<name>javax.portlet.faces.defaultViewId.edit</name>
	<value>/jsf/edit.xhtml</value>
</init-param>
<init-param>
	<name>javax.portlet.faces.defaultViewId.help</name>
	<value>/jsf/help.xhtml</value>
</init-param>

When preserveActionParams is set to TRUE, the bridge must maintain any request parameters assigned during the portlet’s action request. You should set this as true if your application is not receiving request parameters that were set when a button or link was clicked.


<init-param>
	<name>javax.portlet.faces.preserveActionParams</name>
	<value>true</value>
</init-param>

faces-config.xml

The PortletViewHandler ensures that each JSF portlet instance is properly namespaced. Your application will use a combined portal and JSF namespace.


<faces-config>
<application>
	<view-handler>
	  org.jboss.portletbridge.application.PortletViewHandler
	</view-handler>
	<state-manager>org.jboss.portletbridge.application.
PortletStateManager</state-manager>
</application>

web.xml

The following setting tells your portlet to use the FaceletPortletViewHandler when using RichFaces.


<context-param>
	<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
	<param-value>org.jboss.portletbridge.application.
FaceletPortletViewHandler</param-value>
</context-param>

ALWAYS_DELEGATE Indicates the bridge should not render the view itself but rather always delegate the rendering. This is the default setting for Facelets. If strictly using .jsp, then set the following to NEVER_DELEGATE.


<context-param>
	<param-name>javax.portlet.faces.RENDER_POLICY</param-name>
	<param-value>
	   ALWAYS_DELEGATE
	</param-value>
</context-param>

RichFaces Portlet Configuration

web.xml

RichFaces maintains dynamic scripts and styles that are injected in the page at render. The recommended settings for a portal environment are:


<context-param>
	<param-name>org.richfaces.LoadStyleStrategy</param-name>
	<param-value>DEFAULT</param-value>
</context-param>
<context-param>
	<param-name>org.richfaces.LoadScriptStrategy</param-name>
	<param-value>ALL</param-value>
</context-param>

RichFaces does not account for multiple components on the same portal page by default. This following parameter renders all RichFaces component javascript to be portal friendly.


<context-param>
	<param-name>org.jboss.portletbridge.WRAP_SCRIPTS</param-name>
	<param-value>true</param-value>
</context-param>

Seam automatically configures your Ajax4JSF/RichFaces Filter, so if you are running a Seam portlet, you do not need the following Filter config.


<filter>
	<display-name>Ajax4jsf Filter</display-name>
	<filter-name>ajax4jsf</filter-name>
	<filter-class>org.ajax4jsf.Filter</filter-class>
</filter>

	<filter-mapping>
	<filter-name>ajax4jsf</filter-name>
	<servlet-name>FacesServlet</servlet-name>
	<dispatcher>FORWARD</dispatcher>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>INCLUDE</dispatcher>
</filter-mapping>

Seam Portlet Configuration

Hot Tip

It’s important to remember that your portlet may be rendered many times. Since Seam page actions are performed on the RenderRequest, you should only define your navigation in pages.xml.

The SeamExceptionHandler is used to clean Seam contexts and transactions after errors.


<context-param>
	<param-name>org.jboss.portletbridge.ExceptionHandler</param-name>
	<param-value>
	  org.jboss.portletbridge.SeamExceptionHandlerImpl
	</param-value>
</context-param>

USING PORTLET 2.0 COORDINATION WITH JSF

Portlet container

Portlet 2.0 coordination gives us two ways to communicate between portlets (events and public render parameters). This means you can deploy a JSF 2 war and another JSF 1.2/Seam 2 ear and they can send events and messages to each other.

One very important thing to note before using either of the following mechanisms is that you must have the proper 2.0 schema and xsd definition at the top of your portlet.xml.


<portlet-app xmlns=”http://java.sun.com/xml/ns/portlet/portletapp_
2_0.xsd”
	version=”2.0”
	xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
	xsi:schemaLocation=”http://java.sun.com/xml/ns/portlet/
portlet-app_2_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd”>

Hot Tip

Portlet events and public render parameters cannot be set during Ajax requests.

Sending and Receiving Events

The bridge is designed by default to defer to normal portlet processing when sending events. You should set the following parameters allowing portlet events to be sent directly to the bridge (autoDispatchEvents) and which class should process received portlet events (bridgeEventHandler).


<init-param>
	<name>javax.portlet.faces.autoDispatchEvents</name>
	<value>true</value>
</init-param>
<init-param>
	<name>javax.portlet.faces.bridgeEventHandler</name>
	<value>org.foo.eventhandler</value>
</init-param>

For now, you must dispatch the event in the JSF or Seam backing bean. Future versions of the bridge should automate the dispatching and consuming of events.


if (response instanceof StateAwareResponse) {
	StateAwareResponse stateResponse = (StateAwareResponse)
response;
	stateResponse.setEvent(Foo.QNAME, new Bar());
}

Then you must also create the event handler class by implementing the BridgeEventHandler interface to process the event payload.


public class BookingEventHandler implements BridgeEventHandler
  {
public EventNavigationResult handleEvent(FacesContext context,
Event event)
	{
		//process event payload here
	}
  }

Public Render Parameters

Public Render Parameters (or PRPs) are one of the most powerful and simple Portlet 2.0 features. Several portlets (JSF or not) can share the same render parameters. This feature can be used to present a cohesive UI to the user across all portlets on the page (i.e., using an employee ID to display relative data).

The bridge maps a render parameter to a backing bean using settings in your faces-config.xml and portlet.xml. A clear and working example can be found below.

You must define the following init params in your portlet.xml.


<init-param>
<name>javax.portlet.faces.bridgePublicRenderParameterHandler</name>
<value>org.foo.PRPHandler</value>
</init-param>
...
<supported-public-render-parameter>hotelName</supported-publicrender-
parameter>


Create a managed bean and public-parameter-mapping in your faces-config.xml. This should be a simple bean that you can bind the passed parameter to a string with getter and setter.


<managed-bean>
	<managed-bean-name>bookingPRP</managed-bean-name>
	<managed-bean-class>your.class.Name</managed-bean-class>
	<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<application>
  <application-extension>
	 <bridge:public-parameter-mappings>
	   <bridge:public-parameter-mapping>
		 <parameter>portletName:hotelName</parameter>
		 <model-el>#{bookingPRP.hotelName}</model-el>
	   </bridge:public-parameter-mapping>
	 </bridge:public-parameter-mappings>
  </application-extension>
</application>

Hot Tip

The <parameter> must contain the name of your portlet followed by the parameter name defined in <supportedpublic- render-parameter> from the portlet.xml.

You can set the public render parameter in the JSF or Seam backing bean as follows:


if (response instanceof StateAwareResponse) {
	StateAwareResponse stateResponse = (StateAwareResponse) response;
	stateResponse.setRenderParameter(“hotelName”,selectedHotel.
getName());
}

And finally, in the receiving portlet, you must also implement the BridgePublicRenderParameterHandler interface to process any updates from the received parameter.


public void processUpdates(FacesContext context)
{
ELContext elContext = context.getELContext();
BookingPRPBean bean = (BookingPRPBean) elContext.getELResolver().
getValue(elContext, null, “bookingPRP”);
if(null != bean){
  //Do something with bean.getHotelName());
} else {
}
}

Hot Tip

You can find a working example using all coordination features running on JSF 1.2, RichFaces and Seam here: http://bit.ly/seambooking

SERVING JSF RESOURCES, THE PORTLET WAY

The below example shows how to create a simple bean that uses the portlet resource serving mechanism within a JSF portlet.

By creating a simple class (and defining it in your faces-config.xml) that implements the java.util.Map interface, you can create a “ResourceBean” that will make life much easier on the UI.


public String get(Object key) {
	FacesContext facesContext = FacesContext.getCurrentInstance();
	String url = null;
	if(null == key){
		url = null;
	} else if(null != facesContext){
		url = facesContext.getApplication().getViewHandler().
 getResourceURL(facesContext, key.toString());
		url = facesContext.getExternalContext().encodeResourceURL(url);
	} else {
		url = key.toString();
	}
	  return url;
	}
}

From here, you can serve images and other resources based in your web application by using:


#{resource[‘/img/the-path-to-my-image.png’]}

The source for this example can be found here: http://bit.ly/resourcebean

DEVELOPER TIPS & TRICKS

Excluding Attributes from the Bridge Request Scope

When your application uses request attributes on a per request basis and you do not want that particular attribute to be managed in the extended bridge request scope, you must use the following configuration in your faces-config.xml. Below you will see that any attribute namespaced as foo.bar or any attribute beginning with foo.baz(wildcard) will be excluded from the bridge request scope and only be used per that application’s request.


<application>
<application-extension>
  <bridge:excluded-attributes>
	<bridge:excluded-attribute>foo.bar</bridge:excludedattribute>
attribute>
	<bridge:excluded-attribute>foo.baz.*</bridge:excludedattribute>
attribute>
	</bridge:excluded-attributes>
</application-extension>
</application>

Hot Tip

“From The Spec...” To support Faces, the bridge is responsible for encoding portlet (action) responses in a manner that allows it (and Faces) to reestablish the request environment that existed at the end of the corresponding action phase during subsequent render requests that are identified as pertaining to that action (or event). The term used to describe the scope of this managed data is the bridge request scope.

Supporting PortletMode Changes

A PortletMode represents a distinct render path within an application. There are three standard modes: view, edit and help. The bridge’s ExternalContext.encodeActionURL recognizes the query string parameter javax.portlet.faces.PortletMode and uses this parameter’s value to set the portlet mode on the underlying portlet actionURL or response. Once processed, it then removes this parameter from the query string. This means the following navigation rule causes one to render the \edit.jspx viewId in the portlet edit mode:


<navigation-rule>
	<from-view-id>/register.jspx</from-view-id>
	<navigation-case>
	   <from-outcome>edit</from-outcome>
	   <to-view-id>/edit.jspx?javax.portlet.faces.PortletMode=edit</
to-view-id>
   </navigation-case>
</navigation-rule>

Hot Tip

PortletMode changes require an ActionRequest, so they cannot change modes during an Ajax or ResourceRequest.

Navigating to a mode’s last viewId

By default a mode change will start in the mode’s default view without any (prior) existing state. One common portlet pattern when returning to the mode one left after entering another mode (e.g.. view -> edit -> view) is to return to the last view (and state) of this origin mode. The bridge will explicitly encode the necessary information so that when returning to a prior mode it can target the appropriate view and restore the appropriate state. The session attributes maintained by the bridge are intended to be used by developers to navigate back from a mode to the last location and state of a prior mode. As such, a developer needs to describe a dynamic navigation: “from view X return to the last view of mode y”. This is most easily expressed via an EL expression. E.g.


<navigation-rule>
	<from-view-id>/edit.jspx*</from-view-id>
	<navigation-case>
	  <from-outcome>view</from-outcome>
	  <to-view-id>#{sessionScope[‘javax.portlet.faces.viewIdHistory.
  view’]}</to-view-id>
	</navigation-case>
</navigation-rule>


Hot Tip

You should always wildcard your viewId’s as shown in the above from-view-id. Developers are encouraged to use such wildcarding to ensure they execute properly in the broadest set of bridge implementations.

Clearing The View History When Changing Portlet Modes

By default, the bridge remembers the view history when you switch to a different portlet mode (like “Help” or “Edit”). You can use the following parameter in your portlet.xml to use the default viewId each time you switch modes.


<init-param>
	<name>javax.portlet.faces.extension.resetModeViewId</name>
	<value>true</value>
</init-param>

General Error Handling

Hot Tip

If you’re developing a Seam portlet, you can continue to use pages.xml for all error handling.

The following configuration may be used to handle exceptions. This is also useful for handling session timeout and ViewExpiredExceptions. Pay attention to the location element. It must contain the /faces/ mapping to work properly.


<error-page>
	<exception-type>javax.servlet.ServletException</exception-type>
	<location>/faces/error.xhtml</location>
</error-page>
<error-page>
	<exception-type>javax.faces.application.ViewExpiredException</
exception-type>
	<location>/faces/error.xhtml</location>
</error-page>

Custom Ajax Error Handling

By default, error handling is sent to a standard servlet page for Ajax requests. To handle the error inside the portlet, use the following javascript:


<script type=”text/javascript”>
  A4J.AJAX.onError = function(req,status,message){
	window.alert(“Custom onError handler “+message);
  }
  A4J.AJAX.onExpired = function(loc,expiredMsg){
	if(window.confirm(“Custom onExpired handler “+expiredMsg+” for a
location: “+loc)){
		return loc;
	} else {
		return false;
	}
  }
</script>

Also, add the following to web.xml.


<context-param>
	<param-name>org.ajax4jsf.handleViewExpiredOnClient</param-name>
	<param-value>true</param-value>
</context-param>

Hot Tip

Remember to provide a link to the normal flow of your JSF application from your error page. Otherwise, the same error page will be displayed forever.

Communication Between Your Portlets

There are roughly 4 different ways to send messages, events, and parameters between portlets which are contained in different ears/wars or contained in the same war. The Portlet Container does not care if you have 2 portlets in the same war or if they are separated, because each portlet has a different HttpSession.

Of course, with the Portlet 2.0 spec, the recommended way to share a parameter or event payload between 2 or more portlets are the Section 3.4.2, “Public Render Parameters” and Section 3.4.1, “Sending and Receiving Events” mechanisms. This allows you to decouple your application from surgically managing objects in the PortletSession.APPLICATION_SCOPE.

But, if these do not meet your use case or you have a different strategy, you can use one of the following methods.

Storing Components in PortletSession.APPLICATION_SCOPE

Sometimes, it makes sense to store your Seam components in the portlet APPLICATION_SCOPE. By default, these objects are stored in the PORTLET_SCOPE; but with the annotation below, you can fish this class out of the PortletSession and use its values in other portlets across different Seam applications.


@PortletScope(PortletScope.ScopeType.APPLICATION_SCOPE)

Then you would pull the statefull object from the session:


YourSessionClass yourSessionClass = (YourSessionClass)
getRenderRequest().getAttribute(“javax.portlet.p./default/
seamproject/seamprojectPortletWindow?textHolder”);

Using the PortletSession

If you need to access the PortletSession to simply share a parameter/value across multiple portlets, you can use the following to do so.


Object objSession = FacesContext.getCurrentInstance().
getExternalContext().

getSession(false);
try
{
	if (objSession instanceof PortletSession)
	{
		PortletSession portalSession = (PortletSession)objSession;
		portalSession.setAttribute(“your parameter name”,”parameter
value”,PortletSession.APPLICATION_SCOPE);
	…
	
Then, in your JSP or Facelets page, you can use:
#{httpSessionScope[‘your parameter name’]}

Linking to Portlet/JSF Pages Using h:outputink

For linking to any JSF/Facelets page within your portlet web application, you may use the following.


<h:outputLink value=”#{facesContext.externalContext.
				requestContextPath}/home.xhtml”>
<f:param name=”javax.portlet.faces.ViewLink” value=”true”/>
navigate to the test page
</h:outputLink>

Redirecting to an External Page or Resource

To link to a non JSF view (i.e. jboss.org), you can use the following parameter.


<h:commandLink actionListener=”#{yourBean.yourListenr}”>
<f:param name=”javax.portlet.faces.DirectLink” value=”true”/>
navigate to the test page
</h:commandLink>

Then in your backing bean, you must call a redirect().


FacesContext.getCurrentInstance().
		getExternalContext().redirect(“http://www.jboss.org”);

Using Provided EL Variables

All EL variables found in the JSR-329 (Portlet 2.0) specification are available in the JBoss Portlet Bridge. For example, you can use the following to edit the portlet preferences on the UI.


<h:form>
  <h:inputText id=”pref” required=”true” value=”#{mutablePortletPrefe
rencesValues[‘userName’].value}” />
  <h:commandButton actionListener=”#{myBean.savePref}” value=”Save
Preferences” />
</h:form>

Then in your backing bean, you must call the PortletPreferences.store() method.


Object request = FacesContext.getCurrentInstance().
getExternalContext().getRequest();
PortletRequest portletRequest = (PortletRequest)request;
if (request instanceof PortletRequest) {
   try {
	 PortletPreferences portletPreferences = portletRequest.
										getPreferences();
	portletPreferences.store();

Remote Portlet Navigation Using Portlet Events

When you send events, you can also leverage the EventNavigationResult and return a JSF navigation rule. For example, by returning:


new EventNavigationResult(“fromAction”,”Outcome”);

The fromAction can be a wildcard “/*” or a nav rule defined in your faces-config.xml and outcome can be the from-outcome node defined in the faces-config.xml navigation rule.

CONCLUSION

With all the bitter sweetness that JSF and portal technologies offer, the portlet bridge does a good job of keeping everything in check. It also gives you possibilities that may not have been thought of when your JSF app was first created. Some examples are integration of legacy applications to leverage existing investments and the ability to develop newer frameworks and technologies without regression.

About The Authors

By Wesley Hales

By Wesley Hales

Wesley Hales is a software developer on several projects at JBoss, by Red Hat. He is the co-founder of the JBoss Portlet Bridge project, a senior developer on GateIn, and serves as the JBoss representative on the JSR 301 & 329 specifications.

Before working for Red Hat, Wesley focused mainly on web framework and UI-related technologies, thus leading to committer roles for Apache, Mozilla, and JBoss. Wesley produces a series of screencasts on vimeo for each bimonthly release of the bridge. He has written a host of articles on infoq.com and posts occasional tutorials to his blog on jroller.com.

For his sins, he evangelizes portlet and portlet bridge technologies at most major conferences including Jazoon, AjaxWorld, JUDCon, DevNexus and whichever ones a daring enough to have a portal talk in their schedule.

Recommended Book

Portlets in Action

Portlets in Action is a comprehensive guide for Java developers with minimal or no experience working with portlets. Fully exploring the Portlet 2.0 API and using widely adopted frameworks like Spring 3.0 Portlet MVC, Hibernate, and DWR, it teaches you portal and portlet development by walking you through a Book Catalog portlet and Book Portal examples. The example Book Catalog Portlet, developed incrementally in each chapter of the book, incorporates most key portlet features, and the accompanying source code can be easily adapted and reused by readers. The example Book Portal application introduces you to the challenges faced in developing web portals.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

What's New in JPA 2.0

By Mike Keith

17,821 Downloads · Refcard 128 of 151 (see them all)

Download
FREE PDF


The Essential JPA 2.0 Cheat Sheet

Whats new in JPA 2.0 is a cheat sheet written for developers experienced with the Java Persistence API (JPA) 1.0 who are interested in learning about JPA 2.0. This DZone Refcard covers the primary new features introduced in the JPA 2.0 release and provides explanations for how they can be used. JPA 2.0 has some major enhancements compared to 1.0, but to understand the basic concepts behind JPA, youll want to check out our Getting Started With JPA Refcard first. Topics covered include JDBC Properties, Access Mode, Mappings, Shared Cache, the TypedQuery interface, JPQL, Pessimistic Locking, the Criteria API and Validation.
HTML Preview
What’s New in JPA 2.0

What’s New in JPA 2.0

By Mike Keith

INTRODUCTION

The Java Persistence API is the standard for persisting Java objects to a relational database. It includes standardized metadata for defining mappings and configuration, as well as a set of Java APIs that applications can use to persist and query entities. It also includes a standard Service Provider Interface (SPI) that allows applications to easily plug in different JPA providers. If you are new to JPA, read the Refcard Getting Started with JPA first to get an understanding of some basic concepts. This Refcard assumes you are familiar with JPA 1.0 and that you now want to upgrade your knowledge to include JPA 2.0. This Refcard covers the primary new features introduced in the JPA 2.0 release and explains how they can be used.

JDBC PROPERTIES

A set of four new properties were added to provide more portability when specifying the JDBC connection parameters in Java SE mode. The driver class, URL, user, and password were previously different for every provider, but now the four standard ones can be used in a persistence.xml file.

Using the standard JDBC properties:

<persistence-unit name=”Account”>
		…
		<properties>
	<property name=”javax.persistence.jdbc.driver”
			value=”org.apache.derby.jdbc.ClientDriver”/>
	<property name=”javax.persistence.jdbc.url”
			value=”jdbc:derby://dbmachine:1527/accountDB”/>
	<property name=”javax.persistence.jdbc.user” value=”app”/>
	<property name=”javax.persistence.jdbc.password”
			value=”app”/>
		</properties>
	</persistence-unit>

ACCESS MODE

When the provider accesses the state of an entity, it must typically decide whether the state is in fields or in properties. Until JPA 2.0, all of the state in an entity hierarchy had to be accessed either in one mode or the other. Now, through the use of some judiciously placed metadata, some state in an object can be accessed in fields while other state can be accessed through bean property methods.

The entity must first be annotated with an @Access annotation to indicate the default access mode for the class. Then, to deviate from the default and specify accessing in a different mode for a given field or property, the @Access annotation can be placed on the field or property to be accessed.


@Entity @Access(FIELD)
	public class Person {
	@Id
	int id;
	…
	@Access(PROPERTY)
	public String getName() { … }
	public void setName(String pName) { … }
	…
}

Hot Tip

When overriding the access type for a field to its accompanying property make sure to annotate the field with @Transient to prevent the field from being mapped in addition to the property.

MAPPINGS

The mapping arsenal grew dramatically in JPA 2.0 to include mappings that are less common, but were not defined in the first release. A number of mappings were added to provide better support for reading from pre-existing (so-called “legacy”) database schemas. While these mappings are not hugely useful to the average application, they come in handy to those who must work with a schema that is outside the control of the Java developer.

Element Collections

Arguably, the most useful of the new mapping types is the element collection, which allows an entity to reference a collection of objects that are of a basic type (such as String or Integer). The @ElementCollection annotation is used to indicate the mapping. The objects are stored in a separate table called a collection table, which defaults to be named <entityName>_<attributeName>, but can be overridden with the @CollectionTable annotation. The name of the column in the collection table that stores the values defaults to the name of the attribute but is overridable with the @Column annotation.

Element collection of String:


@Entity
public class Person {
	…
	@ElementCollection
	@CollectionTable(name=”NICKNAMES”)
	@Column(name=”NNAME”)
	Collection<String> nicknames;
	…
}

Element collection mappings can be used in embeddables and mapped superclasses as well as entities. They can also contain embeddable objects instead of basic types.

Adding a Join Table

Normally, a bidirectional one-to-many relationship is mapped through a foreign key on the “many” side. However, in some data schemas, the join is done using a separate join table. Similarly a unidirectional or bidirectional one-to-one relationship can use a join table instead of the typical simple foreign key. As one might expect, using a join table for these mappings is as easy as putting an additional @JoinTable annotation on the owning side of the mapped relationship.

Unidirectional One-to-Many With No Join Table

In JPA 1.0, a unidirectional one-to-many relationships required a join table. However, you were stuck if the schema was fixed and had a foreign key in the target table and the target entity was not able to be modified to have a reference back to the source entity.

The ability to do this was added in JPA 2.0 by permitting a @JoinColumn annotation to accompany a @OneToMany annotation that was unidirectional (did not contain a mappedBy element). The join column refers to a foreign key column in the target table, which points to the primary key of the source table.

Unidirectional one-to-many relationship with target foreign key:

@Entity
public class Customer {
	…
	@OneToMany
	@JoinColumn(name=”CUST_ID”)
	List<Purchase> purchases;
	…
}

Hot Tip

A unidirectional one-to-many target foreign key mapping may seem to make life easier in Java but performs worse than using a join table.

Orphan Removal

A parent-child relationship is a one-to-many or one-to-one relationship in which the target entity (the child) is owned by the source entity (the parent) or relies upon it for its existence. If either the parent gets deleted or the relationship from the parent to the child gets severed, then the child should be deleted. Previous support for cascading delete offered a solution for the first case; but to solve the second case when the child is left an orphan, the new orphanRemoval element of the @OneToMany or @OneToOne annotations can be set to true to cause the child object to get removed automatically by the provider.

Configuring and using orphan removal:

@Entity public class Library {
	…
	@OneToMany(mappedBy=”library”, orphanRemoval=true)
	List<Magazine> magazines;
	…
}

In the application code, when a magazine is torn and is to be discarded from the library, the act of removing the magazine from the library causes the magazine to automatically be deleted:


library.getMagazines().remove(magazine);

Persistently Ordered Lists

When a many-valued relationship causes fetching of the related entities in a List and the order of the entities must be determined by sorting one or more attributes of the target entity type, the relationship mapping needs to be annotated with @OrderBy. However, if the order is determined solely by the position of the entity in the in-memory list at the time the list was last persisted, then an additional column is required to store the position. This column is called an order column and is specified on the mapping by the presence of @OrderColumn. The entity’s position in the list is read from and written to this column.

Ordering without using an object attribute:

@Entity public class WaitList {
	…
	@OneToMany
	@OrderColumn(name=”POSITION”)
	List<Customer> customer;
	…
}

Every time a transaction causes a customer to be added to or removed from the waiting list, the updated list ordering will be written to the order column. Because the example is using a unidirectional one-to-many relationship that defaults to using a join table the order column will be in the join table.

Maps

Using a Map for a many-valued relationship traditionally meant that entities were the values and some attribute of the entities was the key. The new Map features allow Map types to be used with keys or values that can be basic types, entities, or embeddables. When the value is an entity type, then the mapping is a relationship. When the value is a basic or embeddable type, the mapping is an element collection. Two examples of using a Map are shown. The deliverySchedule attribute is an element collection of dates on which deliveries are made to given address strings. The @MapKeyColumn annotation indicates the column in the collection table where the keys (address strings) are stored, and @Column references the column in which the date values are stored. The @Temporal annotation is used because the values are Date objects.

The suppliers attribute illustrates a unidirectional one-to-many relationship that has a Map of Supplier entities keyed by Part entities. The @MapKeyJoinColumn annotation indicates the join column in the join table referring to the Part entity table.

Element collection Map and one-to-many Map:

@Entity public class Assembly {
	…
	@ElementCollection
	@CollectionTable(name=”ASSY_DLRVY”)
	@MapKeyColumn(name=“ADDR”)
	@Column(name=“DLRVY_DATE”)
	@Temporal(TemporalType.DATE)
	Map deliverySchedule;
	…
	@OneToMany
	@JoinTable(name=”PART_SUPP”)
	@MapKeyJoinColumn(name=”PART_NO”)
	Map suppliers;
	…
}

The main lesson is that different annotations are useful and applicable depending upon the key and value types in the Map.

Derived Identifiers

New allowances were made in JPA 2.0 for the case when an entity has a compound primary key that includes a foreign key. Multiple @Id annotations can be specified, and they can be on an owned one-to-one or many-to-one mapping. The foreign key of that mapping will be included in the id class, as shown in the example. The id class must still have a field for each of the primary key components and be named the same as the entity attributes, but the types of the foreign key-based id class fields must match the identifier types of the target entity of the relationship. For example, the dept field in the ProjectId class is not of type Department as it is in Project, but is of type int, which is the identifier type of the Department entity.

Derived Identifier:

@IdClass(ProjectId.class)
@Entity public class Project {
	…
	@Id
	String projectName;
	@Id @ManyToOne
	Department dept;
	…
}
@Entity public class Department {
	…
	@Id
	int id;
	…
}
public class ProjectId {
	String projectName;
	int dept;
	…
}

Compound primary keys may also be composed of multiple foreign keys or relationships by adding @Id annotations to additional relationships in the entity and adjusting the id class accordingly.

Hot Tip

Derived identifiers also support a multitude of additional identifier combinations involving embedded identifiers, multiple levels of compounding, and shared relationship primary keys.

Java Persistence Query Language

A number of additional JP QL features were added to support the new mappings, while other features were added simply as improvements to the query language. The table summarizes the changes.

New features of JP QL:
Feature Name Description Example
Date, time, and timestamp literals JDBC syntax was adopted: {d ‘yyyy-mm-dd’} {t ‘hh-mm-ss’} {ts ‘yyyy-mm-dd hh-mm-ss’} SELECT c FROM Customer c WHERE c.birthdate < {d ‘1946-01-01’}
Non-polymorphic queries – TYPE Can query across specific subclasses of a superclass SELECT p FROM Project p WHERE TYPE(p) = DesignProject OR TYPE(p) = QualityProject
Map support - KEY, VALUE, ENTRY Allow comparison and selection of keys and values and selection of entries SELECT e.name, KEY(p), VALUE(p) FROM Employee e JOIN e.phones p WHERE KEY(p) IN (‘Work’, ‘Cell’)
Collection input parameters Allow parameter arguments to be collections SELECT e FROM Employee e WHERE e.lastName IN :names
CASE statement Can be in either of two forms:
  1. CASE {WHEN conditional THEN scalarExpr}+ ELSE scalarExpr END
  2. CASE pathExpr {WHEN scalarExpr THEN scalarExpr}+ ELSE scalarExpr END
UPDATE Employee e SET e.salary = CASE WHEN e.rating = 1 THEN e.salary * 1.1 WHEN e.rating = 2 THEN e.salary * 1.05 ELSE e.salary * 1.01 END
NULLIF, COALESCE Additional CASE variants: COALESCE(scalarExpr {, scalarExpr}+) NULLIF(scalarExpr, scalarExpr SELECT COALESCE(d.name, d.id) FROM Department d
Scalar expressions in the SELECT clause Return the result of performing a scalar operation on a selected term SELECT LENGTH(e.name) FROM Employee e
INDEX in a List Refer to an item’s position index in a list SELECT p FROM Flight f JOIN f.upgradeList p WHERE f.num = 861 AND INDEX(p) = 0
Variables in SELECT constructors Constructors in SELECT clause can contain identification vars SELECT new CustInfo(c.name, a) FROM Customer c JOIN c.address a

TYPED QUERY

One of the simplest but most useful query features added in JPA 2.0 is the TypedQuery interface. When you create a query you can pass in the type for the query result and get back a typed query object that, when executed, will return the correctly typed objects without having to cast. It works for both dynamic queries and named queries.


TypedQuery<Employee> q = em.createNamedQuery(“Employee.findByName”,
						Employee.class);
q.setParameter(“empName”, “Smith”);
List<Employee> emps = q.getResultList();

SHARED CACHE

Entities regularly get cached in a persistence context, but they will also typically get cached by the persistence provider in a longer-lived cache in the entity manager factory. This cache is called a shared cache because the entity data is shared across multiple persistence contexts. Although there are multiple different strategies and approaches to caching, a standard API can be used to operate on it. The standard Cache interface can be obtained from the EntityManagerFactory.getCache() method.


public interface Cache {
	public boolean contains(Class cls, Object primaryKey);
	public void evict(Class cls, Object primaryKey);
	public void evict(Class cls);
	public void evictAll();
}

Hot Tip

It is not a good idea to manipulate the cache as part of the regular application execution. The API is most valuable for testing to clear the cache between test cases/runs.

A shared-cache-mode element can be configured in the persistence.xml file for a given persistence unit. It is used in conjunction with the @Cacheable annotation on entity classes to designate whether instances of entity classes are allowed (or intended) to be cached in the shared cache.

Option Description
ALL All entities in the persistence unit are cached
NONE Caching is disabled for all entities in the persistence unit
ENABLE_SELECTIVE Caching is disabled, except for entities annotated with @Cacheable or @Cacheable(true)
DISABLE_SELECTIVE Caching is enabled, except for entities annotated with @Cacheable(false)
UNSPECIFIED Caching reverts to the default caching option for the current provider

Hot Tip

Providers aren’t strictly required to implement shared caches. If a provider has no cache the cache API is not going to have an effect.

Hot Tip

Providers aren’t strictly required to implement shared caches. If a provider has no cache the cache API is not going to have an effect.

Two additional properties can influence what gets cached at the operational level. The javax.persistence.cache.retrieveMode and javax.persistence.cache.storeMode properties can be set at the level of the entity manager using a setProperty() method, an entity manager find() or refresh() operation, or on an individual query setHint() call. The enumerated javax.persistence.CacheRetrieveMode type contains the valid values for the retrieve mode, and the enumerated javax.persistence.CacheStoreMode type defines the valid store mode values.

CacheRetrieveMode Value Description
USE Read entity data from the cache
BYPASS Don’t use the cache; read entity data from the database
CacheStoreMode Value Description
USE Insert entity data into cache when reading from/writing to the database
BYPASS Don’t insert entity data into the cache
REFRESH Same as USE, but refresh cached version of entity data when reading from database

ADDITIONAL API

Some of the primary API classes have had additional methods added to them to provide more functionality and offer more flexibility, and most of the pertinent ones are listed in the Tables. Some new API classes have also been added.

Additional EntityManager methods:
Method Description
find(Class entityClass, Object pk [,LockModeType lockMode] [,Map <String,Object> properties]) Overloaded find methods allowing optional lockmode and properties parameters.
lock(Object entity, Map<String,Object> properties) Overloaded lock method allowing properties parameter
refresh(Object entity [,LockModeType lockMode] [,Map<String,Object> properties]) Overloaded refresh methods allowing optional lockmode and properties parameters
detach(Object entity) Remove the entity from the persistence context
createQuery(String qlString, Class<T> resultClass) Create a dynamic query and return a TypedQuery<T>
createQuery(CriteriaQuery<T> criteriaQuery) Create a query using the Criteria API and return a TypedQuery<T>
createNamedQuery(String queryName, Class<T> resultClass) Create a named query and return a TypedQuery<T>
unwrap(Class<T> cls) Return an instance of the (often proprietary) specified class associated with the entity manager
getEntityManagerFactory() Return the entity manager factory associated with the entity manager
getCriteriaBuilder() Return a criteria builder for building criteria queries
getMetamodel() Return the metamodel for introspecting the entity structure
Additional Classes:
Class Description
TypedQuery<T> Subclass of Query that is typed according to the result type of the query.
Tuple Representation of a row of typed data elements
TupleElement<T> Representation of a single typed data element in a tuple
Parameter<T> Typed query parameter
PersistenceUnitUtil Class containing a group of utility methods implemented and returned by the provider of a given persistence unit
PersistenceUtil Class containing a group of utility methods that will work across any and all providers
PersistenceProviderResolver Pluggable class used to resolve providers in different environments.
PersistenceProviderResolverHolder Static methods to set/look up the resolver

PESSIMISTIC LOCKING

One of the benefits of the overloaded entity manager find() and refresh() methods taking a lock mode is to enable locking at the operational level. This is most valuable when using the new LockModeType.PESSIMISTIC_WRITE option to pessimistically lock an entity. There is even a javax.persistence.lock.timeout property that can be used to put an upper bound on the wait time to acquire the lock. A PessimisticLockException will be thrown if the lock could not be acquired and the transaction has been rolled back.


Map<String,Object> props = new HashMap<String,Object>();
props.put(“javax.persistence.lock.timeout”, 5000);
try {
	Account acct = em.find(Account.class, accountId, PESSIMISTIC_WRITE,
props);
} catch (PessimisticLockException pessEx) {
	// lock not acquired, bail out and do something reasonable
}

The available lock modes are listed in the following table.

Lock Modes:
OPTIMISTIC New name for JPA 1.0 “READ” mode
OPTIMISTIC_FORCE_INCREMENT New name for JPA 1.0 “WRITE” mode
PESSIMISTIC_READ Pessimistic repeatable read isolation
PESSIMISTIC_WRITE Pessimistically lock to cause write serialization
PESSIMISTIC_FORCE_INCREMENT Pessimistically lock but also ensure update occurs to version field

VALIDATION

Validation is a new specification in its own right and can be used with virtually any Java object, not just persistent entities. However, when used with JPA, some integration was beneficial to provide the additional automatic lifecycle validation support. Validation can be configured to be automatically triggered during any of the PrePersist, PreUpdate, and PreRemove entity lifecycle events. A validation-mode element in the persistence.xml file, or the equivalent javax.persistence.validation.mode property passed in at entity manager factory creation time, will determine whether validation happens. A value of auto means that validation will occur if a validator is available, while a value of callback means that validation is expected to occur and will fail if no validator is available. Setting the mode to none disables validation. Because the default validation-mode is auto, validation of a validation provider that exists on the classpath can be disabled by explicitly setting the mode to none.

Specific validation groups can be used for validation at a given lifecycle event through the corresponding properties: javax.persistence.validation.group.pre-persist, javax.persistence validation.group.pre-update, and javax.persistence.validation group.pre-remove. These properties may be applied either as property elements in the persistence.xml file or as dynamic

properties passed in at entity manager creation. For example, to cause validation of the com.acme.validation.EntityCreation validation group to the entities of a persistence unit at the PrePersist lifecycle event, the javax.persistence.validation.group pre-persist property value should be set to that fully qualified EntityCreation class name. Then, assuming the existence of MyEntity defined in the persistence unit with EntityCreation constraints on it, a call to persist an instance of MyEntity would cause those constraints to be validated before the instance data would be inserted to the database.

For more details about validation, consult the “Bean Validation” specification available at http://jcp.org/en/jsr/detail?id=303.

ENTITY METAMODEL

Although it may be more useful for tools than for regular developers, one interesting feature that was introduced in JPA 2.0 was the ability to access a metamodel of the objects mapped in a persistence unit. The metamodel is available at runtime to query the structure of the objects and is obtained by calling getMetamodel() on an entity manager or entity manager factory. The example shows how the metamodel can be used to introspect the attributes of the Account entity.


Metamodel model = em.getMetamodel();
EntityType<Account> account_ = model.entity(Account.class);
for (Attribute<? super Account, ?> attr : account_.getAttributes()) {
	System.out.println(“Account attribute: “ + attr.getName() +
		“ java type = “ + attr.getJavaType.getName() +
		“ mapping type = “ +
		attr.getPersistentAttributeType());
}

CRITERIA API

Perhaps the biggest new feature (certainly in terms of page count!) is the Criteria API for dynamic query creation. It comprises a Java API to incrementally add nodes to a criteria tree that can be subsequently passed to a query wrapper for evaluation. The criteria nodes are typed according to their semantics and the type of object they are being applied to.

Hot Tip

The Criteria API is not a replacement for JP QL queries but an alternative query mechanism for developers who want to use a more dynamic or more strongly typed API. Developers happy with JP QL may not ever have the need to use the Criteria API.

There are two flavors of criteria usage. The one you will use depends on the reason you are using the API, the development practices of your company, and personal preference.

STRING-BASED CRITERIA

String-based criteria implies specifying attribute names as strings, much like many of the existing criteria APIs and expression frameworks present in Hibernate and TopLink/EclipseLink. The resulting expressions are more typed than what simple JP QL will offer but less typed than the second strongly typed flavor of the Criteria API. They may also result in “raw type” compiler warnings indicative of not declaring the type of a collection that was defined as a parameterized type.


CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery c = cb.createQuery(Account.class);
Root acct = c.from(Account.class);
c.select(acct)
 .where(cb.equal(acct.get(“name”), “Jim Morrison”));
List result = em.createQuery(c).getResultList();

We start by obtaining a CriteriaBuilder, the primary factory both for the criteria query object and for most of the criteria nodes, from the entity manager. We then create the criteria object, get a root, declare our selection clause, and start adding constraint nodes. Of course, declaring the selection clause and building the constraint tree are not really order-dependent and could be done in either order. Once complete, though, the query can be executed through the traditional means of query execution just by passing the criteria object as an argument to the EntityManager.createQuery() method and calling getResultList() on the returned query.

A better typed version of the query can be achieved by adding the types but still using string-based attributes. The types make the code slightly harder to read and use but provide a measure of typing to improve the quality.


CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Account> c = cb.createQuery(Account.class);
Root<Account> acct = c.from(Account.class);
c.select(acct)
.where(cb.equal(acct.get(“name”), “Jim Morrison”));
List<Account> result = em.createQuery(c).getResultList();

STRONGLY TYPED CRITERIA

The problem with the string-based versions above is that the “name” attribute can be mistyped, or the wrong attribute can be specified. The compiler will not be able to catch the error because its argument type is String. As far as the compiler is concerned, any string will do. To protect against these kinds of attribute errors at compile time, the argument must be typed very specifically to match the attribute type. The metamodel types provide the tools to do this.


CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Account> c = cb.createQuery(Account.class);
Root<Account> acct = c.from(Account.class);
c.select(acct)
  .where(cb.equal(acct.get(Account_.name), “Jim Morrison”));
List<Account> result = em.createQuery(c).getResultList();

To use the strongly typed criteria, the “name” string is substituted by Account_.name. The Account_ class is called the canonical metamodel class corresponding to the Account entity. It is generated by the provider for the purposes of the strongly typed Criteria API and contains a static field for each of its mapped attributes. While the details are not that important, the Account_ class can be used for these kinds of strongly typed queries. The compiler will not let you mistype the name of the attribute or supply the wrong attribute because all of the objects along the way are typed strongly enough to catch these kinds of errors.

CRITERIABUILDER

You may have noticed from the examples that if we wanted to start adding operators to the where clause, we needed to obtain them from the CriteriaBuilder instance. The CriteriaBuilder class acts as a node factory for operations, (both string-based and strongly typed), and contains most of the useful operators. The following reference table shows at a glance the operators (by category) that are available in the CriteriaBuilder class.

The arguments for many of these methods are overloaded for convenience.

CriteriaBuilder methods by category:
Category Method Names
Query Construction createQuery(), createTupleQuery()
Selection Construction construct(), tuple(), array()
Ordering asc(), desc()
Aggregate Functions avg(), sum(), sumAsLong(), sumAsDouble(), min(),max(), greatest(), least(), count(), countDistinct()
Subqueries exists(), all(), some(), any()
Boolean Functions and(), or(), not(), conjunction(), disjunction()
Value Testing isTrue(), isFalse(), isNull(), isNotNull()
Equality equal(), notEqual()
Numeric Comparison gt(), ge(), lt(), le()
Comparison greaterThan(), greaterThanOrEqualTo(), lessThan(),lessThanOrEqualTo(), between()
Numeric Operations neg(), abs(), sum(), prod(), diff(), quot(), mod(), sqrt()
Typecasts toLong(), toInteger(), toFloat(), toDouble(), toBigDecimal(), toBigInteger(), toString()
Literals literal(), nullLiteral()
Parameters parameter()
Collection Operations isEmpty(), isNotEmpty(), size(), isMember(), isNotMember()
Map Operations keys(), values()
String Operations like(), notLike(), concat(), substring(), trim(), lower(), upper(), length(), locate()
Temporal Functions currentDate(), currentTime, currentTimestamp()
Expression Construction in(), selectCase()
Misc Operations coalesce(), nullif(), function()

SUMMARY

While we have not been completely exhaustive in our coverage of the new JPA 2.0 features, we have covered the vast majority and most interesting features among them. Clearly, JPA 2.0 has propelled JPA into an even more mature position in the world of persistence, causing it to be more easily applied to old and new data schemas alike.

About The Authors

Mike Keith

Mike Keith

Mike Keith has been a distributed systems and persistence expert for over 20 years. He co-led the expert group that produced the first release of JPA and co-authored the premier JPA reference book, Pro EJB: Java Persistence API, followed up with Pro JPA 2: Mastering the Java Persistence API. He works at Oracle as an architect for enterprise Java and represents Oracle on numerous expert groups and specifications, including the Java EE platform specification, JPA, and others. He leads the Gemini Enterprise Modules project at Eclipse, and is a member of the Eclipse Runtime project PMC.

Recommended Book

Pro JPA 2

Pro JPA 2 introduces, explains, and demonstrates how to use the new Java Persistence API (JPA). JPA provides Java developers with both the knowledge and insight needed to write Java applications that access relational databases through JPA.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.