$ thought | blog

Place to serialize my thoughts…

Archive for the ‘alfresco’ tag

Things to Ponder with Alfresco (Part III: WCM – Improvements)

without comments

Now days using web content management systems (WCM) is trivial. You should continuously update the website content to maintain a fresh look. It increases returning customers and popularity. Almost every major website uses a CMS to achieve this. It might be an in-house developed or an off-the-shelf product. In any case, it helps organizations to separate the content authoring team from the application development cycles.  This helps in quicker content updates without being dependent on release schedules. I am going to point out certain things about WCM feature of alfresco. You can also apply the same principles to your WCM if you are using existing one, or planning to develop a new one!

Content storage format - Alfresco provides a nice feature called "web-forms". There are two types of forms currently available i.e. WCM forms and ECM forms. Both of them capture the input data and store it as XML. You can also choose to apply content transformation using XSL. It helps to save final output as either HTML, Text or PDF etc. Not to forget, the content is actually captured and saved as XML. In my perception one of the strengths of Alfresco is its content repository. If XML is target format, it is saved in CR as a cm:content property and it defeats the whole purpose. If CR is not aware of the structure of the content, it defeats the purpose of content model definition? It is not very different from storing the content xml as plain string in database. Frankly I don't see any benefit of using CR over database in this method.

To avoid such inefficient use of alfresco, you can take some effort and write a custom form component. Use custom forms (develop forms in your application and then communicate with alfresco using API) to capture user data and store them in content repository in defined content model and schema.

This will help you in -

  • Content repository now understands the structure of your content. This is really important and if you have any doubts, please post that in comments. I might write about it later in my blog.
  • You can apply your custom content transformation logic so that content can be exported in XML / HTML / custom output format. Just generate this once every time you update the content. It improves the efficiency of content management system to deliver target content.
  • You will have a flexibility of own input format, use JSP or rails forms, its your choice!

Deployment benefits - Alfresco has another great strength, Deployment Infrastructure. I think its also one of its weaknesses. Use it wisely to improve your release management. On the release date of web application usually you come across content sanity issues, or format differences. To avoid that, setup proper environments where alfresco can sync content and test it before you push it to live. This might save you a lot of frustration.

Although its a great feature, there is a caveat to that. Generally all the code for web application is stored in CVS systems. Alfresco code (web scripts, web form definitions etc.) is stored in alfresco. Keeping the versions of alfresco code and web application code is nightmare. Develop some automated web script deployment tool and every time you release, wipe out all the previous webscripts and deploy new ones from the CVS. This always makes you keep updated code in the CVS and versioning becomes much robust.

Written by Sachin

January 4th, 2010 at 8:48 pm

Posted in Articles,Developer

Tagged with ,

Alfresco: Workflow managed by JavaScript

with 5 comments

If you are a regular reader of this blog, you might have figured out that I am currently working on a project involving alfresco at the center and it's a content management system. Earlier I have worked with Content repository (Apache Jackrabbit) and that was a good experience. Alfresco is next step of a content repository which extends it into a full blown content management system and much more. I was working on a problem where we defined a custom (Advanced workflow) to be precise in Alfresco lingo. This workflow was needed to be monitored, managed and accessed only via a webscript as we have used webscripts to do almost everything in our project. I was very pleased to see this, but that is only available in 2.9 labs release (as of now). We are using alfresco 2.2.0 version for our development and that is production stable version, so I have very little choice but go with production version. Alfresco has very limited JavaScript API support for workflow manipulation and that was difficult job for manage. There was no other option than writing custom JavaScript API which allows to manage workflow in Alfresco. We did that and it was very powerful and easy! :) I wanted following features for JavaScript API -

  • Easy to extend
  • Can handle any workflows
  • Provides easy ways to retrieve tasks, definitions, paths etc.
  • Provides as much functionality possible which is available in Alfresco Workflow Console.

Alfresco workflow console is command line interaction component which allows you to manipulate, get information about workflows using simple commands and I wanted to do all that using JavaScript. I started exploring the source code and found a class 'org.alfresco.service.cmr.workflow.WorkflowService'. This class has generic API which allows you to do all the operations possible through workflow console. This bean is used for workflow console operations. So all I needed was expose this bean in JavaScript as root object and start using it. That simple! I wrote a simple java class to expose the bean as follows:

package com.xxxx.yyyy.workflow;
 
import java.util.List;
 
import org.alfresco.repo.processor.BaseProcessorExtension;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.workflow.WorkflowService;
 
public class WorkflowManager extends BaseProcessorExtension {
	private ServiceRegistry services;
 
	public void setServiceRegistry(ServiceRegistry serviceRegistry) {
		this.services = serviceRegistry;
	}
 
	public WorkflowService getWorkflowService(){
		return services.getWorkflowService();
	}
}

The method getWorkflowService() exposes the workflow service to the JavaScript calls. To expose the Workflow Manager as root object in JavaScript create WEB-INF/classes/alfresco/extension/custom-script-context.xml and you will be good! (If you don't know how to do that, read this) Now, you can get the handle of workflow service in JavaScript code. Yet, we need to write a small component which will allow us to retrieve the active workflows, tasks etc. To do so, I wrote a small JavaScript object which provides those functionality to the user.

var workflowService = workflow.getWorkflowService();
 
var W = {
	transitions: function(noderef){
		var task = W._currentTask(noderef);
		var trans = [];
		try{
		var tasks = task && task.path.node.transitions;
		for(var index=0; index < tasks.length; index++){
			trans[trans.length] = tasks[index].id;
		}
		}catch(error){
			// Ignore error
		}
		return trans;
	},
 
	move: function(noderef, command){
		workflowService.endTask(W._currentTask(noderef).id
                , command);
	},
 
	_workflowPath: function(noderef){
		var workFlows = workflow.getWorkflows
                      ("workspace://SpacesStore/" + noderef, true);
		if(workFlows.size()>0){
			return workFlows.get(0).id + "-@";
		}
		return "";
	},
 
	_currentTask: function(noderef){
		var curTask;
		var tasks;
		try{
		tasks = workflowService.getTasksForWorkflowPath
                           (W._workflowPath(noderef));
		if(tasks.size() > 0)
		      curTask = tasks.get(0);
		} catch(Error){
			// Ignore error
		}
		return curTask;
	}
}
 
function initWorkflow(noderef)
{
	var wflow = actions.create("start-workflow");
	wflow.parameters.workflowName
             = "jbpm$xxxxyyyy:abc"; // your workflow name
	wflow.parameters["bpm:assignee"]
             = person.properties.userName;
	wflow.parameters["bpm:workflowDescription"]
             = "Put your description";
	wflow.execute(noderef_for_which_workflow_will_associate);
}

Thats it! The initiate workflow method is used to apply a workflow to a node. Once that is done, the W object can be used to do operations like retrieving the active tasks, ending the workflow and making the workflow transition. Hope that helps. If you need more workflow related information and reading material you can visit following places:

  • JBPM jPDL Documentation (here)
  • Alfresco workflow wiki (here)
  • ECMArchitect Advance Workflow Guide (here)

Written by Sachin

May 29th, 2008 at 10:35 am