Friday, July 1, 2011

How to plug jdbc into alfresco service registry

The easiest way to start is to build an AMP (Alfresco Module Package) from a simple java/spring project. I use ant to build the AMP.

Configuring Spring
You can plug your spring configs in just about any where as long as you follow the naming conventions *-context.xml and put the file in the correct directory so your amp is correctly over-layed when applied to the alfresco WAR.

I put mine in a file called custom-web-context.xml. Then I put that file into my amps config/alfresco/extension/ directory.

The spring bean configs go as such:

<!-- This bean config creates a singleton instance of our version of alfresco's service registry-->

<bean id="MyCoServiceRegistry" class="org.myco.repo.service.MyCoServiceDescriptorRegistry" parent="ServiceRegistry"></bean>


That is pretty much it as far as the spring config necessary to extend the service registry. Soon I will show you how to extend the Service registry class to make it work with this config. Before that I wanted to mention that I used a DAO pattern along with this service registry extension to implement my JDBC service.

JDBCService Config
<!-- This bean config createers a singleton instance of SimpleJdbcTemplate a very handy spring class -->
<bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
   <constructor-arg ref="defaultDataSource" />
</bean>

<bean id="MyCoJDBCService" class="org.myco.repo.service.MyCoJDBCServiceImpl">
   <property name="workFlowNameMappingDAO" ref="workFlowNameMappingDAO" />
</bean>
<bean id="workFlowNameMappingDAO" class="org.myco.repo.dao.WorkFlowNameMappingDAO">
    <property name="simpleJdbcTemplate" ref="simpleJdbcTemplate" />
</bean>

Now you can simply plug your new service registry into any bean and have all the existing alfresco services available as well as your new service.
Note: One thing to consider using this method, it kind of undermines spring IoC but it is super convenient. 

Extending the service registry class
public class MyCoServiceDescriptorRegistry extends org.alfresco.repo.service.ServiceDescriptorRegistry
{

   static final QName MYCO_JDBC_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "MyCoJDBCService");

   public MyCoJDBCService getMyCoJDBCService()
   {
      return (MyCoJDBCService)getService(MYCO_JDBC_SERVICE);
   }

}

That will just about do it. The overhead should be fairly low because our new class is a singleton. As you know because we are extending Alfresco's ServiceRegistry class we get all those methods as well and by telling spring that Alfresco's ServiceRegistry config is our parent it knows to inject it with all the necessary dependencies.

Enjoy :)

Interface vs. Abstract Class

Method Signatures
Strictly speaking a interface method and an abstract method are similar. In both cases the modifier in the sub class or implementing class must be equal or less restrictive than the super class. Even there signature is very similar. The key difference is: At the class level they are defined by different key words and the abstract class can have impementation methods. Both interface and abstract class access modifiers must be public. This has significant impications on object model and design.

Examples of signatures:
protected abstract void communicates();   //from abstarct class
public abstract String tastesLikeChicken();  //from interface


Abstract Class
An abstact class is best used when the functionality belongs in the heirachy of the class and you want to enforce a contract in this heirarchy.

Example:  implements and defines methods that have to do with all animals
public abstract class Animal
{
   protected abstract void communicates();
   protected abstract void moves();
   protected abstract void eats();
   protected String isAlive(){ return "yes"; } //implemented method
}

public class Dog extends Animal abstract methods
{
   public void communicates()
   {
      System.out.println("Barking!!!");
   }
     
   public void wagsTail(){ //some code that is specific to a dog };

   ...

}

Interface
An interface is best used when the functionality belongs out side a classes heirarchy. Again you want to enforce a contract with the interface. When mixed with other patterns such as IoC (e.g. Spring) this can become a very powerfull tool.

Example: defines methods not related to being an animal

public interface eatable
{
   public String tastesLikeChicken();
}

public class Dog extends Animal implaments eatable, domestic
{
    public String tastesLikeChicken(){ return "yes"; }

    public void communicates()
   {
       System.out.println("Barking!!!");
   }

   ...
}

The interface feature in Java has huge ramifications on desgin. It also solves a anti-pattern common to C/C++ known as the diamond inheitance anti-pattern. Remember a class can implament many interfaces but only extend one parent in Java.

Hope you find this informative. PS: I wound never eat my little mutt Luna :) even if she did taste like chicken.