NexOpen Framework - Reference Documentation

A guide for JEE developers

Marc Baiges,

Toni López and

Francesc Xavier Magdaleno

0.4.0

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

Table of Contents

I. Core Modules
1. NexOpen as a Component Framework
1.1. Main concepts about Components
1.2. Hierarchy of Components in NexOpen
1.3. NexOpen Components in JEE Applications
2. Configuration of NexOpen projects
2.1. The EAR File
2.2. The EJB-JAR 2.x File
2.3. The Business File
2.4. The WAR File
2.5. NexOpen and Maven2
2.5.1. Maven2 configuration
2.5.2. NexOpen Maven2 Archetypes
2.6. Deployment
2.6.1. Tomcat 5.0.x, 5.5.x and 6.0.x
2.6.2. JBoss 4.0.x
2.6.3. JBoss 4.2.x
2.6.4. Bea WebLogic 9.2.x
3. Attribute Contexts Support
3.1. Contexts Framework
3.2. How to provide a custom Context
3.3. Configuration
4. Events and listeners in NexOpen
4.1. Bootstrap events and listeners
4.2. Event dispacthing
4.3. Configuration
5. Resources Support
5.1. Pooling support for components
5.1.1. Configuration
II. Business Tier
6. Service Components
6.1. Business Services
6.1.1. Business Facades
6.1.2. Application Services
6.2. Configurable Business Services
6.2.1. Dependency of other services
6.3. Addition of custom AOP interceptors
6.4. Injection of components
6.5. Caching in components
6.6. Enhacement Phase
6.7. Transactionality in ServiceComponents
6.8. Authorization in Business Components
6.9. Configuration
7. Service Gateway
7.1. Invokers
7.1.1. Configuration of Invokers
7.1.2. EJB configuration
8. Logging and Auditing in NexOpen
8.1. Introduction
8.2. Traditional integration with a RDBMS
8.3. Integration with Oracle FGA
8.4. How to extend it to accomodate to your functionalities
8.5. Configuration
9. Scheduling in NexOpen
9.1. Introduction
9.2. Using OpenSymphony Quartz Provider
9.3. Using the CommonJ Provider
9.4. Configuration of Scheduling Module
10. Workflow
10.1. Main concepts
10.2. JBoss jBPM integration
10.3. Configuration
10.4. How to Enhace an Entity with a Workflow Process
10.5. WorkFlow Annotations
10.5.1. Process Definition
10.5.2. Process Definitions
10.5.3. CreateProcess
10.5.4. BeginTask
10.5.5. ProcessContext
10.5.6. Transition
10.5.7. EndTask
11. NexOpen as a Test-Design Driven Framework
11.1. Test support for Service Components using JUnit3
11.2. Support for JUnit4
12. Web Services Reference
12.1. Introduction
12.2. NexOpen and JAX-WS 2.0
12.3. XFire 1.2.x integration
12.4. Test Support
12.5. Configuration
III. Resource Tier
13. Persistence Manager
13.1. PersistenceManager API
13.2. Query API
13.3. Criteria API
13.4. Integration with Hibernate3
13.5. Integration with Java Persistence API (JPA)
13.6. Integration with EJB3 POJO Validation
13.7. ServiceComponents and common CRUD operations
13.8. Test support for Persistence Module
13.9. Configuration of Persistence Module
14. Asynchronous Tasks
14.1. Main concepts
14.2. J2SE Concurrent integration
14.3. JMS POJO integration
14.4. Message-Driven Beans 2.x integration
14.5. Configuration of Tasks Module
IV. The Web
15. MVC support in NexOpen
15.1. Spring MVC support
15.2. Struts 1.2.x support
15.2.1. Configuration
15.3. Struts 2.0.x support
15.3.1. Configuration
16. Pagination support
16.1. ValueList integration
16.1.1. ValueList Supported Adapters
16.1.2. Configuration
17. AJAX support
17.1. DWR integration
17.1.1. Configuration
17.2. Simple AJAX calls
17.3. Reverse AJAX calls
17.4. Extended features
17.4.1. Autocomplete Tag
18. JavaServer Faces (JSF)
18.1. NexOpen and JavaServer Faces integration
19. Acegi Security Integration
19.1. Introduction
19.2. Relational Database Support
19.2.1. User-Group-Role model
19.2.2. General Configuration
19.2.3. PersistenceManager support
19.2.4. JPA EntityManager support
19.2.5. Integration with externals Security models
19.3. LDAP Support
19.4. Siteminder Support
19.5. OpenID Support
19.6. Different login pages. MultiModule Acegi integration
20. Web Services
20.1. Introduction
20.2. NexOpen and XFire integration
20.3. NexOpen and CXF integration
20.4. NexOpen and Axis2 integration
20.5. Configuration
21. Signature Module
21.1. Introduction
21.2. Apache Signature implementation
21.3. JSR-105 implementation
21.4. Configuration
22. Serialization Module
22.1. Introduction
22.2. Marshaller implementation location in cient side
22.3. XStream implementation
22.3.1. Extension of XStream functionalities
22.3.2. Configuration
22.4. XMLBeans implementation
22.5. XServices
22.6. NexOpen and JAXB2
V. Sample applications
23. Simple application
23.1. Introduction
23.2. Simple and the business and resource layer
23.3. Simple and the presentation layer
23.4. Build and deployment
A. Instrumentation Phase
A.1. Introduction
A.2. Configuration
A.3. Configuration in JEE 5.0
A.4. Frequently Asked Questions
B. Exception Handling
B.1. Introduction
B.2. Exception Handling in Business Components
B.3. Exception Handling in WEB

Core Modules

This initial part of the reference documentation covers all core modules that are absolutely integral to the NexOpen Framework. NexOpen Framework is based in Spring Framework 2 and tries to be beneficied of the Spring philosophy of how to easily develop a JEE project.

Foremost amongst these is the NexOpen Framework's Inversion of Control (IoC) container. A thorough treatment of the Spring Framework's IoC container is closely followed by comprehensive coverage of Spring's Aspect-Oriented Programming (AOP) technologies. The Spring Framework has its own AOP framework, which is conceptually easy to understand, and which successfully addresses the 80% sweet spot of AOP requirements in Java enterprise programming.

Spring also provides an integration with AspectJ (currently the richest - in terms of features - and certainly most mature AOP implementation in the Java enterprise space). Nevertheless, we have enough for our features with AOP Alliance

Finally, the adoption of the test-driven-development (TDD) approach to software development is certainly advocated by the NexOpen team, and so coverage of Spring's support for integration testing is covered (alongside best practices for unit testing). The NexOpen team have found that the correct use of IoC certainly does make both unit and integration testing easier (in that the presence of setter methods and appropriate constructors on classes makes them easier to wire together on a test without having to set up service locator registries and suchlike)... the chapter dedicated solely to testing will hopefully convince you of this as well.

In teh following picture, we would like to introduce a typical structure of a NexOpen project enterprise as is shown in figure Figure 1, “NexOpen typical architecture”

NexOpen typical architecture

Figure 1. NexOpen typical architecture

Here, we can appreciate the existence of a presentation layer (in the case of figure implemented by Spring MVC), a service gateway (represented by a EJB 2 Session Bean Stateless as we will mention in the Service Gateway Section) where it dwells the service components and finally, a reosurce layer represented by our Persistence Manager

Chapter 1. NexOpen as a Component Framework

NexOpen is based in components. A component could be defined as a object which fulfills a functionality inside the application. Examples of components could be Service Componets, Engines or Managed Components (objects that could be easily managed thru a JMX console for instance).

1.1. Main concepts about Components

NexOpen is a JEE Framework based in components and organized in modules for easy distribution. Therefore, you do not need all features of Nexopen for your application. You only choose the most suitables for your application and skip the rest. In the following picture, we try to explain the NexOpen Nature like a jigsaw, where you put the components more suitable for your application.

NexOpen as a component framework

Figure 1.1. NexOpen as a component framework

Therefore, as you have seen, NexOpen besides to have integration with other Open Sources projects and Frameworks provides several good practices such as profiling, stress-loading and Martin Fowler's Continous Integration.

1.2. Hierarchy of Components in NexOpen

The main interface which fulfills the concept of component is obviously Component as you have guessed. From this class, we can observe a rich and complex inheritance such as Managed Components, Engines, Service Components and so on.

1.3. NexOpen Components in JEE Applications

In JEE applications which uses NexOpen as their framework of development, we can observe the presence of the following components

  • Controllers.Represents the flow control in the presentation layer. There are optional, if you use JSF as your view Framework.

  • Business POJOs. The Business Services Objects in NexOpen are just POJOs annotated. The great benefit for any developer is to hidden complexities such as configuration, environment where are managed (such a EJB container, EJB3 container or IoC container) and freedom to choice where you would lik to deploy (due the fact that are JEE-agnostic we can deploy in a J2EE 1.4 or even 1.3 Application Server or in a JEE 5.0 Applicaion Server).

  • Entities.The EJB 3.0 (JSR-220) has introduced the concept of POJO entities which are annotated thru JSR-175 metadata annotations. In this way, we skip the complexity of deployment descriptors, tedious application server configuration and other features which was too misleading for J2EE developers of Entity Beans 2.x.

Chapter 2. Configuration of NexOpen projects

NexOpen is a high-configurable JEE Framework based in Spring2 which is suitable for EAR projects (when the High Availability, scalability, performance or other systemic qualities are important Non Functional Requirements to be fulfilled), simple WAR projects or Business Components projects (JAR projects which follows the generic principles of Service Oriented Architecture). Independently we have choosen, we must ensure to configure properly our JEE project. Next secti

2.1. The EAR File

Here, we can find several modules (WEB, EJB-JAR, RAR, Client or Application Server specific) which could be included in the functionalities of our application.

				
ear
|+META-INF
  |+application.xml
  ....
				 
		

The application.xml is an standard Deployment Descriptor (aka DD) where we define the modules presents in our projet. It also coul be present specific DD related to JEE Application Servers.

2.2. The EJB-JAR 2.x File

The ejbapp is the way that is packaged in a typical NexOpen application. It contains the Sun Deployment Descriptors (ejb-jar.xml) and Spring configuration files

				
ejbapp
|+beanRefContext.xml
|+hibernate.cfg.xml
|+META-INF
  |+spring
    |+nexopen-dataAccessContext.xml
    |+nexopen-modulesConfigurer.xml
  |+ejb-jar.xml

			 
		

The beanRefContext.xml file represents the main file where we configure all the business tier in NexOpen projects. Mainly it defines the Spring configuration files related to access to a persistence storage, definition of messaging and already defined files contained in the NexOpen JAR files. In the ejb-jar.xml file, it contains the definition of the ServiceGatewayBean, and EJB which represents a Gateway [Fowler2002] to the Business layer. An example of beanRefContext is as follows

		  
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	   xmlns:components="http://www.nexopen.org/schema/components" 
	   xsi:schemaLocation="....">
  <bean id="nexopen" 
        class="org.nexopenframework.deployment.context.AnnotationApplicationContext"> 
  <!-- information about project -->  
  <components:module name="test001War" ejbModule="false" ejb3Module="false"
                     description="test001War application, which uses NexOpen Framework"/>  
	......	  
		  
		

Look at the NexOpen implementation of ApplicationContext for dealing with custom or standard JSR-175 metadata (such as the JSR-250 metadata that you can define inside the NexOpen components) and the element components:module which provides information to the runtime Nexopen container (extension of Spring), such as if the projet does or does not support EJB module or even EJB3 mdoule, module name and a short description.

2.3. The Business File

Usually, the business logic is packaged in a Java JAR file, where you can find all the business objects, model objects of your application.

				
business
|+META-INF
  |+spring
    |+production //folder for configuration related to environment production
    |+integration //folder for coniguration related to environment integration
    |+openfrwk-module-beans.xml //optional file
  |+nexopen.properties
			 
		

Moreover, if you need to configure some beans in your application, you can add in Spring configuration files which suffix -beans.xml and explicitely located under META-INF/spring folder.

However, the artifact that you are creating in development is completely different from production, usually details such as RDBMS, Application Server and so on distant from one environment to other. This could be easily solved using the Profiles which are well integrated in Maven2.

2.4. The WAR File

Here, we can find the static and dynamic content of your application. The dynamic part, it is formed by controllers, such as Struts 1.x, Struts 2.0.x or Spring MVC controllers. Moreover, configuration files for web layer (views, exception hanlding, value list pagination and so on) are also included.

				
webapp
|+css
|+img
|+js
|+WEB-INF
  |+web.xml
  |+applicationContext.xml
  |+nexopen-servlet.xml
  |+openfrwk-module-controllers.xml //optional file
  |+openfrwk-module-eventsDispatcher.xml
			 
		

The configuration files in the WEB layer applying to controllers and bootstrapping of application. In the Deployment Descriptor we must configure the Spring DispatchServlet and the ServletContext listener needed or bootstrapping the application.

				
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee ....">
    .....
     <servlet>
        <servlet-name>nexopen</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    ....
    <listener>
        <listener-class>org.nexopenframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    ......
			 
		

Besides, we should mention the presence of the Spring configuration files applicationContext.xml and nexopen-servlet.xml which contains information for the WEB tier.

2.5. NexOpen and Maven2

NexOpen team recommends highly use of Maven2 as your project modelling tool. Maven2 is a tool for managing the entire build process of a project (including compilation, bytecode instrumentation, running tests and others).

Dependencies that your application has only need to be uniquely specified in the projects pom.xml configuration files using a groupId, artifactId and version. Before the artifact is needed, a local caching repository as well as remote organizational repositories and the standard ibiblio.com repositories are searched. If the artifact is found on a remote repository it is downloaded to local cache and provided to project. As weel as the artifact you requested, any additional transiive dependencies that are needed by teh requested artifact are also downloaded.

2.5.1. Maven2 configuration

In order to properly download the NexOpen modules, you must be sure to include in your pom.xml the following repository

				
<repositories>
  ......   
  <repository>
   <id>nexopen-plugin-releases</id>
   <name>NexOpen repository for Maven2</name>
   <url>http://www.nexopen.org/artifactory/repo</url>
  </repository>
</repositories>
.....				
				 
		

2.5.2. NexOpen Maven2 Archetypes

Maven2 introduces the concept of Archetype. In short, Archetype is a Maven project templating toolkit. An archetype is defined as an original pattern or model from which all other things of the same kind are made . The names fits as we are trying to provide a system that provides a consistent means of generating Maven projects. Archetype will help authors create Maven project templates for users, and provides users with the means to generate parameterized versions of those project templates (see also the following address http://maven.apache.org/guides/introduction/introduction-to-archetypes.html for more details about archetypes).

NexOpen provides several archetypes for easy-building completely configured projects in J2EE 1.4 and we also plan to provide archetypes for JEE 5.0 development. We provide EAR, WAR and reusable Business Components archetypes for easy startup without worrying about previous mentioned configuration.

In the next example, we show an easy example of generation of a EAR project using Maven2 comamnd line

				
mvn archetype:create -DarchetypeGroupId=org.nexopenframework.plugins 
	-DarchetypeArtifactId=openfrwk-archetype-application -DarchetypeVersion=2.0.0 	
	-DgroupId=<my-group-id> -DartifactId=<my-artifact-id>
				
				 
		

After execution of archetype, it has been created the next structure, full complaint with Maven2 structures

				
example
|+business
  |+src
    |+main
      |+java //business logic java files
      |+resources
    |+test
      |+java //JUnit Test java files
      |+resources
  |+pom.xml
|+ear
  |+src 
    |+main
      |+resources //specific deployment descriptors of JEE Application Servers    
  |+pom.xml
|+ejb
  |+src
    |+main
      |+resources //deployment descriptor and configuration files (Spring, Hibernate,...)
  |+pom.xml    
|+web
  |+src
    |+main
    |+test
  |+pom.xml
|+.classpath
|+.project
|+pom.xml
				 
		

This generated project is also a configured Eclipse project and could be easily exported into any Eclipse IDE (it could be great that this Eclipse includes the plugin for Maven2 from http://m2eclipse.codehaus.org/). This structure is necessary to be completely understood by Maven2. Notice that Spring, Hibernate3 and other configuration files are generated by archetype for easy startup.

2.6. Deployment

NexOpen it is a JEE Framework and by its JEE nature could be easily deployed in any Application Server. However, due the fat of great variety of choices, we have centered into the following options, mainly due their popularity among developers

2.6.1. Tomcat 5.0.x, 5.5.x and 6.0.x

NexOpen is certificated to be compliant with this popular Web Container for staisfaction of Tomcat fans. However, it is important to notice to be aware with the choice of your Spring PlatformTransactionManager because Tomcat does not provide any implementation of JTA/JTS (this definition is located into the nexopen-dataAccessContext.xml file of your business module under folder META-INF/spring).

		  
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="....">  
  <!-- ========================= RESOURCE DEFINITIONS ========================= -->  
  <!-- The JTA Spring Transaction Manager implementation -->  
  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <description>JTA Spring Transaction Manager implementation</description>  
    <!-- 
 		        avoid retrieve javax.transaction.UserTransaction 
 		        in a EJB CMT environment, otherwise turn on
 		        (for example in a pure web application, only one web module)
 		   -->  
    <!-- IMPORTANT NOTE : this property does not work with spring version 2.0.3 -->  
    <!--property name="userTransactionName"><null/></property-->  
    <property name="sessionFactory" ref="openfrwk.sessionFactory"/>
  </bean>  
  .......	
		 
		

Moreover, you must include a file called context.xml under META-INF folder for properly deployment of your application into your Tomcat environment

		  
example
|+business
 ..... 
|+web
  |+src
    |+main
      |+webapp
        |+META-INF
          |+context.xml  //Tomcat deployment descriptor
        |+WEB-INF
          |+web.xml      //Sun web Deployment Descriptor
  .... 
|+.classpath
|+.project
|+pom.xml
		   
		

There you can specify Tomcat properties and define Connection Pooling configuration for your application. Notice that some differences appears between resource connection pooling definition in Tomcat 5.0.x versions and Tomcat 5.5.x and higher (see Tomcat documentation for more details)

		  
....
<Context path="/example" docBase="example.war" 
         debug="2" privileged="true" crossContext="false">
    <!-- logging support for example -->
    <Logger className="org.apache.catalina.logger.FileLogger" 
            prefix="localhost_example_log." suffix=".log"    
            timestamp="true"/>
    <!-- definition for Tomcat 5.0.x -->
    <!--Resource name="jdbc/exampleDS" auth="Container"
            type="javax.sql.DataSource"
     		description="Employees Database for Example Applications"/>
     <ResourceParams name="jdbc/exampleDS">
	    <parameter>
	      <name>driverClassName</name>
	      <value>com.mysql.jdbc.Driver</value>
	    </parameter>
	    <parameter>
	      <name>url</name>
	      <value>jdbc:mysql://localhost:3306/eclipse?autoReconnect=true</value>
	    </parameter>
	    <parameter>
	      <name>username</name>
	      <value>user</value>
	    </parameter>
	    <parameter>
	      <name>password</name>
	      <value>pwd</value>
	    </parameter>
    </ResourceParams-->
    <!-- definition for Tomcat 5.5.x and higher -->
    <Resource name="jdbc/exampleDS" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="user" password="pwd" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/eclipse?autoReconnect=true"/>    
 </Context>		  
		  
		

2.6.2. JBoss 4.0.x

NexOpen has been certificated to be complaint with JBoss 4.0.5.ga and other minor releases. In order to satisfy the resources depedencies of your project (such as Database connections, JMS Queues,...) you must also provide the suitable deployment descriptors of JBoss which links these resources defined in the Environment Naming Context (ENC, in other words resources such as javax.sql.DataSource presents into a JNDI Context under name java:comp/env) and resources defined in the application server. Then, you would find under META-INF folder of your EJB module the jboss.xml file and the jboss-web.xml under folder WEB-INF in your WEB module.

				
example
|+business
 .....
|+ear
  |+src 
    |+main
      |+resources //specific deployment descriptors of JEE Application Servers    
  |+pom.xml
|+ejb
  |+src
    |+main
      |+resources
        |+META-INF
          |+ejb-jar.xml //Sun ejb Deployment Descriptor
          |+jboss.xml   //JBoss ejb Deployment Descriptor
  |+pom.xml    
|+web
  |+src
    |+main
      |+webapp
        |+WEB-INF
          |+web.xml          //Sun web Deployment Descriptor
          |+jboss-web.xml    //JBoss web Deployment Descriptor
  .... 
|+.classpath
|+.project
|+pom.xml
				 
		

2.6.3. JBoss 4.2.x

NexOpen has been certificated to be complaint with JBoss 4.2.x.ga. Despite the fact that it is not a full complaint Java EE 5.0 Application Server, it provides several features of such specification as EJB 3.0 container. Nevertheless, we should make some changes due to hibernate3 problems originated by a lower version of hibernate-annotations present in the server classpath. Obviously, one straigh solution could be removed such dependency, but could generate several errors to other applications and violates the JBoss release. Therefore, we will try to explain the steps in order to avoid the problems presented by this lower version. First of all, we should write the following propertie, if we want to avoid a ClassCastException, a typical example of a classloader problem

				
<hibernate-configuration>
 <!-- a SessionFactory instance listed as /jndi/name -->
 <session-factory>
  <!-- properties -->
  <property name="hibernate.connection.datasource">java:comp/env/jdbc/exampleDS</property>
  <!-- avoid registering of validation and search listeners due to classloader problems 
       in JBoss 4.2.x.ga [in classpath, we find an older version of hibernate-annotations
       which incudes the validator and search listeners, now belonging to separate projects] -->
  <property name="hibernate.validator.autoregister_listeners">false</property>
  <property name="hibernate.search.autoregister_listeners">false</property>
  <property name="hibernate.validator.apply_to_ddl">false</property>
  <!-- Annotated classes -->				
				
		

Moreover, we have to add into tthe pom.xml the following dependency in order to avoid a NoSuchMethodException

				
<!-- this dependency is needed if you want to deploy to JBoss 4.2.0.ga -->
<!-- Hibernate validator -->
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-validator</artifactId>
	<version>3.0.0.ga</version>
</dependency> 				
				
		

Finally and related to specific deployment descriptors of JBoss, it is same as before section JBoss 4.0.x.

2.6.4. Bea WebLogic 9.2.x

Nexopen is certified to properly deploy into a Bea WebLogic Application Server version 9.2.x. As well as JBoss, you must add the specific Deployment Descriptors of Bea WebLogic located in the same places as JBoss.

		
example
|+business
 .....
|+ear
  |+src 
    |+main
      |+resources //specific deployment descriptors of JEE Application Servers
        |+META-INF
          |+weblogic-application.xml
  |+pom.xml
|+ejb
  |+src
    |+main
      |+resources
        |+META-INF
          |+ejb-jar.xml            //Sun ejb Deployment Descriptor
          |+weblogic-ejb-jar.xml   //Bea WebLogic ejb Deployment Descriptor
  |+pom.xml    
|+web
  |+src
    |+main
      |+webapp
        |+WEB-INF
          |+web.xml          //Sun web Deployment Descriptor
          |+weblogic.xml     //Bea WebLogic web Deployment Descriptor
  .... 
|+.classpath
|+.project
|+pom.xml
				 
		

Notice existence of a weblogic-application.xml suitable for dealing with customization of your classloader using the Filtering Classloader technique (see Bea WebLogic documentation for more details)

		
<?xml version="1.0" encoding="UTF-8"?>

<wls:weblogic-application
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:wls="http://www.bea.com/ns/weblogic/90"
	xsi:schemaLocation="....">
	<wls:application-param>
		<wls:param-name>webapp.encoding.default</wls:param-name>
		<wls:param-value>UTF-8</wls:param-value>
	</wls:application-param>
	<!-- 
	     In WebLogic 9.2 a new feature called Filtering Classloader 
	    (documented in the WebLogic server documentation) has been implemented 
	-->
	<wls:prefer-application-packages>
	  <wls:package-name>javax.jws.*</wls:package-name>
	</wls:prefer-application-packages>
</wls:weblogic-application>		
		
		

Chapter 3. Attribute Contexts Support

The way to access in a given context is a complex task when we dealing with a JEE environment. As you probably know, in a JEE application exists several contexts (javax.servlet.ServletContext, javax.servlet.ServletRequest,javax.servlet.http.HttpSession and others) and sometimes is misleading where to look up your attribute. So, the need for a Facade to access to an attribute to all contexts or to an specific context it is an utility that could be interesting to offer in a JEE Framework. Most modern JEE Frameworks, for example JBoss Seam, provides this unfied way to access in a similar manner that our Framework. Nevertheless, our way it is more extensible that the JBoss Seam way.

It is important to note that Spring Framework has easy ways to access to almost all WEB contexts, but this unified view, as a Facade, it is not provided. So, our idea it is to integrate the Spring functionalities and allow the possibility to extend it for other modules of Framework (such as Workflow Module, see the Workflow section for more details) or even offer the possibility to customize to your JEE application.

3.1. Contexts Framework

We provide a unified way (using the Facade pattern) of to acces to a context or a group of contexts represented by the class import org.nexopenframework.context.framework.Contexts

				
.....
import org.nexopenframework.context.framework.Contexts;
......
//access to all contexts registered
Object obj = Contexts.getAttribute("my.attribute");
//acccess to contexts with scope REQUEST
Object obj_req = Contexts.getAttribute("my.request.attribute", Contexts.REQUEST);
				 
			

Note the presence of a specific method for searching for an attribute in the REQUEST context.

3.2. How to provide a custom Context

The way to provide a customized Context it is just implementing the interface org.nexopenframework.context.framework.Context

				
.....
import org.nexopenframework.context.framework.Context;
import org.nexopenframework.context.framework.ContextAdaptor;
.....
public class MyContext extends ContextAdaptor implements Context {

	public Object getAttribute(String name) {
	.......
	}
	
	public int getScope() {		
		return Contexts.APPLICATION;
	}
}
				
			

3.3. Configuration

You must be sure that in the beanRefContext.xml to be present the following entry into the constructor argument element

			
<!-- NexOpen Contexts mdoule -->  
<value>classpath*:META-INF/spring/openfrwk-module-contexts.xml</value>			
			
		

Chapter 4. Events and listeners in NexOpen

4.1. Bootstrap events and listeners

One important feature of NexOpen is to provide a nice way to deal wih the events of Spring thru BootstrapListener

		
...
import org.nexopenframework.spring.context.BootstrapEvent;
import org.nexopenframework.spring.context.BootstrapListener;
...
public clas MyListener implements BootstrapListener {

	public void contextDestroyed(final BootstrapEvent event) {
		.......
	}

	public void contextInitialized(final BootstrapEvent event) {
		......
		
	}
	......

}
		
		

4.2. Event dispacthing

One important feature in NexOpen is the possibility to send events easily thanks to EventDispatcher class. In this way, you can easily create any event class type following the java onvention (extending from java.util.EventObject) and fire it. Here, we provide an easy example of use that could be found in any Business Service Component class.

		
....
import org.nexopenframework.context.event.EventDispatcher;
....
EventDispatcher.publishEvent(new NotificationEvent(data));
		
		

This is the base in the AJAX-Reverse integration, as you can see in the AJAX chapter.

4.3. Configuration

In order to easily configure this module, you must define a file called openfrwk-module-eventsDispatcher.xml in the WEB tier and define a Spring bean as follows (this file also contains other bean for events but we only center in the event dispatcher bean)

		
.....		
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="...">
	<description>Objects used to publish events</description>
	<!-- ========================= RESOURCE DEFINITIONS ========================= -->
	<!-- 
	  	Event dispatcher class. After this is initialized by Spring 
	    could be used in a static way forany class of the 
	    simple application 
	-->
	<bean id="publisher" class="org.nexopenframework.context.event.EventDispatcher">
		<description>Event dispatcher for handling notifications</description>
	</bean>
	......	
		
		

Afterwards, yo must import the above Spring configuration file in the nexopen-servlet.xml file

		
 <!-- 
  Spring Event support ::
   1.- sending notifications from any layer of your application 
 -->
 <import resource="openfrwk-module-eventsDispatcher.xml" />		
  		
		

With this, we can easily fire events for any service component and will be catched in the presentation layer.

Chapter 5. Resources Support

5.1. Pooling support for components

Pooling is a main characteristic of managed JEE components (such as Servlet Thread Pool, EJBs, javax.sql.DataSource,...). One of the characteristics of Frameworks such as Spring is the possibilty to obtain such features easily thru configuration. In NexOpen, we have choosen to offer such features in a transpaent way or developer and we have though to hide such configuration and offer a set of metadata for easy development.

The way than we can declare that a Business ServiceComponent needs pooling support is thru a JSR-175 annotation

			
.......
import org.nexopenframework.business.annotations.BusinessService;
import org.nexopenframework.business.annotations.BusinessType;
import org.nexopenframework.business.resources.annotations.ObjectPooling;
/**
 *  <p>Example of use of {@link ObjectPooling} annotation</p>
 */
@ObjectPooling(minSize=2,maxWait=100,maxIdleTime=200)
@BusinessService(type=BusinessType.FACADE)
public class ObjectPoolingFacadeImpl implements ObjectPoolingFacade {
	............

}
			 
	

5.1.1. Configuration

In order to use this module, you must provide the following configuration file in your beanRefContext.xml which is related to easily configuration of service components which could be benfiated from the pooling feature.

			
<!-- services for j2se 5.0 -->  
<value>classpath*:META-INF/spring/openfrwk-module-services-pool-jdk15.xml</value>			
			
		

Be sure, not include the file openfrwk-module-services-jdk15.xml which is the non-pool aware configuration file for service components.

Business Tier

This part of the reference documentation is concerned with the business tier, and specifically the separation of concerns among business components. In NexOpen Framework, we catalog between Facades and Application Services using standard patterns for such division (GoF and Core J2EE patterns). Inside the Application Services exist another division related to Congigurable Services that are called Serices or simplicity (Aplication Services or Business Services that could be easily mnaged thru a JMX console for instance).

NexOpen's comprehensive transaction management support is covered in detail by the use of the facilities of Spring Framework. This feature as well others, like exception handling, are hidden to developers by use of Aspect Oriented Programming (AOP).

Chapter 6. Service Components

In the OOSE modeling, James Rumbaugh defined a Service Component as a control component such as "represent coordination, seuqencing, transactions, and control of other objects and are often used to encapsulate control related to a specific use case". Following this definition, in NexOpen we have structured the business layer for dealing with POJOs whih fulfills the requeriments before mentioned. Notice that these divisions also are related with notions of best practices in JEE development.

6.1. Business Services

All the business logic of an application JEE must be located into this tier. However, several mistakes and misconcepts could appears if a Service-Oriented architecture it is not well applied in your JEE solution. Therefore, we should apply some sound patterns in order to easily adopt a systemic quality of manageability and extensibility.

Business Services are an special kind of components inside NexOpen which fulfills the above descibed features. The main features that are essencial to be included in these components, are transactionality, concurrency control and exception handling. Moreover, in environments or solutions that not included EJB container, we can offer resource pooling support. The J2SE 5.0 annotation of NexOpen which describes this component is given as follows

        
@Target(TYPE) @Retention(RUNTIME)
@Documented
public @interface BusinessService {
	/**
	 * Type of business. Mainly, there are <code>FACADE</code> based in the GoF
	 * Facade pattern and <code>APPLICATION</code> based in the Core J2EE pattern
	 * Application Services.
	 */
	BusinessType type() default BusinessType.FACADE;
	/**
	 * <p>The complete name of the Component interface defining the Business 
	 * Service Component contract.</p> 
	 * 
	 * <p>Only applied for implementation classes of a business service 
	 * of type<code>FACADE</code>. In a <code>APPLICATION</code> has nonsense 
	 * due the fact that has not client view (so, it is not necessary 
	 * to specify a interface).</p>
	 */
	String componentInterface() default "";
}           
			
        

As you have noticed appears a new attribute componentInterface which is special for FACADE business type.

Other important feature of this service components is the possibilty of using the inheritance support of Java as typical Object Oriented language. usually, you can extend a set of Service Components from other class or classes which provides several common methods (such as CRUD operations).

We can adopt the following catalog refering to ServiceComponents : Business Facades, Application Services and Configurable Services.

6.1.1. Business Facades

Business Facades classes (using the GoF pattern Facade) provides a unified interface to a group of service components in a subsystem. This kind of classes are benefiated of several services, due the fact that are Service Components, that the surrender container provides, such as transactionality, security, concurrent control or pooling, in a transparent way for developer.

The way that we declare that a class it is a Business Facade is as follows (see that we assume J2SE 5.0 environment)

				
package org.nexopenframework.samples.example.facades;

import org.nexopenframework.business.annotations.BusinessService;
import org.nexopenframework.business.annotations.BusinessType;
/**
 * <p>example using NexOpen Framework</p>
 * 
 * <p>Example of BusinessService</p>
 * 
 * @author <a href="mailto:yourname@yourmail.com">Name Surname</a>
 * @see BusinessService
 * @version 1.0
 * @since 1.0
 */
@BusinessService(type = BusinessType.FACADE)
public class ExampleFacadeImpl implements ExampleFacade {

  ......
}
	      
			

The Facades are an important entry point to the business logic module of an application.

6.1.2. Application Services

Application services is based in the Core J2EE pattern [Alur2003] of same name, which mainly is based in providing a class where the business logic of a component of domain model of your application is located. In this way, we propouse and easy way to manage your application focusing the business logic into a simple class (an providing easy manageability of your application). Moreover, as follows from [Alur2003] the benefits of using Application Services can be enumerated as follows

  1. Minimize business logic in Facades

  2. You want to provide a coarse-grained service API over existing business-tier components and services.

  3. You want to encapsulate use case-specific logic outside of individual Business Objects.

Following, we show how a POJO class could be identified as a Business Application Service

					
package org.nexopenframework.samples.example.services;

import org.nexopenframework.business.annotations.BusinessService;
import org.nexopenframework.business.annotations.BusinessType;
/**
 * <p>example using NexOpen Framework</p>
 * 
 * <p>Example of BusinessService</p>
 * 
 * @author <a href="mailto:yourname@yourmail.com">Name Surname</a>
 * @see BusinessService
 * @version 1.0
 * @since 1.0
 */
@BusinessService(type = BusinessType.APPLICATION)
public class ExampleAppService {

  ......
}
	      
				

Here, we define the logic methods associated to a given entity or entities related to our domain model. It is highly recommended use of Application Services in large applications. For easy applications, specially CRUD operations the use of Application Services could not be seen as benefitious as large applications and in this case could be skipped. So, in short and easy applications, we recommend a Facade centric solution.

6.2. Configurable Business Services

Configurable Services (hereafter Services) are an special kind of Business Service Components that can configure some properties of these component thru a JMX console. Notice that these componets, offers the possibility to manage some properties without the need of redeploying an Application Server.

The J2SE 5.0 annotation which describes this component is the following

		  
@Target(TYPE) @Retention(RUNTIME)
@Inherited
@Documented
public @interface Service {
	/**name of the service*/
	String name();
	/**domain*/
	String domain();
	/** A description of the service*/
	String description() default "Service";
	/** If the service has the statistics service enabled*/
	boolean statistics() default false;
	/** If the service is dealing in a distributed environment*/
	boolean distributable() default false;
}		
			
		

Notice that services are prepared to support distributable environemnts, if you specify the attribute distributable as true, automatically any change done in a node of your cluster is broadcasted to all nodes of such cluster. In order to properly done this feature, you must not forget to configure the appropiate module in your beanRefContext.xml (see Configuration for more details)

Here, we describe an example of a configurable business service with the above mentioned annotation

			
package org.nexopenframework.samples.example.services;

import org.nexopenframework.core.annotations.Property;
import org.nexopenframework.services.annotations.PropertyOpType;
import org.nexopenframework.services.annotations.Service;
import org.nexopenframework.services.annotations.ServiceConfigProperty;

@Service(name="ExampleService",domain="simple.business",statistics=false,
 		  distributable=true,description="Example Service for simple aplication")
public class ExampleService {
	
	 @ServiceConfigProperty(operation=PropertyOpType.READ_WRITE)
	 @Property(bean="external.sytemProperty")
	 /**this property could be easily configured from a JMX console*/
	 private String myProperty;
	
	.....
}
		
		

Notice the presence of ServiceConfigProperty as the annotation responsable to indicate which properties could be easily configured or not and if framework should create accessors or mutators (you could not define any getter and setter for this proeprty, framework during the instrumentation phase automatically creates for you the accesors and mutators).

In this example, the property called myProperty could be easily managed in a read-write style by a JMX console, because by default, Instrumentation Phase provides getter and setter methods (in the ServiceConfigProperty annotation exists an operation attribute with default value PropertyOpType.READ_WRITE and then automatically creates such accessors and mutators methods). If you want to modify this default behaviour, you must specify it in this attribute, for instance, if you plan to use only read methods in some properties you have to specify PropertyOpType.READ, and then the Class Transfomer related with Services, in the Instrumentation Phase, will generate only accessors methods (getters) but not mutators (setters).

Finally it is important to note, that inheritance is forbidden in this kind of configurable business components, because in the Intsrumentation Phase is provided a suitable parent to deal with lifecycle methods associated to this component. The parent class could be the specific ServiceSupport or the customized JBoss serice support class

6.2.1. Dependency of other services

Sometimes, you need to explicitely start a given service after other ones has been alredy started, because you want to be benefitied from such services. In this case, a dependency among services. NexOpen provides a JSR-175 metadata which fulfills these requierements, the Depends annotation.

			  
package org.nexopenframework.services.annotations;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Target(TYPE) @Retention(RUNTIME)
@Documented
public @interface Depends {
	/**
	 * <p>The services classes array that the annotated class depends</p>
	 * 
	 * @return the services classes whihc the given service depends
	 */
	Class[] value();
}			  
			  
			

The following example show you how to use it

			
........			
@Depends({OtherService.class, AService.class})
@Service(name="easy",domain="test.example")
public class SomeService {
........
}			
			
			
			

Therefore, the lifecycle of this service will no be executed till OtherService and AService has been completedly started (in other words, are in the State START )

6.3. Addition of custom AOP interceptors

You have the possibility of addition of custom AOP interceptors in any service component. The way to do is thru an annotation Interceptors. If any annotation is present, in the enhacement phase, will be recovered and searching into Spring IoC container or just created as a single instance (take into account that it is injected any depedency in this phase, if you want to inject something, you must declare such interceptor into a Spring configuration file) and added to the chain of interceptors associated to service components.

	 
package org.nexopenframework.core.interceptors.annotations;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import org.aopalliance.aop.Advice;

@Target(TYPE) @Retention(RUNTIME)
@Inherited
public @interface Interceptors {
	/**
     * <p>The interceptors to be added to a service component. The class must be an AOP alliance
     * {@link Advice}</p>
     * 
     * @return the interceptors class objects to be added to a given ServiceComponent
     */
	Class<? extends Advice>[] value();
}

	 

Notice the dependency with AOP Alliance, an easy to use implementation of the AOP philosophy. Following we show an example o using this annotation

	 
.....	 
@Interceptors({EasyInterceptor.class, PerformanceMonitorInterceptor.class})
@BusinessService(type=BusinessType.FACADE)
public class ExampleFacade implements ExampleFacadeIf {

	@Component OtherFacadeIf other;
	/* (non-Javadoc)
	 * @see org.nexopenframework.example.business.ExampleFacadeIf#doBusiness()
	 */
	public void doBusiness() {
		System.out.println("ExampleFacade.doBusiness()");
	}
}
	 
	 

In next releases, we probably relax such dependency with AOP Alliance Advice class, in order to inrodce other AOP Frameworks such as AspectJ which is widely supported by Spring2.

6.4. Injection of components

Usually, Service Components could depend of other components or resources. The usual way to access to these components is thru injection using the fact that components are managed thru a IoC container (in this case Spring Framework IoC container). NexOpen provides an annotation tha is defined as follows

		
package org.nexopenframework.core.annotations;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Target({TYPE,METHOD,FIELD}) @Retention(RUNTIME)
@Documented
@Inherited
public @interface Component {
	/**
	 * 
	 * @return
	 */
	String name() default "";
	/**
	 * <p>The type of the Service Component</p>
	 * @return
	 */
	Class<?> type() default Object.class;
}
		 
		

An example of how to inject components (service components or even resources managed by any JEE application server) is given as follows

			
....
import javax.annotation.Resource;
...
import org.nexopenframework.core.annotations.Component;

@BusinessService(type = BusinessType.FACADE)
public class MyFacade implements MyFacadeIf {
    /**Access to a ApplicationServer component*/
    @Resource javax.transaction.UserTransaction ut;
    /**Access to a Component managed by Spring IoC container*/
    @Component mypackage.service.MyAppService appService;
}			
			
		

As we notice, there two main annotations in order to access to Components. The first one, it is a component managed by an JEE Application Server (a JTA/JTS User Transaction implementation of such Application Server) and the second one is managed by a IoC container, such as Spring Framework. Notice that all of these components, they will be injected during the deployment phase.

6.5. Caching in components

One important feature of ServiceComponents is the possibility of caching values in a structure Map type. A typical example could be the next one, we have a service component which uses the OCSP certificate revocation, if we do not use cache of the response, every time we would like to know if a certificate it is revoked, we should make an HTTP invocation in order to ensure it. However, if we can ensure that during an among of time this reponse would not change, it is not necessary to make an HTTP invocation and increasing performance of the application.

The way that we inject a cache, it is as follows using the annotations @org.nexopenframework.cache.annotations.Cache. Look that we are injecting a proxy which deals with a suitable configured provider (such as EhCache or JBossCache) and hides the complexities of Cache API offering a well-known interface to operate. Features such as cache eviction, policies and others they are hidden and could be adminsitered using a JMX console.

			
....
import static org.nexopenframework.cache.annotations.CacheConcurrency.NONSTRICT_READ_WRITE;
....
import java.util.Map;
import org.nexopenframework.cache.annotations.Cache;			
....
public class MyAppService {
    
	/**represents a proxy of a selected cache*/
	@Cache(concurrency=NONSTRICT_READ_WRITE) 
	Map cache;
	.....
}			
			
		

In order o use this feature, we must add into our beanRefContext.xml the following entry

			
 <!-- cache services -->
 <value>classpath*:META-INF/spring/openfrwk-module-cache.xml</value>			
			
		

Internally, it looks for a suitable implemnetations of org.nexopenframework.cache.providers.CacheProvider. If no one is provided, first tries to load the EhCache provider if it is found in classpath and in negative case provides a naive implementation based in an implementation of java.util.Map. However, you can provide your custom provider just declaring into your business spring files

6.6. Enhacement Phase

The Enhacement Phase it is an important phase in the lifecyle of deployment of a NexOpen application, in which all the Service Components, presents in the Spring IoC container, will be enhaced thru the addition of fixed and custom AOP interceptors. The fixed interceptors deals with transactionality support, exception handling and performance monitoring. Therefore, this components will be translated to proxies which can deal in a transparent way with features that could be tought to developers.

It is important to note that in the current release, we only support addition of AOP Alliance interceptors.

6.7. Transactionality in ServiceComponents

Transactionality in ServiceComponents is managed internally by framework thru AOP which intercepts a call and pass the invocation to ServiceComponentEngine. This is an internal component of NexOpen which guarantees to execute the invoked methods in a transactional environment thanks to Spring Transactional module. Internally this engine has an ordered list of Spring TransactionAttributeSource implementations

  • AnnotationTransactionAttributeSource. Spring implementation which checks existence of Spring annotation Transactional.

  • EJB3AnnotationTransactionAttributeSource. NexOpen implementation which checks existence of JEE 5.0 annotation TransactionAttribute.

  • NameMatchTransactionAttributeSource. Spring implementation whcih checks matching wwith the method name of your Business Service Component.

The name matches, of this last TransactionAttributeSource option, are the following (as it is carried into the services spring configuration files).Therefore, if your method begins with one of this name, you can not declare any specific annotation for dealing with tx behaviour


 ......	  
<bean id="nameMatchAttributeSource"
  class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
  <description>Name Match attribute source</description>
  <property name="properties">
	<props>
		<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
		<prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
		<prop key="exits*">PROPAGATION_SUPPORTS,readOnly</prop>
		<prop key="retrieve*">PROPAGATION_SUPPORTS,readOnly</prop>
		<prop key="query*">PROPAGATION_SUPPORTS,readOnly</prop>
		<prop key="update*">PROPAGATION_REQUIRED</prop>
		<prop key="store*">PROPAGATION_REQUIRED</prop>
		<prop key="handle*">PROPAGATION_REQUIRED</prop>
		<prop key="save*">PROPAGATION_REQUIRED</prop>
		<prop key="insert*">PROPAGATION_REQUIRED</prop>
		<prop key="create*">PROPAGATION_REQUIRED</prop>
		<prop key="persist*">PROPAGATION_REQUIRED</prop>
		<prop key="set*">PROPAGATION_REQUIRED</prop>
		<prop key="add*">PROPAGATION_REQUIRED</prop>
		<prop key="make*">PROPAGATION_REQUIRED</prop>
		<prop key="delete*">PROPAGATION_REQUIRED</prop>
		<prop key="remove*">PROPAGATION_REQUIRED</prop>
		<prop key="erase*">PROPAGATION_REQUIRED</prop>
		<prop key="execute*">PROPAGATION_REQUIRED</prop>
	</props>
  </property>
</bean>
	......
	  

Following caption, shows examples of the before mentioned mechanisms of transactionality

			
/**
 * this method will be executed in a tx environment due the fact of matching
 * with internal rules
 */
 public void createPerson(final Person p) {
    this.pm.persist(p);
 }

/**
 * this method will not be executed in a tx environment
 */
 public void doSomeBusiness(final Person p) {
    this.pm.persist(p);
 }
/**
 * this method will execute in a tx environment using Spring Transactional 
 * annotations support
 */
 @org.springframework.transaction.annotation.Transactional
 public void doBusiness(final Person p) {
    this.pm.persist(p);
 }
 
 /**
  * <p>Client customs the tx using EJB3</p>
  *
  */
  @javax.ejb.TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRED)
  public void doOperationWithTx() {
  
  }
			
		

As you can see, from a Name Pattern strategy to EJB 3.0 annotations specs strategy are contempled in NexOpen. Notice the inhered Container Managed Transaction (CMT) nature of Service Components, you only declare the transaction and other will do the hard work (beyond scenes, the transactional engine interceptor communicates to Spring PlatormTransactionManager which finally performs the transactional operations).

However, if you would like to deal with transactionality in your Service Components, either by JTA/JTS of just JDBC or even with a custom way, such as the interfaces offered by JPA or Hibernate3, in other words being a Bean Managed Transaction Component (BMT), you must indicate using a JEE 5.0 annotation as follows

			
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

@TransactionManagement(TransactionManagementType.BEAN)
@BusinessService(type=BusinessType.FACADE)
public class DummyBeanFacadeImpl implements DummyBeanFacade {

   /**using JTA/JTS support*/
   @Resource javax.transaction.UserTransaction ut;
   
   /**Application Server managed DataSource*/
   @Resource(name="jdbc/myDs") javax.sql.DataSource ds;

   public void methodJdbcTx() {
     //if you use this choice, you do not need
     //the javax.transaction.UserTransaction object
     Connection conn = null;
     try {
        conn = ds.getConenction();
        conn.setAutomCommit(false);
        //do business operations
        ....
        conn.commit();
     } finally {
        //close transaction
     }
   }
   
   public void methodJtaTx() {
        ut.begin();
        //do business operations
        ....
        ut.commit();
   }
}
			
		

Internally, the ServiceComponent Engine suspends a current transaction, if any it is in process, and invokes the method without transactionality. After the invocation of method, the Engine resumes this transaction

6.8. Authorization in Business Components

Usually, we would like to perform authorization constraints in business components. There two ways o deal with it in NexOpen Framework, one programmatic and teh other one declarative.

The programmatic way, is to obtain n instance of Actor and perform teh operations such as obatine the current User, or if a given role is allowed

		
.....
import org.nexopenframework.security.context.Actor;
.....
public void doBusinessMethod (final Map<String, Serializable> filter) {
    final Actor actor = Actor.getInstance();
 	//retrieve the current User
 	final User user = actor.getCurrentUser();
 	....
 	//of perform programatic authz
 	if (actor.isUserInRole("ROLE_ADMIN") {
 	  ........
 	}
 	......
}		
		
		
		

The declarative way, is to use JEE 5.0 RolesAllowed annotation. This annotation should be declared at method level and in the specific case of Facades, it must be declared at the interface level, as follows in the given example

		
...
import javax.annotation.security.RolesAllowed;
...
@RolesAllowed("ROLE_ADMIN")
void createPerson(final Person person);
....
	
		
		

6.9. Configuration

In order to use such module you must be sure that the Spring configuration file for services it si included in your beanRefContext.xml

			
<!-- services for j2se 5.0 -->  
<value>classpath*:META-INF/spring/openfrwk-module-services-jdk15.xml</value> 			
			
		

Moreover, you must include such dependency in your pom.xml

<dependency> 
  <groupId>org.nexopenframework</groupId>  
  <artifactId>openfrwk-services-jdk15</artifactId>  
  <version>${nexopen.version}</version>  
  <exclusions> 
    <exclusion> 
      <artifactId>commonj-twm</artifactId>  
      <groupId>com.bea.wlplatform</groupId> 
    </exclusion>  
    <exclusion> 
      <artifactId>junit</artifactId>  
      <groupId>junit</groupId> 
    </exclusion>  
    <exclusion> 
      <artifactId>commons-logging</artifactId>  
      <groupId>commons-logging</groupId> 
    </exclusion> 
  </exclusions> 
</dependency> 		
		

We should exclude such dependencies in order not to be included in the artifact (ear, war, ...)

Chapter 7. Service Gateway

The access to the business layer from the presentation tier is thru a Service Gateway component which hides a container (a EJB 3.0 container, a EJB 2.x container or a IoC container such as Spring Framework).

At first design of this module, NexOpen team considered the possibility of hidden calls, using AOP, thru a EJB remote or local container. Nevertheless, we have assumed that this scenario is erroneous and does not offer solutions to developers which would like to use web containers such as Tomcat 5.0.x or 5.5.x or Jetty 5.x or 6.x

7.1. Invokers

Invokers are a chain of implementations of ServiceGatewayInvoker which are able to communicate to a given container. In this sense, for a developer point of view always see the same code from a client class, but the way of how to perform invocation to business components, it is different depending the deployment configuration.

				
.....
public class MyController implements Controller {

  /**
   * Proxy which hides a call to MyFacade in a given
   * container. For instance, an EJB container or a POJO container such as Spring, 
   * or even a EJB3 container could be examples of invoked containers. 
   * Expose always your applications business methods 
   * thru Business Facades patterns.
   */
   @ServiceGatewayRef MyFacade myFacade;

   ......
}
				
				
		

The metadata ServiceGatewayRef makes possible the communication with a given container. This one, it is defined as follows

				
package org.nexopenframework.core.runtime.annotations;
.....
@Target({TYPE,METHOD,FIELD}) @Retention(RUNTIME)
@Inherited
@Documented
public @interface ServiceGatewayRef {
  /**the business service to be proxied*/
  Class businessService() default Object.class;
  /**JNDI name of the Service Gateway component*/
  String jndiName() default "";
  /**if must include the prefix java:comp/env to previous JNDI name*/
  boolean resourceRef() default true;
  /**if we use the local or remote call*/
  /**This attribute has been deprecated*/
  @Deprecated
  boolean localEJB() default false;
  /**additional interceptors [now support for AOP Alliance]*/
  Class<? extends Advice>[] interceptors() default {};
}
				
		

Elements such as jndiName and resourceRef are necessary when we deal with communication to EJB 3.0 Stateless Session Beans. Finally, element interceptors is suitable when you would like to enhace the chain of AOP advices to be applied to invocation of Business Facade (very useful, if you want to perform authorization mechanisms, for isntance)

7.1.1. Configuration of Invokers

We can configure a list of suitable invokers in the applicationContext.xml available under WEB-INF folder

				
....
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:jee="http://www.springframework.org/schema/jee"
	   xsi:schemaLocation="....">
  ....
 <!-- ========================= RESOURCE DEFINITIONS ========================= -->
	
 <bean id="servGatewayProcessor"
	class="org.nexopenframework.deployment.processor.ServiceGatewayProcessor">
	<description>
		Processor which deals with service gateway references in controllers
	</description>
	<!-- Invokers -->
	<property name="invokers">
       <list>
          <value>org.nexopenframework.core.runtime.invokers.EJBLocalInvoker</value>
          <value>org.nexopenframework.core.runtime.invokers.EJBRemoteInvoker</value>
       </list>
    </property>
</bean>
....
				 
		

There, we can define a list of invokers to be proceeded, when a controller or some client, which dwells in the presentation tier, tries to invoke a service component (usually a Facade) in the business tier.

7.1.2. EJB configuration

We must ensure that in the pom.xml of the ejb module must present the ollowing dependency

		  
 <!-- EJB Gateway (Gateway pattern [See Fowler2002, 466])-->
<dependency>
	<groupId>org.nexopenframework</groupId>
	<artifactId>openfrwk-ejbgateway</artifactId>
	<version>${nexopen.version}</version>
	<exclusions>
		<exclusion>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
		</exclusion>
	</exclusions>
</dependency>
		 
		 

Chapter 8. Logging and Auditing in NexOpen

in this section, we will introduce NexOpen Audting module

8.1. Introduction

Logging/Auditing are common modules which appears in traditional JEE developments

				
.....
import org.nexopenframework.audit.annotations.Auditable;
import org.nexopenframework.audit.intercept.AuditMethodInterceptor;
import org.nexopenframework.core.interceptors.annotations.Interceptors;
.....
@Interceptors(AuditMethodInterceptor.class)
@BusinessService(type=BusinessType.FACADE)
public class MyFacadeImpl implements MyFacade {

 /**
  * <p>audit will be invoked after doBusiness invocation</p>
  */
  @Auditable(perform=PerformType.AFTER_INVOCATION)
  public void doBusiness() {
    ......
  }
  
 /**
  * <p>audit will be invoked before doBusiness invocation</p>
  */
  @Auditable
  public void doMoreBusiness() {
    ......
  }
}				
				
		

As you can observe, you do not need to perform

		
....
@Auditable
public class MyFacadeImpl implements MyFacade {
  ...
}
		
		

in this case, all the methods are auditable

8.2. Traditional integration with a RDBMS

8.3. Integration with Oracle FGA

NexOpen provides a way to deal with Oracle FGA support

8.4. How to extend it to accomodate to your functionalities

However, several times you need a particular auditing that it is not contempleted by our implementations or extend it. In order to integrate it, you must implement the Provider interafce as follows

	   
....
import org.nexopenframework.audit.AuditContext;
import org.nexopenframework.audit.AuditException;
import org.nexopenframework.audit.Provider;
....
public class MyCustomProvider implements Provider {
  .....
  
  public void audit(AuditContext context) throws AuditException {
     ........
  }
}
	   
		

Moreover, you must also create you custom configuration file

8.5. Configuration

In order to use the audit module, you must be sure to correctly introduce the next entrance into the beanRefContext.xml as follows

	   
...
<!-- services for j2se 5.0 -->  
<value>classpath*:META-INF/spring/openfrwk-module-audit-jdk15.xml</value>
<!-- synchronous audit Orale FGA -->
<value>classpath*:META-INF/spring/openfrwk-module-audit-fga.xml</value> 
...
	   
		

Moreover, you can also configure several properties such as execution in synchronous mode or asynchronous

Chapter 9. Scheduling in NexOpen

Scheduling is a feature commonly used in traditional JEE developments

9.1. Introduction

Independently of the scheduler provider that we are using, the way to declare that a method must be scheduled is as follows

			
....
import org.nexopenframework.core.scheduling.annotations.Scheduler;
....			
@Scheduler(delay=1000,period=5000,executeOnStartup=true)
public void simpleScheduler() {
	System.out.println("EasyFacadeImpl.simpleScheduler()");
}
			
		

As you have notice is the common way to deal in NexOpen, thru J2Se 5.0 annotations. This annotation provides support for common periodic schedulings as well cron expressions (you must be sure that your provider supports such feature)

9.2. Using OpenSymphony Quartz Provider

9.3. Using the CommonJ Provider

Besides Quartz, we have integrate with CommonJ, a specification developed by IBM and Bea WebLogic in order to stablish an standard of development of scheduled tasks (an te base of JSR-)

9.4. Configuration of Scheduling Module

In the beanRefContext.xml MUST exists an entry in order to ensure the use of the Scheduling Module in NexOpen applications.

			
....
<beans xmlns="http://www.springframework.org/schema/beans" 
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	   xmlns:components="http://www.nextret.org/schema/components" 
	   xsi:schemaLocation=".....">  
	   
  <bean id="nexopen"
        class="org.nexopenframework.deployment.context.AnnotationApplicationContext">
   <constructor-arg> 
    <list>
     ......
     <!-- Scheduler modules using Quartz -->  
    <value>classpath*:META-INF/spring/openfrwk-module-scheduler-quartz.xml</value>   
     .......
    </list>
   </constructor-arg>  
  ......
  </bean>
			
		

Here, we have selected the use of Quartz provider, in the case of Commonj we should specify its spring configuration file instead.

			
 <!-- Scheduler modules using CommonJ -->  
<value>classpath*:META-INF/spring/openfrwk-module-scheduler-commonj.xml</value>   			
			
		

Chapter 10. Workflow

Nowadays workflows is one of the most important features that usually appears in projects. A workflow could be defined as the movement of documents and/or tasks through a work process. NexOpen Workflow Module encapsulates the complexity of a workflow implementation, JBoss jBPM, in order to provide an easy solution to deal with document movements and tasks.

10.1. Main concepts

More specifically, workflow is the operational aspect of a work procedure: how tasks are structured, who performs them, what their relative order is, how they are synchronized, how information flows to support the tasks and how tasks are being tracked.

NexOpen Workflow Module offers a business process management engine for any Java EE environment. Based on JBoss jBPM, Workflow Module lets you represent a business process as a graph of nodes representing wait states, decision, tasks, etc... NexOpen Workflow module offers you a simply way to enhace your Business Services to interact with the business process management engine.

JBoss jBPM and Nexopen Workflow Module use JPDL (JBpm Process Definition Language) as a language to define business process. These Business Process are defined using XML documents written in JPDL. These XMLs specify entities such as the various states in the process (known as nodes), the task associated with each node, the transitions from one node to the next, the actions associated to the events on nodes and more. You can find information about JPDL on http://www.jboss.com/products/jbpm/docs/jpdl and in the jBPM reference guide http://docs.jboss.com/jbpm/v3/userguide/jpdl.html

10.2. JBoss jBPM integration

We've designed our integration with JBoss jBPM using Spring Modules in order to make jBPM Call Backs, that allow code to be executed directly on jBPMContext. The relationship between Process Instance and Associated Entities is made throught saving Primary Key at Process Context. We use NexOpen Context Module in order to perfom this Integration. The Current Process Context is loaded using Hiberante Listeners. When a business service method load an Entity the Workflow module is responsible to load the process Instances binded to this Entity

We have implemented the above interfaces with the Open Source project JBoss jBPM 3.1.x

NexOpen Workflow Integration with jBPM 3.1.x

Figure 10.1.  NexOpen Workflow Integration with jBPM 3.1.x

NexOpen Workflow

Figure 10.2. NexOpen Workflow

NexOpen Workflow Context

Figure 10.3. NexOpen Workflow Context

Now we're gonna comment the most significative classes that help us to integrate JBoss jBPM.

10.3. Configuration

The way to configure WorkFlow module in your project is by adding workflow module dependency to your business pom file

			
<dependencies>
	<dependency>
		<groupId>org.nexopenframework</groupId>
		<artifactId>openfrwk-workflow</artifactId>
		<version>${nexopen.version}</version>
	</dependency>
</dependencies>					  		
  		
		
If you are planning to work with jdk15 you should use WorkFlow Module with Annotation Support
			
<dependencies>
	<dependency>
		<groupId>org.nexopenframework</groupId>
		<artifactId>openfrwk-workflow-jdk15</artifactId>
		<version>${nexopen.version}</version>
	</dependency>
</dependencies>					
				
		

The next step is update the beanRefContext.xml File. In that file MUST exists an entry in order to ensure the use of the Workflow Module in NexOpen applications.

			
......
<beans xmlns="http://www.springframework.org/schema/beans" 
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	   xsi:schemaLocation=".....">  	   
  <bean id="nexopen"
        class="org.nexopenframework.deployment.context.AnnotationApplicationContext">
   <constructor-arg> 
    <list>
     ......
     <!-- WorkFlow Module -->  
    <value>classpath*:META-INF/spring/openfrwk-module-workflow-jbpm.xml</value>
     .......
    </list>
   </constructor-arg>  
  ......
  </bean>
</beans>
			
		

In you prefer to use WorkFlow module with Annotation Support and with Hibernate Integration you should reference one of these files

			
.......
<!-- WorkFlow Module Annotation Support -->  
<value>classpath*:META-INF/spring/openfrwk-module-workflow-jbpm-jdk15.xml</value>
<!-- WorkFlow Module Annotation Support + Hibernate Integration -->  
<value>classpath*:META-INF/spring/openfrwk-module-workflow-jbpm-hb-jdk15.xml</value>
     ....... 
		

It's also necessary to include jbpm Mapping files in Hibernate Configuration file hibernate.cfg.xml

				
     .......
<!-- # jbpm mapping files # -->		
<!-- hql queries and type defs -->
<mapping resource="org/jbpm/db/hibernate.queries.hbm.xml" />

<!-- graph.def mapping files -->
<mapping resource="org/jbpm/graph/def/ProcessDefinition.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/Node.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/Transition.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/Event.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/Action.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/SuperState.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/ExceptionHandler.hbm.xml"/>
<mapping resource="org/jbpm/instantiation/Delegation.hbm.xml"/>

<!-- graph.node mapping files -->
<mapping resource="org/jbpm/graph/node/StartState.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/EndState.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/ProcessState.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/Decision.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/Fork.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/Join.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/State.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/TaskNode.hbm.xml"/>

<!-- context.def mapping files -->
<mapping resource="org/jbpm/context/def/ContextDefinition.hbm.xml"/>
<mapping resource="org/jbpm/context/def/VariableAccess.hbm.xml"/>

<!-- taskmgmt.def mapping files -->
<mapping resource="org/jbpm/taskmgmt/def/TaskMgmtDefinition.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/def/Swimlane.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/def/Task.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/def/TaskController.hbm.xml"/>

<!-- module.def mapping files -->
<mapping resource="org/jbpm/module/def/ModuleDefinition.hbm.xml"/>

<!-- bytes mapping files -->
<mapping resource="org/jbpm/bytes/ByteArray.hbm.xml"/>

<!-- file.def mapping files -->
<mapping resource="org/jbpm/file/def/FileDefinition.hbm.xml"/>

<!-- scheduler.def mapping files -->
<mapping resource="org/jbpm/scheduler/def/CreateTimerAction.hbm.xml"/>
<mapping resource="org/jbpm/scheduler/def/CancelTimerAction.hbm.xml"/>

<!-- graph.exe mapping files -->
<mapping resource="org/jbpm/graph/exe/Comment.hbm.xml"/>
<mapping resource="org/jbpm/graph/exe/ProcessInstance.hbm.xml"/>
<mapping resource="org/jbpm/graph/exe/Token.hbm.xml"/>
<mapping resource="org/jbpm/graph/exe/RuntimeAction.hbm.xml"/>

<!-- module.exe mapping files -->
<mapping resource="org/jbpm/module/exe/ModuleInstance.hbm.xml"/>
    
<!-- context.exe mapping files -->
<mapping resource="org/jbpm/context/exe/ContextInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/TokenVariableMap.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/VariableInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/ByteArrayInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/DateInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/DoubleInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/HibernateLongInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/HibernateStringInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/LongInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/NullInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/StringInstance.hbm.xml"/>

<!-- msg.db mapping files -->
<mapping resource="org/jbpm/msg/Message.hbm.xml"/>
<mapping resource="org/jbpm/msg/db/TextMessage.hbm.xml"/>
<mapping resource="org/jbpm/command/ExecuteActionCommand.hbm.xml"/>
<mapping resource="org/jbpm/command/ExecuteNodeCommand.hbm.xml"/>
<mapping resource="org/jbpm/command/SignalCommand.hbm.xml"/>
<mapping resource="org/jbpm/command/TaskInstanceEndCommand.hbm.xml"/>

<!-- taskmgmt.exe mapping files -->
<mapping resource="org/jbpm/taskmgmt/exe/TaskMgmtInstance.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/exe/TaskInstance.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/exe/PooledActor.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/exe/SwimlaneInstance.hbm.xml"/>

<!-- scheduler.exe mapping files -->
<mapping resource="org/jbpm/scheduler/exe/Timer.hbm.xml"/>

<!-- logging mapping files -->
<mapping resource="org/jbpm/logging/log/ProcessLog.hbm.xml"/>
<mapping resource="org/jbpm/logging/log/MessageLog.hbm.xml"/>
<mapping resource="org/jbpm/logging/log/CompositeLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/ActionLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/NodeLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/ProcessInstanceCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/ProcessInstanceEndLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/ProcessStateLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/SignalLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/TokenCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/TokenEndLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/TransitionLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/VariableLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/VariableCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/VariableDeleteLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/VariableUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/ByteArrayUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/DateUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/DoubleUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/HibernateLongUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/HibernateStringUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/LongUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/StringUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/TaskLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/TaskCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/TaskAssignLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/TaskEndLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/SwimlaneLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/SwimlaneCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/SwimlaneAssignLog.hbm.xml"/>

<!-- # end jbpm mapping files # -->
   .......
      
			

Now the Workflow module it's ready to work

10.4. How to Enhace an Entity with a Workflow Process

Due to business reasons it could be interesting to you to enhance some of your entities by binding an specific Workflow to them. This workflow must be in charge of perform some cross operations that allow to your Analist to detach workflow business logic from your entity logic. By this way we could add a Process Event Dispatcher Bean to dispatch the events defined in the Workflow Process Definition, a Process Decision Manager Bean in charge of manage the decisions in the Workflow Process Definition and so on.

Now we're gonna show in a few steps how to enhace one of your business Entity with a Workflow Process

Step 1. Add the Process Definition reference to your Application business Service

			
import org.nexopenframework.workflow.annotations.ProcessDefinition;
import es.example.Example;

@ProcessDefinition(entity = Example.class, name = "example-process-definition")</para>
			
		

Step 2. You must configure a jBPM process definition as a Spring Bean to be referenced by your Application Service

			 
<!-- process definition -->
<bean id="example-process-definition"
	class="org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean">
	<property name="definitionLocation"
		value="classpath:META-INF/bpm/example-process-definition/processdefinition.xml">
	</property>
</bean>			
			
		

Step 3. Add the Process Manager Interceptor to Interact with your Application Business Service

			 
import org.nexopenframework.core.interceptors.annotations.Interceptors;
import org.nexopenframework.workflow.intercept.ProcessManagerInterceptor;

@Interceptors( { ProcessManagerInterceptor.class }}
			
		

Step 4. Add Spring Configuration for the business Entity

			
<bean id="serviceContext"
	 class="org.nexopenframework.workflow.providers.jbpm31.JbpmProcessInstanceContext">
	 <description>Custom context related with business logic</description>
	 <property name="order" value="1"/>
	 <property name="entityClass" value="es.exanple.Example"/>
	 <property name="queryHints">
		<map>
 			<entry key="org.nexopenframework.persistence.hibernate3.cacheEnabled" value="true" />
			<entry key="org.nexopenframework.persistence.hibernate3.cacheRegion" value="jbpm" /> 		 		
 		</map>
 	</property> 
</bean>
		
		

Step 5. Now you can annotate your Business Methods with the Workflow Module Annotations

			
@org.nexopenframework.workflow.annotations.ProcessDefinitions{@ProcessDefiniton(), @ProcessDefinition()}
@org.nexopenframework.workflow.annotations.ProcessDefinition(name=“”, entity=Object.class)
@org.nexopenframework.workflow.annotations.CreateProcess(name=“”, transition=“”)
@org.nexopenframework.workflow.annotations.BeginTask(process=“”, name=“”, id=“”)
@org.nexopenframework.workflow.annotations.ProcessContext(value=“”)
@org.nexopenframework.workflow.annotations.Transition(process=“”, name=“”)
@org.nexopenframework.workflow.annotations.EndTask(process=“”, name=“”, id=“”, transition=“”)
			
		

10.5. WorkFlow Annotations

10.5.1. Process Definition

Type Annotation to define a Process Definition. The basis of a process definition is a graph that is made up of nodes and transitions. That information is expressed in an xml file called processdefinition.xml . You can find more information about how to define a Business Process using Java Process Definition Language on http://www.jboss.com/products/jbpm/docs/jpdl Using Process Definition Annotation we're binding the process-definition referenced by the process-definition.xml, the Entity Class and the Business Service.

				
@BusinessService(type = BusinessType.APPLICATION)
@ProcessDefinition(entity = Example.class, name = "example-process-definition")
public class ExampleAppService {
	//		
}
....
public class Example {
	//
}			
				
			

10.5.2. Process Definitions

Type Annotation to define a set of Process Definition that binds to this Business Service. We usually use this Annotation when we're moving two process definitions with the same Business Service. After that, in the business service methods, you could the choose between differents process definitions using ProcessContext annotation.

				
@BusinessService(type = BusinessType.APPLICATION)
@ProcessDefinitions{
	@ProcessDefinition(entity = Example.class, name = "example-process-definition"), 
	@ProcessDefinition(entity = AnotherExample.class, name = "another-example-process-definition")
}	
public class ExampleAppService {
	//		
}
....
public class AnotherExample{
	//
}

public class Example {
	//
}			
				
			

10.5.3. CreateProcess

Method Annotation to create a Process Instance. Those methods annotated with CreateProcess creates a new Process Instance of the process-definition binded with the Business Service. You could force a transition or not after the creation of a process definition using the boolean property transition.

				
@CreateProcess(transition=true)
public void create(Example ex) {
	//
}								
				
			

10.5.4. BeginTask

Method Annotation that Marks a method as causing jBPM Task associated to the process-definition binded to the Business Service to be started. You can identify the task using the name of the task defined in the process definition. If there's more than a process definition binded to the business service you can choose the process definition to work on using the property process of the BeginTask annotation.

				
@BeginTask(name="exampleTask", process="processDefinition")
public void create(Example ex) {
	//
}								
				
			

10.5.5. ProcessContext

Process Context Annotation marks a Business Service method to be used in a Workflow Process Context and loads the Entity binded to the Process Context associated to the Business Service.

				
@ProcessContext(name="exampleTask")
public void doSomething(Example ex) {
	//
}								
				
			

10.5.6. Transition

Annotation method that marks as causing a jBPM transition to the Process-definition binded to the Business Service.

				
@Transition(name="nextStep")
public void update (Example ex){
	//
}
				
			

10.5.7. EndTask

Method Annotation to mark as Ended a Task Instance.

				
@EndTask(name="exampleTask")
public void done(Example ex) {
	//
}								
				
			

Chapter 11. NexOpen as a Test-Design Driven Framework

Nowdays, a well defined application has to provide tests suites for checking unitary and functionality features. In java and JEE applications JUnit has the reference test framework for fulfilling these features.

11.1. Test support for Service Components using JUnit3

NexOpen extends the JUnit3 TestCase for providing a development mark to easily test your complex funtionalities of yours JEE applications.

11.2. Support for JUnit4

NexOpen 0.4.0 and higher release also offer support for dealing with test annotation-driven frameworks such as JUnit4.

	
...
import org.junit.Test;
import org.junit.runner.RunWith;
import org.nexopenframework.test.junit4.NexOpenJUnit4ClassRunner;
import org.nexopenframework.test.junit4.annotations.TestCallbackListeners;
import org.nexopenframework.test.junit4.support.PerformanceCallbackListener;
.....
@TestCallbackListeners(PerformanceCallbackListener.class)
@RunWith(NexOpenJUnit4ClassRunner.class)
public class MBeanServerManagerTest {
   ....
   @Test(imeout=60)
   public void doSomeTestOp() {
      ..........
   }
}	
		
	

Chapter 12. Web Services Reference

Sometimes, in the Business Layer, we must integrate with one or several third party Web Services

12.1. Introduction

In order to deal with this feature, exists the JAX-WS 2.0 specification in order to provide a common way to deal with Web Services integration

12.2. NexOpen and JAX-WS 2.0

NexOpen uses JAX-WS 2.0 in order to integrate with Web Services. Following the nice practices developed by Spring Team, we use AOP and we leave to develoeprs to define properly the interface which provides the gateway to invoke the methods exposed by the foreign Web Service which would like to integrate. Next, we show how to develope the before mentioned ideas, just following the JAX-WS 2.0 specs

	
	....
	import javax.jws.WebMethod;
	import javax.jws.WebParam;
	import javax.jws.WebResult;
	import javax.jws.WebService;
	import javax.jws.soap.SOAPBinding;
	import javax.xml.ws.WebServiceClient;
	import javax.xml.ws.WebServiceRef;
	....
	
	@Business(type=BusinessType.APPLICATION)
    public class MyAppService {   
       
       /***/
       @WebServiceRef(ExampleServiceService.class)
       private ExampleService wsref;
   
       ......
    }
    
    @WebService(targetNamespace = "http://ws.nexopenframework.org/example",
			name="ExampleWS")
    @SOAPBinding(style=SOAPBinding.Style.RPC)
    public interface ExampleService {
	  @WebMethod
	  public String sayHello();
	  @WebMethod
	  @WebResult(name="user")
	  public User findUserByPrimaryKey(@WebParam(name="id") long id) 
	  			throws UserNotFoundException;
    }
    ......
    @WebServiceClient(targetNamespace = "http://ws.nexopenframework.org/example", 
                      name="ExampleWS")
	public class ExampleServiceService extends javax.xml.ws.Service {

      public ExampleServiceService() throws java.net.MalformedURLException {
           super(new java.net.URL("http://my.domain.com/services/ExampleWSService?wsdl"),
                 new javax.xml.namespace.QName("http://ws.nexopenframework.org/example",
                                               "ExampleWSService"));
		}
		
		public ExampleServiceService(java.net.URL wsdlDocumentLocation, 
		                             javax.xml.namespace.QName serviceName) {
			super(wsdlDocumentLocation, serviceName);
		}
		
	}
   .....
	
	

As we can observe, from our Business component, in this case an Application Service, but it is also possible to be defined in a Facade or Configurable Service, we define the needed to integrate with a foreign Web Service

Despite the fact that we write at code level the wsdl URL location, this can be easily changed because NexOpen provides an Standard MBean in order to manage this integration.

12.3. XFire 1.2.x integration

Moreover of the specification annotations and nexOpen custom annotations, in the case of XFire NexOpen provides also the possibility to integrate with common features developed by XFire when client would like to invoke a Web Service

	
.....
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

import org.codehaus.xfire.annotations.EnableMTOM;
import org.codehaus.xfire.annotations.InHandlers;
import org.codehaus.xfire.annotations.OutHandlers;
......
@WebService(targetNamespace = "http://ws.nexopenframework.org/example",
			name="ExampleWS")
@SOAPBinding(style=SOAPBinding.Style.RPC)
@EnableMTOM
@InHandlers(handlers={"org.nexopenframework.example.xfire.DummyHandler"})
@OutHandlers(handlers={"org.nexopenframework.example.xfire.LoggerHandler"})
public interface ExampleService {
 .......
}	
	
	

12.4. Test Support

NexOpen provides support for using JUnit3 as test Framework support. using NexOpen facilities we can easily test if the call related to Web Service is correct or not

	
.....
import org.nexopenframework.core.ws.WebServiceException;
import org.nexopenframework.jaxws.test.xfire.AbstractXFireWebServiceTestCase;
.....
public class ClassificationWSTest extends AbstractXFireWebServiceTestCase {

  /**
   * <p>Here, we initialize our test providing the 
   *    Service Endpoint Interface (SEI) to be tested.</p>
   */
   public ClassificationWSTest() {
      //the service endpoint interface to be tested
      //you must be aware that this interface has JSR-181 annotations
      //Also supports NexOpen WS Reference annotations such as
      //Credentials for BASIC authentication and ProxySettings
      //if you have behind a proxy.
      this.setServiceEndpointInterface(ClassificationWS.class);
      //HTTP wsdl location
      this.setWsdlLocation("http://www.mydomain.com/mycontext/"+
                           "services/ClassificationWSService?wsdl");
	}

	/**
	 * <p>Unique method to be invoked by JUnit3 for
     *   test the ClassificationWS interface. Here, 
     *   you will perform the invocations to publish 
     *   web service methods</p>
	 */
     public void testWebService() throws WebServiceException, IOException {
     
       if (logger.isDebugEnabled()) {
         logger.debug("WSDL location to be tested :: "+ wsdlLocation);
       }
       //retrieve the client to communicate to the external
       //web service
       final Object client = getClient();
       assertNotNull(client);
  	   assertTrue(client instanceof ClassificationWS);
       final ClassificationWS sei = (ClassificationWS) client;
  	   if (logger.isDebugEnabled()) {
           logger.debug("Service Endpoint Interface :: "+ sei);
       }
       //invoke the published methods by external web service
		....
    }  
}
	
	

12.5. Configuration

In case of XFire integration, we must ensure to

Finally, we specify where to place the javax.xml.ws.spi.Provider if you plan to use NexOpen-XFire extension. This file conatins only one line, where we exlicetly specify the NexOpen Provider extension

org.nexopenframework.xfire.jaxws.Provider

In a EAR you must be sure to place at root in a folder META-INF/services as indicate the specs. In a NexOpen-maven2 structure the correct place is

	
+earProject
 |+ear
   |+src
     |+main
       |+resources
         |+META-INF
          |+services
            |+javax.xml.ws.spi.Provider
 .....
	
	

In the case of a WAR artifact you should place into the classpath also in same folder but under WEB-INF/classes location

	
+webProject
 .....
 |+web
   |+src
     |+main
       |+resources
         |+META-INF
          |+services
            |+javax.xml.ws.spi.Provider
 .....
	
	

Resource Tier

This part of the reference documentation is concerned with how NexOpen covers the rersource tier, and we mainly focus with Persistence Manager, a Facade unified interface which it is the main point of dealing with ORM operations. NexOpen mainly focus with ORM approach and provides an intgeration with Hibernate3 or JPA and the JSR-220 specification for to implement, using the javax.entity.Entity annotation and others, the domain model of your application.

Finally, we will deal with how Asynchronous tasks are done in NexOpen Framework. For this kind of feature, we provide a Facade, defined by TaskExecutor class, which hides the complexities of JMS 1.1 and even the EJB Message-Driven Bean. Thru this class we can easily

Chapter 13. Persistence Manager

Nowdays, the use of a Data Access Object Pattern (DAO) it could be a tedious maintenance problem due to the great number of classes that apparently have the same pattern (Create, Retrieve, Update and Delete). However, we do not say that it is unseful, because sometimes the use of this Core J2EE pattern allows to decouple the resource layer and the business layer avoiding the existence of a OQL or SQL (for example a dynamic query if we do not want to use teh Criteria facility explained after) in your code. Nevertheless, it exists other patterns like the Domain Store pattern that simplifies the number of classes and recently has appeared the JSR-220 specification with the javax.persistence.EntityManager which provides a Facade to the resource layer avoiding a great number of classes and then simplifying the maintenance of your application.

In this section, we will try to explain why NexOpen has selected this option of a unified interface in order to deal with the persistence and when it is recommended to use the famous Core J2EE pattern DAO

13.1. PersistenceManager API

Persistence Manager is based in the Object Relational Mapping (ORM) philosophy. It is important to note that NexOpen Framework does not provide a implementation of a new ORM, NexOpen only try to integrate several know ORM OpenSource, like Hibernate3 or any JPA Open Source provider, trying to simplify the knowlodgement of these implementations. Besides having a several CRUD operations like persist, delete, update and simple finders, it is also a Query factory and Criteria Factory. The main point it is to consider this interface as a part of the integration or resource layer. DAO's will be needed,as we have mentioned before, if we have query strings that compromises and couples the business layer. Just persisting, deleting or easy retrieval including query finder with named queries could be kept in a Service Component (business layer) without need of DAOs. The SPI it is based in the javax.persistence.EntityManager interface from JSR-220 spec (EJB 3.0). It is important to note that all the POJO classes which represents the entities in a persistence storage should be annotated with the JSR-220 annotation javax.persistence.Entity

The way that it is used in a J2SE 5.0 environment, it is as easy as we can see in the following example, where a Service Component use this API for ORM operations

				
import org.nexopenframework.persistence.PersistenceManager;

....

	      
/**The PersistenceManager SPI for persistence storage operations*/
@PersistenceManagerContext
PersistenceManager pm;

/**
 * <p>PersistenceManager is a Facade which hides the complexities
 * of deal with ORM providers (such as Hibernate3, JPA and so on)</p>
 * 
 * @param pm
 */
public void setPersistenceManager(PersistenceManager pm) {
	this.pm = pm;
}


public void persistIssue(Issue issue) {
	//way that we persist a POJO entity
	this.pm.persist(issue);
}
	      
			

Looks the presence of the annotation PersistenceManagerContext which tell to NexOpen Framework the need of injection of a PersistenceManager. The PersistenceManager SPI provides several useful methods for persist and object or a Collection, delete an existent mapped object in a persistence storage (like a RDBMS, for example a MySQL or Oracle) and updating (merging) and object

However, if you need to inject into your class a PersistenceManager and it is not a NexOpen component (Business Service class, Configurable Service or a JobTask), you can do it in the traditional Spring way, injecting the PersistenceManager under bean name openfrwk.persistenceManager in a Spring configuration file

				
......
<bean id="myBean" class="org.mypackage.MyBean">
    <property name="persistenceManager" ref="openfrwk.persistenceManager"/>
    ......
</bean>
.....				
				
		

or another alternative is just creating a simple locator of PersistenceManager and using in any class which it is not a ServiceComponent without needs of declaring in any Spring configuration file

					
....
import org.nexopenframework.persistence.PersistenceManager;
import org.nexopenframework.spring.BeanLocator;

public abstract class PersistenceManagerLocator {

    public static PersistenceManager getPersistenceManager() {
          return (PersistenceManager) BeanLocator.getBean("openfrwk.persistenceManager");  
    }

}
		

Notice the presence of BeanLocator class, which is able to locate any bean registered in the Business ApplicationContext (take in mind that Spring offers a hierarchy of ApplicationContexts and Beanlocator is registered in the business layer, so it has not access to beans regsitered in the web layer such as Spring MVC controllers, Struts actions and so on).

13.2. Query API

The PersistenceManager class it is also factory of Query . This class presents a simplified way to execute queries (such as OQL, HQL, JPQL) and native queries (using SQL). In the following exemple we show, how to execute a named query (defined in a xml file, package-info class or metadata at class level) and execute a list of values

			
import org.nexopenframework.persistence.PersistenceManager;
import org.nexopenframework.persistence.Query;
....

/**The PersistenceManager SPI for persistence storage operations*/
@PersistenceManagerContext
PersistenceManager pm;

...
public List<Issue> findIssuesByCriteria(final String name, final int age1, final int age2) {
	//retrieval [Named query]
	final Query q = pm.createNamedQuery("findByName");
	q.setParameter("name", name).setParameter("age1", new Integer(age));
	q.setParameter("age2", new Integer(24));
	final List values = q.execute();
	.....
}     
	      
		

You can create native queries using the createNativeQuery method and also createQuery where you put the HQL.

	
	//how to create a native query
	final Query q_native = 
	       pm.createNativeQuery("SELECT NAME, FIRSTNAME, SECONDNAME FROM PERSON "+
	                            "WHERE PERSON.ID LIKE ? AND SECONDNAME IS NOT NULL");
	.....
	//how to create a HQL query object
	final Query q_hql = 
	       pm.createQuery("from Person as p where p.id like :id and "+
	                      "p.secondName is not null");
	...
	 
	

After it has been created, we can easily add the parameters associated to this query and execute the result. Moreover, we can execute Stored Procedures using this object. Take in mind, that we are delagating execution to Hibernate3 and this powerful ORM Framework can easily execute Stored Procedures.

Moreover, we can easily add several features such as query caching facilities, custom hints and pagination support (see javadoc for more detailed information)

	
     //query cache facilities
     final Query q_cache = pm.createNamedQuery("findByComplexFilter");
     //activation of query caching facility
     q_cache.setCacheEnabled(true);
     //region name where query results is saved
     q_cache.setRegionName("nexopen");
     ....
     //query hints
     final Query q_hint = pm.createNamedQuery("findByCriteria");
     //fecth support
     q_hint.setHint("org.nexopenframework.persistence.hibernate3.fetchSize","10");
     //Hibernate Hints interface in order to provide Hints supported by Hibernate3 
     //[located at org.nexopenframework.persistence.hibernate3.support.HibernateHints]
     q_hint.setHint(HibernateHints.HIBERNATE_TIMEOUT,"60");
     ....
     //query pagination support
     final Query q_pag = pm.createNamedQuery("findByPagination");
     q_pag.setFirstResult(10);
     q_pag.setMaxResults(20);
     ....
	
	

13.3. Criteria API

This API is related to build dynamic queries dependending of the values you would like to add. It is a well way to deal with filters in the presentation layer

		    
...
 import org.nexopenframework.persistence.Criteria;
 import org.nexopenframework.persistence.PersistenceManager;
 import org.nexopenframework.persistence.criterion.CriterionFactory;
 ....

  public void doSomething(final String someValue) {
    final Criteria criteria = this.pm.createCriteria(MyEntity.class);
    criteria.add(CriterionFactory.like("someValue", someValue));
    final List values = criteria.execute();
     ....
  }			
			
		

Look at the presence of CriterionFactory a factory of Criterions which fulfills all the specific features of a persistence storage grammar (in other words, typical SQL like, equals, between operations or even maximum and minimal) as you can see in the next example and adding to Criteria object

		    
  //create a like criterion
  final Criterion c_like = CriterionFactory.like("someValue", someValue);
  criteria.add(c_like);
  //create a non-equals criterion
  final Criterion c_ne = CriterionFactory.ne("someValue2", someValue2);
  criteria.add(c_ne);
  //create a between criterion
  final Criterion c_between = CriterionFactory.between("otherValue", lo, hi);
  criteria.add(c_between);
		   .......
		    
		

Moreover, in criteria you can also add pagination features and also specify hints

		    
    ...
    //use of pagination support
    final Criteria criteria = this.pm.createCriteria(MyEntity.class);
    criteria.setFirstResult(10).setMaxResults(20);
    ....
    //use of hints thru Criteria API
    //Hibernate Hints interface in order to provide Hints supported by Hibernate3 
    //[located at org.nexopenframework.persistence.hibernate3.support.HibernateHints]
    criteria.setHint(HibernateHints.HIBERNATE_TIMEOUT,"60");
    ....
    
		

13.4. Integration with Hibernate3

Hibernate (http://www.hibernate.org/) is one of the most popular ORM frameworks. NexOpen provides an implementation of PersistenceManager based in Hibernate3. In this way, w can easily deal with Hibernate3 forgetting the complexities related to deal with the Hibernate3 Session in disconnected way (internally we delegate to the Spring Framework excellent implementation).

13.5. Integration with Java Persistence API (JPA)

The EntityManager API is the standard way to deal with persistence in the new JEE 5.0 specification, the JPA specification. NexOpen PersistenceManager provides an easy way to deal with this feature without changing code. Nevertheless, if you plan to start a new project and you would like to offer an standard way to deal with persistence, we strongly recommend use directly JPA and enjoy of the excellent integration which offers Spring.

You must notice that this feature is supported since 0.4.x versions and higher.

13.6. Integration with EJB3 POJO Validation

New in 0.4.x versions and higher it is validation support at EJB3 POJO level using Oval Framework or Hibernate Validators. Oval supports JSR-220 annotations and it provides an non-intrusive way to deal with validations at diference from Hibernate Validator which provides several useful annotations to be added to your Entity Model. Following example uses

	     
....
import org.hibernate.validator.Email;
import org.hibernate.validator.Length;
import org.hibernate.validator.NotNull;	   
....
@Entity
public class Person extends BaseEntityImpl implements Serializable {
 ....
 /**Person name*/
 @Length(min=3, max=50)
 @NotNull
 private String name;
 /**Person first name*/
 @Length(min=4, max=100)
 @NotNull
 private String firstName;
 /**Person second name*/
 @Length(max=100)
 private String secondName;
 /**person's email*/
 @Email
 @NotNull
 private String email;
 ........
 }
	     
	    

If your are using JPA as your persistence layer, you can declare easily a Entity Listener which performs the validations

	     
......
import javax.persistence.EntityListeners;
......
@Entity
@EntityListeners(JpaValidatorListener.class)
public class Person extends BaseEntityImpl implements Serializable {
......
	    

13.7. ServiceComponents and common CRUD operations

NexOpen provides since 0.4.x versions and higher a typed DAO interface for dealing with common CRUD operations thru GenericServiceDAO. If your Facades and Application Services has common operations related to a given entity, we strongly recommend the use of this DAO and choose the persistence model of your application, using the generic PersistenceManager or JPA. in the following example, we show an example of such feature for JPA persistence framework

	     
....
import org.nexopenframework.persistence.jpa.support.JpaGenericServiceDAO;
.....
public class UserFacadeImpl extends JpaGenericServiceDAO<User, Long> 
                                                 implements UserFacade {
      public UserFacadeImpl() {
        //the entity to be managed
        super(User.class);
      }                                           
....
}	     	      
		
	    

Also, in the case of Facades,it has a good practice to extend from GenericServiceDAO, as we show below

	     
....
import org.nexopenframework.persistence.support.GenericServiceDAO;
....	     
public interface UserFacade extends GenericServiceDAO<User, Long> {
.....
}	     
	     
	    

In this way, we can asily deal with common CRUD operations in Facades and Application Services

13.8. Test support for Persistence Module

As we have mentioned before, a well defined application has several TestCases in order to test the functionalities of your application. However, we realize that soemtimes it is a tedious work to perform a integrated test like to acces to a database or create a Spring Bean Factory, because we have to perfom a stuff of code. Fortunately, Spring provides a base mock frmaework based in JUNit3 to easily dealing with Spring applications and NexOpen has extended these classes in order to provide a base start for NexOpen applications based in Hibernate.

A typical JUnit3 test, based in Hibernate3, of a ServiceComponent which has integrated a simple database a HSQLDB, it is as follows

			....
import org.nexopenframework.persistence.hibernate3.AnnotationLocatorSessionFactoryBean;
import org.nexopenframework.persistence.hibernate3.test.AbstractHibernateTransactionalTests;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;

/**
 * <p>example using NexOpen</p>
 * 
 * <p>Base TestCase for MyAppService</p>
 */
public class MyAppServiceTest extends AbstractHibernateTransactionalTests {
   
   /** NexOpen ServiceComponent class to test*/ 
   protected MyAppService sc;
  /**
   * <p>Constructor in order to initialize custom SQL if necessary</p>
   */
   public MyAppServiceTest() {
        //put the SQL file location to initialize the data loading 
        //if it is necessary for your test 
        //setSqlFile("myFile.sql");
   }
  /**
   *  <p>Generic test method to check the main functionalities of this
   *     ServiceComponent class. This method invokes other non-public visibility methods
   *     which fulfills the functionalities of this ServiceComponent {@link MyAppService}</p>
   *  TODO Implement properly this method
   */
   public void testTestAppService() {
        //start a unit of work, in other words a transaction 
        this.beginTransaction();
        //TODO call your functionalities related with this ServiceComponent
        
        //commit unit of work
        this.commitTransaction();
        //your can repeat this operation several times
   }
  /**
   *  <p>Custom initialization</p>
   *
   *  @see org.nexopenframework.test.AbstractTransactionalTests#onSetUpInternal()
   */
   protected final void onSetUpInternal() throws Exception  {
        this.sc = new MyAppService();
        //a field of type org.nexopenframework.persistence.PersistenceManager
        //should exist in your ServiceComponent. Please, use NexOpen wizards if
        //you have compilation problems
        this.sc.pm = this.getPersistenceManager();
        //TODO put if necessary other suitable initialization
        
   }
  /**
   *  <p>Cleaning resources</p>
   *  
   *  @see AbstractHibernateTransactionalTests#onTearDownAfterCommit() 
   */
   protected final void onTearDownAfterCommit() throws Exception {
        //Do not remove the parent invocation
        super.onTearDownAfterCommit();
        //a field of type org.nexopenframework.persistence.PersistenceManager
        //should exist in your ServiceComponent. Please, use NexOpen wizards if
        //you have compilation problems
        {
     	  this.sc.pm = null;
     	  this.sc = null;
        }
   }
  /**
   *  <p>Returns a custom {@link LocalSessionFactoryBean} for dealing 
   *     with auto-discovery of entities</p>
   *    
   *  @see AbstractHibernateTransactionalTests#newLocalSessionFactoryBean()
   */
   protected final LocalSessionFactoryBean newLocalSessionFactoryBean() {
        //Do not overwrite this code unless it is necessary.
        //It should be present a nexopen.properties file in the classpath
        //in order to scan correctly the classes annotated with
        //javax.persistence.Entity (JSR-220)
        return new AnnotationLocatorSessionFactoryBean();
   }
  /**
   *  <p>Customize initialization of the org.hibernate.SessionFactory</p>
   *  TODO Implement if necessary handleLocalSessionFactoryBean method
   */
   protected final void handleLocalSessionFactoryBean(LocalSessionFactoryBean lsf) {
        //put here your custom code
   }
}
		
		

Based in this base definition, we observe that it is not necessary to configure the entities annotated with the JSR-220 annotation in the hibernate configuration files and we can focus in the business features.

13.9. Configuration of Persistence Module

In the beanRefContext.xml MUST exists an entry in order to ensure the use of the Persistence Module in NexOpen applications.

			
....
<beans xmlns="http://www.springframework.org/schema/beans" 
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	   xmlns:components="http://www.nextret.org/schema/components" 
	   xsi:schemaLocation=".....">  
	   
  <bean id="nexopen"
        class="org.nexopenframework.deployment.context.AnnotationApplicationContext">
   <constructor-arg> 
    <list>
     ......
     <!-- persistence manager for j2se 5.0 allowing auto-discovery of JSR-220 entities-->  
     <value>classpath*:META-INF/spring/openfrwk-module-persistence-jdk15-auto.xml</value>
     <!-- allow the injection of PersistenceManager or EntityManager -->
     <value>classpath*:META-INF/spring/openfrwk-module-persistence-jee50.xml</value>
     .......
    </list>
   </constructor-arg>  
  ......
  </bean>
			
		

Here, we have selected the auto-discovery EJB 3.0 entities thru Hibernate3 and the possibility of injection of the PersistenceManager or EntityManager in your ServiceComponents.

At end of this section, we will indeicate ho to configure use of EJB3 POJO validation support. If you plan to use the validation facilities provided by NexOpen you must be sure to define properly next entrance into beanRefContext.xml in list defined by bean nexopen whcih appears in the previous caption

			
.....
 <!-- hibernate validation support -->
<value>classpath*:META-INF/spring/openfrwk-module-persistence-validator-hibernate.xml</value>
.....
			
		

You can choose between Oval support and Hibernate Validator component (at the example, we have choosen this option, nevertheless if you would like to choose Oval framework you must use openfrwk-module-persistence-validator-oval.xml instead).

Moreover, if you are using Persistence Manager support with Hibernate3, you must also define into your hibernate.cfg.xml next entrance

			
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC 
	"-//Hibernate/Hibernate Configuration DTD//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
 <!-- a SessionFactory instance listed as /jndi/name -->
 <session-factory>
  .......
  <!-- validation events -->
  <event type="pre-update">
   <listener class="org.nexopenframework.persistence.validation.event.HibernateValidatorListener"/>
  </event>
  <event type="pre-insert">
   <listener class="org.nexopenframework.persistence.validation.event.HibernateValidatorListener"/>
  </event>
 </session-factory>
</hibernate-configuration>
			
		

If your ORM choose has been JPA you do not need to define such entrance, because as we have mentioned before you can choose the EntityListeners annotation for doing the same.

Do not forget to properly define such dependencies into your pom.xml of your business module as follows

			
<!-- Put it if you have choosen Hibernate Validator alternative -->
 <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>3.0.0.ga</version>
</dependency>
<!-- Put it if you have choosen Oval Validator Framework alternative -->
 <dependency>
    <groupId>net.sf.oval</groupId>
    <artifactId>oval</artifactId>
    <version>1.0</version>
</dependency>
			
		

Chapter 14. Asynchronous Tasks

Asynchronous tasks are a kind of messaging that acts in paralel to the given request.

14.1. Main concepts

The contract in order to use the Asyncrhonous tasks is implementing the interface org.nexopenframework.tasks.JobTask as follows in the given example

				
import org.nexopenframework.tasks.JobTask;
import org.nexopenframework.tasks.JobTaskContext;
import org.nexopenframework.tasks.TaskExecutionException;
....
public class MyJobTask implements JobTask {
....
	/**
	 * <p>Asynchronous task </p>
	 * 
	 *@see JobTask#execute(JobTaskContext)
	 */
	public void execute(JobTaskContext context) throws TaskExecutionException {
	   ....
	}
}				
				 
			

The way to invoke an asynchronous task it is as follows, notice that we can also provide a context which is passed to the given instance.

				
java.util.Map context = new java.util.HashMap(2);
context.put("some.value","Some value");
context.put("time.now",new java.util.Date();
TaskExecutor.executeTask(com.mypackage.MyJobTask.class, context);				
				 
			

It is important to note that the context MUST be serializable

14.2. J2SE Concurrent integration

14.3. JMS POJO integration

As we have observed of the before section, we only specify the JobTask to be executed and a context

14.4. Message-Driven Beans 2.x integration

If we deal with EJBs we should configure properly the DD (the ejb-jar.xml) in order to add the Message Driven Bean from NexOpen

			
<!-- MDB for executing tasks in itunes application-->
<message-driven>
  <ejb-name>exampleTaskExecutor</ejb-name>
  <ejb-class>org.nexopenframework.tasks.jms.MessageDrivenBeanServiceExporter</ejb-class>
  <messaging-type>javax.jms.MessageListener</messaging-type>
  <transaction-type>Container</transaction-type>
  <message-destination-type>javax.jms.Queue</message-destination-type>
  <activation-config>
    <activation-config-property>
      <activation-config-property-name>destinationType</activation-config-property-name>
      <activation-config-property-value>javax.jms.Queue</activation-config-property-value>
    </activation-config-property>
    <activation-config-property>
             <activation-config-property-name>acknowledgeMode</activation-config-property-name>
             <activation-config-property-value>AUTO_ACKNOWLEDGE</activation-config-property-value>
         </activation-config-property>
  </activation-config>
  <env-entry>
	<description>
		Key locator for Spring beanRefContext.xml
	</description>
	<env-entry-name>bootstrap/BeanFactoryLocator</env-entry-name>
	<env-entry-type>java.lang.String</env-entry-type>
	<env-entry-value>nexopen</env-entry-value>
  </env-entry>
  <resource-ref>
     <description>
			DataSource used by itunes business objects
		</description>
		<res-ref-name>jdbc/exampleDS</res-ref-name>
		<res-type>javax.sql.DataSource</res-type>
		<res-auth>Container</res-auth>
		<res-sharing-scope>Shareable</res-sharing-scope>
  </resource-ref>
</message-driven>			
			 
		

Moreover, we should assign the ConnectionFactory and the Queue

			
<!-- ========================= JMS DEFINITIONS  ========================= -->		
<!-- uncomment if you want to work with asynchronous tasks module -->
<!-- JMS ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
	<property name="jndiName" value="jms/exampleCF"/>
	<property name="lookupOnStartup" value="true"/>
	<property name="resourceRef" value="true"/>
</bean>
<!-- JMS Queue -->
<bean id="queue" class="org.springframework.jndi.JndiObjectFactoryBean">
	<property name="jndiName" value="jms/exampleQ"/>
	<property name="lookupOnStartup" value="true"/>
	<property name="resourceRef" value="true"/>
</bean>			
			 
		

And you must also assign in the DD of Application Servers the correct link between the ENC names and the names defined in the application server

14.5. Configuration of Tasks Module

In the beanRefContext.xml MUST exists an entry in order to ensure the use of the Tasks Module in NexOpen applications.

			
....
<beans xmlns="http://www.springframework.org/schema/beans" 
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	   xmlns:components="http://www.nextret.org/schema/components" 
	   xsi:schemaLocation=".....">  
	   
  <bean id="nexopen"
        class="org.nexopenframework.deployment.context.AnnotationApplicationContext">
   <constructor-arg> 
    <list>
     ......
     <!-- Tasks modules using MDB -->  
    <value>classpath*:META-INF/spring/openfrwk-module-tasks-mdb.xml</value> 
     .......
    </list>
   </constructor-arg>  
  ......
  </bean>
			
		

Here, we have selected MDB configuration, so it is necessary to define in the deployment descriptor ejb-jar.xml, the nexOpen Message-Driven Bean MessageDrivenBeanServiceExporter.

The Web

This part of the reference documentation covers the NexOpen Framework's support for the presentation tier (and specifically web-based presentation tiers).

NexOpen provides several integrations with some open source projects. Moreover, it also have an integration with the JavaServer Faces specification

Chapter 15. MVC support in NexOpen

NexOpen provides integration with several MVC Frameworks but it does not provide an implementation of such pattern. NexOpen team believes that exists excellent OpenSource implementations or even Standars (such as JSR-168 Portlets or JSF) so it is much better integrate with such framework than create a new implementation.

15.1. Spring MVC support

Spring MVC is the MVC Framework which is used by default in NexOpen related to presentation layer. Moreover, thanks to the architecture of Spring MVC, most of the MVC Frameworks could be easily handled by Spring.

The way that we specify to NexOpen that a class is a Spring MVC Controller is implementing directly or indiretly from Controller and annotate properly with the UrlMapping orUrlMappings

		
package org.nexopenframework.web.mvc.spring.annotations;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Target({TYPE})   
@Retention(RUNTIME)
public @interface UrlMapping {
	/**The mapped url associated to a given Controller*/
	String value();
}		
		
		

Here, we can show you an example o use of the above mentioned annotation, we should notice, as we will mention before, that with this annotation, we do not need to declare any bean in any Spring XML configuration file

				
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.nexopenframework.core.runtime.annotations.ServiceGatewayRef;
import org.nexopenframework.web.mvc.spring.annotations.UrlMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.web.servlet.mvc.Controller;

import com.package.facades.EasyFacade;

@UrlMapping("/easy.htm")
public class EasyController extends AbstractController implements Controller {
 	  	  	 
 	 /**
 	  * Proxy which hides a call to EasyFacade in a given
 	  * container. For instance, an EJB container or a POJO container such as Spring, 
 	  * or even an EJB3 container could be examples of invoked containers. 
 	  * Expose always your applications business methods 
 	  * thru Business Facades patterns.
 	  */
 	 @ServiceGatewayRef EasyFacade easyFacade;
 	 ....

	  protected  ModelAndView handleRequestInternal(HttpServletRequest request,
                                                    HttpServletResponse response)
		    throws Exception {
		   .....
		   //return view
		   return new ModelAndView("default",model); 
	  }
	  ....	 				    				
			
		

We should mention that folowing the NexOpen nature, we do not need to register in a Spring configuration file such Controller. In order to fulfill this feature, you must be sure that the following context parameter element is present at least, in your deployment descriptor web.xml

		  
<context-param>
   <param-name>openfrwk.web.definitionRegistries</param-name>
   <param-value>org.nexopenframework.web.mvc.spring.support.ControllerDefinitionRegistry</param-value>
</context-param>
		  
		

15.2. Struts 1.2.x support

Struts1 is one of the most famous MVC Frameworks n JEE development. Originally, it was a revolution in the development JEE applications and became a standard. Nowdays, there are several MVC Frameworks and Struts has loose the importance but we continous found it in JEE applications.

Spring2 offers support for Spring in seevral ways. One of them, and the prefered by NexOpen team, is thru a Spring Controller, which wraps the lifecycle of a given Servlet. In our case this servlet is the well-known AcionServlet which is the HTTP Listener of such Framework (internally this servlet delegates to RequestProcessor)

The way that we specify in NexOpen that a clas is an Struts Action is thru a J2SE 5.0 annotation such as in the following example

				
......				
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.nexopenframework.core.runtime.annotations.ServiceGatewayRef;
import org.nexopenframework.web.mvc.struts.annotation.Action;
import org.nexopenframework.web.mvc.struts.annotation.Forward;

import com.mypackage.facades.EasyFacade;

@Action(path="/easy",forwards=@Forward(name ="success",path ="/WEB-INF/jsp/easy.jsp"))
public class EasyAction extends org.apache.struts.action.Action {

	@ServiceGatewayRef EasyFacade facade;
	
	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form, 
                                 HttpServletRequest req, HttpServletResponse resp) 
 								 throws Exception {
		......
		return new ActionForward("success");
	}
}						    				
			
		

15.2.1. Configuration

In order to ensure that we are using Struts1, we must include such dependency in our pom.xml of the web module

				
<!-- Struts1 dependency -->				
<dependency>
   <groupId>struts</groupId>
   <artifactId>struts</artifactId>
   <version>1.2.9</version>
</dependency>			    				
				
			

15.3. Struts 2.0.x support

Struts2 is a fusion of older Struts Apache Project and WebWork2 Framework.

Struts2 is a typical pull-MVC (or MVC2) framework; slightly different from the tradiional MVC in that action takes the role o model rather than controller [Roughley2006]. This Framework does not use a traditional Servlet as the HTTP listener. Its architecture is based in a FilterDispatcher which is a JEE Filter for handling the HTTP requests

				
import static com.opensymphony.xwork2.Action.SUCCESS;

import org.apache.struts2.config.Result;
import org.nexopenframework.core.runtime.annotations.ServiceGatewayRef;
import org.nexopenframework.struts2.annotations.Action;
import org.nexopenframework.struts2.dispatcher.NexOpenRequestDispatcherResult;

import com.package.facades.EasyFacade;

@Action
@Result(name=SUCCESS, value="easy", type=NexOpenRequestDispatcherResult.class)
public class Easy {

	@ServiceGatewayRef EasyFacade facade;
	
	String hello;
	
	public String execute() {
	    //invoke business method published in your Facade
		hello = facade.getHello();
		return SUCCESS;
	}

	public String getHello() {
		return hello;
	}

	public void setHello(String hello) {
		this.hello = hello;
	}
}				
			
		

It is important to notice that in order to automatically be registered into Struts2 container, your class must satisfy one of the following rules

  1. Have a JSR-175 metadata Action as the previous example
  2. Class name ends with Action suffix. EasyAction for example
  3. Implements com.opensymphony.xwork2.Action from WebWork2

Finally, you must not forget to register as configuration provider the class NexOpenConfigurationProvider and be sure to be present in the root of classpath a nexopen.properties file.

15.3.1. Configuration

In the deployment descriptor web.xml we must ensure to define the JEE Filter responsable for dealing with struts actions

				
<!-- Struts2 Filter -->
<filter>
  <filter-name>nexopen-struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  <init-param>
	<param-name>configProviders</param-name>
	<param-value>org.nexopenframework.struts2.config.NexOpenConfigurationProvider</param-value>
   </init-param>
</filter>
<filter-mapping>
   <filter-name>nexopen-struts2</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
				
			

And be aware to have a struts.xml in the web resources folder which contains some constants. Here, we can also provide optional interceptors and dealing with custom packages

				<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<!-- Here you can extend functionalities for your application -->
	
	<!-- constants -->
	<constant name="struts.action.extension" value="do"/>
	<constant name="struts.devMode" value="false" />
    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
    <constant name="struts.objectFactory" value="nexopen" />
    <!-- Add packages here -->
    
</struts>
				
			

In order to fulfill correctly all the above mentioned, you must include the following lines into your pom.xml (preferly in the web component module if you follow a j2ee maven2 structure)

			    
<dependency>
   <groupId>org.nexopenframework</groupId>
   <artifactId>openfrwk-struts2-jdk15</artifactId>
   <version>0.4.0</version>
</dependency>
<dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts2-core</artifactId>
   <version>2.0.9</version>
</dependency>			    
			    
			

Chapter 16. Pagination support

16.1. ValueList integration

Pagination is a typical feature that appears often in JEE developments. Such feature has been also documented as a JEE Core Pattern [Alur2003] called ValueList. Fortunately, ValueList Open Source project has implemented this pattern and provides several ways to integrate it. Moreover, it provides integration with Spring Famework for dealing a bean oriented programming style. Nevertheless, in NexOpen we think that things could be even more easy and we have tried avoiding several written of spring configuration files. Then, we have defined package annotations that could be easily to define the paginations of your application

      
package org.nexopenframework.web.vlh.annotations;

import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import net.mlw.vlh.ValueListAdapter;

import org.nexopenframework.web.annotations.Property;

@Target({TYPE,PACKAGE})   
@Retention(RUNTIME)
@Inherited
@Documented
public @interface ValueList {
	/**identifier name of the related valuelist*/
	String name();
	/**default number per page. Default value <code>20</code>*/
	int defaultNumberPerPage() default 20;
	/**default sort column*/
	String defaultSortColumn() default "";
	/**default sort direction. Default value <code>asc</code>*/
	String defaultSortDirection() default "asc";
	/**the query*/
	Query query();
	/**custom properties of the adapter*/
	Property[] properties() default {};
	/**type of adapter*/
	AdapterType adapter() default AdapterType.PERSISTENCE_MANAGER_ADAPTER;
	/**adapter class. Only used in case {@link AdapterType#FACADE_ADAPTER}*/
	Class<? extends ValueListAdapter> adapterClass() default ValueListAdapter.class;
	/**setters for custom behaviour*/
	Setter[] setters() default {};
}    
      
      

Besides, it exists a holder of valueList called ValueLists for more than one pagination in your application. These annotations must be located into a special class called package-info.java in your web module, as it shows the next example

      
@ValueList(name = "persons", defaultNumberPerPage = 5, 
        defaultSortColumn = "creationDate", 
        query = @Query(value = "FROM Person as p WHERE 1=1" +
                  "/~personName: AND p.name LIKE {personName}~/ " +
                  "/~personFirstName: AND p.firstName LIKE {personFirstName}~/ "+
                  "/~personSecondName: AND p.secondName LIKE {personSecondName}~/",
        //match mode AnyWhere in the query.
        //see org.nexopenframework.persistence.criterion.MatchMode.ANYWHERE
        matchMode=MatchModeType.ANYWHERE, columns={"personName", "personFirstName", 
                                                   "personSecondName"}) , 
        properties = {@Property(name = "removeEmptyStrings", value = "true")}) 

package org.nexopenframework.samples.simple.info;

import org.nexopenframework.web.annotations.Property;
import org.nexopenframework.web.vlh.annotations.MatchModeType;
import org.nexopenframework.web.vlh.annotations.ValueList;
import org.nexopenframework.web.vlh.annotations.Query;      
      
      

16.1.1. ValueList Supported Adapters

NexOpen has extended the ValueList AbstractValueListAdapter in order to support PersistenceManager queries. Nevertheless, this solution and other adopted by ValueList breaks the traditional organization of layers in a JEE development. It is mainly done beacuase we query results from the presentation layer and no from a business layer. This is no dramatic but this solution does not scale at all.

16.1.2. Configuration

      
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:jee="http://www.springframework.org/schema/jee"
	   xsi:schemaLocation="....">
......
<!-- ========================= VALUE LIST ========================= -->
<!-- uncomment all these beans if you plan to use ValueList in your application -->
<!-- convenient class in order to allow custom registering -->
<bean id="valueListHandler"
	class="org.nexopenframework.web.vlh.DefaultValueListHandlerImpl">
	<description>Declare different value lists</description>
	<property name="config.adapters">
	  <map>
	  <!-- put here your custom adapters-->

	  </map>
	</property>
</bean>
<!-- register of custom valuelist's -->
<bean id="exporter"
	class="org.nexopenframework.web.vlh.support.ValueListExporter">
	<description>Exported for delaing with ValueList Adapters</description>
	<property name="valueListAdapterResolver"
		ref="valueListAdapterResolver" />
</bean>
<!-- resolver related with annotations provided by NexOpen -->
<bean id="valueListAdapterResolver"
	class="org.nexopenframework.web.vlh.support.AnnotationValueListAdapterResolver">
	<!-- 
        please put in a package-info.java class file located at package com.myproject.info
        all the annotations related with ValueList notifications 
    -->
	<property name="packageName" value="org.nexopenframework.samples.simple.info" />
</bean>

<bean id="valueListConfig" class="net.mlw.vlh.web.ValueListConfigBean">
	<description>List style definition</description>
	<property name="styleCount">
		<value>2</value>
	</property>
	<property name="stylePrefix">
		<value>valueListTableLook</value>
	</property>
	<property name="displayHelper">
		<bean class="net.mlw.vlh.web.util.ImagesHomeDisplayHelper"/>
	</property>
	<property name="messageSource">
	  <bean class="org.springframework.context.support.ResourceBundleMessageSource">
		<description>Declare properties file</description>
		<property name="basename">
			<value>valueListTableLook</value>
		</property>
	  </bean>
	</property>
	<property name="displayProviders">
	 <map>
	  <entry key="html">
		<bean id="valueListTableLookHtmlDisplayProvider"
			class="net.mlw.vlh.web.tag.support.HtmlDisplayProvider">
			<description>
				HTML displaying configurations
			</description>
			<property name="imageHome">
				<value>img/valueList</value>
			</property>
			<!-- append or not the context path to images location -->
			<property name="preAppendContextPath" value="true"/>
		</bean>
	   </entry>
	 </map>
	</property>
</bean>
.....
      
      

Chapter 17. AJAX support

Nowdays, when we design a framework it is unreasoable not support the new features of Web 2.0. NexOpen, in its aim to provide easy solutions for such common tasks, offers an integration with Direct Web Remoting ( http://getahead.org/dwr ), a popular and powerful open source library for AJAX in Java.

17.1. DWR integration

NexOpen Framework, in its 0.4 version, integrates with DWR 2.0.1, exposing all the desired business layer logic to AJAX requests performed from web pages, but following the same phillosophy that in all other calls done from the presentation tier to the business layer, using the chain of all possible invokers described in the Chapter Service Gateway, from the Part II Business Tier. DWR integration can be found in the web module of NexOpen 0.4, so this one has to be added in the project's modules in order to offer AJAX features.

17.1.1. Configuration

The DWR functionality is ready to use if you check the related component checkbox while creating a new project using the NexOpen IDE (while selecting the desired project facets, under Web Components -> DWR Component).

In case the NexOpen IDE is not available, some manual configurations should be done:

1. Add dependencies to the required modules.

As said before, the NexOpen web module must be added as dependency to have DWR features available. Also the DWR itself must be added as dependency. The pom.xml file of the desired web project must include, a part from the NexOpen web module, then the dependency:

   <!-- DWR Ajax Support -->
    <dependency>
      <groupId>org.directwebremoting</groupId>
      <artifactId>dwr</artifactId>
      <version>2.0.1</version>
  </dependency>    	
      

2. Specify the servlet handling ajax requests.

The NexOpen philosophy is to have all requests served by a unique servlet, and this delegating to the proper handler adapter. Then, the first thing is to have all DWR queries routed to the NexOpen servlet. This can be configured in the web.xml file as it follows:

  <servlet-mapping>
    <servlet-name>nexopen</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
  </servlet-mapping>  	
      

3. Specify the controller class that will handle every DWR request.

In the nexopen-servlet.xml file, an instance of DWRController has to be declared through its own xml tag, and then DWR requests should be routed to it, for example, with a Spring's SimpleUrlHandlerMapping.

  <!-- Define the controller for DWR requests -->
  <dwr:controller id="dwrController" debug="true"/>
  <!-- Map requests to the controller ->
  <bean id="integrationMapping"
    class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
      <description>Handler Mapping for dealing with integrated components such as DWR 2.0 and 
        Marshaller NexOpen component</description>
      <property name="mappings">
        <props>
          <prop key="/dwr/**">dwrController</prop>
        </props>
      </property>
      <property name="alwaysUseFullPath" value="true"/>
  </bean>
      

When DWR tags are to be used in a xml configuration file (like in the case above in nexopen-servlet.xml), remember to define the its namespace properly.

  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:dwr = "http://www.directwebremoting.org/schema/spring-dwr"
    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.xsd 
      http://www.directwebremoting.org/schema/spring-dwr 
      http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd">
     ...
  </beans>
      

4. Register NexOpen creator to instantiate business objects using NexOpen's philosophy.

Last DWR configuration consists in defining a custom creator, NexOpen's one, which will get instances of your business classes and expose them to browser's javascript calls using the behaviour of ServiceGateways.

  <dwr:configuration>
    <dwr:init>
    <!-- Register NexOpen's custom creator -->
      <dwr:creator id="nexOpen" 
        class="org.nexopenframework.web.dwr.creator.DWRServiceGatewayCreator"/>
    </dwr:init>
  </dwr:configuration>	
      

5. Add the custom SpringConfigurator.

Due some problems in the way DWR integrates with SpringFramework, a specific SpringConfigurator has to be declared, in order to get the business objects created with the NexOpen creator correctly configured.

  <bean id="__dwrConfiguration"
    class="org.nexopenframework.web.dwr.support.SpringConfigurator">
    <description>
      In order to inject the params into the creators, we should
      extend it in order to deal properly
    </description>
  </bean>
      

With this steps, the web module will be configured to allow web pages make ajax calls to business methods. Let's see how to implement them.

17.2. Simple AJAX calls

To handle simple AJAX calls where web pages ask for information to server without reloading, business logic must me implemented as is usually done in NexOpen projects, creating business services that expose its methods to the web layer through a facade interface and its implementation.

Once the business is implemented, the desired methods to be used from webpages must registered in the dwr configuration section, the place where the NexOpen creator was declared.

  <dwr:configuration>
    <dwr:init>
      <!-- Register NexOpen's custom creator -->
      <dwr:creator id="nexOpen" 
        class="org.nexopenframework.web.dwr.creator.DWRServiceGatewayCreator"/>
    </dwr:init>
    <!-- Remotely exposed business objects -->
    <dwr:create javascript="AjaxService" type="nexOpen">
      <dwr:param name="businessService" 
        value="org.nexopen.samples.facades.TestDWRFacade"/>
		<dwr:param name="invokers" value="EJBRemote" />
		<dwr:param name="jndiName" value="ejb/serviceGateway" />
		<dwr:param name="resourceRef" value="true" />
      <dwr:include method="getTestInfo"/>
    </dwr:create>
  </dwr:configuration>	

As seen, all that has to be done is to declare "dwr:create" sections, were the business objects are declared, given a name to be accessed from javascript and specify that they will use NexOpen's custom creator. The invocation parameters should be configured here, specifying the invokers to be used, as a comma separated string of values, between the offered possibilities (pojo,EJBLocal,EJBRemote), as when declaring the invokers for regular services.

Due the DWR SpringFramework limitations noted before, the SpringConfiguration bean definition has to be updated with the new business object entry. An entry for every object being exposed must be added in the creators section, referencing the given javascript name, preceded by a "__".

  <bean id="__dwrConfiguration"
    class="org.nexopenframework.web.dwr.support.SpringConfigurator">
    <description>
      In order to inject the params into the creators, we should
      extend it in order to deal properly
    </description>
    <property name="creators">
      <map>
        <entry>
          <key><value>TestFacade</value></key>
          <ref bean="__AjaxService" />
        </entry>				
      </map>
    </property>    
  </bean>

The business class is specified using the "dwr:param" with "businessService" as name and from here, just declare which methods should be made public.

With this configuration it will be possible to import a TestDWRFacade.js from a web page, which will have an instanced TestDWRFacade JavaScript object where all the methods defined as included will be accessible. An outline of a web page using it:

  <html>
    <head>
      <script type="text/javascript" src="dwr/engine.js"></script>
      <script type="text/javascript"
        src="/your_web_app/dwr/interface/AjaxService.js"></script>
      <script type="text/javascript" language="JavaScript"> 
        function ajaxTest(){
          AjaxService.getTestInfo(handlerExample);
        }
			
        function handlerExample(recievedData){
          alert(recievedData); 
        } 
      </script> 
    </head>
    <body onload="javascript:ajaxTest();"> 
      Ajax call on load!
    </body>
    </html>

17.3. Reverse AJAX calls

In the previous point it's been described how to do a typical AJAX call from a web page, but DWR allows to do it in the inverse, generating events from server side and notifying the browser about them. NexOpen extends this feature, allowing this reverse calls to be made not only from the web layer in your application, but from the business one, where those events can be generated due complex business methods, scheduling events, workflow transitions...

For an application to be able to publish those events from the business module in an application, two things must be configured in the nexopen-servlet.xml file under WEB-INF folder. Make sure also that the parameter "activeReverseAjaxEnabled" is set to true in the DWRController.

... 
  <!-- Define the controller for DWR requests -->
  <dwr:controller id="dwrController" debug="true">
  	<dwr:config-param name="activeReverseAjaxEnabled" value="true"/>
  </dwr:controller>

<!-- ========================= AJAX NOTIFICATION ========================= -->
<!-- uncomment if you plan to use AJAX NexOpen support in your application -->
   <bean id="ajaxNotifier"
	class="org.nexopenframework.web.dwr.AjaxNotifier">
	<description>
		Bean used to send AJAX notifications to browser
	</description>
	<dwr:remote javascript="AjaxNotifier"/>
	<property name="eventExecutorRegistry">
		<bean id="eventExecutorRegistry"
			class="org.nexopenframework.web.dwr.EventExecutorRegistry">
		</bean>
	</property>
  </bean>	 

  <bean id="__dwrConfiguration"
    class="org.nexopenframework.web.dwr.support.SpringConfigurator">
    <description>
      In order to inject the params into the creators, we should
      extend it in order to deal properly
    </description>
    <property name="creators">
    <map>
      <entry>
        <key><value>AjaxNotifier</value></key>
        <ref bean="__AjaxNotifier" />
      </entry>				
    </map>
    </property>
  </bean>
...

Here, the AjaxNotifier bean, that will recieve the events generated in the application and also, like in the simple ajax calls, to add the bean in the SpringConfigurator section, with the preceding "__". Remember to program an implementation of org.nexopenframework.web.dwr.AjaxEventExecutor, which is the class that really will know what to do with the given org.springframework.context.ApplicationEvent subclasses that the application fires. AjaxEventExecutor's don't need to be declared in any configuration files, NexOpen framework will autodiscover them.

The usual way to manage this would be defining a hierarchy of org.springframework.context.ApplicationEvent classes, related to the application business and purposes. Every instance of the objects in this hierarchy should handle the information willing to be notified. This object would be then published using the org.nextret.openfrwk.context.event.EventDispatcher static class, that will send the event to the Spring ApplicationContext. The event will reach then the executor implemented from the interface org.nexopenframework.web.dwr.AjaxEventExecutor, and call its execute method, recieving as parameters the published event and the DWR ServerContext implementation. The later has all methods needed to connect from the server to the client browser, so information can be extracted from the former and sent to the client to get the job done.

... 
public class NotificationEventExecutor implements AjaxEventExecutor { 
  public void execute(ApplicationEvent event, ServerContext sCtx){ 
    // Get all browser connected sessions 
    Collection sessions = sCtx.getAllScriptSessions(); 
    Util dwrUtil = new Util(sessions); 
    // Build the javascript action
    ScriptBuffer sb = null;
    // For instance, our UserDefinedEvent class could have a 
    // getClientCode method that would give us the JavaScript 
    // code to be executed in the client browser 
    sb = new ScriptBuffer(((UserDefinedEvent)event).getClientCode());
    // So add the new JavaScript to all those connected sessions 
    dwrUtil.addScript(sb); 
  } 
  // Describe which kind of events is supporting this executor 
  public boolean supports(ApplicationEvent event) { 
    return (UserDefinedEvent.class.isAssignableFrom(event.getClass()));
  } 
} 
...

Webpages wishing to handle reverse AJAX calls just will need to import he AjaxNotifier javascript to make it possible, and remeber activating the reverese ajax feature.

<html> 
  <head>
  <script type="text/javascript" 
    src="/your_web_app/dwr/interface/AjaxNotifier.js"></script>
  <script type="text/javascript">
  function init(){
  	DWREngine.setActiveReverseAjax(true);
  }
  </script>  
  </head>  
  <body onload="javascript:init();">
  </body>
</html> 
...

17.4. Extended features

NexOpen Framework provides other features added to those ones offered by default by DWR.

17.4.1. Autocomplete Tag

The framework gives it's own JSTL tag to implement a common AJAX feautre, autocompletion of text fields. To do so, it's as simple as having added the web module with AJAX support to your project and having exposed a facade method as described in the previous section. Then it's ready to be used in a jsp pages as it follows:

  <nexopenAjax:autocomplete fieldName="exampleID" remoteFunc="testRetrieveFunc"
    remoteObject="TestDWRFacade"options="minChars:2">
    <input class="beautifulTextClass" name="exampleTextField" id="exampleID" >
  </nexopenAjax:autocomplete>

This example would create a textfield where, after 2 characters have been added to it, the remote function TestDWRFacade.testRetreiveFunc would be called to suggest autocomplete suggestions.

Chapter 18. JavaServer Faces (JSF)

18.1. NexOpen and JavaServer Faces integration

TO BE DOCUMENTED

Chapter 19. Acegi Security Integration

Despite the fact that J2EE arhitecture offers a way to deal with authentication/authorization thru JAAS, almost developments offers a module of security out of scope of JAAS.

19.1. Introduction

Related to security in JEE Applications, we have choosen Acegi Security Framework (see http://www.acegisecurity.org/ for more details).Thanks to its configurable architecture, we can easily plug-in among several topologies present in common applications (Relational DataBase solutions, LDAP, Siteminder, OpenID and so on). Moreover, it is based in Spring Framework and provides a well-stablished architecture for dealing with security issues.

We have extended some prop

19.2. Relational Database Support

This is the most traditional way to deal with authentication/authorization.

19.2.1. User-Group-Role model

We propouse a typical relation among users, roles and groups

In NexOpen, we have developed a generic implementation in order to deal with a ORM Frameworks (such as Hibernate3, where we have developed the mapping files and included into the jar file under META-INF/hibernate)

19.2.2. General Configuration

Here, we will guideline the general configuration in order to integrate with Acegi and NexOpen security. First, we must ensure that in the pom.xml in the module web is present the acegi dependency and nexopen security core

             
<!-- Acegi Security Framework for Spring -->
<dependency>
    <groupId>org.acegisecurity</groupId>
    <artifactId>acegi-security</artifactId>
    <version>1.0.4</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-remoting</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-support</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-mock</artifactId>
        </exclusion>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
        <exclusion>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
        </exclusion>
        <exclusion>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
        </exclusion>
        <exclusion>
            <groupId>ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- NexOpen dependencies -->
<dependency>
    <groupId>org.nexopenframework</groupId>
    <artifactId>openfrwk-security-core</artifactId>
    <version>${nexopen.version}</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-support</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.nexopenframework</groupId>
    <artifactId>openfrwk-security-jdk15</artifactId>
    <version>${nexopen.version}</version>
</dependency>
        	 
            

And you must not forget to put the dependency of the security model in your pom.xml of the business module, because we need the definitions of the User-Role-Group interfaces, support classes, integration with other modules and so on.

             
<dependency> 
  <groupId>org.nexopenframework</groupId>  
  <artifactId>openfrwk-security-model</artifactId>  
  <version>${nexopen.version}</version> 
</dependency> 
             
            

Moreover, you must have present the Acegi Filter into you deployment descriptor web.xml. this filter represents a chain of filters managed inside the Spring IoC which provides several features such authenication, authorization and otehr features (see Acegi reference guide for more details)

             
<filter>
    <filter-name>Acegi Filter Chain Proxy</filter-name>
    <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
    <init-param>
        <param-name>targetClass</param-name>
        <param-value>org.acegisecurity.util.FilterChainProxy</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>Acegi Filter Chain Proxy</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
              
            

We must also add the follwoings beans into the applicationContext.xml located at web module under the WEB-INF folder.

             
<bean id="web.propertyConfigurer"
      class="org.nexopenframework.spring.config.PropertyPlaceholderConfigurer">
      <property name="ignoreResourceNotFound" value="true"/>
      <property name="locations">
          <list>
             <!-- classpath properties file for overwritten this default properties -->
             <value>classpath:acegi.properties</value>
          </list>
      </property>
      <!-- Acegi configuration -->
      <property name="properties">
          <props>
              <prop key="acegi.secure.channel.urls">
                 \A.*\Z=REQUIRES_INSECURE_CHANNEL
              </prop>
			  <prop key="acegi.secure.urls">
                 /login.jsp=ROLE_ANONYMOUS
                 <!-- 
                    Configure here the roles of your application 
                    and the allowed url patterns like the following example
                    /**=ROLE_USER,ROLE_ADMIN
                    /admin/*=ROLE_ADMIN
                  -->
                  /**=ROLE_ADMIN,ROLE_USER
                  /secure/**=ROLE_ADMIN
              </prop>
              <prop key="acegi.access.denied.url">/accessDenied.jsp</prop>
              <prop key="acegi.authentication.failure.url">/login.jsp?login_error=1</prop>
              <prop key="acegi.default.target.url">/index.jsp</prop>
              <prop key="acegi.filter.process.url">/j_acegi_security_check</prop>
              <prop key="acegi.login.form.url">/login.jsp</prop>
              <prop key="acegi.force.https">false</prop>
              <!-- role prefix configurable -->
              <prop key="acegi.role.prefix">ROLE_</prop>
              .....
          </props>
      </property>
  </bean>
  <!-- Acegi role list -->
  <bean id="openfrwk.roles"
        class="org.springframework.beans.factory.config.ListFactoryBean">
     <description/>
     <property name="sourceList">
          <list>
            <!-- the specific roles of your application -->
            <value>ROLE_ADMIN</value>
		    <value>ROLE_USER</value>
          </list>
     </property>
  </bean>
              
            

The first bean, a Spring custom property configurer, defines custom properties to be passed to the spring beans defined in the NexOpen Acegi module files. Here, you can modify, for instance, the secure urls, the role prefix, the url form login,where to redirect if some acces is denied, which url is processed for authentication and so on. The last bean, with name openfrwk.roles, defines a list of your custom roles to be passed also to the NexOpen Acegi configuration files. Notice that the name of the bean it is inmutable and must not be changed, because problems will appear at deployment time.

19.2.3. PersistenceManager support

We provide an integration between Acegi and NexOpen PersistenceManager thru the implementation of the PersistenceProvider, the class PersistenceManagerProvider. In this way, we can easily deal with authentication thru a RDBMS using the NexOpen PersistenceManager interface without need of how to integrate with RDBMS.

In order to configure this module, you must add into your applicationContext.xml

             
<!-- Authentication using JPA -->
<import resource="classpath:/META-INF/spring/openfrwk-module-security-authn-pm.xml"/>
              
            

Finally, we can customize some properties of the PersistenceManager implementation, such as the name (identifier) of the OQL NamedQuery (HQL, for instance), the property name of this query and if we should force the initialization of collections (roles and groups for implementations of NexOpen User-Role-Group) of the associate entity.

             
....
<bean id="web.propertyConfigurer"
      class="org.nexopenframework.spring.config.PropertyPlaceholderConfigurer">
<!-- PersistenceManager support -->
<!-- the identifier of the named query -->
<prop key="openfrwk.acegi.pm.queryName">myCustomLoadUser</prop>
<!-- the named parameter of the above query -->
<prop key="openfrwk.acegi.pm.usernameParameter">name</prop>
<prop key="openfrwk.acegi.pm.forceInitialization">true</prop>
......
             
            

We must take into account that the query, in order to load a user MUST only accept a unique parameter, the username and no more parameters are allowed. Examples of these queries, that could be found in a custom JSR-220 user entity or in a package-info.java class, could be

             
@javax.persistence.NamedQueries({
	@javax.persistence.NamedQuery(name="myCustomLoadUserFetch", 
	            query="select distinct cu from CustomUser cu 
	                   join fetch cu.roles roles where cu.username=:name"),
	@javax.persistence.NamedQuery(name="myCustomLoadUser", 
	            query="from CustomUser cu where cu.username=:name")
})
             
            

Notice that one of them, the myCustomLoadUserFetch, forces the load of the roles collection, avoiding initialization of collections (therefore, we could put the openfrwk.acegi.pm.forceInitialization to false).

If you are using the NexOpen Hibernate implementation of the security model, you must not be worried about configuration.

19.2.4. JPA EntityManager support

In this release, we also offer an integration with JPA also implementing the PersistenceProvider as the previous section.

In order to configure this module, we assume that you have defined a Spring Bean of type EntityManagerFactory (either local thru the FactoryBean implementations provided by Spring or found in the JNDI and configured in the Application Server). Moreover, you must also add into your applicationContext.xml the following import

             
<!-- Authentication using JPA -->
<import resource="classpath:/META-INF/spring/openfrwk-module-security-authn-jpa.xml"/>
              
            

it represents the acegi beans integrated with JPA. As well as the previous section, we can modify some specific properties related to JPA, as the identifier of the named query, the paramter name used in this query and if we force or not the initialization of collections.

             
....
<bean id="web.propertyConfigurer"
      class="org.nexopenframework.spring.config.PropertyPlaceholderConfigurer">
......
<!-- jpa support -->
<prop key="openfrwk.acegi.jpa.queryName">loadCustomUser</prop>
<prop key="openfrwk.acegi.jpa.usernameParameter">name</prop>
<prop key="openfrwk.acegi.jpa.forceInitialization">true</prop>
......
             
            

Refer to previous section, for a detailed discussion about the previous properties.

19.2.5. Integration with externals Security models

In this integration we realize that several times, almost all applicatiosn provides a secuity model whih differs dramatically of the proposed. You have different ways. One of them is implements the User

However, if you would not like to implement the above security module, you can also use the annotations for retrieving details of user, useful for Acegi. We have defined the following three annotations, that we can use at field or method level

  1. @Enabled to identify a enabled property holder.

  2. @Password to identify a password property holder

  3. @RolesCollection to identify a property as holder of roles collection. This annotation is not tagged as the before mentioned and accepts two attributes. The type attribute identifies the role class and the mappedName the field name of the role class.

We provide the following example for how to use the above annotations in a class

             
.....
import org.nexopenframework.security.annotations.Enabled;
import org.nexopenframework.security.annotations.Password;
import org.nexopenframework.security.annotations.RolesCollection;
.....             
@Entity
@Table(name="MYAPP_USER")
@NamedQuery(name="loadCustomUser", query="from User where username=:name")
public class User implements Serializable {
	
	private String password;
	
	private boolean enabled;
	
	private Set<Role> roles = new HashSet<Role>();
	
	......
	
	@Enabled
	@Column(name="USER_ENABLED")
	public boolean isEnabled() {
		return enabled;
	}

	@Password
	public String getPassword() {
		return password;
	}

	@ManyToMany
	@JoinTable(name="MYAPP_USER_ROLE",
			   joinColumns={@JoinColumn(name="ID_USER")},
			   inverseJoinColumns={@JoinColumn(name="ID_ROLE")})
	@Fetch(SUBSELECT)
	@RolesCollection(type=Role.class, mappedName="name")
	public Set<Role> getRoles() {
		return roles;
	}
	....
             
            

In order to ensure, the use of these annotations, we must add the following dependency in the pom.xml of your business module

             
<dependency> 
  <groupId>org.nexopenframework</groupId>  
  <artifactId>openfrwk-security-annotations</artifactId>  
  <version>${nexopen.version}</version> 
</dependency> 
             
            

In order to configure this module, you must also add into your applicationContext.xml the following import, which includes the beans which resolves the above annotations.

             
<!-- Acegi Security Framework -->
<!-- User details resolution -->
<import resource="classpath:/META-INF/spring/openfrwk-module-security-userdetails.xml"/>
              
            

Finally, if you do not want to use the metadata, you can implement the interface UserDetailsResolverDelegate for resolving the user details (the annotations dependency is not bnecessary but the before import is needed) as follows

             
....
import org.nexopenframework.security.acegi.resolver.UserDetailsResolverDelegate;
....
public class MyCustomResolverDelegate implements UserDetailsResolverDelegate {

  public GrantedAuthority[] getAuthorities(final Object userClass) {
	if (userClass instanceof MyUser) {
		Set roles = ((MyUser) userClass).getRoles();
		GrantedAuthority[] authorities = new GrantedAuthority[roles.size()];
		int k= 0;
		final Iterator it_roles = roles.iterator();
		while (it_roles.hasNext()) {
			final MyRole role = (MyRole) it_roles.next();
			authorities[k++] = new GrantedAuthorityImpl(role.getRoleName());
		}
		return authorities;
    }
	return new GrantedAuthority[0];
  }
	
  public String getPassword(final Object userClass) {
	if (userClass instanceof MyUser) {
		final MyUser user = (MyUser) userClass;
		return user.getPassword();
	}
	return null; 
  }
	
  public boolean isEnabled(final Object userClass) {
	if (userClass instanceof MyUser) {
		final MyUser user = (MyUser) userClass;
		return user.isEnabled();
	}
	return true;
  }
	
}
             
            

Afterwards, you must create spring bean into the above mentioned applicationContext.xml and define a property called openfrwk.acegi.resolver.delegate specifyng the bean name of this custom implementation

             
....
<bean id="web.propertyConfigurer"
      class="org.nexopenframework.spring.config.PropertyPlaceholderConfigurer">
  .......    
  <prop key="openfrwk.acegi.resolver.delegate">myapp.resolver.delegate</prop>
  ...
</bean>  
...
<bean id="myapp.resolver.delegate" class="om.mypackage.resolver.MyCustomResolverDelegate">
 ...
</bean>  
             
            

19.3. LDAP Support

TO BE DOCUMENTED

19.4. Siteminder Support

In order to configure this module, you must add into your applicationContext.xml

             
<!-- Acegi Security Framework -->
<!-- User details resolution -->
<import resource="classpath:/META-INF/spring/openfrwk-module-security-auth.siteminder.xml"/>
              
            

19.5. OpenID Support

TO BE DOCUMENTED

19.6. Different login pages. MultiModule Acegi integration

Sometimes in the same application, we must define several login pages which are the entry point to different parts of a given application (an example could be a generic application and its adminsitration module). Acegi Framework does not provide a way to deal this problem, but allows an easy extension for dealing with this problem.

NexOpen provides support for this feature and you have to follow the next steps for correct integration. First of all, we must define the following beans related to extensions of Acegi Security Framework in the applicationContex.xml located under the WEB-INF folder in the web module. These extensions considers the existence of different modules in your application

		   
.....            
<!-- MultiModules support -->
<!--  if you wish to use channel security, add "channelProcessingFilter," in front
	   of "httpSessionContextIntegrationFilter" in the list below -->
<bean id="multiFilterChainProxy"
	class="org.nexopenframework.security.acegi.util.FilterChainProxy">
  <property name="filterInvocationDefinitionSource">
	<value>
	  CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
	  PATTERN_TYPE_APACHE_ANT
	  /**=channelProcessingFilter,httpSessionContextIntegrationFilter,logoutFilter,
	      multiAuthenticationProcessingFilter,basicProcessingFilter,
	      securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,
	      anonymousProcessingFilter,exceptionTranslationFilter,
	      filterInvocationInterceptor
     </value>
  </property>
</bean>
<bean id="multiAuthenticationProcessingFilter"
  class="org.nexopenframework.security.acegi.ui.webapp.MultiModuleAuthenticationProcessingFilter" >
    <description></description>
    <property name="authenticationManager" ref="authenticationManager"/>
	<property name="authenticationFailureUrl">
		<value>${acegi.authentication.failure.url}</value>
	</property>
	<property name="defaultTargetUrl">
		<value>${acegi.default.target.url}</value>
	</property>
	<property name="filterProcessesUrl">
		<value>${acegi.filter.process.url}</value>
	</property>
	<!-- 
	     If true, will always redirect to the value of getDefaultTargetUrl 
	     upon successful authentication, irrespective of the page 
	     that caused the authentication request (defaults to false) 
	-->
	<property name="alwaysUseDefaultTargetUrl" value="${acegi.always.use.defaultTargetUrl:false}"/>
	<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
<bean id="multiAuthenticationProcessingFilterEntryPoint"
  class="org.nexopenframework.security.acegi.ui.webapp.MultiModuleAuthenticationProcessingFilterEntryPoint">
    <property name="loginFormUrl">
		<value>${acegi.login.form.url}</value>
	</property>
	<property name="forceHttps">
		<value>${acegi.force.https}</value>
	</property>
	<!-- -->
	<property name="serverSideRedirect" value="${acegi.serverSide.redirect:false}"/>
</bean>
<bean id="moduleResolver" class="org.nexopenframework.security.acegi.ui.ModuleResolver">
    <property name="modules">
       <list>
         <value>admin</value>
       </list>
    </property>
</bean>
......              	
		   
		

In this example we have consider only one module called admin. Afterwards, we must also define the following property belonging to the property of bean PropertyPlaceholderConfigurer in the above mentioned applicationContex.xml

             
 .....            
<bean
  class="org.nexopenframework.spring.config.PropertyPlaceholderConfigurer" 
  id="web.propertyConfigurer">
  <property name="ignoreResourceNotFound" value="true"/>
  <property name="locations">
     <list>
       <!-- classpath properties file for overwritten this default properties -->
       <value>classpath:acegi.properties</value>
     </list>
  </property>
  <!-- Acegi configuration -->
 <property name="properties">
     <props>
         ......
         <!-- multimodule support -->
         <prop key="acegi.auth.processor.entryPoint">
              multiAuthenticationProcessingFilterEntryPoint
         </prop>
         ......
  </proeprty>
</bean>  
......
        
      

and you must not forget to declare as ROLE_ANONYMOUS the page where the login is located (also located in the previous PropertyPlaceholderConfigurer bean)

          
......
 <prop key="acegi.secure.urls">
	/login.jsp=ROLE_ANONYMOUS
	/admin/tttlogin.jsp=ROLE_ANONYMOUS
    ......
           
      

In the deployment descriptor, we must also define the param targetBean with the suitable spring bean name, with contains the filter chain with the new authentication filter for multimodule environments

          
......
<filter>
 <filter-name>Acegi Filter Chain Proxy</filter-name>
 <filter-class>
	org.acegisecurity.util.FilterToBeanProxy
 </filter-class>
 <init-param>
  <param-name>targetBean</param-name>
  <param-value>multiFilterChainProxy</param-value> 
 </init-param>
</filter>
<filter-mapping>
  <filter-name>Acegi Filter Chain Proxy</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
.......
           
      

The structure of your project must be as follows concerning the location of your JSPs, look at the presence of a folder at root level with the same name that the modules defined and with two JSP's (index.jsp and login.jsp). Moreover, we must create another folder inside WEB-INF/jsp where we will locate the JSPs related to this module. This operation must be repited for each new module you define

          
webapp
|+admin
 |+index.jsp
 |+login.jsp
|+css
|+img
|+js
|+WEB-INF
  |+jsp
   |+welcome.jsp
   ....
   |+admin
    |+welcome.jsp
    ......
  |+web.xml
  |+applicationContext.xml
  .....
|+index.jsp
|+login.jsp  
           
      

Chapter 20. Web Services

Nowdays, integration features is one of the most common features in the JEE applications. Web Services provides a way to integrate with third party aplications. In this section, we will speak about how NexOpen supports developemnt of Web Services and the libraries supported.

20.1. Introduction

20.2. NexOpen and XFire integration

20.3. NexOpen and CXF integration

20.4. NexOpen and Axis2 integration

TO BE DOCUMENTED

20.5. Configuration

In case of XFire integration

			
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<bean id="nexopen.web.propertyConfigurer"
	  class="org.nexopenframework.spring.config.PropertyPlaceholderConfigurer">
  <property name="ignoreResourceNotFound" value="true" />
  <!-- XFire configuration -->
  <property name="properties">
	<props>
     <!-- 
       configuration value for webservices using XFire. 
       This indicates that must keep the servlet path to
       perform a lookup into the registered webservices with xfire
      -->
      <prop key="openfrwk.xfire.alwaysUseFullPath">true</prop>
	</props>
  </property>
</bean>			
			
		

Moreover, you also mut provide an XFire Annotations processor for JSR-181 metadata

			
<!-- ========================= WEB SERVICES DEFINITIONS ========================= -->
<!-- XFire web services annotations -->
<!-- IMPORTANT NOTE: For web services with auto-discovery strategy, this the correct place to be defined, 
	 at difference from older versions of framework where was defined in the 'nexopen-servlet.xml' file.
-->
<!-- uncomment if you plan to use webservices support in your application -->
<bean id="webAnnotations"
	class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations" />			
			
		

Chapter 21. Signature Module

21.1. Introduction

21.2. Apache Signature implementation

21.3. JSR-105 implementation

21.4. Configuration

Chapter 22. Serialization Module

Serialization of XML data is one of the features common in JEE developments. From Web Services following SOAP specification to modern XML-protocol REST services thru a transport (such as HTTP or JMS) marshalling and unmarshalling has been an important feature for perfomance in your applications. This module tries to solve in a common API such as

22.1. Introduction

As we have mentioned before, serialization of structured data in XML format is an important feature to be deal with modern applications which would like to be integrated by third-party applications (the well-known EAI, Enterprise Application Integration).

22.2. Marshaller implementation location in cient side

In order to retrieve the implemented Marshaller, we can use the MarshallerHolder a custom class which keeps an instance of the thread-safe Marshaller (internally, teh first time lookups inside the Spring BeanFcatory)

    
    ....
    import org.nexopenframework.xml.binding.client.MarshallerHolder;
    ....
    final Marshaller marshaller = MarshallerHolder.getMarshaller();
    //do marshalling stuff
    ....
     
    

This class assumes, that you are doing your marshalling process into the presentation layer. finally, in order to properly use this class, you must declare into a Spring XML configuration file

    
 <!-- MarshallerHolder -->
<bean id="marshaller.holder" 
      class="org.nexopenframework.xml.binding.client.MarshallerHolder">
   <description>Holder of the Marshaller</description>
</bean>    
     
    

22.3. XStream implementation

XStream is a powerful and easy-to-use API for marshalling the data.

22.3.1. Extension of XStream functionalities

        
 <!-- ========================= XSTREAM SUPPORT ========================================= -->
 <!-- XStream beans support -->
 <!-- aliases -->
 <bean id="aliasMapper" 
       class="org.nexopenframework.xml.binding.xstream.support.AliasMapper">
    <description>The alias for custom xml file</description>
    <property name="alias">
      <map>
       <entry key="key" value="com.mypackage.xstream.mapper.KeyType"/>
       <entry key="true" value="com.mypakage.xstream.mapper.BooleanType"/>
       <!-- data element is ignored -->
       <entry key="data" value="com.thoughtworks.xstream.mapper.Mapper$Null"/>
      </map>
    </property>
 </bean>
 <!-- converters -->
 <bean id="converterList" 
       class="org.nexopenframework.xml.binding.xstream.support.ConverterList">
    <description>A converter list for custom xml file</description>
    <property name="converters">
       <list>
         <bean class="com.mypackage.xstream.converters.MyCustomConverter"/>
         <bean class="com.mypackage.xstream.converters.DataConverter"/>
         <bean class="com.thoughtworks.xstream.converters.extended.ISO8601DateConverter"/>
       </list>
    </property>
 </bean>
 <!-- list of classes with JSR-175 metadata -->
 <bean id="annotatedClassList" 
       class="org.nexopenframework.xml.binding.xstream.support.AnnotatedClassList">
    <description>A converter list for custom xml file</description>
    <property name="topLevelClasses">
       <list>
         <value>com.mypackage.model.PropertyList</value>
         <value>com.mypackage.DateAttribute</value>
       </list>
    </property>
 </bean>        
        
        

22.3.2. Configuration

In the applicationContext.xml

        
....
<!-- use XStream support in your application -->
<import resource="classpath:/META-INF/spring/openfrwk-module-serialization-xstream.xml"/> 
     
       

22.4. XMLBeans implementation

XMLBeans is a powerful Framework of marshalling/unmarshalling started by Bea WebLogic an donated to Apache Foundation.

22.5. XServices

In NexOpen we offer a way to handle with structured data thru HTTP transport, the XServices. Roughly speaking an XService, is a command which is associated to a given URI and ofers an easy way to speak with the service components of your application.

22.6. NexOpen and JAXB2

Related to serialization and standards, Sun proposed JAXB as the standard way to mrshalling structured data. The new version, JAXB2, also offers support for J2SE 5.0 annotations and it is used in the new specification of JAX-WS 2.0 when we speak about document/literal web services. This specification also belongs to JEE 5.0 spec.

Sample applications

This final part of the reference documentation covers the sample applications that come with the NexOpen Framework distribution. In this release we provide the simple application as an example of how to use NexOpen in your JEE applications.

Chapter 23. Simple application

23.1. Introduction

The NexOpen Framework distribution provides the Simple JEE application, which it is an enterprise application using Maven2 as the dependency and build manager and it has been tested in J2EE 1.4 complaint Application Servers such as JBoss 4.0.x and Bea WebLogic 9.2. Presents a simple appeareance, but under scenes shows all the main modules of NexOpen Framework. The main idea it is to provide an startup point for develoeprs which would like to be involved with NexOpen. We enumerate the main modules present in this application

  1. Service Component Architecture. It presents all the service components that NexOpen defines, such as an Business Facade, Application Service and (Configurable) Services.

  2. Persistence Manager. It shows the main methods that a developer use thru the PersistenceManager

  3. Asynchronous Tasks. It exhibits a Message-Driven Bean 2.x fully configured and transaprent for developers

  4. Spring MVC integration. We provide several controllers using Spring MVC but annotated in order to avoid tconfiguration of XML files.

  5. AJAX support. We use the DWR framework for delaing with AJAX. Moreover, we provide an example of AJAX reverse, which they are notificactions from the a EJB container to a WEB container.

23.2. Simple and the business and resource layer

23.3. Simple and the presentation layer

23.4. Build and deployment

Appendix A. Instrumentation Phase

A.1. Introduction

NexOpen follows the philosophy to avoid complex developments offering a weaving module which translates specific classes into fulfill components of framework. Even more, we can perfectly create new JEE managed components in an easy and transparent way.

A.2. Configuration

Instrumentation module offers a ANT task in order to instrument the bytecode generated by your application. In Maven2, we usually configure in the pom.xml of business module

			
<tasks>
 <echo>Running NexOpen Framework Instrumentation tools</echo>
 <mkdir dir="${basedir}/target/generated-sources/javassist"/>
 <taskdef
  classname="org.nexopenframework.instrument.javassist.tools.JavassistInstrumentorEngineTask"
  name="instrument"/>
 <instrument criticaltime="600" 
    destdir="${basedir}/target/generated-sources/javassist" 
    dir="${basedir}/target/classes" 
    verbose="true" writefile="true">
  <include name="**/*.class"/>
  <transformer 
    classname="org.nexopenframework.instrument.javassist.transformers.ServiceCtClassTransformer"/>
  <transformer
    classname="org.nexopenframework.instrument.javassist.transformers.BusinessCtClassTransformer"/>
  <transformer 
    classname="org.nexopenframework.instrument.javassist.transformers.LoggingCtClassTransformer"/>
  <transformer 
    classname="org.nexopenframework.instrument.javassist.transformers.HACtClassTransformer"/>
 </instrument>
</tasks>  
 ....              
			
		

A.3. Configuration in JEE 5.0

If we want to deploy our application into any JEE 5.0 Application Server and Facades being EJB 3.0 Stateless Session Bean, we must include the following transformers into the previous list

      
....
<instrument criticaltime="600" 
    destdir="${basedir}/target/generated-sources/javassist" 
    dir="${basedir}/target/classes" 
    verbose="true" writefile="true">
  <include name="**/*.class"/>
  .....
  <!-- EJB 3.0 transformers -->
  <!-- support for EJB 3.0 @Interceptors -->
  <transformer 
    classname="org.nexopenframework.instrument.javassist.transformers.InterceptorCtClassTransformer"/>
  <!-- support for EJB 3.0 Stateless Session Bean -->
  <transformer 
    classname="org.nexopenframework.instrument.javassist.transformers.EJB3CtClassTransformer"/>
</intrument>
......        
      
      

A.4. Frequently Asked Questions

if you have moved from a 0.3.x version to a 0.4.x version or higher, you can find this ugly error

       
java.lang.NoClassDefFoundError: org/nexopenframework/instrument/annotations/UnInstrumentable
  at org.nexopenframework.instrument.javassist.AnnotationsUnInstrumentableSupport.isUnInstrumentable
  at org.nexopenframework.instrument.javassist.CompositeUnInstrumentableSupport.isUnInstrumentable
  at org.nexopenframework.instrument.javassist.JavassistInstrumentorEngine.instrumentClass
  at org.nexopenframework.instrument.tools.InstrumentorEngineTask.execute(InstrumentorEngineTask.java:99)
  at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
  at org.apache.tools.ant.Task.perform(Task.java:364)
  at org.apache.tools.ant.Target.execute(Target.java:341)
  at org.apache.maven.plugin.antrun.AbstractAntMojo.executeTasks(AbstractAntMojo.java:108)
  at org.apache.maven.plugin.antrun.AntRunMojo.execute(AntRunMojo.java:83)
  at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:412)
  at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:534)
  at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:475)
  at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:454)
  at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:306)
  at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:273)
  at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:140)
  at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:322)
  at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:115)
  at org.apache.maven.cli.MavenCli.main(MavenCli.java:256)
  at org.maven.ide.eclipse.ext.embedder.Maven2Executor.main(Maven2Executor.java:106)
       
       

This is done due the fact of introduction of a new module which deals with annotations for instrumentation purposes in the service components classes. This ugly exception it is easily solved putting the corresponding depedency with this module into the Maven2 ant plugin in the pom.xml of business module

       
...
<build> 
    <plugins> 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-antrun-plugin</artifactId>  
        <executions> 
          <execution> 
            <phase>process-classes</phase>  
            <configuration> 
              <tasks> 
                <echo>Running NexOpen Framework Instrumentation tools</echo>  
                <mkdir dir="${basedir}/target/generated-sources/javassist"/>  
                <taskdef name="instrument" 
                         classname="....."/>  
                <instrument dir="${basedir}/target/classes" 
                        destdir="${basedir}/target/generated-sources/javassist" 
                        verbose="true" writefile="true" 
                        criticaltime="600"> 
                  <include name="**/*.class"/>  
                  <!-- custom transformers -->  
                  <transformer classname="org.nexopenframework.instrument.javassist.transformers.ServiceCtClassTransformer"/>  
                  ......
                </instrument>  
                <copy todir="${basedir}/target/classes"> 
                  <fileset dir="${basedir}/target/generated-sources/javassist"/> 
                </copy> 
              </tasks> 
            </configuration>  
            <goals> 
              <goal>run</goal> 
            </goals> 
          </execution> 
        </executions>  
        <dependencies>
          <dependency> 
            <groupId>org.nexopenframework</groupId>  
            <artifactId>openfrwk-instrument-annotations</artifactId>  
            <version>${nexopen.version}</version> 
          </dependency>
          ......
       
       

If you put this dependency into the dependencies plugin, it is automatically solved the previous exception

Another ugly exception which could appears it is the following

       
Caused by: Problem Instrumenting class name com/mypackage/tasks/LoaderTask.class
 at org.nexopenframework.instrument.tools.InstrumentorEngineTask.execute(InstrumentorEngineTask.java:104)
 at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
 at org.apache.tools.ant.Task.perform(Task.java:364)
 at org.apache.tools.ant.Target.execute(Target.java:341)
 at org.apache.maven.plugin.antrun.AbstractAntMojo.executeTasks(AbstractAntMojo.java:108)
 ... 12 more
Caused by: org.nexopenframework.instrument.ClassTransformationException: 
 javassist.NotFoundException: org.nexopenframework.tasks.JobTask
 at org.nexopenframework.instrument.javassist.DefaultUnInstrumentableSupport.isUnInstrumentable(DefaultUnInstrumentableSupport.java:51)
 at org.nexopenframework.instrument.javassist.CompositeUnInstrumentableSupport.isUnInstrumentable(CompositeUnInstrumentableSupport.java:46)
 at org.nexopenframework.instrument.javassist.JavassistInstrumentorEngine.instrumentClass(JavassistInstrumentorEngine.java:198)
 at org.nexopenframework.instrument.tools.InstrumentorEngineTask.execute(InstrumentorEngineTask.java:99)
 ... 16 more
Caused by: javassist.NotFoundException: org.nexopenframework.tasks.JobTask
 at javassist.ClassPool.get(ClassPool.java:301)
 at javassist.CtClassType.getInterfaces(CtClassType.java:393)
 at org.nexopenframework.instrument.javassist.DefaultUnInstrumentableSupport.isUnInstrumentable(DefaultUnInstrumentableSupport.java:40)
 ... 19 more       
       
       

This exception is related to a dependency not found by the classloader of instrumentation and it is solved in teh same way as before, putting the dependency into the Maven2 ant plugin

Appendix B. Exception Handling

B.1. Introduction

Exception Handling has been one of the most common modules developed in JEE applications. Traditional developments has expend several time trying to handle in a custom way, the exceptions which might occurs in your application

B.2. Exception Handling in Business Components

In business components (our serice components), we declare a method level, using the annotations ExceptionHandler as follows

			
package org.nexopenframework.core.annotations;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Target(METHOD) @Retention(RUNTIME)
public @interface ExceptionHandler {
	/**the exception type*/
	Class<? extends Throwable> type() default Throwable.class;
	/**severity related to this excption*/
	SeverityType severity() default SeverityType.ERROR;
	/**message to be included in the exception handler framework*/
	String message() default "";
	
}
			
		

and ExceptionHandlers for declaring a set of exceptions handlers

			
package org.nexopenframework.core.annotations;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Target(METHOD) @Retention(RUNTIME)
public @interface ExceptionHandlers {

	ExceptionHandler[] value();
}			
			
		

Look at the following exemple, in order how to use the above mentioned metadata

			
import org.nexopenframework.core.annotations.ExceptionHandler;
import static org.nexopenframework.core.annotations.SeverityType.ERROR;
import static org.nexopenframework.core.annotations.SeverityType.INFO;
.....			
@ExceptionHandler(type=Throwable.class, severity=ERROR)		
public void saveDictionaries(final PropertyList propList) {
.....
}
	
@ExceptionHandlers({@ExceptionHandler(type=java.io.IOException, severity=ERROR),
                     @ExceptionHandler(type=com.mypackage.MyBusinessException, severity=INFO)})
public java.util.Map doBusiness() throws java.io.IOException, com.mypackage.MyBusinessException {
.....
}                     	
			
		

Fortunately, this the only that we must done as developers. Beyond the scenes, NexOpen catches the exception in the AOP interceptor, logs associated to this severity and put the information related to the exception class MBean.

B.3. Exception Handling in WEB

The exception handling, as we have mentioned above, has been one o the most important features in tradiional JEE developments. The specifications has marked guidelines for vendors for dealing with such behaviours. Nevertheless, developers has needed more advanced features that the specifications declared.

Following Servlet 2.4 specification, we can define in the Deployment Descriptor web.xml the following elements for customization of errors that appears in the application

			
<!-- error codes 404 and 500 -->
<error-page>
   <error-code>404</error-code>
   <location>/WEB-INF/jsp/404.jsp</location>
</error-page>
<error-page>
   <error-code>500</error-code>
   <location>/WEB-INF/jsp/500.jsp</location>
</error-page>
    
			
		

Not only status code, exceptions are also contempleted and we can declare custom JSPs pages associated to custom exceptions which achieves the presentation layer.

Due the fact of using Spring Framework, we can also define, in the nexopen-servlet.xml, the following bean in order to deal with the exceptions which arises the presentation layer

			
<!-- ========================= EXCEPTION HANDLING  ========================= -->
<!-- Exception handling mapper -->
<bean id="exceptionHandlingMapper"
	class="org.nexopenframework.web.mvc.spring.handler.NexOpenExceptionResolver">
	<description>
		Handles the mapping between exceptions and defined views to
		avoid showing server errors
	</description>
	<!-- apply logging facility -->
	<property name="warnLogCategory" value="org.nexopenframework.myapplication"/>
	<property name="exceptionMappings">
		<props>
		  <!-- IMPORTANT NOTE put here your custom pages for your application specific exceptions -->
		  <prop key="java.lang.Throwable">500</prop>
		</props>
	</property>
</bean>			
			
		

Finally in teh case of Spring MVC controllers, the exception handling and the validation it is done at Controller class level

		
....
public final ModelAndView handleException(final HttpServletRequest request, 
              final HttpServletResponse response, 
              final Throwable thr) throws Exception {
	//model to be saved in the request attribute context
	final Map<String, Object> model = new HashMap<String, Object>(1);
	final Object command = new FileUploadBean();
	ServletRequestDataBinder binder = this.createBinder(request, command);
	{
	 	//bind the values of the request
	 	binder.bind(request);
	 	model.put("upload", command);
	 }
	 //problem which has caused the problem
	if (thr instanceof ServletRequestBindingException) {
		//validations problems
		final ServletRequestBindingException srbe = (ServletRequestBindingException) thr;
		final Throwable valCause = srbe.getRootCause();
		if (valCause instanceof BindException) {
			final BindException be = (BindException) valCause;
			final Errors errors = be.getBindingResult();
			final StringBuilder sb = new StringBuilder(BindingResult.MODEL_KEY_PREFIX);
	 	sb.append("upload");
			model.put(sb.toString(), errors);
		}
	}
	//forward to the form page
	return new ModelAndView("myForm", model); 
}