cancel
Showing results for 
Search instead for 
Did you mean: 

How to remove bpm_package items programmatically

francesco_lilli
Champ in-the-making
Champ in-the-making
Hi all,

after a task rejection I need to remove one (it's the only one) package item programmatically. After that, I will choose my new file and continue with my workflow. The problem is NOT with the new file I'm adding, but with the old one which is not removed correctly.

In the user task I tried:


   <activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
      <activiti:field name="script">
         <activiti:string>
            logger.log("TRYING TO REMOVE OLD (REJECTED) PACKAGE ITEM…");
            execution.setVariable('bpm_package', null);
         </activiti:string>
      </activiti:field>
   </activiti:taskListener>
   <activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
      <activiti:field name="script">
          <activiti:string>
               logger.log("TRYING TO SET NEW PACKAGE ITEM…");
               execution.setVariable('bpm_package', task.getVariable('bpm_package'));
            </activiti:string>
          </activiti:field>
        </activiti:taskListener>


This does not work as it still tries to point to a node which does not exist anymore. So I tried:


   <activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
      <activiti:field name="script">
         <activiti:string>
            logger.log("TRYING TO REMOVE OLD (REJECTED) PACKAGE ITEM…");
            execution.removeVariable('bpm_package');
         </activiti:string>
      </activiti:field>
   </activiti:taskListener>
   <activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
      <activiti:field name="script">
          <activiti:string>
               logger.log("TRYING TO SET NEW PACKAGE ITEM…");
               execution.setVariable('bpm_package', task.getVariable('bpm_package'));
            </activiti:string>
          </activiti:field>
        </activiti:taskListener>


More or less same issue. And:


   <activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
      <activiti:field name="script">
         <activiti:string>
            logger.log("TRYING TO REMOVE OLD (REJECTED) PACKAGE ITEM…");
            var input_package = execution.getVariable('bpm_package');
            input_package.remove();
            execution.setVariable('bpm_package', input_package);
         </activiti:string>
      </activiti:field>
   </activiti:taskListener>
   <activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
      <activiti:field name="script">
          <activiti:string>
               logger.log("TRYING TO SET NEW PACKAGE ITEM…");
               execution.setVariable('bpm_package', task.getVariable('bpm_package'));
            </activiti:string>
          </activiti:field>
        </activiti:taskListener>


Which still does not work. I have the impression I'm missing something out there. Any idea?

12 REPLIES 12

frederikherema1
Star Contributor
Star Contributor
Do not delete the bpm_package variable. The package should be kept, it's connected forever to the worklfow-instance. Rather, you can modify the children of the package. The bpm_package is actually an ActivitiScriptNode (http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/COMMUNITYTAGS/V4.2c/root/projects/reposi...), so you can do all kinds of cool stuff like listing children/properties and altering them.

So you should manipulate the children of the package, rather than replacing the package itself…

I value the blog.Really looking forward to read more. Keep writing.
[ <a href="http://droz-garciniacambogia.org">Dr Oz Garcinia Cambogia</a> ]
[ <a href="http://wheretobuy-garcinia-cambogia.com">where to buy garcinia cambogia</a> ]
[ <a href="http://garciniacambogiawow.org/diabacor">Diabacor</a> ]

to realize results, and fast. The blood serum contains 5 evidenced ingredients for skin health, improvement, and restoration. each ingredient employed in the merchandise works in synthesis to supply you with wonderful results.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=>>>> more info-> <a href="http://dermalloantiaging.blog.com">http://dermalloantiaging.blog.com</a>

frederikherema1
Star Contributor
Star Contributor
Feel free to share your solution here Smiley Wink

francesco_lilli
Champ in-the-making
Champ in-the-making
I also attempted a Javascript-only approach:

<javascript>
var input_package = execution.getVariable('bpm_package');
logger.log("INPUT_PACKAGE BEFORE");
logger.log(input_package.getChildren());
input_package.children[0] = null;
logger.log("INPUT_PACKAGE AFTER");
logger.log(input_package.getChildren());
input_package.save();
execution.setVariable('bpm_package', input_package);
logger.log("DONE");
</javascript>

Logs are, again:

<code>
00:41:57,192 DEBUG [org.alfresco.repo.jscript.ScriptLogger] INPUT_PACKAGE BEFORE
00:41:57,196 DEBUG [org.alfresco.repo.jscript.ScriptLogger] Node Type: {http://www.alfresco.org/model/content/1.0}content, Node Aspects: [{http://www.alfresco.org/model/content/1.0}auditable, {http://www.alfresco.org/model/content/1.0}thumbnailModification, {http://www.alfresco.org/model/system/1.0}referenceable, {http://www.alfresco.org/model/content/1.0}titled, {http://www.alfresco.org/model/content/1.0}author, {http://www.alfresco.org/model/content/1.0}taggable, {http://www.alfresco.org/model/rendition/1.0}renditioned, {http://www.alfresco.org/model/system/1.0}localized]
00:41:57,196 DEBUG [org.alfresco.repo.jscript.ScriptLogger] INPUT_PACKAGE AFTER
00:41:57,196 DEBUG [org.alfresco.repo.jscript.ScriptLogger]
00:41:57,198 DEBUG [org.alfresco.repo.jscript.ScriptLogger] DONE
</code>

But in the next task I still get the old file, like nothing happened. Is there something I should know? Like variables that are not REALLY editable?

francesco_lilli
Champ in-the-making
Champ in-the-making
oh, instructions
<java>
ScriptableObject children = (ScriptableObject)inputPackage.getChildren();
</java>
and
<java>
children = (ScriptableObject)inputPackage.getChildren();
</java>
are there just for debugging purposes. Everything seems to be fine even Java-side. Any suggestions?


EDIT: In Java I could debug my code using Eclipse IDE. In the first screenshot you can see the runtime value of the variable "children", before the "delete" instruction is performed:

[img]http://s28.postimg.org/ennsfu8kp/children_before.png[/img]

And here's what I see after "delete" is performed:

[img]http://s28.postimg.org/q1abr1j3d/children_after.png[/img]

I'm not sure whether to consider that red "Unique Tag" a bad sign, but at least I know that the old node was actually removed.

francesco_lilli
Champ in-the-making
Champ in-the-making
Mh, I'm still having issues…

this is what I do in my JS code (user task code):

<code>
var input_package = execution.getVariable('bpm_package');
logger.log("INPUT_PACKAGE BEFORE");
logger.log(input_package.getChildren());
input_package = MyJavaClass.resetWorkflowItem(input_package);
logger.log("INPUT_PACKAGE AFTER");
logger.log(input_package.getChildren());
execution.setVariable('bpm_package', input_package);
logger.log("DONE");
</code>

where in MyJavaClass (Spring injection) there's this method:

<java>
public ActivitiScriptNode resetWorkflowItem(ActivitiScriptNode inputPackage) {
  ScriptableObject children = (ScriptableObject)inputPackage.getChildren();
  inputPackage.getChildren().delete(0);
  children = (ScriptableObject)inputPackage.getChildren();
  return inputPackage;
}
</java>

Javascript-side logs are:

<code>
18:33:15,097 DEBUG [org.alfresco.repo.jscript.ScriptLogger] INPUT_PACKAGE BEFORE
18:33:15,106 DEBUG [org.alfresco.repo.jscript.ScriptLogger] Node Type: {http://www.alfresco.org/model/content/1.0}content, Node Aspects: [{http://www.alfresco.org/model/content/1.0}auditable, {http://www.alfresco.org/model/content/1.0}thumbnailModification, {http://www.alfresco.org/model/system/1.0}referenceable, {http://www.alfresco.org/model/content/1.0}titled, {http://www.alfresco.org/model/content/1.0}author, {http://www.alfresco.org/model/content/1.0}taggable, {http://www.alfresco.org/model/rendition/1.0}renditioned, {http://www.alfresco.org/model/system/1.0}localized]
18:37:15,542 DEBUG [org.alfresco.repo.jscript.ScriptLogger] INPUT_PACKAGE AFTER
18:37:15,542 DEBUG [org.alfresco.repo.jscript.ScriptLogger]
18:37:15,542 DEBUG [org.alfresco.repo.jscript.ScriptLogger] DONE
</code>

So seems like it actually did delete the first child, but going back to the workflow it's still there…


frederikherema1
Star Contributor
Star Contributor
Storing the bpm_package agian (using setVariable) has no effect, as activiti only keeps a reference to the package-node (a node-ref). So you should use the appropriate services/method calls to remove children from the package itself, not re-setting the variable.

Re-assigning the input_package.children[0] to null doesn't have any effect, since the children-array is cached on the Scriptable object, but changes to it are not reflected in the DB. You should call input_package.remove(input_package.children[0], I guess:


/**
     * Remove an existing child node of this node.
     *
     * Severs all parent-child relationships between two nodes.
     * <p>
     * The child node will be cascade deleted if one of the associations was the
     * primary association, i.e. the one with which the child node was created.
     *
     * Beware: Any unsaved property changes will be lost when this is called.  To preserve property changes call {@link save()} first.
     *   
     * @param node  child node to remove
     */
    public void removeNode(ScriptNode node)
    {

francesco_lilli
Champ in-the-making
Champ in-the-making
You are perfectly right, I have tried many methods in ScriptNode but I wasn't doing stuff correctly. The solution is indeed extremely simple.

my-workflow.bpmn20.xml:
<code>

var input_package = execution.getVariable('bpm_package');
MyJavaClass.resetWorkflowItem(input_package);

</code>
MyJavaClass.java:
<java>

public void resetWorkflowItem(ActivitiScriptNode workflowPackage) {
NativeArray children = (NativeArray)workflowPackage.getChildren();
ScriptNode firstChild = (ScriptNode)children.get(0, null);
// firstChild.remove(); ::::: THIS WOULD ACTUALLY REMOVE THE NODE (E.G. FROM ALFRESCO)!
workflowPackage.removeNode(firstChild);
        workflowPackage.save();
}

</java>

Thanks a lot for the tips!
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.