From 5f3df6283a0d506decec0049c6fde833eed69c63 Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Tue, 1 Sep 2015 11:24:35 +0200 Subject: [PATCH] Optimize project reactor builder --- .../batch/scan/ProjectReactorBuilder.java | 65 ++++++++----------- .../batch/scan/ProjectReactorBuilderTest.java | 6 +- .../modules/module1/module1/sources/Fake.java | 0 .../modules/module1/sources/Fake.java | 0 .../sonar-project.properties | 0 5 files changed, 29 insertions(+), 42 deletions(-) rename sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/{multi-module-repeated-names => multi-module-repeated-id}/modules/module1/module1/sources/Fake.java (100%) rename sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/{multi-module-repeated-names => multi-module-repeated-id}/modules/module1/sources/Fake.java (100%) rename sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/{multi-module-repeated-names => multi-module-repeated-id}/sonar-project.properties (100%) diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java index abbb9602d1a7..a20e8abd3e44 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.scan; +import org.apache.commons.lang.ArrayUtils; + import org.sonar.batch.analysis.AnalysisProperties; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; @@ -30,14 +32,12 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; -import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -118,59 +118,46 @@ public ProjectReactorBuilder(AnalysisProperties props) { public ProjectReactor execute() { Profiler profiler = Profiler.create(LOG).startInfo("Process project properties"); - Map> propertiesByModuleId = extractPropertiesByModule("", taskProps.properties()); + Map> propertiesByModuleId = new HashMap<>(); + extractPropertiesByModule(propertiesByModuleId, "", taskProps.properties()); ProjectDefinition rootProject = defineRootProject(propertiesByModuleId.get(""), null); rootProjectWorkDir = rootProject.getWorkDir(); defineChildren(rootProject, propertiesByModuleId); cleanAndCheckProjectDefinitions(rootProject); // Since task properties are now empty we should add root module properties - for (Map.Entry entry : propertiesByModuleId.get("").entrySet()) { - taskProps.properties().put((String) entry.getKey(), (String) entry.getValue()); - } + taskProps.properties().putAll(propertiesByModuleId.get("")); profiler.stopDebug(); return new ProjectReactor(rootProject); } - private static Map> extractPropertiesByModule(String currentModuleId, Map parentProperties) { - Map allProperties = new HashMap<>(); - allProperties.putAll(parentProperties); + private static void extractPropertiesByModule(Map> propertiesByModuleId, String currentModuleId, Map parentProperties) { + if (propertiesByModuleId.containsKey(currentModuleId)) { + throw new IllegalStateException(String.format("Two modules have the same id: %s. Each module must have a unique id.", currentModuleId)); + } + Map currentModuleProperties = new HashMap<>(); - String prefix = !currentModuleId.isEmpty() ? currentModuleId + "." : ""; + String prefix = !currentModuleId.isEmpty() ? (currentModuleId + ".") : ""; + int prefixLength = prefix.length(); + // By default all properties starting with module prefix belong to current module - for (Map.Entry entry : allProperties.entrySet()) { - String key = entry.getKey(); - int prefixLength = prefix.length(); + Iterator> it = parentProperties.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry e = it.next(); + String key = e.getKey(); if (key.startsWith(prefix)) { - currentModuleProperties.put(key.substring(prefixLength), entry.getValue()); - parentProperties.remove(key); + currentModuleProperties.put(key.substring(prefixLength), e.getValue()); + it.remove(); } } - List moduleIds = new ArrayList<>(Arrays.asList(getListFromProperty(currentModuleProperties, PROPERTY_MODULES))); + String[] moduleIds = getListFromProperty(currentModuleProperties, PROPERTY_MODULES); // Sort module by reverse lexicographic order to avoid issue when one module id is a prefix of another one - Collections.sort(moduleIds); - Collections.reverse(moduleIds); + Arrays.sort(moduleIds); + ArrayUtils.reverse(moduleIds); - Map> result = new HashMap<>(); - result.put(currentModuleId, currentModuleProperties); + propertiesByModuleId.put(currentModuleId, currentModuleProperties); for (String moduleId : moduleIds) { - Map> subModuleProps = extractPropertiesByModule(moduleId, currentModuleProperties); - checkRepeatedModuleNames(result.keySet(), subModuleProps.keySet()); - result.putAll(subModuleProps); - } - return result; - } - - private static void checkRepeatedModuleNames(Collection currentModules, Collection modulesToMerge) { - Set union = new HashSet<>(); - union.addAll(currentModules); - union.retainAll(modulesToMerge); - if (!union.isEmpty()) { - if (union.size() > 1) { - throw new IllegalStateException(String.format("Modules have the following repeated names: %s. Each module must have a unique name.", union)); - } else { - throw new IllegalStateException(String.format("Two modules have the same name: %s. Each module must have a unique name.", union.iterator().next())); - } + extractPropertiesByModule(propertiesByModuleId, moduleId, currentModuleProperties); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java index b4bdeb07877b..82db9d87976d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java @@ -79,11 +79,11 @@ public void shouldNotFailIfBlankSourceDirectory() { } @Test - public void modulesRepeatedNames() { + public void modulesRepeatedIds() { thrown.expect(IllegalStateException.class); - thrown.expectMessage("Two modules have the same name: module1"); + thrown.expectMessage("Two modules have the same id: module1"); - loadProjectDefinition("multi-module-repeated-names"); + loadProjectDefinition("multi-module-repeated-id"); } @Test diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/module1/sources/Fake.java b/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-id/modules/module1/module1/sources/Fake.java similarity index 100% rename from sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/module1/sources/Fake.java rename to sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-id/modules/module1/module1/sources/Fake.java diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/sources/Fake.java b/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-id/modules/module1/sources/Fake.java similarity index 100% rename from sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/modules/module1/sources/Fake.java rename to sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-id/modules/module1/sources/Fake.java diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/sonar-project.properties b/sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-id/sonar-project.properties similarity index 100% rename from sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-names/sonar-project.properties rename to sonar-batch/src/test/resources/org/sonar/batch/scan/ProjectReactorBuilderTest/multi-module-repeated-id/sonar-project.properties