AnsweredAssumed Answered

Recursive Function Groovy

Question asked by peter.barnes580504 on Nov 27, 2017
Latest reply on Nov 27, 2017 by peter.barnes580504

Is it possible to define a recursive function as a custom scripting step in a data process shape. I have a need to build a tree from a flat list, so that we can extract the full path to each node as a concatenation of the name of each accessor.

I have created a function in groovy that can perform the transformation, however boomi gives a runtime error on the step.

 

Below is the code, it errors "Script2.groovy: 18: unexpected token: traverse @ line 17, column 3"

 

import java.util.Properties;
import java.io.InputStream;
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import java.util.logging.Logger;

Logger logger = ExecutionUtil.getBaseLogger();

def jsonSlurper = new JsonSlurper()


for( int i = 0; i < dataContext.getDataCount(); i++ ) {
  InputStream is = dataContext.getStream(i);
  Properties props = dataContext.getProperties(i);

  def array = jsonSlurper.parseText(is.getText("UTF-8")

  traverse(array)
  def json = JsonOutput.toJson(array)

  logger.info(JsonOutput.prettyPrint(json));
  dataContext.storeStream(is, props);
}

def traverse(array, item=null) {
    def parent_id = item?.id
    def parent_path = item?.path ?: ''
    children = array.findAll { it.parent_id == parent_id }
    if (children.length == 0) return;
    children.collect {
        it.path = parent_path ? parent_path + '/' + it.name : it.name
        traverse(array, it)
    }
}

 

Does anyone know if function declarations are supported and if so why this is giving an error? If its not supported, does anyone know another way to do this.

 

The input data looks as follows 

 {
  "cost_centers": [
    {
      "id": 1540749,
      "name": "Cost Center 3"
    },
    {
      "id": 1540929,
      "parent_id": 1540749,
      "name": "CC3_1",
      "payroll_code": "546",
      "external_id": "213"
    },
    {
      "id": 1540930,
      "parent_id": 1540749,
      "name": "CC3_2",
      "description": "Description for CC3_2",
      "payroll_code": "78"
    },
    {
      "id": 1540931,
      "parent_id": 1540929,
      "name": "CC3_1.1",
      "external_id": "123"
    },
    {
      "id": 1540932,
      "parent_id": 1540930,
      "name": "CC3_2.1",
      "description": "Description for CC3_2.1",
      "payroll_code": "89",
      "external_id": "9"
    },
    {
      "id": 1540933,
      "parent_id": 1540929,
      "name": "CC3_1.2"
    }
  ]
}

 

The required output is effectively a name value pair

1540749, Cost Center 3
1540929, Cost Center 3 / CC3_1
1540930, Cost Center 3 / CC3_2
1540931, Cost Center 3 / CC3_1 / CC3_1.1
1540932, Cost Center 3 / CC3_2 / CC3_2.1
1540933, Cost Center 3 / CC3_1 / CC3_1.2

Outcomes