Tuesday, October 13, 2009

Struts 2 cookie interceptor

A few weeks ago i developed a Struts2 cookie interceptor plugin.

I just upload it to http://code.google.com/p/struts-cookie-interceptor/

The interceptor is a Bidirectional interceptor (In Out interceptor) that works the following way.

in your action you annotate a property declaration like this:

@Cookie("cookie")
private String valor;
.. getter...setter

Then, the interceptor will inject the value of the "cookie" cookie to the annotated property. If the value of the property "valor" is changed in the action, this value, will be written to the cookie on the return of the action automatically. this is way i say it is bidirectional.

The annotation takes as values, the name of the cookie, the path, and the time to live attributes.

For full detail, feel free to download the source code.

Bye

Tuesday, September 1, 2009

Spring Security 2 Explained. Part 1. The filters.

The following article will try to explain Spring security with detail.

The vast majority of Spring Security articles and books, explain the framework making emphasis in the easy of configuration and use. Which is great for almost everything. However to really understand what is going on, i need to go a little deeper and study the elements tha actually participate on the framework.

I will make a very simple application and try to explain what happens in Spring Security through the different paths of executions i do.

The first thing to do is to add the security filter and context configuration to your web.xml file.

This is my web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>articleSpringSecurity</display-name>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/security.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

Here, the Delegating Filter Proxy is the entry point into Spring Security. It's actually not a Spring Security Filter, but a Spring Web Filter, is just that in this case we are using it to delegate to the security filters we will define in the Spring Application Context “security.xml”

Defining the simplest Spring Security Configuration File:

security.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
</http>

<authentication-provider>
<user-service>
<user name="carlo" password="carlo" authorities="ROLE_USER" />
</user-service>
</authentication-provider>

</beans:beans>

This file will include Spring security in our Application.

Let's explain what is on this file, by accessing our application. Pointing to the base path of our web application automatically shows us a login form. How does this happen?.


The XML element http with auto-config= “true” defines the following:

First of all Spring will automatically register the following servlet filters:

HttpSessionContextIntegrationFilter
LogoutFilter
AuthenticationProcessingFilter
DefaultLoginPageGeneratingFilter
BasicProcessingFilter
SecurityContextHolderAwareRequestFilter
RememberMeProcessingFilter
AnonymousProcessingFilter
ExceptionTranslationFilter
SessionFixationProtectionFilter
FilterSecurityInterceptor


These filters execute from top to bottom and carry the following resposibilities:


HttpSessionContextIntegrationFilter job is to create a default SecurityContext. It tries to read the context from the Session, and if there isn't any, it creates a new Instance of SecurityContextImpl and put it in the ThreadLocal SecurityContextHolder. The it passes Control to the next filter in the Chain.
After returning from the chain, this filter consults the SecurityContextHolder for the SecurityContext in it to see if it has changed during request processing.
I SecurityContext has changed and authentication is not anonymous, then the new SecurityContext is stored in session.


LogoutFilter. This filter consults the URL invoked to see if it is a URL that requires logout. The default Logout Requring URL is j_spring_security_logout. So if you invoke this URL in your application you are explicitly asking to logout from the application. If the URL is for logut, the This filter delegates in handlers the actual logout process. By default it delegates to SecurityContextLogoutHandler and TokenBasedRememberMeServices. The first Handler invalidates the Session, and the second handler, deletes the remember me cookie (set age to 0)


AuthenticationProcessingFilter
. This is one of the most important filters. Its job is the following. First it it checks if the Invocation URL is for a login petition, it does this by consulting if the URL matches the default /j_spring_security_check URL.
If the previous step requirement is met, then this filter looks in the request parameters for a Username and a password (in the request parameters j_username and j_password respectively). Then it creates an UsernamePasswordAuthenticationToken which is an Implementation of an Authentication Class, so it set the authentication Principal to the username and the Authentication credentials to the passoword provided.
Then it puts the username in the session under the name SPRING_SECURITY_LAST_USERNAME. The next important Step is to call the AuthenticationManager's authenticate method with our newly created Authentication Object.
From the preceding paragraph we can see that the first time we access the application home, the filter will stop it's processing in the point where it checks if the invocation URL is an authentication petition. The home page is not the URL for authentication (which we now know is j_spring_security_check) so this filter won't do anything (right now) but to continue to the next filter.

DefaultLoginPageGeneratingFilter
. This Filter is almost explained by its name. It's function is to generate a default login page when required. With "when required" I mean when the URL invoked corresponds to the default URL for login page which is /spring_security_login. When this filter detects that this URL is being invoked it renders a default login page. When we first invoke the application home we are not invoking this URL. So why does it show the login Page. We'll see why soon enough.


BasicProcessingFilter. This filter's job is to check if the request has standard http authentication headers. If it does, it creates a new Authentication (UsernamePasswordAuthenticationToken) object from it, and like the AuthenticationProcessingFilter, it delegates to the AuthenticationManager's authenticate method the authentication job. If authentication fails, the filters sets the SecurityContext to null.

SecurityContextHolderAwareRequestFilter. This filter wraps the Servlet request in a SavedRequestAwareWrapper. This wrapper somehow maintains a saved request, but I don't know what this wrapper exactly brings to the table.


RememberMeProcessingFilter. This filter's job is to query the security context to see if there is an Authentication Object on it, if not, it will create (or try to) a new one, by calling the autoLogin method of AbstractRememberMeServices which will retrieve a Remember Me cookie and try to authenticate using it.
The cookie's default name is SPRING_SECURITY_REMEMBER_ME_COOKIE. If the filter finds this cookie, it decodes it, make some validations and call the userDetailsService with the cookie information. If the userDetails returned is valid, The RememberMeServices creates a new RememberMeAuthenticationToken that return to the filter and the filter saves it into the SecurityContext.

AnonymousProcessingFilter
. This simple filter, detects if there already is an authentication object in the security context. if there is not any, it creates a new one (AnonymousAuthenticationToken) with the username "guest" and the rol "ROLE_ANONYMOUS" (this names can be overriden).


ExceptionTranslationFilter. This filter is in charge of Capturing and initiating the handling of any security exceptions that may come from the application (AccessDeniedException,AuthenticationException). The filter serves as a translator between the Java Exceptions and the Http Errors. If the filter detects an authentication Exception (Basically No Authentication Object) it initiates the authentication mechanism by invoking the authentication entry point to show the login page. If the exception is a AccessDeniedException, the filter first checks if the authenticated user is Anonymous. If it is, it follows the same path as if there wasn't any authentication at all. If it isn't anonymous, it basically means that a USer with some privileges is trying to access resources that he can't. So an access denied exception is returned to the browser

SessionFixationProtectionFilter. This filter checks if there is a user authenticated but there is not a Session attribute associated with the securityContext. This can happen if the user is not authenticated from the start of the request but is authenticated during the duration of the request thread. If this is the case, the filter creates a new session with the information required.

FilterSecurityInterceptor. This is the Filter version of the AbstractSecurityInterceptor. it delegates to it's super class (the mentioned AbstractSecurityInterceptor) the authorization to access the required resource. If it can not access the resource the AbstractSecurityInterceptor will throw an accessDeniedException. We'll cover the AbstractSecurityInterceptor in detail in the next par of this Article.

Sunday, August 23, 2009

Running Java App in Debugging Mode

Without an IDE, to Run An Application In Debug Mode you do the following

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=11550,suspend=n "your-program"

The Application "your-program" Starts and listens for connections on the 11550 port for debugging.

Monday, June 29, 2009

Implementing Strategies with Enums.

Implementing Strategies with Enums.

As most Design Patterns, Strategy pattern is an incredibly useful pattern to express polimorphic behaviour.
I don't pretend to explain Strategy pattern on this post. My intention is only to show you a nice way of implementing the pattern using a Java Enum.

Sometimes the difference between strategies is small, and you have control over all the strategies. (There is no intention that a client implements its own strategy).
Also, usually each strategy comes in the form of a Singleton instance.
It would be nice to have all Strategies in a common place, sharing a common namespace.

All the previous can be addressed with the use of the Enum construct in Java 1.5+

Let's suppose a Voice "strategizable" class, with two concrete strategies Screaming Voice and Whisper Voice

This is how we would do this with an Enum.

public enum Voice {
SCREAM(){
@Override
public String say(String say){ return say.toUpperCase()+" !!";}
},
WHISPER(){
@Override
public String say(String say){return say.toLowerCase()+ " please ";}
};
public abstract String say(String say);
}

There we have our two Strategy implementations under the same namespace (the ENUM type), singleton guaranteed. To test the startegy we have the following test case.


package misc;

import org.junit.Test;
import static org.junit.Assert.*;

public class VoiceTest {
@Test
public void testVoice() {
// if in good mood
VoiceUser user = new VoiceUser(Voice.WHISPER);

// if in bad mood
VoiceUser user2 = new VoiceUser(Voice.SCREAM);

assertEquals("do that please", user.askSomeone());
assertEquals("DO THAT !!", user2.askSomeone());
}
}

class VoiceUser {
public VoiceUser(Voice voice) {
this.voice = voice;
}

Voice voice;

String askSomeone() {
String string = "Do that";
return voice.say(string);
}
}

Tuesday, June 23, 2009

From which Jar is a class Loaded

I post this for future reference.

public class Main {

public static void main(String[] args) {
System.out.println(findJar(System.class));
}

public static String findJar(Class clase) {
String name = clase.getName();
name = name.substring(name.lastIndexOf('.') + 1) + ".class";
String jar = clase.getResource(name).toString();
return jar;
}

}

Fast Flex Cairngorm Explanation

Flex Cairngorm fast explanation

As an experienced Spring and Spring MVC developer, i started my new Flex-Java based personal project with the idea of using a flex framework that encourages the same kind of patterns that i'm used to.
I took on the Cairngorm framework from de Adobe people.

I'll try to establish correspondences between Cairngorm elements and Spring MVC elements.

The elements:

The elements that form part of a Flex Cairngorm Architectura are the following:

View: The view is normally an mxml file. The view shows the data to the user and receives his interactions. The view allows to initiate updates of the model. When an update is to happen, it generates an appropiate event informing of this. The view holds a binded reference to the model that is automatically updated on change. This Object corresponds to the JSPs (Or any other view technology) in Spring MVC.

Model Domain Objects: Are the objects that form part of the Model of the application, are the objects on which the application logic is applied.

Events: Is the flex preferred way of communicating that an action must be taken due to something happening. In cairngorm, the Event object usually carry a Model Object reference on it. This object corresponds, more or less, to the HttpRequest that is sended to the Servlet Container on the Submit event.

Front Controller. As in the major of MVC frameworks, the front controller is the central piece that ties together and routes flow between the view and the business logic. If you are familiar with Spring MVC, this Object corresponds to the DispatcherServlet of Spring.

ModelLocator: In Flex, a Model locator is a Registry that contains references to the different model objects.

Command Objects: Following the GoF Command design pattern, Cairngorm Command Objects are objects that implements an execute method, and are selectively invoked by the front Controller to carry on certain business logic. In normal cairngorm applications, the command object basicaly only extracts the model object from the Event object and passes it to a Business Delegate Object. If you are experienced with Spring MVC this Command Object corresponds to the Controller in the Spring MVC Framework.

Business Delegate: This object's job is to hold a reference to the (usually remote) Service that is going to be called. (Usually this reference is obtained from a ServiceLocator). The business delegate Calls the remote object, and on response, invoke's the Command Object's result method, which is in charge of updating the model in the Model Locator.

Groovy Dynamic Typing

Groovy Dynamic Beahaviour.

As oposed to Java, Groovy is dynamically typed. Which basically means that the type is not checked at compile time, but instead only at runtime.
Besides some drawbacks, this allows to do many cool things including Duck Typing.
The principle of duck typing is that "if it quacks like a duck it's a duck". this basically means that the behaviour of the Object is based on the use it has on the application, not on its specific type.
In essence this allows to call an object's methods without knowing (at compile time) that these methods exist. In Runtime the methods are invoked. Note that this works even with two different unrelated (No hierarchy or interfaces shared) objects, that implements the method, and precisely this is the beauty of it.

For example

[CODE]
def metodo(anything){
anything.call(144)
}

metodo{
println it
}

def clos2= {println it+it}
metodo(clos2)

class X{
public def call(value){
println value*3
}
}

metodo(new X())
[/CODE]

As you can see, the method "metodo" is called three times with different types.
The first two times is called with a Closure, one inline closure and other declared closure.
And the third time with a totally different object X. That happens to implement the methdo in its own way.

Friday, June 12, 2009

Understanding workflow languages

Using JBPM as a starting point and taking a look at its documentation, I’ve realized that it’s not really that hard to build a very simple Workflow Model. It basically consists of the following classes.

Node: Each Step in the workflow flow is defined by a node. A node is a Command object (Command Design Pattern) and has references to the incoming transitions and to the outgoing transitions.

Transition: A directional link that links two nodes together.

Execution: An execution is the context that the workflow is currently working on. An execution has a reference to the node it is at the moment. Transitions pass this context from node to node.

So the workflow basically works this way.

An Execution object is instantiated with a reference to the first node. From that point on, the execution of the flow is controlled by events passed to the Execution Object.
In general, Nodes are responsible for sending events to the Execution Object, determining what the execution of the process will do next.

So this is a very simple example of a workflow Model implementation. In Pseudo.

Class XNode implements Node{
Public execute(Execution exe){
doSomething…..
exe.event(“transicionA”)
}
}
Class Execution{
Node currentNode;
Public event(Event e){
currentNode.getTransitionForEvent(e).take(this)
}
}
Class Transition{
Node origin;
Node destination;
Public take(Execution e){
destination.execute(e)
}
}

Monday, May 11, 2009

Comprendiendo algunos conceptos avanzados de Spring

Comprendiendo algunos conceptos avanzados de Spring.

Este artículo pretende explicar de una manera comprensible los siguientes conceptos avanzados de Spring.
- BeanPostProcessors
- BeanFactoryPostprocessors.
- Introductions.
- AOP con anotaciones.

El enfoque del artículo será la realización de un pequeño ejemplo que ponga de manifiesto los conceptos anteriores y su utilidad.

El artículo supone cierta familiarización con los conceptos principales del Framework Spring en su versión 2.5.

La idea del siguiente ejemplo es permitir que un Bean tenga una referencia a su ApplicationContext, sin implementar (ni en desarrollo ni en compilación) ninguna interfaz dependiente de Spring. Luego este ApplicationContext será accedido desde un Aspecto que imprimirá su “displayName”. Una funcionalidad que en principio no parece que aporte mucho, pero nos sirve para ilustrar los conceptos.

1.- Extendiendo la Interfaz ApplicationContextAware.

La interfaz ApplicationContextAware es una interfaz auto detectada por Spring. Cuando un Bean definido en un ApplicationContext implementa esta interfaz, Spring, al cargar el contexto, inyectara el ApplicationContext al bean a través del método.
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;

Para nuestro ejemplo, necesitamos obtener el ApplicationContext asociado a un bean, pero no desde el mismo bean, sino desde un Aspecto. Por tanto extenderemos la interfaz ApplicationContextAware para incluir un getter.

public interface ApplicationContextAwareWithGetter extends ApplicationContextAware{
ApplicationContext getApplicationContext();
void setApplicationContext(ApplicationContext beanFactory);
}

Además, como dijimos antes, los beans de servicio no deben tener dependencia directa a Spring, por lo que dichos beans no implementaran ApplicationContextAware. Entonces necesitamos definir una implementación por defecto para ApplicationContextAware, que luego en tiempo de ejecución será añadida a los beans.

public class ApplicationCntextAwareDefaultImpl implements ApplicationContextAwareWithGetter{

public ApplicationContext context;
public ApplicationContext getApplicationContext() {
return context;
}

public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context=context;
}
}


2. Definiendo la Introduction.

Una Introduction o Mixin en Aspectj y en Spring AOP, es un tipo de Aspecto, que permite añadir, en tiempo de ejecución, una interfaz y su respectiva implementación a un objeto existente. Esto causa la impresión de que el objeto utilizara herencia múltiple.
Esto es precisamente lo que necesitamos. Necesitamos añadir la Interfaz ApplicationContextAwareWithGetter y la implementación ApplicationCntextAwareDefaultImpl a los beans de servicio que queramos que tengan referencia a su ApplicationContext.

Definiimos el Aspecto Introduccion de la siguiente forma:

@Aspect
@Order(1)
public class ApplicationContextAwareIntroductionAdder{

@DeclareParents(defaultImpl=test.business.ApplicationCntextAwareDefaultImpl.class,value="test.business.services.*+")
public static ApplicationContextAwareWithGetter applicationContextAware;
}

Esta introduction define que todos los beans dentro del paquete test.business.services implementaran la interfaz ApplicationContextAwareWithGetter y delegaran sus métodos a la implementación ApplicationCntextAwareDefaultImpl.

3. Seteando el ApplicationContext a los beans:

Es necesario ahora setear el ApplicationContext a los beans de servicio. Que en tiempo de ejecución implementaran la interfaz ApplicationContextAwareWithGetter. Para setear el ApplicationContext en los beans utilizaremos el siguiente BeanPostProcessor.

public class AddApplicationContextPostProcessor implements BeanPostProcessor {
ApplicationContext context;

public AddApplicationContextPostProcessor(ApplicationContext context) {
this.context = context;
}

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ApplicationContextAwareWithGetter) {
((ApplicationContextAwareWithGetter) bean).setApplicationContext(context);
}
return bean;
}

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

Un BeanPostProcessor es un tipo especial de bean que permite tratar los bean de un ApplicationContext uno a uno luego de que estos son instanciados e inicializados.
En nuestro caso estamos haciendo lo siguiente. Luego de que cada bean en el ApplicationContext sea inicializado, revisamos si el bean implementa la interfaz ApplicationContextAwareWithGetter. De ser asi, le seteamos el aplication context que tenemos guardado en una variable de instancia (que luego mostraremos como la seteamos).

4. Registrando el BeanPostProcessor.

El BeanPostProcessor anterior se podría registrar directamente en el applicationContext.xml como un bean mas, sin embargo, como vimos, el PostProcessor necesita una referencia al ApplicationContext, para setearsela luego a los beans de servicio. Si hacemos que el PostProcessor implemente ApplicationContextAware, tampoco sirve, ya que se invocara al método setApplicationContext muy tarde, cuando ya se han “postProcesado” los beans por lo que el contexto inyectado a los beans es null.

Por tanto es necesario implementar otra estrategia. La solución mas obvia resulta implementar un BeanFactoryPostProcessor y registrar el BeanPostProcessor en el ApplicationContext manualmente.

4.1 El BeanFactoryPostProcessor.

Un BeanFactoryPostProcessor es un tipo especial de Bean que es invocado por Spring luego de cargar la definición de beans del ApplicationContext (o BeanFactory) pero antes de cualquier instanciación o inicialización. De esta forma, un BeanFactoryPostProcessor tiene acceso a la BeanFactory donde es definido y puede modificar la BeanFactory de diversas formas. Por ejemplo definiendo nuevos beans, sustituyendo elementos de definición, etc.

Cuando se implementa la interfaz BeanFactoryPostProcessor, es necesario implementar el método public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException.

La clase ConfigurableListableBeanFactory ofrece un API bastante amplio para trabajar con la BeanFactory.

La versión final de nuestro BeanFactoryPostProcessor queda de la siguiente forma:

public class RegisterBeanPostProcessorFactoryPostProcessor implements BeanFactoryPostProcessor,ApplicationContextAware{
private ApplicationContext context;
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
BeanDefinitionRegistry registry=(BeanDefinitionRegistry)factory;
RootBeanDefinition definition=
new RootBeanDefinition(AddApplicationContextPostProcessor.class);
ConstructorArgumentValues constArguments=new ConstructorArgumentValues();
constArguments.addGenericArgumentValue(context);
definition.setConstructorArgumentValues(constArguments);
registry.registerBeanDefinition("postProcessor", definition);

}

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context=applicationContext;
}

}

Como se puede ver, la clase implementa ApplicationContextAware, para recibir la inyección del ApplicationContext, que es con el cual se instanciará luego el BeanPostProcessor.

ConfigurableListableBeanFactory posee un método para registrar BeanPostProcessors llamado addBeanPostProcessor. Sin embargo, si registráramos el BeanPostProcessor utilizando este método, no habría forma de colocar este PostProcessor al final en la lista de los PostProcessors que se aplicaran a los beans. Es decir, registrándolo de esta forma, el BeanPostProcessor sería invocado antes de que se invocara el BeanPostProcessor encargado de añadir las Introductions a los Beans, por lo que los beans que le llegarían no estarían implementado la interfaz ApplicationContextAwareWithGetter, de hecho nuestro bean PostProcessor procesaría incluso los BeansPostProcessors definidos en el fichero de configuración.

Por lo expuesto anteriormente, se decidió como solución registrar manualmente el Bean en la BeanFactory como cualquier otro Bean. Definiendo un RootBeanDefinition y registrándolo en la BeanFactory, añadiéndole como argumento del constructor el ApplicationContext.

5. Interceptando las llamadas a los servicios y accediendo a su AplicationContext.

El último paso que nos queda para comprobar el funcionamiento de lo que acabamos de hacer es la creación de un Aspecto que intercepte las llamadas a los servicios, y acceda al ApplicationContext de dichos servicios a través de la interfaz ApplicationContextAwareWithGetter.

El Aspecto es el siguiente:

@Aspect
public class ServiceInterceptor {
@Around ("execution(public * test.business.services.*.*(String))")
public Object intercept(ProceedingJoinPoint pjp) throws Throwable {
ApplicationContextAwareWithGetter appContextAware =
(ApplicationContextAwareWithGetter) pjp.getThis();
System.out.println("Display Name " + appContextAware.getApplicationContext().getDisplayName());
return pjp.proceed();
}
}

Este aspecto, lo único que hace es interceptar las llamadas a cualquier método publico de los servicios (definidos en el paquete test.business.services) que reciben un String como parámetro, e imprimir el “displayName” asociado a su AplicationContext. Nótese el Casting a ApplicationContextAwareWithGetter. Recordemos que nuestros servicios no implementan esta interfaz. Es la Introduction la que en tiempo de ejecución creó el Proxy que sí la implementa.

Esto es todo. Ya tenemos completa la funcionalidad. Hicimos que un POJO implementara en tiempo de ejecución una interfaz (con su implementación por defecto). Logramos definir un BeanPostProcessor programáticamente e incluirlo manualmente en la BeanFactory, y Post Procesamos nuestros Beans para añadirles una propiedad que no tenían, dependiendo de si implementaban una interfaz.

A continuación copio todo el código fuente del ejemplo.


Clase Main.java

package test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.business.services.Service1;

public class Main {

/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
((Service1)context.getBean("servicio1")).executeService("BUU");
((Service1)context.getBean("servicio2")).executeService("BUU");
}
}


Clase ApplicationContextAwareIntroductionAdder.java

package test.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

import test.business.ApplicationContextAwareWithGetter;

@Aspect
@Order(1)
public class ApplicationContextAwareIntroductionAdder{

@DeclareParents(defaultImpl=test.business.ApplicationCntextAwareDefaultImpl.class,value="test.business.services.*+")
public static ApplicationContextAwareWithGetter applicationContextAware;
}

Clase ServiceInterceptor.java

package test.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;

import test.business.ApplicationContextAwareWithGetter;

@Aspect
@Order(1)
public class ServiceInterceptor {
private String[] contextsToIntercept = { "context2" };

@Around("execution(public * test.business.services.*.*(String))")
public Object intercept(ProceedingJoinPoint pjp) throws Throwable {
ApplicationContextAwareWithGetter appContextAware = (ApplicationContextAwareWithGetter) pjp.getThis();
System.out.println("Display Name " + appContextAware.getApplicationContext().getDisplayName());
return pjp.proceed();
}
}





Clase AddApplicationContextPostProcessor.java

package test.beans;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;

import test.business.ApplicationContextAwareWithGetter;

public class AddApplicationContextPostProcessor implements BeanPostProcessor {
ApplicationContext context;

public AddApplicationContextPostProcessor(ApplicationContext context) {
this.context = context;
}

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ApplicationContextAwareWithGetter) {
((ApplicationContextAwareWithGetter) bean).setApplicationContext(context);
}
return bean;
}

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

}


Clase RegisterBeanPostProcessorFactoryPostProcessor.java

package test.beans;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class RegisterBeanPostProcessorFactoryPostProcessor implements BeanFactoryPostProcessor,ApplicationContextAware{
private ApplicationContext context;
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
BeanDefinitionRegistry registry=(BeanDefinitionRegistry)factory;
RootBeanDefinition definition=new RootBeanDefinition(AddApplicationContextPostProcessor.class);
ConstructorArgumentValues constArguments=new ConstructorArgumentValues();
constArguments.addGenericArgumentValue(context);
definition.setConstructorArgumentValues(constArguments);
registry.registerBeanDefinition("postProcessor", definition);

}

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context=applicationContext;
}

}











Interface ApplicationContextAwareWithGetter.java

package test.business;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public interface ApplicationContextAwareWithGetter extends ApplicationContextAware{
ApplicationContext getApplicationContext();
void setApplicationContext(ApplicationContext beanFactory);
}

Clase ApplicationContextAwareDefaultImpl.java

package test.business;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;

public class ApplicationCntextAwareDefaultImpl implements ApplicationContextAwareWithGetter{

public ApplicationContext context;
public ApplicationContext getApplicationContext() {
return context;
}

public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context=context;
}

}

Interface Service.java

package test.business.services;
public interface Service {
String executeService(String cadena);
}


Clase ServiceImpl.java

package test.business.services;
public class ServiceImpl implements Service {

public String executeService(String cadena) {
return "hola "+cadena;
}

}

Fichero ApplicationContext.xml


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">












Bibliografia

Spring in Action, Second Edition. Manning.
Spring 2.5 Recipes. Appress
Spring Reference Manual

Tuesday, February 17, 2009

A pretty nice DRY Template Method Refactoring.

I had a class with already duplicated code as follows (Excluding irrelevant parts):



public class FileWriterImpl implements FileWriter {

public void write(A1 a1) {
BufferedWriter writer = null;
try {
File file = new File(filePathFinal);
file.delete();
if (!file.exists()) {
file.createNewFile();
}
writer = new BufferedWriter(new java.io.FileWriter(new File(filePathFinal)));
write(a1, writer);
} catch (IOException e) {
throw new A1GenerationException(ErrorCodeConstants.FILE_CREATION_ERROR,new Object[]{e.getMessage()});
} finally {
try {
writer.flush();
writer.close();
} catch (Exception e) {

}
}
}

public void writeOneLineToFileAndCloseWriter(Line line) {
if (line == null) {
logger.info("LA LINEA ES NULA. NO SE ESCRIBE NADA EN EL FICHERO");
return;
}
BufferedWriter writer = null;
try {
File file = new File(filePathFinal);
if (!file.exists()) {
file.createNewFile();
}
writer = new BufferedWriter(new java.io.FileWriter(new File(filePathFinal), true));
writeLineToWriter(line, writer);
} catch (IOException e) {
throw new A1GenerationException(ErrorCodeConstants.FILE_CREATION_ERROR,new Object[]{e.getMessage()+filePathFinal});
} finally {
try {
writer.flush();
writer.close();
} catch (Exception e) {

}
}
}

}

As you can see there is very common code beetwen the two methods. But i didn't do anything about it. Until yet another method needed to be introduced!!..
So i decided to refactor it to eliminate duplicated code.

I observed that the file accessing stuff was basically a template method with the only differences in the code being the parts that come after the "writer = new BufferedWriter(new java.io.FileWriter(new File(filePathFinal)));".

Not implementing the exact Template Method Pattern (As is in literature) but rather the way Spring implements it in JdbcTemplate and alikes, i created a CallbackInterface:

interface FileWritingOperation{
void execute(BufferedWriter writer) throws IOException;
}

Objects implementing this interface will receive a writer and execute any logic they want on it. But zero Boilerplate code. Just the functionality they need.

Then i refactored the previous method into the following more generic method:

public void doInFileWriterResourceSecure(FileWritingOperation operation) {
BufferedWriter writer = null;
try {
File file = new File(filePathFinal);
if (!file.exists()) {
file.createNewFile();
}
writer = new BufferedWriter(new java.io.FileWriter(new File(filePathFinal), true));
operation.execute(writer);
} catch (IOException e) {
throw new A1GenerationException(ErrorCodeConstants.FILE_CREATION_ERROR, new Object[] { e.getMessage() + filePathFinal });
} finally {
try {
writer.flush();
writer.close();
} catch (Exception e) {

}
}
}

As you can see the method now receives a FileWritingOperation as a parameter. The method is in charge of managing the File resources, and wher appropiate invokes the execute method of the FileWritingOperation passed.

Now all three individual methods look like the following:

public void write(final A1 a1) {
doInFileWriterResourceSecure(new FileWritingOperation(){
public void execute(BufferedWriter writer) throws IOException {
write(a1, writer);
}

});
}

public void writeBlock(final Block lineBlock) {
if (lineBlock == null) {
logger.info("Bloque Nulo. NO SE ESCRIBE NADA EN EL FICHERO");
return;
}

doInFileWriterResourceSecure(new FileWritingOperation(){
public void execute(BufferedWriter writer) throws IOException {
for (Line line : lineBlock.getLines()) {
writeLineToWriter(line, writer);
}
}

});
}


public void writeOneLineToFileAndCloseWriter(final Line line) {
if (line == null) {
logger.info("LA LINEA ES NULA. NO SE ESCRIBE NADA EN EL FICHERO");
return;
}
doInFileWriterResourceSecure(new FileWritingOperation(){
public void execute(BufferedWriter writer) throws IOException{
writeLineToWriter(line, writer);
}
});
}


And there is no more Repetition and definetly a more elegant code.

Thursday, January 15, 2009

Programatically chaining Interceptors in Spring

I have several services configured like the following:









es.indra.dominioInversis.utilidades.invocarProcesoBatch.servicios.SrvInvocarProcesoBatchService



comisionesErroresOperacionInterceptor serviceTransactionInterceptor
hibernateInterceptor





Today i needed to create a Spring Interceptor that saves language information. (Functionality not important for what i'm about to say). And intercepts every service, like the previous, in the application

I easily implemented the Interceptor, but for some reason my Chief Architect told me that the functionality must be included in the "comisionesErroresOperacionInterceptor", so not adding another interceptor line to the config of every service. I thought this solution was not good, because it would mix totally different functionalities in the same Interceptor.
So i decided to have two diferent interceptors but using only one in each service definition. To achieve this, i did the following.

First i defined a CompositeInterceptor that contains a List of Interceptors.

public class CompositeServicesInterceptor implements MethodInterceptor {
private List interceptors;

public List getInterceptors() {
return interceptors;
}

public void setInterceptors(List interceptors) {
this.interceptors = interceptors;
}
}

Then i asigned the name "comisionesErroresOperacionInterceptor" to this interceptor, so now every service would be intercepted by this Interceptor.
I defined this interceptor like the following:










where "erroresOperacionInterceptor" makes reference to the previous "comisionesErroresOperacionInterceptor" and "languageForPetitionInterceptor" is my new interceptor.

Ok, The last step was to implement the invoke method in the new CompositeInterceptor:

The first attempt was:

public Object invoke(MethodInvocation invocation) throws Throwable {
ProxyMethodInvocation proxyMethodInvocation=(ProxyMethodInvocation)invocation;
Advised advised = (Advised)proxyMethodInvocation.getProxy();
for (MethodInterceptor interceptor : interceptors) {
advised.addAdvice(interceptor);
}
advised.removeAdvice(this);
return invocation.proceed();
}

This didn't work for the first petition, but yes for the followings.
The reason is that the first time when calling invocation.prooceed(), the call is passed to the target object from this point, and not to the proxy with the new advices.
The second and following times it worked great. Calling the others Interceptors instead of this one:

This problem was solved with the following


public Object invoke(MethodInvocation invocation) throws Throwable {
ProxyMethodInvocation proxyMethodInvocation=(ProxyMethodInvocation)invocation;
Advised advised = (Advised)proxyMethodInvocation.getProxy();
for (MethodInterceptor interceptor : interceptors) {
advised.addAdvice(interceptor);
}
advised.removeAdvice(this);
Method method=invocation.getMethod();
return method.invoke(advised, invocation.getArguments());
}

This time instead of calling proceed, i directly invoked the method on the proxy object. So getting the result i wanted.
The second and following invocations were like in the previous case.