cancel
Showing results for 
Search instead for 
Did you mean: 

Create / Edit Rule with Script?

e-manuel
Champ on-the-rise
Champ on-the-rise
Hi,

is it possible to create a script (Javascript/Webscript/…) to create Space-Rules or to edit them?

I have many many spaces (about 200 - 250) and i want to apply "notification-email-rules" to all these spaces.
I also want to edit other rules, there are already in some spaces (also rules, that sends emails to space-users on "any item").

How can i do this?
Example: In the Webclient, i would select "Create Rule", Condition="All Items", Action="Send an email to specified users", Value="Group_testgroup", Subject="New Document", Template="new_doc_template.ftl".

I already created all spaces and subspaces with a Javascript.

regards
Manuel

ps.: it's Alfresco 2.1
14 REPLIES 14

dc_noze
Champ in-the-making
Champ in-the-making
Hi guys,
i was looking for a solution and i finally came up with this one. I hope could help.


var jsonRule = {
   title: "Sample Rule",
   description: "Sample rule creation",
   ruleType: ["inbound"],
   applyToChildren: true,
   executeAsynchronously: false,
   disabled: false,
   action :
   {
      actionDefinitionName: "composite-action",
      actions:
      [
         {
            actionDefinitionName: "script",
            parameterValues:
            {
               'script-ref': "workspace://SpacesStore/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
            }
         }
      ],
      conditions:
      [
         {
            conditionDefinitionName: "no-condition",
            parameterValues: {}
         }
      ]
   }
};

var jsonRuleBody = jsonUtils.toJSONString(jsonRule);


var uri = '/api/node/workspace/SpacesStore/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/ruleset/rules';
uri += '?alf_ticket=' + session.getTicket();

var rsp = remote.connect('alfresco').post(uri, jsonRuleBody, 'application/json');

To have this to work you have to configure the remote object to works with the repository.You can find information here: http://forums.alfresco.com/en/viewtopic.php?f=36&t=27962&p=101380

I have tested this solution on Alfresco3.3g, but this should work either on 3.0.
Here you can find reference to remote object: http://wiki.alfresco.com/wiki/Surf_Platform_-_Freemarker_Template_and_JavaScript_API#remote
Here reference about rule object: http://wiki.alfresco.com/wiki/Rule_REST_API_Design_Notes

Happy coding!

sjeandroz
Champ in-the-making
Champ in-the-making
Hi,
I want to create a rule on a node, from a java backed web script…
I tried the code below in my script but some function are undefined (eg getActionService())
Can someone help me please, I'm a noob on alfresco's java developpment,
You can create rules programatically by using the following java code.
I don't know how to do it wid javascript.
For ex: If u want to create rule which converts the arriving document to pdf, u can do it programmatically as follows.

private void setupSpaceRuleConvToPDF(NodeRef data){
      
      Rule rule=new Rule();
      
       rule.setRuleType("inbound");
       rule.setTitle("Transform to PDF n copy to Data-PDF");
       rule.setDescription("Transform to PDF n copy to Data-PDF");
            rule.applyToChildren(false);
          // rule.setExecuteAsynchronously(true);
        System.out.println("Rule creation started…Part-II");
        CompositeAction compositeAction = getActionService().createCompositeAction();
        rule.setAction(compositeAction);
        ActionCondition actionCondition = getActionService().createActionCondition("no-condition");
        actionCondition.setParameterValues(new HashMap());
        compositeAction.addActionCondition(actionCondition);
        IHandler handler=null;
        Map repoActionParams = new HashMap();
        Map actionParams=new HashMap();
       
        NodeRef destination = new NodeRef(Repository.getStoreRef(),(String)getNodeService().getProperty(data, ContentModel.ASPECT_COPIEDFROM));
       
       
       
        actionParams.put("actionName", "transform");
        actionParams.put("transformer", "application/pdf");
        actionParams.put("destinationLocation",destination); // prntDestinationNodeRef
      actionParams.put("actionSummary", "Transform and copy content to a specific space");
      try {
          handler=(IHandler)Class.forName("org.alfresco.web.bean.actions.handlers.TransformHandler").newInstance();
      } catch (Exception e) {
         System.out.println("Class Generation Exception:"+e);
      }
      if(handler != null){
         handler.prepareForSave(actionParams, repoActionParams);
      }
       //System.out.println("B4 saving action");
      Action action = getActionService().createAction("transform");
      action.setParameterValues(repoActionParams);
        compositeAction.addAction(action);
        getRuleService().saveRule(data, rule);
   }

Thanks!

wass
Champ in-the-making
Champ in-the-making
i'm with sjeandroz's same problem

anyone can help?

thanks.

Will.

Hi,
I want to create a rule on a node, from a java backed web script…
I tried the code below in my script but some function are undefined (eg getActionService())
Can someone help me please, I'm a noob on alfresco's java developpment,
You can create rules programatically by using the following java code.
I don't know how to do it wid javascript.
For ex: If u want to create rule which converts the arriving document to pdf, u can do it programmatically as follows.

private void setupSpaceRuleConvToPDF(NodeRef data){
      
      Rule rule=new Rule();
      
       rule.setRuleType("inbound");
       rule.setTitle("Transform to PDF n copy to Data-PDF");
       rule.setDescription("Transform to PDF n copy to Data-PDF");
            rule.applyToChildren(false);
          // rule.setExecuteAsynchronously(true);
        System.out.println("Rule creation started…Part-II");
        CompositeAction compositeAction = getActionService().createCompositeAction();
        rule.setAction(compositeAction);
        ActionCondition actionCondition = getActionService().createActionCondition("no-condition");
        actionCondition.setParameterValues(new HashMap());
        compositeAction.addActionCondition(actionCondition);
        IHandler handler=null;
        Map repoActionParams = new HashMap();
        Map actionParams=new HashMap();
       
        NodeRef destination = new NodeRef(Repository.getStoreRef(),(String)getNodeService().getProperty(data, ContentModel.ASPECT_COPIEDFROM));
       
       
       
        actionParams.put("actionName", "transform");
        actionParams.put("transformer", "application/pdf");
        actionParams.put("destinationLocation",destination); // prntDestinationNodeRef
      actionParams.put("actionSummary", "Transform and copy content to a specific space");
      try {
          handler=(IHandler)Class.forName("org.alfresco.web.bean.actions.handlers.TransformHandler").newInstance();
      } catch (Exception e) {
         System.out.println("Class Generation Exception:"+e);
      }
      if(handler != null){
         handler.prepareForSave(actionParams, repoActionParams);
      }
       //System.out.println("B4 saving action");
      Action action = getActionService().createAction("transform");
      action.setParameterValues(repoActionParams);
        compositeAction.addAction(action);
        getRuleService().saveRule(data, rule);
   }

Thanks!

acarpine
Champ in-the-making
Champ in-the-making
The snippet use the getActionService() method of Repository class to obtain AstionService, RuleService…
For example in my case I injected services using Spring. In your cases you could use
Repository.getActionService()

and all should work correctly.

I hope this help
Andrea

nickburch
Confirmed Champ
Confirmed Champ
A few hours ago, I thought I'd knock up a quick script to create some rules for me, while dinner cooked. Turned out to not be nearly as easy as I'd thought, as others here have found. However…. Not out of the box, but you can do it with some tweaks. You really really shouldn't, would be my advice after those hours, but you can…

First up, you need to inject the
ServiceRegistry
to your JavaScript somehow, and you need to use the <a href="https://github.com/share-extras/js-console">JavaScript Console</a>. I would advise against injecting the
ServiceRegistry
as a root object, as that opens up a huge can of security worms. Injecting your own bean, which does some security checks (eg admin only) is less bad, but still a little evil. Take care, and/or don't go there to start with… Or just inject in the action and rules services securely. Next up, you need to work out the action parameters and condition parameters. These are not fun to do by hand, best bet is to set up a rule much like you want with the UI, then use the node browser to see how that gets turned into composites and name/values.

Assuming you've <em>safely</em> injected in the service registry, and you (say) want to create a folder based on this month in a site + add a rule to it which will run a script if a non-zero sized file with a name that starts "Completed" is uploaded/created there, you can do so with a JS Console script like this:

<javascript>
var sitename = "my-rules-test";
var rulesSite = siteService.getSite("sitename");
if (rulesSite == null) {
   throw "No rules site found: " + sitename;
}
var doclib = rulesSite.getContainer("documentLibrary");

// TODO Inject in the service registry *securely* here
var services = myExtension.securelyGetServices();
// Get the services we need
var ruleService = services.getRuleService();
var actionService = services.getActionService();

// When are we running for? This month, or next?
var whenFor = new Date();
if (whenFor.getDate() >= 15) {
   whenFor.setMonth(whenFor.getMonth()+1);
}
whenFor.setDate(1);
// Get the friendly date names
var nameFmt = new java.text.SimpleDateFormat("YYYY-MM");
var monthFmt = new java.text.SimpleDateFormat("MMMM");
var monthName = monthFmt.format(whenFor);

// To find the NodeRef of a Data Dictionary script
function getScriptNodeRef(name) {
   var scriptsHome = companyhome.childByNamePath("Data Dictionary/Scripts");
   var script = scriptsHome.childByNamePath(name);
   if (script == null) {
      throw "Script not found in Data Dictionary '" + name + "'";
   }
   return script.getNodeRef();
}
// To make a QName
function makeQName(qname) {
   if (qname.indexOf("{") > -1 && qname.indexOf("}") > -1) {
      return Packages.org.alfresco.service.namespace.QName.createQName(qname);
   }
   return Packages.org.alfresco.service.namespace.QName.createQName(qname, services.getNamespaceService());
}

// Create the year folder if needed
var yearFolder = doclib.childByNamePath(year);
if (yearFolder == null) {
   logger.log("Creating year folder " + year);
   yearFolder = doclib.createFolder(year);
} else {
   logger.log(year + " available as " + yearFolder.getNodeRef());
}

// Is the month folder already there?
var folderName = nameFmt.format(whenFor);
var monthFolder = yearFolder.childByNamePath(folderName);
if (monthFolder == null) {
   logger.log("Creating folder for month " + folderName);
   monthFolder = yearFolder.createFolder(folderName);
   monthFolder.properties["cm:title"] = monthName + " " + year + " Reports";
   monthFolder.save();

   // Setup the rule on it, for when it's "complete"
   var rule = new Packages.org.alfresco.service.cmr.rule.Rule();
   rule.setTitle("Remove Permissions When Complete");
   rule.setDescription("When the Complete file is created, remove the permissions");
   rule.applyToChildren(false);
   rule.setRuleType("inbound");

   // Create our conditions
   var condition1 = actionService.createActionCondition("compare-property-value");
   var condition2 = actionService.createActionCondition("compare-property-value");
   condition1.setParameterValue("operation","BEGINS");
   condition1.setParameterValue("value","Complete");
   condition1.setParameterValue("property",makeQName("cm:name"));
   condition2.setParameterValue("operation","GREATER_THAN");
   condition2.setParameterValue("content-property","SIZE");
   condition2.setParameterValue("value",0);
   condition2.setParameterValue("property",makeQName("cm:content"));

   // For all files, we'd use this instead
   var noCondition = actionService.createActionCondition("no-condition");
   noCondition.setParameterValues(Packages.java.util.Collections.emptyMap());

   // Setup the action
   var action = actionService.createCompositeAction();
   action.addActionCondition(condition1);
   action.addActionCondition(condition2);
   var saction = actionService.createAction("script");
   saction.setParameterValue("script-ref", getScriptNodeRef("do-restrict-permissions.js"));
   action.addAction(saction);

   rule.setAction(action);
   ruleService.saveRule(folderName.getNodeRef(), rule);
} else {
   logger.log(folderName + " available as " + monthFolder.getNodeRef());
}
</javascript>

Run that today, and it'll create a <em>2015/August 2015 Reports</em> folder, run it after the 15th for <em>2015/September 2015 Reports</em>, tweak logic as needed! It'll apply the rule to it. Injecting the services (safely!) is the hard bit, so it won't work out of the box, but can be done. But probably shouldn't…!