github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/src/com/sap/piper/MapUtils.groovy (about)

     1  package com.sap.piper
     2  
     3  class MapUtils implements Serializable {
     4      static boolean isMap(object){
     5          return object in Map
     6      }
     7  
     8      static Map pruneNulls(Map m) {
     9  
    10          Map result = [:]
    11  
    12          m = m ?: [:]
    13  
    14          m.each { key, value ->
    15              if(isMap(value))
    16                  result[key] = pruneNulls(value)
    17              else if(value != null)
    18                  result[key] = value
    19          }
    20          return result
    21      }
    22  
    23      /**
    24       * Merge two maps with the second one has precedence
    25       * @param base First map
    26       * @param overlay Second map, takes precedence
    27       * @return The merged map
    28       */
    29      static Map merge(Map base, Map overlay) {
    30  
    31          Map result = [:]
    32  
    33          base = base ?: [:]
    34  
    35          result.putAll(base)
    36  
    37          overlay.each { key, value ->
    38              result[key] = isMap(value) ? merge(base[key], value) : value
    39          }
    40          return result
    41      }
    42  
    43      /**
    44       * @param m The map to which the changed denoted by closure <code>strategy</code>
    45       *        should be applied.
    46       *        The strategy is also applied to all sub-maps contained as values
    47       *        in <code>m</code> in a recursive manner.
    48       * @param strategy Strategy applied to all non-map entries
    49       */
    50      static void traverse(Map m, Closure strategy) {
    51  
    52          def updates = [:]
    53          m.each { key, value ->
    54              if(isMap(value)) {
    55                  traverse(value, strategy)
    56              } else {
    57                  // do not update the map while it is traversed. Depending
    58                  // on the map implementation the behavior is undefined.
    59                  updates.put(key, strategy(value))
    60              }
    61          }
    62          m.putAll(updates)
    63      }
    64  
    65      static private def getByPath(Map m, def key) {
    66          List path = key in CharSequence ? key.tokenize('/') : key
    67  
    68          def value = m.get(path.head())
    69  
    70          if (path.size() == 1) return value
    71          if (value in Map) return getByPath(value, path.tail())
    72  
    73          return null
    74      }
    75  
    76      /*
    77       * Provides a new map with the same content like the original map.
    78       * Nested Collections and Maps are copied. Values with are not
    79       * Collections/Maps are not copied/cloned.
    80       * &lt;paranoia&gt;&/ltThe keys are also not copied/cloned, even if they are
    81       * Maps or Collections;paranoia&gt;
    82       */
    83      static deepCopy(Map original) {
    84          Map copy = [:]
    85          for (def e : original.entrySet()) {
    86              if(e.value == null) {
    87                  copy.put(e.key, e.value)
    88              } else {
    89                  copy.put(e.key, deepCopy(e.value))
    90              }
    91          }
    92          copy
    93      }
    94  
    95      /* private */ static deepCopy(Set original) {
    96          Set copy = []
    97          for(def e : original)
    98              copy << deepCopy(e)
    99          copy
   100      }
   101  
   102      /* private */ static deepCopy(List original) {
   103          List copy = []
   104          for(def e : original)
   105              copy << deepCopy(e)
   106          copy
   107      }
   108  
   109      /*
   110       * In fact not a copy, but a catch all for everything not matching
   111       * with the other signatures
   112       */
   113      /* private */ static deepCopy(def original) {
   114          original
   115      }
   116  }