Creating an Alfresco Task History; The Java style

Geplaatst op 14 september 2007 door Marc

17 reacties

I have been working with Alfresco for a while now. It is a very comprehensive tool, but I was missing a nice feature in it. A task history in the document details screen. Now i know you can do alot of coding with the scripting engine in Alfresco, but what I wanted was not possible in my opinion and I wanted it to fully integrate in the java code base instead of scripted into pages. Time for me to go to work. In this article I will briefly explain what I have done to make this feature work.

Intended public

This article is written with the Alfresco developer in mind. If you are not atleast a moderate Alfresco developer you might not be able to fully comprehend what is explained. Also I will omit information in this article that I deem basic Alfresco knowledge.

The creation process

Very early on in my effort to build the task history panel I cam eto the conclusion that I not only needed extra coding effort, but also a solid way of integrating my code into the codebase of alfresco. Now Alfresco has provided me and you with a method of doing this. You can find details about this integration process on the Alfresco wiki. I will in this article give you a brief overview on how to integrate your code into the Alfresco codebase, but I will not go into detail on this. What I will describe is the Task history functionality.

Functionality overview

What am I creating is a panel in the document-details page that displays the tasks for me specific for the document in question. Furthermore I want to see active and completed tasks here. ALL tasks that is. To give you a impression of my wish; a picture to illustrate it.
Task history
My other wish was that it would be coded in Java and integrate in the Alfresco way with the Alfresco codebase. Given these wishes I started this small project.

What do you need to do?

1.Create a extension project
2.Create a new workflowbean class with the added functionality.
3.Modify the faces-config-custom.xml, supplying a enhanced workflowbean
4.Modify the document-details.jsp, to show the task history
5.Create a faces-config.xml, supplying the new navigation rules for your new jsp.
6.Create a custom webclient.properties file for your new labels.

The extension project

The first thing I did was to create a new extension project. I followed the example SDK custom JSP project structure for my own project. You can read on the wiki or in the source on how to do this. I asume you have the nessesary skill.

The new workflowbean

For my function I have to code some extra lines. It is bad practise to start hacking the alfresco source (unless you have no other option), so I created my own java class extending the existing WorkflowBean class. Here is the added code:


package nl.wowww.alfresco.web.bean.workflow;
import java.util.ArrayList;
import java.util.List;

import org.alfresco.service.cmr.workflow.WorkflowInstance;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
import org.alfresco.web.bean.DocumentDetailsBean;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.workflow.WorkflowBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Extended workflowbean.
* This extension adds extra task functionality.
*
* @author Marc de Kwant, www.wowww.nl
*/
public class WowwwWorkflowBean extends WorkflowBean {

protected DocumentDetailsBean documentDetailsBean;

protected List allTasks;

private static final Log logger = LogFactory.getLog(WowwwWorkflowBean.class);

public static final String BEAN_NAME = "WowwwWorkflowBean";

// ------------------------------------------------------------------------------
// Bean Getters and Setters

public List getAllTasks() {

this.allTasks = new ArrayList();
List workflows = new ArrayList();
workflows = workflowService.getWorkflowsForContent(
documentDetailsBean.getDocument().getNodeRef(), false);
workflows.addAll(workflowService.getWorkflowsForContent(
documentDetailsBean.getDocument().getNodeRef(), true));

if (workflows != null && workflows.size() > 0) {
for (WorkflowInstance wi : workflows) {
WorkflowTaskQuery query = new WorkflowTaskQuery();
query.setActive(wi.active);
query.setTaskState(null);
query.setProcessId(wi.id);
List tasks = this.workflowService.queryTasks(query);

// create a list of transient nodes to represents
for (WorkflowTask task : tasks)
{
Node node = createTask(task);
this.allTasks.add(node);

if (logger.isDebugEnabled())
logger.debug("Added task: " + node);
}

}
}
return this.allTasks;
}

/**
* @param documentDetailsBean the documentDetailsBean to set
*/
public void setDocumentDetailsBean(DocumentDetailsBean documentDetailsBean) {
this.documentDetailsBean = documentDetailsBean;
}

}

The code above is what you need to retrieve all tasks, weather complete/active/non-active, and make them available to the front-end.

Faces-config-custom.xml

To make the above bean available to the jsf framework, you need to provide a managed bean configuration. The faces framework provides for this in the form of a faces-config-custom.xml file. I have put the below code into this file:


<managed-bean>
<managed-bean-name>WowwwWorkflowBean</managed-bean-name>
<managed-bean-class>nl.wowww.alfresco.web.bean.workflow.WowwwWorkflowBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>navigationBean</property-name>
<value>#{NavigationBean}</value>
</managed-property>
<managed-property>
<property-name>documentDetailsBean</property-name>
<value>#{DocumentDetailsBean}</value>
</managed-property>
<managed-property>
<property-name>nodeService</property-name>
<value>#{NodeService}</value>
</managed-property>
<managed-property>
<property-name>workflowService</property-name>
<value>#{WorkflowService}</value>
</managed-property>
</managed-bean>

This file represents the only manual manipulation of files in the alfresco codebase since the faces framework gives me no alternate option in this. The file must be put into the WEB-INF folder in the alfresco webclient project and nowhere else.

Document-details.jsp

To display my net Task history panel I created a duplicate of the original document-details jsp and added the following panel/richlist to display the tasks provided by my allTasks method in my new WowwwWorkflowBean class.


<f:loadBundle basename="alfresco.extension.webclient" var="customMsg"/>
<a:panel label="#{customMsg.task_history}" id="task-panel" facetsId="workflow-panel-facets" progressive="true"
border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white"
expanded='#{DocumentDetailsBean.panels["task-panel"]}' expandedActionListener="#{DocumentDetailsBean.expandPanel}">
<!-- tasksCompleted -->
<a:richList id="taskHistoryList" viewMode="details" value="#{WowwwWorkflowBean.allTasks}"
var="t" styleClass="recordSet" headerStyleClass="recordSetHeader"
rowStyleClass="recordSetRow" altRowStyleClass="recordSetRowAlt" width="100%"
pageSize="10" initialSortColumn="taskId" initialSortDescending="false">

<!-- task id column -->
<a:column id="col1" width="10" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{customMsg.taskId}" value="taskId" styleClass="header"/>
</f:facet>
<h:outputText id="tid" value="#{t['bpm:taskId']}" />
</a:column>

<!-- task create date column -->
<a:column id="col2" width="120" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{customMsg.taskCreateDate}" value="taskCreateDate" styleClass="header"/>
</f:facet>
<h:outputText id="tcreatedate" value="#{t['cm:created']}">
<f:convertDateTime pattern="yyyy-MMM-dd H:mm:ss" />
</h:outputText>
</a:column>

<!-- task description column -->
<a:column id="col3" width="170" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{customMsg.taskDescription}" value="taskDescription" styleClass="header"/>
</f:facet>
<h:outputText id="tdescription" value="#{t['bpm:description']}" />
</a:column>

<!-- task comment column -->
<a:column id="col5" width="170" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{customMsg.taskComment}" value="taskComment" styleClass="header"/>
</f:facet>
<h:outputText id="tcomment" value="#{t['bpm:comment']}" />
</a:column>

<!-- task status column -->
<a:column id="col6" width="80" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{customMsg.taskStatus}" value="taskStatus" styleClass="header"/>
</f:facet>
<h:outputText id="tstatus" value="#{t['bpm:status']}" />
</a:column>

<!-- task start date column -->
<a:column id="col7" width="120" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{customMsg.taskStartDate}" value="taskStartDate" styleClass="header"/>
</f:facet>
<h:outputText id="tstartdate" value="#{t['bpm:startDate']}">
<f:convertDateTime pattern="yyyy-MMM-dd H:mm:ss" />
</h:outputText>
</a:column>

<!-- task due date column -->
<a:column id="col8" width="120" style="text-align:left">
<f:facet name="header">
<a:sortLink label="#{customMsg.taskDueDate}" value="taskDueDate" styleClass="header"/>
</f:facet>
<h:outputText id="tduedate" value="#{t['bpm:dueDate']}">
<f:convertDateTime pattern="yyyy-MMM-dd H:mm:ss" />
</h:outputText>
</a:column>
</a:richList>
</a:panel>

First I load my custom message bundle and secondly I code the task history panel.

Faces-config.xml

To display our newly created document-details.jsp we need to overrule the navigation rules that are present in the alfresco WEB-INF folder. This is not done as the faces-config-custom but in a more sophisticated manner. In the extension project you put a file named faces-config.xml in the META-INF directory. in this file i have declared the following navigation rules to be overruled:


<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>

<navigation-rule>
<from-view-id>/jsp/*</from-view-id>
<navigation-case>
<from-outcome>showDocDetails</from-outcome>
<to-view-id>/jsp/extension/document-details.jsp</to-view-id>
</navigation-case>
</navigation-rule>

<navigation-rule>
<from-view-id>/jsp/extension/document-details.jsp</from-view-id>
<navigation-case>
<from-outcome>checkoutFile</from-outcome>
<to-view-id>/jsp/dialog/checkout-file.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>checkinFile</from-outcome>
<to-view-id>/jsp/dialog/checkin-file.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>undoCheckoutFile</from-outcome>
<to-view-id>/jsp/dialog/undocheckout-file.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>updateFile</from-outcome>
<to-view-id>/jsp/dialog/update-file.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>deleteFile</from-outcome>
<to-view-id>/jsp/dialog/delete-file.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>editFile</from-outcome>
<to-view-id>/jsp/dialog/edit-file.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>editHtmlInline</from-outcome>
<to-view-id>/jsp/dialog/edit-html-inline.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>editTextInline</from-outcome>
<to-view-id>/jsp/dialog/edit-text-inline.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>editSimpleWorkflow</from-outcome>
<to-view-id>/jsp/dialog/edit-simple-workflow.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>editCategories</from-outcome>
<to-view-id>/jsp/dialog/edit-category.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>createAction</from-outcome>
<to-view-id>/jsp/wizard/create-action/action.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>previewContent</from-outcome>
<to-view-id>/jsp/dialog/preview-file.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>showForum</from-outcome>
<to-view-id>/jsp/forums/forum.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>manageContentUsers</from-outcome>
<to-view-id>/jsp/roles/manage-content-users.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>applyTemplate</from-outcome>
<to-view-id>/jsp/dialog/apply-doc-template.jsp</to-view-id>
</navigation-case>
</navigation-rule>

<navigation-rule>
<from-view-id>/jsp/dialog/edit-simple-workflow.jsp</from-view-id>
<navigation-case>
<from-outcome>cancel</from-outcome>
<to-view-id>/jsp/extension/document-details.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>finish</from-outcome>
<to-view-id>/jsp/extension/document-details.jsp</to-view-id>
</navigation-case>
</navigation-rule>

<navigation-rule>
<from-view-id>/jsp/dialog/edit-category.jsp</from-view-id>
<navigation-case>
<from-outcome>cancel</from-outcome>
<to-view-id>/jsp/extension/document-details.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>finish</from-outcome>
<to-view-id>/jsp/extension/document-details.jsp</to-view-id>
</navigation-case>
</navigation-rule>

</faces-config>

In this file I overrule all references to document-details with my own reference.

webclient.properties

The final and last thing I did was to create a webclient.properties file and put all my custom labels into it.


task_history=Task History
taskId=Task id
taskDescription=Description
taskCreateDate=Create date
taskStartDate=Start date
taskDueDate=Due date
taskStatus=Status
taskComment=Comment

Final note.

I have omitted all explenation regarding the extension project. This article was intended for a Alfresco developer. And the layout of the article is not that good, but I cannot alter the look and feel of it.

Regards.

Marc de Kwant

wowww.nl

Gepost in categorie: TechTalk

Reacties

Plaats reactie zonder facebook account

Anoniem

  1. Aki Backman Aki Backman

    This is THE needed feature. Can you do some installation package that users can benefit from your work?

  2. Simon Simon

    YES! YES! even labs3 is missing this…Please can you do some sort of installation package to download and use.

  3. Melissa Melissa

    Hey guys nice blog, love it 🙂

  4. Craig Burnett Craig Burnett

    This is a great feature Marc. Thanks for posting your work here.

    I used this as a starting point and made some changes to the java, properties and jsp so it works in Labs 3.0. If you would like to update this post with the updated code, please send me an email.

    The JSP now shows the task title, assignee and workflow ID. I also fixed the sorting and date presentation so it works properly and shows the correct date and times.

    Please keep up the good work!

    Craig

  5. Aki Backman Aki Backman

    Would be nice to have this option also for us that are not that handy with coding….. Craig can you publish your work somewhere?

    Thanks!

  6. Craig Craig

    Aki,

    I placed the modified code here:

    http://sites.google.com/site/clbforge/Home

    Let me know if you have any problems accessing the files.

    Craig

  7. God bless Open Source God bless Open Source

    […] to drop this requirement, while googling around I came across this genius post, in which Marc de Kwant describes and shares the code of exactly this feature. Ok, I understand […]

  8. Dranakan Dranakan

    Hello,

    Thank you for this job, it’s great 😉

    I have take source from Craig’s site, where it’s write : Notes: I could not get Alfresco to see the new jsp in the extensions directory (alfresco.war\jsp\extension), so I just updated the original jsp (alfresco.war\jsp\content).

    Craig, have you found the problem ?

  9. Dranakan Dranakan

    Hello,

    If you have problems to indicate to Alfresco that the jsp is in /jsp/extension/document-details.jsp
    (problems with faces-config.xml)

    Go here : http://forums.alfresco.com/en/viewtopic.php?f=10&t=20249&p=65779#p66019

  10. vinu vinu

    this link was very useful.

    can any one please tell me how to create a new task with java style ?, with creating properties,packages resources and transitions ???

    tnx
    vin

  11. la la

    Great post! One question — Which “example SDK custom JSP project”? Could you please post a link?
    Or please post a link to where it says *how to deploy/compile Java* in Alfresco.
    Thanks!

  12. Aaron Paxson Aaron Paxson

    Okay, this is a great post, but I’m quite eluded.

    With the nature of open source, and the fact that this post is not only 3 years old, but also linked from Alfresco’s website……..

    Why not include this in their current product? Quite frustrating, and I’m thinking about dropping Alfresco just because of this simple feature. Obviously there is a fix for it…. why not implement it?

  13. hl hl

    Hi Marc, you can I get this feature?

  14. hl hl

    sorry, I mean, How can I get this feature?

  15. Marc Marc

    hi,

    As was state. This post is over 3 years old. I have read my own post again and can only say that I think the full source is in this post itself… With some understanding of alfresco and the extension of alfresco, you should be able to use the given code in this post and create the widget yourself.

    Kind regards,

    Marc

  16. sleesuggisamb sleesuggisamb

    Ja, waarschijnlijk dus het is

  17. Kassey Kerns Kassey Kerns

    644 I just could not depart your site prior to suggesting that I actually enjoyed the standard info an individual provide on your guests? Is going to be again often to inspect new posts.