Copy a Noderef – either Non-Recursive or Recursive

I am replacing the CrossRepositoryCopyService().copy action since we are going from multiple repo’s to one. So I am replacing this service..

// RECURSIVE copy – but specific for multiple repo’s.
serviceRegistry.getCrossRepositoryCopyService() .copy(src, dst,new_name);

 

So I started by re-using the FileFolderService to copy a node from A to B. This works great, but it only copies the node & leaves all children of the source untouched (and more importantly un-copied)  => Non-recursive copy. The FileFolderService() has no recursive copy action available.

// Non-RECURSIVE copy of one node
FileInfo finf = serviceRegistry.getFileFolderService().copy(src, dst, new_name);
return finf.getNodeRef();
There are quite a lot of copy actions available in Alfresco, but this one seems quite elegant. Also the service name alone gives me some hope of giving me what i need.
Enter the CopyService()

 

// RECURSIVE copy

NodeRef copy2 = serviceRegistry.getCopyService().copy(src, dst, ContentModel.ASSOC_CHILDREN, QName.createQName(new_name), true);

and since I am here now – it also has a usefull

// NON-RECURSIVE copy

NodeRef copy = this.copyService.copy(src, dst, ContentModel.ASSOC_CHILDREN, QName.createQName(“newname”));
Big thanks to : http://kickjava.com/

Creating my own document type in Share (3.4)

I want to create my own type of document in the share environment.

Let start with adding it to the contentmodel.xml
……………..
<type name=”mjb:tnsDocument”>
<title>TNS Document</title>
<parent>cm:content</parent>
<mandatory-aspects>
<aspect>mjb:documentProperties</aspect>
<aspect>mjb:regionable</aspect>
<aspect>mjb:collectionable</aspect>
<aspect>cm:versionable</aspect>
</mandatory-aspects>
</type>
…………………….

Next, add it to the web-client-config-custom.xml
…………………….
<config evaluator=”string-compare” condition=”Content Wizards”>
<content-types>
<type name=”mjb:tnsDocument” display-label=”TNS Document” />
</content-types>
</config>
…..++…………………….
<config evaluator=”string-compare” condition=”Action Wizards”>
<aspects>
</aspects>
<subtypes>
<type name=”mjb:tnsDocument” />
<!– // Shown in is-subtype condition –>
</subtypes>
<specialise-types>
<type name=”mjb:tnsDocument” />
</specialise-types>
……….+++……………………….
<config evaluator=”node-type” condition=”mjb:tnsDocument”>
<property-sheet>
<separator name=”tnsDocument” display-label=”TNS Document” component-generator=”HeaderSeparatorGenerator” />
</property-sheet>
</config>
…………………………………

 

 

Custom Action in Share

I`ll extract the information from here; http://ecmarchitect.com/images/articles/alfresco-actions/actions-article-2ed.pdf  and here: http://wiki.alfresco.com/wiki/Custom_Actions
This post = just to be able to quickly grab the files I need to change to add more buttons.

In the Share project (part of the my personal Eclipse setup)

/web/share/components/documentlibrary/recalculate-workflow-action.css

CONTENT:
.doclist .onActionXopus a {    background-image: url(plaatje-16.gif) !important; }

/web/share/components/documentlibrary/recalculate-workflow-action.js

CONTENT:

/** DocumentList “Recalculate Workflow ” action **/
(function() {
Alfresco.doclib.Actions.prototype.onActionRecalculateWorkflow = function DL_onActionRecalculateWorkflow(asset)  {
nodeRef = new Alfresco.util.NodeRef(asset.nodeRef);
alert(“comment MJB=” + file.nodeRef);
}
} )  ( ) ;

/config/web-extensions/site-webscripts/org/alfresco/components/documentlibrary/actions-common.get.head.ftl

…..add this line …..
<#– WF Action –>
<@link rel=”stylesheet” type=”text/css” href=”${page.url.context}/res/components/documentlibrary/recalculate-workflow-action.css” />
<script type=”text/javascript” src=”${page.url.context}/res/components/documentlibrary/recalculate-workflow-action.js”></script>
……………………………..

/config/web-extensions/site-webscripts/org/alfresco/components/documentlibrary/documentlist.get.config.xml

…..add this line …..
<action type=”action-link” id=”onActionRecalculateWorkflow” permission=”edit” label=”actions.document.recalculateWorkflow” />
…………………………

 

… there is still something missing here….

..  i’ll figure that out soon….

Date Calendar GregorianCalendar

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

 

If I extract a date from a node in Alfresco, I cannot cast directly to Calendar or GregorianCalendar. So I cast the Serializable return type from Alfresco to the Date class.
Date d = (java.util.Date) nodeService.getProperty(nr, INCENTROmodel.STARTDATE);

 

But java.util.Date is depricated since Java 1.1
The date.getTime() function still works.
It return the amount of ms since the beginning of time (aka 1 jan 1970)
long gt = d.getTime();

 

And the GregorianCalendar knows this. So
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(gt);

Post no. 3_million_and_1 about the java.util.Date / java.util.Calendar / java.util.GregorianCalendar

getting a boolean value from a Serializable return value (returned from nodeService.getProperty(X,Y);)

So this is the easy way to get a boolean value.

When all you have is a noderef with a boolean aspect (property)

boolean started = DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(noderef, INCENTROmodel.PROP_TASKPLAN_TASK_STARTED));

boolean stopped = DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(noderef, INCENTROmodel.PROP_TASKPLAN_TASK_ENDED));

Logging for scripts – javascript and java

log4j.logger.org.alfresco.repo.jscript.ScriptLogger=debug

=> This one allows me to see what comment are generated in my javascripts

log4j.logger.org.alfresco.repo.workflow=debug

=> This one give me feedback from my workflow process definition (.xml)

log4j.logger.com.incentro.companyx.script.WorkflowScriptHelper=debug

=> And this one allows me to log stuff in my own created java clasess

Workflow in Javascript.

I cant’ make it more clear than this person is doing – so here’s the link to his blog ;
http://thoughtworker.in/2008/05/29/alfresco-workflow-managed-by-javascript/

Also – this can explain quite a lot.
http://docs.jboss.com/jbpm/v3/userguide/taskmanagement.html#tasktimers

But I still can manage to assign a task to a certain user….
*frown*

This seems usefull information.

11.3.3. THE PERSONAL TASK LIST


The personal task list denotes all the task instances that are assigned to a specific individual. This is indicated with the property actorId on a TaskInstance. So to put a TaskInstance in someone’s personal task list, you just use one of the following ways:
  • Specify an expression in the attribute actor-id of the task element in the process
  • Use TaskInstance.setActorId(String) from anywhere in your code
  • Use assignable.setActorId(String) in an AssignmentHandle

However; Assignable, assignable and TaskInstance cannot be called directly in javascript.

…. <time passes>

…. < more time passes>

And I`m back to messing around with the swimlanes. It seems they have priority over setting parameter in bmp-assignee and other values. So I solved it like this;

<swimlane name=”assignee”>
<assignment class=”org.alfresco.repo.workflow.jbpm.AlfrescoAssignment”>
<actor>#{people.getPerson(“incentro”)}</actor>
</assignment>
</swimlane>

Lesson learned – This week I`ll close with a succesfull working workflow and next week i`ll start adding behaviour.

More workflows in Alfresco

Still working on workflows;

This is  good example to make a workflow with a lifecycle.

http://wiki.alfresco.com/wiki/WorkflowSample_Lifecycle

I only run into some issues with user authentication. If I start a workflow (as admin) on a txt document and refer it to a user (myself) there are some authentication errors. It might have something to do with this code;

<swimlane name=”reviewer”>
<assignment class=”org.alfresco.repo.workflow.jbpm.AlfrescoAssignment”>
<actor>#{bpm_assignee}</actor>
</assignment>
</swimlane>

I have no solution yet.. So back to research..