$ thought | blog

Place to serialize my thoughts…

Archive for the ‘javascript’ tag

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

Don’t put JavaScript validation, I’ll Firebug!

with 10 comments

Recently, I was with my friend to book a cab. The cab service provided an online booking facility which allows you to provide some details (phone number, address, destination and time of cab etc.). We went ahead and tried to book the cab and it wasn’t accepting the request. It seemed that they put a validation to check that user shall not book a cab less than 4 hours prior to departure.

Unfortunately, we wanted to book the cab on a 3 hours notice and it was mandatory for us to book the cab.  We couldn’t resist but started looking for options at our hand. We pulled the website in Firefox and opened firebug to see where the validation is executed. We were surprised by the validation was done in browser using a very simple JavaScript. We thought; let’s see if we could just pass the 4 hours validation by bypassing the validation or maybe mocking the action. The validation code was very simple; we just put the breakpoint in the function and then set the variable value via firebug to an acceptable level. Bang! The code ran successfully and cab service accepted the request.

We made a successful cab reservation and my friend could take a peaceful ride back home!  Moral of the story: Please put all the business critical validations on the server side instead of browser based JavaScript. If you really want to do some browser based validation then it will be really good idea to obfuscate the code.

Written by Sachin

April 20th, 2008 at 9:45 pm