# Thu, 20 Aug 2026 13:11:52 GMT
---
version: 23
data:


- type: Credential
  attributes:
    displayName: XDM Lookup Table Credential
    description: Credential for XDM Lookup Table
    user: sa
    password: ""

- type: MappingTableContainer
  attributes:
    displayName: XDM Lookup Table
    description: Mapping table to use the xdm lookup tables
    variableName: lookupTable
    credential: XDM Lookup Table Credential

- type: ModificationMethod
  attributes:
    displayName: Latitude
    description: |
          Generates a latitude component of geographical coordinates based on the specified seed value.
          The country parameter specifies the country/region of origin ('US', 'DE', 'FR', 'IT', 'NL', 'AT', 'BE', 'CA', 'CH', 'UK').
          Only a single country value can be specified (e.g. 'DE').
          *This method requires the lookup tables to be installed.*
    scriptLanguage: "GROOVY"
    legacyScript: false
    inputType: "COLUMN"
    mappingTableContainers:
      - "XDM Lookup Table"
    mappingTableAccessMode: READ
    code: |
        /*
         * *****************************************************************************
         * Latitude
         * *****************************************************************************
         *
         * The following variables are available in this script:
         * =====================================================
         * ctx             : A context object that offers a number of methods.
         *                   The method indexOf() can be used to get the index of a
         *                   specific column within the data.
         * data       : The data array. This array contains the contents of all
         *                   columns of the current row of the table that is being
         *                   masked by this method.
         *
         * Additionally for column based modification methods the following two
         * variables are available:
         * columnName      : The name of the column that matched the pattern.
         * columnIndex     : The position of the column that matched the pattern within
         *                   the data array. This value is zero-based.
         * *****************************************************************************
         */
        import de.ubs.xdm3.batch.modification.MappingTableUtils
        import de.ubs.xdm3.batch.modification.ModificationException
        import de.ubs.xdm3.batch.modification.CompositeKey
        import de.ubs.xdm3.batch.modification.HashUtils
        
        TABLE_NAME = 'ADDRESSES';
        countMap = [:]
        mappingTableUtils = new MappingTableUtils(lookupTable)
        
        /*
         * This function is called once before the processing starts. The method
         * is called once per table.
         */
        def init() {
            // Pre-calculate, for each country (KEY_01), how many rows exist in the lookup table.
            // The result is stored in countMap and used later to compute a valid row number.
            countMap = mappingTableUtils.count(TABLE_NAME, "KEY_01")
        
            return null
        }
        
        
        /*
         * This function should modify the row that is provided by the data. The
         * method is called for each single row of the table.
         */
        def apply() {
            // The configured seed is hashed twice to prevent deriving the original seed value
            def seedHash = HashUtils.hashInt(HashUtils.hashStringLikeInt(modificationMethod.seed.toString()))
        
            // Country parameter configured on the modification set
            def countryValue = modificationMethod.country.toString()
        
            // Check how many lookup entries exist for the selected country
            def count = countMap.get(new CompositeKey(countryValue))
            if (count == null || count <= 0) {
                throw new ModificationException("No entries for country ='${modificationMethod.country}'.")
            }
        
            // Compute a 1-based row number within the lookup table
            // based on the hashed seed and the number of available entries for that country.
            def rowNumber = (seedHash % count) + 1
        
            // Fetch the selected row from the lookup table for the given country.
            def result = mappingTableUtils.get(TABLE_NAME, rowNumber, countryValue)
            if (result == null) {
                throw new ModificationException("Failed to retrieve data from table ${TABLE_NAME}")
            }
        
            // Use the value from the lookup result to overwrite the current column value.
            data[columnIndex] = result[4]
            return true
        }
        
        /*
         * This function is executed once after the modification of a table is complete. The method
         * is called once per table.
         */
        def close() {
            mappingTableUtils.close()
        }
    parameters:
    - displayName: Seed
      description: |
          Column that is used to calculate the hash.
      variableName: seed
      dataType: STRING
    - displayName: Country
      description: |
          Specifies the origin of the latitude.
      variableName: country
      dataType: STRING
