diff --git a/biopet-utils/src/main/scala/nl/lumc/sasc/biopet/utils/ConfigUtils.scala b/biopet-utils/src/main/scala/nl/lumc/sasc/biopet/utils/ConfigUtils.scala index 9dd5c884c9f392bd30c7179c15abbda871a7233b..dea70caf2b77dcf17fb2198d856203a5dd6157cb 100644 --- a/biopet-utils/src/main/scala/nl/lumc/sasc/biopet/utils/ConfigUtils.scala +++ b/biopet-utils/src/main/scala/nl/lumc/sasc/biopet/utils/ConfigUtils.scala @@ -30,6 +30,34 @@ import scala.collection.JavaConversions._ * */ object ConfigUtils extends Logging { + /** + * This method give back all nested values that does exist in map1 but not in map2 + * + * @param map1 input map + * @param map2 input map + * @return Uniqe map1 + */ + def uniqueKeys(map1: Map[String, Any], map2: Map[String, Any]): Map[String, Any] = { + filterEmtpyMapValues(map1 + .flatMap { + case (key, value: Map[_, _]) => Some(key -> uniqueKeys(value.asInstanceOf[Map[String, Any]], map2.getOrElse(key, Map()).asInstanceOf[Map[String, Any]])) + case (key, value) if !map2.contains(key) => Some(key -> value) + case _ => None + }) + } + + /** + * Filter values that are a map but are empty + * @param map input map + * @return output map + */ + def filterEmtpyMapValues(map: Map[String, Any]): Map[String, Any] = { + map.filter { + case (key, value: Map[_, _]) => value.nonEmpty + case _ => true + } + } + /** * Merge 2 maps, when value is in a map in map1 and map2 the value calls recursively this function * @param map1 Prio over map2 diff --git a/biopet-utils/src/main/scala/nl/lumc/sasc/biopet/utils/config/Config.scala b/biopet-utils/src/main/scala/nl/lumc/sasc/biopet/utils/config/Config.scala index bb0aee504100004e8231de189662089a5c162de2..3569a5dbef59b56a6a48330bc25ea4c52126519e 100644 --- a/biopet-utils/src/main/scala/nl/lumc/sasc/biopet/utils/config/Config.scala +++ b/biopet-utils/src/main/scala/nl/lumc/sasc/biopet/utils/config/Config.scala @@ -215,6 +215,17 @@ class Config(protected var _map: Map[String, Any], // Positions where values are found val found = convertIndexValuesToMap(foundCache.filter(!_._2.default).toList.map(x => (x._2.foundIndex, x._2.value))) val fixed = convertIndexValuesToMap(fixedCache.filter(!_._2.default).toList.map(x => (x._2.foundIndex, x._2.value))) + val unused = uniqueKeys(map, found) + + def reportUnused(map: Map[String, Any], path: List[String] = Nil): Unit = { + map.foreach { + case (key, value: Map[_, _]) => reportUnused(value.asInstanceOf[Map[String, Any]], path :+ key) + case (key, value) => logger.warn(s"config key in user config is never used, key: $key" + + (if (path.nonEmpty) s", path: ${path.mkString(" -> ")}" else "")) + } + } + + reportUnused(unused) // Positions where to start searching val effectiveFound = convertIndexValuesToMap(foundCache.filter(!_._2.default).toList.map(x => (x._2.requestIndex, x._2.value)), Some(false)) @@ -226,7 +237,8 @@ class Config(protected var _map: Map[String, Any], val fullEffective = ConfigUtils.mergeMaps(effectiveFound, effectiveDefaultFound) val fullEffectiveWithNotFound = ConfigUtils.mergeMaps(fullEffective, notFound) - writeMapToJsonFile(_map, "input") + writeMapToJsonFile(map, "input") + writeMapToJsonFile(unused, "unused") writeMapToJsonFile(_defaults, "defaults") writeMapToJsonFile(found, "found") writeMapToJsonFile(fixed, "fixed") @@ -238,7 +250,7 @@ class Config(protected var _map: Map[String, Any], writeMapToJsonFile(fullEffectiveWithNotFound, "effective.full.notfound") } - override def toString: String = _map.toString() + override def toString: String = map.toString() } object Config extends Logging { diff --git a/biopet-utils/src/test/scala/nl/lumc/sasc/biopet/utils/ConfigUtilsTest.scala b/biopet-utils/src/test/scala/nl/lumc/sasc/biopet/utils/ConfigUtilsTest.scala index 6bac74cdf9f3bf6148a78b05271593242d9b2d07..b2e5cfe78f19200674a44b3fe83ff3f52a2e32ef 100644 --- a/biopet-utils/src/test/scala/nl/lumc/sasc/biopet/utils/ConfigUtilsTest.scala +++ b/biopet-utils/src/test/scala/nl/lumc/sasc/biopet/utils/ConfigUtilsTest.scala @@ -223,6 +223,21 @@ class ConfigUtilsTest extends TestNGSuite with Matchers { mergeMaps(map2, map1, (a, b, k) => a.toString + b.toString) shouldBe Map("c" -> Map("x" -> "21")) mergeMaps(map2, map2, (a, b, k) => a.toString + b.toString) shouldBe Map("c" -> Map("x" -> "22")) } + + @Test def testFilterEmtpyMapValues: Unit = { + ConfigUtils.filterEmtpyMapValues(Map("bla" -> "bla")) shouldBe Map("bla" -> "bla") + ConfigUtils.filterEmtpyMapValues(Map("bla" -> Map())) shouldBe Map() + ConfigUtils.filterEmtpyMapValues(Map("bla" -> Map("bla" -> "bla"))) shouldBe Map("bla" -> Map("bla" -> "bla")) + ConfigUtils.filterEmtpyMapValues(Map("bla" -> Map("bla" -> Map()))) shouldBe Map("bla" -> Map("bla" -> Map())) + ConfigUtils.filterEmtpyMapValues(Map("bla" -> Map("bla" -> "bla"), "bla2" -> "bla")) shouldBe Map("bla" -> Map("bla" -> "bla"), "bla2" -> "bla") + } + + @Test def testUniqeKeys: Unit = { + ConfigUtils.uniqueKeys(Map("bla" -> "bla"), Map("bla" -> "bla")) shouldBe Map() + ConfigUtils.uniqueKeys(Map("bla" -> "bla"), Map()) shouldBe Map("bla" -> "bla") + ConfigUtils.uniqueKeys(Map("bla" -> Map("bla" -> "bla")), Map("bla" -> Map("bla" -> "bla"))) shouldBe Map() + ConfigUtils.uniqueKeys(Map("bla" -> Map("bla" -> "bla")), Map("bla" -> Map())) shouldBe Map("bla" -> Map("bla" -> "bla")) + } } object ConfigUtilsTest {