Granite data services
Encyclopedia
Granite Data Services (GraniteDS or GDS) is a comprehensive development and integration solution for building Flex / JavaEE RIA
Rich Internet application
A Rich Internet Application is a Web application that has many of the characteristics of desktop application software, typically delivered either by way of a site-specific browser, via a browser plug-in, independent sandboxes, extensive use of JavaScript, or virtual machines...

 applications. The entire framework is open-source and released under the LGPL v2 license.

It features:
  • A client development framework (Tide) that brings familiar JavaEE concepts to the Flex side: dependency injection, context management, authentication and secured access, bean validation, etc.
  • A comprehensive integration with major JavaEE application servers, frameworks and JPA engines: JBoss, GlassFish, WebLogic, WebSphere, Tomcat and Jetty; Hibernate, EclipseLink, OpenJPA and DataNucleus.
  • An efficient real-time module (Gravity), based on Comet implementations, allowing scalable data-push.
  • Code generation tools (Gas3) that help in replicating Java entity beans and services into their ActionScript3 equivalent. These tools are available as an Eclipse plug-in or an Ant task.
  • Simplified configuration and high performances for critical deployments: most of the configuration is automated by scanning deployment environments and standard libraries are optimized for scalability.

Integration and Features Stack

See integration & features stack image for a comprehensive overview of JPA engines, JavaEE frameworks and Java application servers supported by GraniteDS.

Connecting JavaEE Components with Dependency Injection

GraniteDS integrates with the major JavaEE frameworks:
  • EJB3
    Enterprise JavaBean
    Enterprise JavaBeans is a managed, server-side component architecture for modular construction of enterprise applications.The EJB specification is one of several Java APIs in the Java EE specification. EJB is a server-side model that encapsulates the business logic of an application...

    .
  • Spring.
  • JBoss Seam
    JBoss Seam
    Seam is a web application framework developed by JBoss, a division of Red Hat.- Seam 3 :Seam 3 is very active project consisting of over 50 developers and engineers, which provides a modular set of extensions to the CDI programming model...

    .
  • CDI (Contexts and Dependency Injection).
  • Google Guice
    Google Guice
    Google Guice is an open source software framework for the Java platform released by Google under an Apache license. It provides support for dependency injection using annotations to configure Java objects...

    .


Additionally, it comes with a basic Java component framework (called Pojo) that let you expose simple Java beans as remote destinations (with 3 possible scopes: request, session or application).

Accessing these frameworks from a Flex application is straightforward if you use:
  • The dependency injection
    Dependency injection
    Dependency injection is a design pattern in object-oriented computer programming whose purpose is to improve testability of, and simplify deployment of components in very large software systems....

     mechanism provided by the Tide.
  • GraniteDS code generation
    Automatic programming
    In computer science, the term automatic programming identifies a type of computer programming in which some mechanism generates a computer program to allow human programmers to write the code at a higher abstraction level....

     tools (available as an Eclipse
    Eclipse (software)
    Eclipse is a multi-language software development environment comprising an integrated development environment and an extensible plug-in system...

     plug-in or an Ant
    Apache Ant
    Apache Ant is a software tool for automating software build processes. It is similar to Make but is implemented using the Java language, requires the Java platform, and is best suited to building Java projects....

     task, see Gas3) that replicate on-the-fly your JavaEE components in ActionScript3.

Example

With a basic EJB3 like this one (it would work the same with other frameworks):


@RemoteDestination
public interface Hello {

public String welcome(String name);
}

@Stateless
@Local(Hello.class)
public class HelloBean {

public String welcome(String name) {
return "Hello " + name + "!";
}
}


You will get these ActionScript3 generated classes:


[RemoteClass(alias="path.to.java.Hello")]
public class Hello extends HelloBase {
// put your custom code here...
}

public class HelloBase extends Component {

public function welcome(arg0:String, resultHandler:Object = null, faultHandler:Function = null):void {
// skipped generated code (actually calls the remote method)...
}
}


And here is a sample remote call from an injected component:


[In]
public var hello:Hello;

hello.welcome("World", welcomeResult);

private function welcomeResult(event:TideResultEvent):void {
trace(event.result); // print "Hello World!"
}


Note that the variable name "hello" is implicitly bound to the uncapitalized name of the EJB3 interface (if your EJB3 was named "MyService", you would use a variable named "myService").

The @RemoteDestination on the interface serves two purposes:
  • It tells the code generator to generate ActionScript3 classes for remote calls.
  • It restricts the EJB that may be called from Flex.


A type-safe annotation for dependency injection (Inject) is also available for the Spring and CDI frameworks.

JPA and Lazy-Initialization

GraniteDS integrates with the major Java Persistence API
Java Persistence API
The Java Persistence API, sometimes referred to as JPA, is a Java programming language framework managing relational data in applications using Java Platform, Standard Edition and Java Platform, Enterprise Edition....

 engines available in the JavaEE world:
  • Hibernate
    Hibernate (Java)
    Hibernate is an object-relational mapping library for the Java language, providing a framework for mapping an object-oriented domain model to a traditional relational database...

    .
  • OpenJPA
    Apache OpenJPA
    OpenJPA is an open source implementation of the Java Persistence API specification. It is an object-relational mapping solution for the Java language, which simplifies storing objects in databases. It is open source software distributed under the Apache 2.0 Licence.- History :Kodo, a Java Data...

     (formerly WebLogic Kodo).
  • EclipseLink
    EclipseLink
    EclipseLink is the open source Eclipse Persistence Services Project from the Eclipse Foundation. The software provides an extensible framework that allows Java developers to interact with various data services, including databases, web services, Object XML mapping , and Enterprise Information Systems...

     (formerly Oracle TopLink).
  • DataNucleus
    DataNucleus
    DataNucleus is an open source project which provides a series of software products around data management in Java....

     (formerly JPOX).


This integration is again closely coupled with code generation tools available in GraniteDS that replicate on-the-fly JPA entities into an ActionScript3
ActionScript
ActionScript is an object-oriented language originally developed by Macromedia Inc. . It is a dialect of ECMAScript , and is used primarily for the development of websites and software targeting the Adobe Flash Player platform, used on Web pages in the form of...

 model. The serialization of JPA entities from Java to Flex (or from Flex to Java) uses a custom mechanism called externalization, that preserves the entire state of the objects, instead of keeping only public properties.

With code generation and externalization, GraniteDS is able to retain JPA entities metadata in the ActionScript3 entities, such as their entire initialization
Lazy initialization
In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed....

 states. Serializing partially uninitialized entities with GraniteDS guaranties that:
  • Uninitialized properties are not unexpectingly initialized during the serialization (for both single-valued associations and collections).
  • ActionScript3 beans keep internally informations about unitialized properties.
  • Sending partially uninitialized ActionScript3 beans back to Java (with these metadata) allows the recreation of JPA entities with the same uninitialized properties.


Thus, this mechanism prevents database and memory overloads (only expected references between entities are actually loaded end serialized) and unexpected database updates (an uninitialized property sent back from Flex to Java will not be considered as a null reference or an empty collection).

Together with the Tide client framework, you may even benefit from transparent initialization, when accessing a lazy-loaded property in your Flex code: this access will trigger an asynchronous initialization request to the server that will serialize back the initialized value.

Example

With a simple data model like this one (note the LAZY fetch type of the addresses set):


@Entity
public class Person {

@Id @GeneratedValue
private Integer id;

@Version
private Integer version;

@Basic
private String firstname;

@Basic
private String lastname;

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="person")
private Set
addresses;

public Integer getId {
return id;
}

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 Set
getAddresses {
return contacts;
}
public void setAddresses(Set
addresses) {
this.addresses = addresses;
}
}

@Entity
public class Address {

@Id @GeneratedValue
private Integer id;

@ManyToOne(optional=false)
private Person person;

// skipped code...
}


You will get these ActionScript3 generated classes:


[Bindable]
[RemoteClass(alias="path.to.java.Person")]
public class Person extends PersonBase {
// put your custom code here...
}

public class PersonBase implements IExternalizable {

private var __initialized:Boolean = true;
private var __detachedState:String = null;

private var _id:Number;
private var _version:Number;
private var _firstname:String;
private var _lastname:String;
private var _addresses:ListCollectionView;

public function get id:Number {
return _id;
}

public function get fisrtname:String {
return _firstname;
}
public function set firstname(value:String):void {
_firstname = value;
}

// other getters/setters...

public override function readExternal(input:IDataInput):void {
__initialized = input.readObject as Boolean;
__detachedState = input.readObject as String;
if (meta::isInitialized) {
_id = function(o:*):Number { return (o is Number ? o as Number : Number.NaN) } (input.readObject);
_addresses = input.readObject as ListCollectionView;
_firstname = input.readObject as String;
_lastname = input.readObject as String;
_version = function(o:*):Number { return (o is Number ? o as Number : Number.NaN) } (input.readObject);
}
else {
_id = function(o:*):Number { return (o is Number ? o as Number : Number.NaN) } (input.readObject);
}
}

public override function writeExternal(output:IDataOutput):void {
// ...
}
}


The important things to notice here are:
  • The version field (used with optimistic locking
    Optimistic concurrency control
    In the field of relational database management systems, optimistic concurrency control is a concurrency control method that assumes that multiple transactions can complete without affecting each other, and that therefore transactions can proceed without locking the data resources that they affect...

    ) is purely opaque (no getter or setter) and remains as is in the generated code.
  • The id field is read only (no setter) and remains as is in the generated code.
  • The generated code add two meta fields (__initialized and __detachedState) that keep information about the initialization state of the entity.
  • When a Person entity is uninitialized, only its id is serialiazed (with the meta fields), so only this information is read (see the readExternal method in the ActionsScript3 bean).
  • Since the addresses set is lazily fetched, its content will not be serialized unless you explicitly initialize it in the Java code (or if you use Tide). The collection in the ActionScript3 code will be empty, with a meta information stating that the collection is unitialized.

Real-time messaging (Comet/Servlet 3.0)

Real-time messaging lets a Flex application publish to and receive from other clients data in so-called real-time. Messages may also be sent from the JavaEE server itself (known as data push
Push technology
Push technology, or server push, describes a style of Internet-based communication where the request for a given transaction is initiated by the publisher or central server...

), such as special alerts or progress events.

The implementation of real-time messaging in GraniteDS is based on the Comet
Comet (programming)
Comet is a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it. Comet is an umbrella term, encompassing multiple techniques for achieving this interaction. All these methods rely on features included by...

 model, now standardized in the Servlet
Java Servlet
A servlet is a Java programming language class used to extend the capabilities of servers that host applications accessed via a request-response programming model. Although servlets can respond to any type of request, they are commonly used to extend the applications hosted by Web servers...

 3.0 specification (JSR-303). Specifically, the transport protocol relies on a partial implementation of the standard Bayeux protocol.

On the server side, this implementation relies on specific servlet containers capabilities (such as Tomcat's CometProcessor or Jetty's Continuations) or on standardized Servlet 3.0 implementations when available. These implementations allow scalable real-time messaging by providing a way of releasing servlet threads when the HTTP connections are idle: the standard thread-per-connection model is replaced by a much more efficient thread-by-request model (see explanations in Jetty documentation).

GraniteDS uses a long polling model for managing HTTP requests between Flex client applications and the server: when a request for incoming data stays idle for a given amount of time (usually 30 s), it is closed and immediately reopened. This model prevents unexpected closing of idle HTTP connections traversing Internet proxies
Proxy server
In computer networks, a proxy server is a server that acts as an intermediary for requests from clients seeking resources from other servers. A client connects to the proxy server, requesting some service, such as a file, connection, web page, or other resource available from a different server...

.

Real-time messaging with GraniteDS is based on a consumer–producer model and lets you define topics and subtopics for partitioning groups of messages. You may also filter topic's messages by using specific selectors.

Example

Implementing a basic chat
Instant messaging
Instant Messaging is a form of real-time direct text-based chatting communication in push mode between two or more people using personal computers or other devices, along with shared clients. The user's text is conveyed over a network, such as the Internet...

application with GraniteDS requires configuring a specific servlet in the web.xml file of your application:



GravityServlet
org.granite.gravity.servlet3.GravityAsyncServlet
true


GravityServlet
/gravity/*



The server configuration requires also the definition of a specific destination (services-config.xml):





class="flex.messaging.services.MessagingService"
messageTypes="flex.messaging.messages.AsyncMessage">














uri="http://{server.name}:{server.port}/{context.root}/gravity/amf"
class="flex.messaging.endpoints.AMFEndpoint"/>






In a Flex application, you may then use the Consumer and Producer classes in order communicate with other clients:



private function connect(nickname:String):void {
consumer = new Consumer;
consumer.destination = "gravity";
consumer.topic = "discussion";
consumer.subscribe;
consumer.addEventListener(MessageEvent.MESSAGE, messageHandler);

producer = new Producer;
producer.destination = "gravity";
producer.topic = "discussion";
}

private function messageHandler(event:MessageEvent):void {
var msg:AsyncMessage = event.message as AsyncMessage;
var message:String = msg.body as String;

trace('You have received a message: ' + message);
}

private function send(message:String):void {
var msg:AsyncMessage = new AsyncMessage;
msg.body = message;
producer.send(msg);
}


In this quick code snippet, all Flex applications subscribe and publish to the same topic ("discussion"), so each message sent by a client is dispatched to other clients.

Together with the Tide framework, one may quickly configure a JavaEE server to automatically dispatch an entity's modifications in a specific topic: updates of shared data are then instantly visible in all clients (see GraniteDS documentation for more details).

External links

The source of this article is wikipedia, the free encyclopedia.  The text of this article is licensed under the GFDL.
 
x
OK