All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.societegenerale.githubcrawler.parsers.YamlParserForPropertyValue.kt Maven / Gradle / Ivy

There is a newer version: 2.2.0
Show newest version
package com.societegenerale.githubcrawler.parsers

import com.societegenerale.githubcrawler.IndicatorDefinition
import org.springframework.stereotype.Component
import org.yaml.snakeyaml.Yaml

@Component
class YamlParserForPropertyValue : FileContentParser {

    companion object {
        const val FIND_PROPERTY_VALUE_IN_YAML = "findPropertyValueInYamlFile"
        const val PROPERTY_NAME = "propertyName"
    }

    override fun getNameInConfig(): String {
        return FIND_PROPERTY_VALUE_IN_YAML
    }

    override fun parseFileContentForIndicator(fileContent: String, pathToFileToGetIndicatorsFrom:String, kpi: IndicatorDefinition): Map {

        return internalParseFileContentForIndicator(fileContent,kpi)
    }

     fun internalParseFileContentForIndicator(fileContent: String, kpi: IndicatorDefinition): Map {

        val yamlDocuments = Yaml().loadAll(fileContent)

        val result = HashMap()

        //TODO write a config validation rule making sure that property name is always provided
        val propertyName = kpi.params.get(PROPERTY_NAME)!!

        yamlDocuments.forEach {

            val yamlDocument = it as Map

            try {

                result.put(kpi.name, yamlDocument.get(propertyName)?.toString() ?: parseForNestedProperties(yamlDocument, propertyName))
            } catch (e: PrefixNotFoundInDocumentException) {
                //do nothing, iterate to next document if any
            }

            if (result.isNotEmpty()) {
                //returning the result found in first document
                return result;
            }

        }

        return result
    }

    private fun parseForNestedProperties(content: Map, propertyName: String): String {

        val propertyNameComponents = propertyName.split(".")

        val propertyPrefix = propertyNameComponents[0]

        var matchingValue : Any? = null

        var nbOfProperties : Int = 0

        while(matchingValue==null && nbOfProperties<=propertyNameComponents.size){

            //building the property name incrementally
            var tmpPropertyName = propertyNameComponents.subList(0, nbOfProperties).joinToString(".")

            matchingValue = content.get(tmpPropertyName)
            nbOfProperties++
        }

        //TODO refactor this part.. it probably doesn't work for all scenarios
        if (matchingValue == null) {
           throw PrefixNotFoundInDocumentException("can't find property 'starting with' or '' $propertyPrefix")
        }

        return when (matchingValue) {

            is String -> matchingValue

            is Boolean -> matchingValue.toString()

            is Map<*, *> -> {

                val recombinedPropertyNameWithoutFirstElement = propertyNameComponents.subList(1, propertyNameComponents.size).joinToString(".")

                //TODO see why explicit cast is required, while it should be implicit
                return parseForNestedProperties(matchingValue as Map, recombinedPropertyNameWithoutFirstElement)

            }

            else -> throw ParsingException("don't know  how to process this " + matchingValue)

        }
    }

}

class PrefixNotFoundInDocumentException(message: String) : Throwable()

class ParsingException(message: String) : Throwable()




© 2015 - 2024 Weber Informatics LLC | Privacy Policy