sfgroups
sfgroups

Reputation: 19099

groovy YAML delete few lines

Using groovy yaml parser I need delete below lines and write into the file.

lines to remove.

 - name: hostname
    required: true
    secure: false
    valueExposed: true

When I try to load the yaml data to map. its failing with 'org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object ' exception.

I am looking help on. How to load this yaml data and remove 4 lines from it.

import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.Yaml

class Test {
    def static main(args) {

        DumperOptions options = new DumperOptions()
        options.setPrettyFlow(true)
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK)
        Yaml yaml = new Yaml(options)
        def Map map = (Map) yaml.load(data)
        println yaml.dump(map)
    }


    def static String data = '''
- description: checkc the disk spacce
  executionEnabled: true
  loglevel: INFO
  name: disk spacce
  options:
  - description: file system name
    name: filesystem
    required: true
  - name: hostname
    required: true
    secure: false
    valueExposed: true
  scheduleEnabled: true
  sequence:
    commands:
    - exec: df -h
    keepgoing: false
'''
}

Upvotes: 0

Views: 1778

Answers (2)

Sachin
Sachin

Reputation: 1218

as already mentioned by @sandeep-poonia that cast exception was because of Map data type, you can refer to this code for parsing and removing those lines.

static Map dataToBeRemoved = [
        name        : 'hostname',
        required    : true,
        secure      : false,
        valueExposed: true
]

static def removeEntries
removeEntries = {def yaml ->
   if(yaml.getClass() == ArrayList){
      yaml = yaml.collect {
         removeEntries(it)
      }
      yaml = yaml.findAll{it} // remove empty items (list or map) from list. 
   } else if(yaml.getClass() == LinkedHashMap){
      if(!(dataToBeRemoved - yaml)){
         yaml = yaml - dataToBeRemoved
      }
      yaml.each{
         yaml[it.key] = removeEntries(it.value)
      }
   }
   yaml
}
   def static main(args){
        DumperOptions options = new DumperOptions()
        options.setPrettyFlow(true)
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK)
        Yaml yaml = new Yaml(options)
        List yamlData = yaml.load(data)
        yamlData = removeEntries(yamlData)
        println yaml.dump(yamlData)
    }

Upvotes: 0

Sandeep Poonia
Sandeep Poonia

Reputation: 2188

If you have looked into exception message carefully, you would have noticed that you are trying to convert a List into a Map, which would throw a ClassCastException. You surely need to read and understand the YAML structure as you made the same mistake in your previous question.

So to load the data into a list: List list = (List) yaml.load(data)

Now if you are sure about the structure of the yaml data, then you can remove the data in an ugly but direct way using list.first().options.remove(1).

Or you can iterate over the data and find the data that you need to remove and then remove it.

static Map dataToBeRemoved = [
        name        : 'hostname',
        required    : true,
        secure      : false,
        valueExposed: true
]

public static findAndRemoveMap(List list) {
    Object o
    ListIterator iterator = list.listIterator()
    while (iterator.hasNext()) {
        o = iterator.next()
        if (o instanceof Map) {
            if (compareJsonObjects(dataToBeRemoved, o)) {
                iterator.remove()
            } else {
                o.findAll { it.value instanceof List }.each {
                    findAndRemoveMap(it.value)
                }
            }
        } else if (o instanceof List) {
            findAndRemoveMap(o)
        }
    }
}

compareJsonObjects is a method that compares two maps and return whether they are equal or not. You can create your own implementation or can use an external library like jsonassert from skyscreamer. Using jsonassert, the implementation for compareJsonObjects would be:

public static boolean compareJsonObjects(Map<String, Object> obj_1, Map<String, Object> obj_2) {
    String one = new groovy.json.JsonBuilder(obj_1).toPrettyString()
    String two = new groovy.json.JsonBuilder(obj_2).toPrettyString()

    JSONCompareResult r = JSONCompare.compareJSON(one, two, JSONCompareMode.NON_EXTENSIBLE)
    return r.passed()
}

Upvotes: 1

Related Questions