]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3024 Perform one shot migration of all project resources
authorJulien HENRY <julien.henry@sonarsource.com>
Thu, 23 Jan 2014 08:47:58 +0000 (09:47 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Thu, 23 Jan 2014 08:52:57 +0000 (09:52 +0100)
21 files changed:
sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java
sonar-batch/src/main/java/org/sonar/batch/index/ResourceKeyMigration.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/phases/FileIndexer.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java
sonar-batch/src/test/java/org/sonar/batch/index/ResourceKeyMigrationTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/phases/FileIndexerTest.java
sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shouldSaveNewDirectory-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shouldSaveNewLibrary-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/ResourceKeyMigrationTest/shouldMigrateResourceKeys-result.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/index/ResourceKeyMigrationTest/shouldMigrateResourceKeys.xml [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java
sonar-core/src/main/resources/org/sonar/core/resource/ResourceMapper.xml
sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java
sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Resource.java
sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileQuery.java

index afeec5e589ba51d832a69d1f539eb819846cf317..10aa20e78727e0003f278ecda74b351b590faa1e 100644 (file)
@@ -91,14 +91,17 @@ public class DefaultIndex extends SonarIndex {
   private final DeprecatedViolations deprecatedViolations;
   private ModuleIssues moduleIssues;
 
+  private ResourceKeyMigration migration;
+
   public DefaultIndex(PersistenceManager persistence, DefaultResourceCreationLock lock, ProjectTree projectTree, MetricFinder metricFinder,
-    ScanGraph graph, DeprecatedViolations deprecatedViolations) {
+    ScanGraph graph, DeprecatedViolations deprecatedViolations, ResourceKeyMigration migration) {
     this.persistence = persistence;
     this.lock = lock;
     this.projectTree = projectTree;
     this.metricFinder = metricFinder;
     this.graph = graph;
     this.deprecatedViolations = deprecatedViolations;
+    this.migration = migration;
   }
 
   public void start() {
@@ -111,6 +114,7 @@ public class DefaultIndex extends SonarIndex {
   void doStart(Project rootProject) {
     Bucket bucket = new Bucket(rootProject);
     buckets.put(rootProject, bucket);
+    migration.checkIfMigrationNeeded(rootProject);
     persistence.saveProject(rootProject, null);
     currentProject = rootProject;
 
@@ -555,7 +559,6 @@ public class DefaultIndex extends SonarIndex {
     }
 
     resource.setEffectiveKey(ComponentKeys.createEffectiveKey(currentProject, resource));
-    resource.setDeprecatedEffectiveKey(ComponentKeys.createDeprecatedEffectiveKey(currentProject, resource));
     bucket = new Bucket(resource).setParent(parentBucket);
     buckets.put(resource, bucket);
 
index 21b36dfc29e89e4ad266b04f6a981e60c03b0992..4931060321c43fe4064b373eae3aea609b9cf118 100644 (file)
@@ -89,6 +89,8 @@ public final class DefaultResourcePersister implements ResourcePersister {
     project.setEffectiveKey(project.getKey());
 
     ResourceModel model = findOrCreateModel(project);
+    // Used by ResourceKeyMigration in order to know that a project has already being migrated
+    model.setDeprecatedKey(project.getKey());
     // ugly, only for projects
     model.setLanguageKey(project.getLanguageKey());
 
@@ -271,10 +273,6 @@ public final class DefaultResourcePersister implements ResourcePersister {
     ResourceModel model;
     try {
       model = session.getSingleResult(ResourceModel.class, "key", resource.getEffectiveKey());
-      if (model == null && !StringUtils.equals(resource.getEffectiveKey(), resource.getDeprecatedEffectiveKey())) {
-        // Fallback on deprecated key when resource has not already been migrated
-        model = session.getSingleResult(ResourceModel.class, "key", resource.getDeprecatedEffectiveKey(), "deprecatedKey", null);
-      }
       if (model == null) {
         if (StringUtils.isBlank(resource.getEffectiveKey())) {
           throw new SonarException("Unable to persist resource " + resource.toString() + ". Resource effective key is blank. This may be caused by an outdated plugin.");
@@ -296,8 +294,6 @@ public final class DefaultResourcePersister implements ResourcePersister {
     model.setEnabled(Boolean.TRUE);
     model.setDescription(resource.getDescription());
     model.setKey(resource.getEffectiveKey());
-    String deprecatedEffectiveKey = resource.getDeprecatedEffectiveKey();
-    model.setDeprecatedKey(StringUtils.isNotBlank(deprecatedEffectiveKey) ? deprecatedEffectiveKey : resource.getEffectiveKey());
     model.setPath(resource.getPath());
     if (resource.getLanguage() != null) {
       model.setLanguageKey(resource.getLanguage().getKey());
@@ -316,12 +312,6 @@ public final class DefaultResourcePersister implements ResourcePersister {
   static void mergeModel(ResourceModel model, Resource resource) {
     model.setEnabled(true);
     model.setKey(resource.getEffectiveKey());
-    if (StringUtils.isNotBlank(resource.getDeprecatedEffectiveKey())) {
-      model.setDeprecatedKey(resource.getDeprecatedEffectiveKey());
-    } else if (StringUtils.isBlank(model.getDeprecatedKey())) {
-      // By default deprecated key is the same as previous key
-      model.setDeprecatedKey(model.getKey());
-    }
     if (StringUtils.isNotBlank(resource.getName())) {
       model.setName(resource.getName());
     }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ResourceKeyMigration.java b/sonar-batch/src/main/java/org/sonar/batch/index/ResourceKeyMigration.java
new file mode 100644 (file)
index 0000000..ae97d13
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.index;
+
+import com.google.common.annotations.VisibleForTesting;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.ResourceModel;
+import org.sonar.api.resources.Directory;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Java;
+import org.sonar.api.resources.JavaFile;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.api.scan.filesystem.internal.InputFile;
+import org.sonar.api.utils.PathUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ResourceKeyMigration {
+
+  private final Logger logger;
+  private final DatabaseSession session;
+
+  private boolean migrationNeeded = false;
+
+  public ResourceKeyMigration(DatabaseSession session) {
+    this(session, LoggerFactory.getLogger(ResourceKeyMigration.class));
+  }
+
+  @VisibleForTesting
+  ResourceKeyMigration(DatabaseSession session, Logger logger) {
+    this.session = session;
+    this.logger = logger;
+  }
+
+  public void checkIfMigrationNeeded(Project rootProject) {
+    ResourceModel model = session.getSingleResult(ResourceModel.class, "key", rootProject.getEffectiveKey());
+    if (model != null && StringUtils.isBlank(model.getDeprecatedKey())) {
+      logger.info("Resources keys of project '" + rootProject.getName() + "' should be migrated");
+      this.migrationNeeded = true;
+    }
+  }
+
+  public void migrateIfNeeded(Project module, Iterable<InputFile> inputFiles) {
+    if (migrationNeeded) {
+      logger.info("Starting migration of resource keys");
+      Map<String, InputFile> deprecatedFileKeyMapper = new HashMap<String, InputFile>();
+      Map<String, InputFile> deprecatedTestKeyMapper = new HashMap<String, InputFile>();
+      Map<String, String> deprecatedDirectoryKeyMapper = new HashMap<String, String>();
+      for (InputFile inputFile : inputFiles) {
+        String deprecatedKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_DEPRECATED_KEY);
+        if (deprecatedKey != null) {
+          if (InputFile.TYPE_TEST.equals(inputFile.attribute(InputFile.ATTRIBUTE_TYPE))) {
+            deprecatedTestKeyMapper.put(deprecatedKey, inputFile);
+          } else {
+            deprecatedFileKeyMapper.put(deprecatedKey, inputFile);
+          }
+        }
+      }
+
+      ResourceModel moduleModel = session.getSingleResult(ResourceModel.class, "key", module.getEffectiveKey());
+      int moduleId = moduleModel.getId();
+      migrateFiles(module, deprecatedFileKeyMapper, deprecatedTestKeyMapper, deprecatedDirectoryKeyMapper, moduleId);
+      migrateDirectories(deprecatedDirectoryKeyMapper, moduleId);
+      session.commit();
+    }
+  }
+
+  private void migrateFiles(Project module, Map<String, InputFile> deprecatedFileKeyMapper, Map<String, InputFile> deprecatedTestKeyMapper,
+    Map<String, String> deprecatedDirectoryKeyMapper,
+    int moduleId) {
+    // Find all FIL or CLA resources for this module
+    StringBuilder hql = new StringBuilder().append("from ")
+      .append(ResourceModel.class.getSimpleName())
+      .append(" where enabled = true ")
+      .append(" and rootId = :rootId ")
+      .append(" and scope = '").append(Scopes.FILE).append("'");
+    List<ResourceModel> resources = session.createQuery(hql.toString()).setParameter("rootId", moduleId).getResultList();
+    for (ResourceModel resourceModel : resources) {
+      String oldEffectiveKey = resourceModel.getKey();
+      boolean isTest = Qualifiers.UNIT_TEST_FILE.equals(resourceModel.getQualifier());
+      InputFile matchedFile = findInputFile(deprecatedFileKeyMapper, deprecatedTestKeyMapper, oldEffectiveKey, isTest);
+      if (matchedFile != null) {
+        String newEffectiveKey = matchedFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY);
+        // Now compute migration of the parent dir
+        String oldKey = StringUtils.substringAfterLast(oldEffectiveKey, ":");
+        Resource sonarFile;
+        if (Java.KEY.equals(resourceModel.getLanguageKey())) {
+          sonarFile = new JavaFile(oldKey);
+        } else {
+          sonarFile = new File(oldKey);
+        }
+        String parentOldKey = module.getEffectiveKey() + ":" + sonarFile.getParent().getDeprecatedKey();
+        String parentNewKey = module.getEffectiveKey() + ":" + getParentKey(matchedFile);
+        if (!deprecatedDirectoryKeyMapper.containsKey(parentOldKey)) {
+          deprecatedDirectoryKeyMapper.put(parentOldKey, parentNewKey);
+        } else if (!parentNewKey.equals(deprecatedDirectoryKeyMapper.get(parentOldKey))) {
+          logger.warn("Directory with key " + parentOldKey + " matches both " + deprecatedDirectoryKeyMapper.get(parentOldKey) + " and "
+            + parentNewKey + ". First match is arbitrary chosen.");
+        }
+        resourceModel.setKey(newEffectiveKey);
+        resourceModel.setDeprecatedKey(oldEffectiveKey);
+        logger.info("Migrated resource " + oldEffectiveKey + " to " + newEffectiveKey);
+      } else {
+        logger.warn("Unable to migrate resource " + oldEffectiveKey + ". No match was found.");
+      }
+    }
+  }
+
+  private InputFile findInputFile(Map<String, InputFile> deprecatedFileKeyMapper, Map<String, InputFile> deprecatedTestKeyMapper, String oldEffectiveKey, boolean isTest) {
+    if (isTest) {
+      return deprecatedTestKeyMapper.get(oldEffectiveKey);
+    } else {
+      return deprecatedFileKeyMapper.get(oldEffectiveKey);
+    }
+  }
+
+  private void migrateDirectories(Map<String, String> deprecatedDirectoryKeyMapper, int moduleId) {
+    // Find all DIR resources for this module
+    StringBuilder hql = new StringBuilder().append("from ")
+      .append(ResourceModel.class.getSimpleName())
+      .append(" where enabled = true ")
+      .append(" and rootId = :rootId ")
+      .append(" and qualifier = '").append(Qualifiers.DIRECTORY).append("')");
+    List<ResourceModel> resources = session.createQuery(hql.toString()).setParameter("rootId", moduleId).getResultList();
+    for (ResourceModel resourceModel : resources) {
+      String oldEffectiveKey = resourceModel.getKey();
+      if (deprecatedDirectoryKeyMapper.containsKey(oldEffectiveKey)) {
+        String newEffectiveKey = deprecatedDirectoryKeyMapper.get(oldEffectiveKey);
+        resourceModel.setKey(newEffectiveKey);
+        resourceModel.setDeprecatedKey(oldEffectiveKey);
+        logger.info("Migrated resource " + oldEffectiveKey + " to " + newEffectiveKey);
+      } else {
+        logger.warn("Unable to migrate resource " + oldEffectiveKey);
+      }
+    }
+  }
+
+  private String getParentKey(InputFile matchedFile) {
+    String filePath = PathUtils.sanitize(matchedFile.path());
+    String parentFolderPath;
+    if (filePath.contains(Directory.SEPARATOR)) {
+      parentFolderPath = StringUtils.substringBeforeLast(filePath, Directory.SEPARATOR);
+    } else {
+      parentFolderPath = Directory.SEPARATOR;
+    }
+    return parentFolderPath;
+  }
+}
index 408557f9c2b88eaba4381f6dff12503aa284438c..880f74d44e07e31328edf337a605cb7f727847f4 100644 (file)
@@ -35,40 +35,39 @@ import org.sonar.api.resources.Resource;
 import org.sonar.api.scan.filesystem.FileQuery;
 import org.sonar.api.scan.filesystem.internal.InputFile;
 import org.sonar.api.utils.SonarException;
+import org.sonar.batch.index.ResourceKeyMigration;
 import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 /**
- * Index all files/directories of the module in SQ database.
+ * Index all files/directories of the module in SQ database and importing source code.
  * @since 4.2
  */
 @InstantiationStrategy(InstantiationStrategy.PER_PROJECT)
 public class FileIndexer implements BatchComponent {
 
-  private final Project module;
   private final DefaultModuleFileSystem fs;
   private final Languages languages;
   private final Settings settings;
   private final SonarIndex sonarIndex;
+  private ResourceKeyMigration migration;
+  private Project module;
 
-  private boolean importSource;
-
-  public FileIndexer(Project module, DefaultModuleFileSystem fs, Languages languages, SonarIndex sonarIndex, Settings settings) {
+  public FileIndexer(Project module, DefaultModuleFileSystem fs, Languages languages, SonarIndex sonarIndex, Settings settings, ResourceKeyMigration migration) {
     this.module = module;
     this.fs = fs;
     this.languages = languages;
     this.sonarIndex = sonarIndex;
     this.settings = settings;
+    this.migration = migration;
   }
 
   public void execute() {
-    this.importSource = settings.getBoolean(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY);
-    String languageKey = module.getLanguageKey();
-    indexFiles(fs.inputFiles(FileQuery.onSource().onLanguage(languageKey)), false, languageKey);
-    indexFiles(fs.inputFiles(FileQuery.onTest().onLanguage(languageKey)), true, languageKey);
-  }
-
-  private void indexFiles(Iterable<InputFile> files, boolean unitTest, String languageKey) {
-    for (InputFile inputFile : files) {
+    boolean importSource = settings.getBoolean(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY);
+    Iterable<InputFile> inputFiles = fs.inputFiles(FileQuery.all());
+    migration.migrateIfNeeded(module, inputFiles);
+    for (InputFile inputFile : inputFiles) {
+      String languageKey = inputFile.attribute(InputFile.ATTRIBUTE_LANGUAGE);
+      boolean unitTest = InputFile.TYPE_TEST.equals(inputFile.attribute(InputFile.ATTRIBUTE_TYPE));
       Resource sonarFile;
       if (Java.KEY.equals(languageKey)) {
         sonarFile = JavaFile.create(inputFile.path(), inputFile.attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH), unitTest);
index 3edf7f278eca43a765a5c1a15967ce2e8c313a8a..cac9e05a53464d8710787d79bcd00d6f222441a1 100644 (file)
@@ -52,6 +52,7 @@ import org.sonar.batch.index.LinkPersister;
 import org.sonar.batch.index.MeasurePersister;
 import org.sonar.batch.index.MemoryOptimizer;
 import org.sonar.batch.index.ResourceCache;
+import org.sonar.batch.index.ResourceKeyMigration;
 import org.sonar.batch.index.SnapshotCache;
 import org.sonar.batch.index.SourcePersister;
 import org.sonar.batch.issue.DefaultProjectIssues;
@@ -134,6 +135,7 @@ public class ProjectScanContainer extends ComponentContainer {
       MetricProvider.class,
       ProjectConfigurator.class,
       DefaultIndex.class,
+      ResourceKeyMigration.class,
       DefaultFileLinesContextFactory.class,
       ProjectLock.class,
       LastSnapshots.class,
index 87b15d8c4df59a2e6ad570ee1719b6b76c5c158a..886ca6c083430e2f257a31c1c5a7fe9d257de051 100644 (file)
@@ -86,7 +86,7 @@ public class DefaultIndexTest {
     ruleFinder = mock(RuleFinder.class);
 
     ProjectTree projectTree = mock(ProjectTree.class);
-    index = new DefaultIndex(mock(PersistenceManager.class), lock, projectTree, metricFinder, mock(ScanGraph.class), deprecatedViolations);
+    index = new DefaultIndex(mock(PersistenceManager.class), lock, projectTree, metricFinder, mock(ScanGraph.class), deprecatedViolations, mock(ResourceKeyMigration.class));
 
     java.io.File baseDir = temp.newFolder();
     project = new Project("project");
index b08ab61d30340a7b607e2ec83d64ddc8d6a70710..8799039f1ce72d40af0ae746d25c078c6f1cfe34 100644 (file)
@@ -146,7 +146,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
     ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class), snapshotCache, resourceCache);
     persister.saveProject(singleProject, null);
     persister.saveResource(singleProject,
-      Directory.create("src/main/java/org/foo", "org.foo").setEffectiveKey("foo:src/main/java/org/foo").setDeprecatedEffectiveKey("foo:org.foo"));
+      Directory.create("src/main/java/org/foo", "org.foo").setEffectiveKey("foo:src/main/java/org/foo"));
 
     // check that the directory is attached to the project
     checkTables("shouldSaveNewDirectory", new String[] {"build_date", "created_at"}, "projects", "snapshots");
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/ResourceKeyMigrationTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/ResourceKeyMigrationTest.java
new file mode 100644 (file)
index 0000000..aad9df2
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.index;
+
+import com.google.common.base.Charsets;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.slf4j.Logger;
+import org.sonar.api.resources.Project;
+import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.api.scan.filesystem.internal.InputFile;
+import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class ResourceKeyMigrationTest extends AbstractDbUnitTestCase {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  Project multiModuleProject, phpModule, javaModule;
+  SnapshotCache snapshotCache = mock(SnapshotCache.class);
+  ResourceCache resourceCache = mock(ResourceCache.class);
+  private Iterable<InputFile> javaInputFiles;
+  private Iterable<InputFile> phpInputFiles;
+  private File baseDir;
+
+  @Before
+  public void before() throws ParseException, IOException {
+    SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
+
+    multiModuleProject = newProject("root", "java");
+    multiModuleProject.setName("Root").setAnalysisDate(format.parse("25/12/2010"));
+
+    phpModule = newProject("a", "php");
+    phpModule.setName("A").setAnalysisDate(format.parse("25/12/2010"));
+    phpModule.setParent(multiModuleProject);
+    phpModule.setPath("/moduleA");
+
+    javaModule = newProject("b", "java");
+    javaModule.setName("B").setAnalysisDate(format.parse("25/12/2010"));
+    javaModule.setParent(multiModuleProject);
+    javaModule.setPath("/moduleB");
+
+    baseDir = temp.newFolder();
+
+    javaInputFiles = (Iterable) Arrays.asList(
+      newInputFile(javaModule, "src/main/java/org/foo/Bar.java", "org.foo.Bar", false),
+      newInputFile(javaModule, "src/main/java/RootBar.java", "[default].RootBar", false),
+      newInputFile(javaModule, "src/test/java/org/foo/BarTest.java", "org.foo.BarTest", true));
+
+    phpInputFiles = (Iterable) Arrays.asList(
+      newInputFile(phpModule, "org/foo/Bar.php", "org/foo/Bar.php", false),
+      newInputFile(phpModule, "RootBar.php", "RootBar.php", false),
+      newInputFile(phpModule, "test/org/foo/BarTest.php", "org/foo/BarTest.php", true));
+
+  }
+
+  private DefaultInputFile newInputFile(Project module, String path, String deprecatedKey, boolean isTest) {
+    File file = new File(baseDir, path);
+    String effectiveKey = module.getKey() + ":" + path;
+    String deprecatedEffectiveKey = module.getKey() + ":" + deprecatedKey;
+    return new InputFileBuilder(file, Charsets.UTF_8, path)
+      .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, effectiveKey)
+      .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_DEPRECATED_KEY, deprecatedEffectiveKey)
+      .attribute(InputFile.ATTRIBUTE_TYPE, isTest ? InputFile.TYPE_TEST : InputFile.TYPE_SOURCE).build();
+  }
+
+  @Test
+  public void shouldMigrateResourceKeys() {
+    setupData("shouldMigrateResourceKeys");
+
+    Logger logger = mock(Logger.class);
+    ResourceKeyMigration migration = new ResourceKeyMigration(getSession(), logger);
+    migration.checkIfMigrationNeeded(multiModuleProject);
+    verify(logger).info("Resources keys of project 'Root' should be migrated");
+
+    migration.migrateIfNeeded(javaModule, javaInputFiles);
+    migration.migrateIfNeeded(phpModule, phpInputFiles);
+
+    verify(logger).info("Migrated resource b:org.foo.Bar to b:src/main/java/org/foo/Bar.java");
+    verify(logger).warn("Directory with key b:org/foo matches both b:src/main/java/org/foo and b:src/test/java/org/foo. First match is arbitrary chosen.");
+    verify(logger).info("Migrated resource b:org.foo.BarTest to b:src/test/java/org/foo/BarTest.java");
+    verify(logger).info("Migrated resource b:[default].RootBar to b:src/main/java/RootBar.java");
+    verify(logger).info("Migrated resource b:org/foo to b:src/main/java/org/foo");
+    verify(logger).info("Migrated resource b:[root] to b:src/main/java");
+
+    checkTables("shouldMigrateResourceKeys", new String[] {"build_date", "created_at"}, "projects");
+  }
+
+  private static Project newProject(String key, String language) {
+    PropertiesConfiguration configuration = new PropertiesConfiguration();
+    configuration.setProperty("sonar.language", language);
+    return new Project(key).setConfiguration(configuration).setAnalysisType(Project.AnalysisType.DYNAMIC);
+  }
+
+}
index cf8d3aaf20c5bb2c42b8ca1ee053b0b24f34148d..e029d097752865740f447ca7a964d9f6d8948abe 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.batch.phases;
 
 import com.google.common.base.Charsets;
-import edu.emory.mathcs.backport.java.util.Collections;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.CharEncoding;
 import org.junit.Before;
@@ -40,8 +39,10 @@ import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.scan.filesystem.FileQuery;
+import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
 import org.sonar.api.scan.filesystem.internal.InputFile;
 import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
+import org.sonar.batch.index.ResourceKeyMigration;
 import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 
 import java.io.File;
@@ -88,19 +89,13 @@ public class FileIndexerTest {
   }
 
   @Test
-  public void should_index_java_files() {
-    File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java");
-    File javaFile2 = new File(baseDir, "src/main/java2/foo/bar/Foo.java");
-    when(fs.inputFiles(FileQuery.onSource().onLanguage(Java.KEY))).thenReturn((Iterable) Arrays.asList(
-      new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/foo/bar/Foo.java").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java").build(),
-      new InputFileBuilder(javaFile2, Charsets.UTF_8, "src/main/java2/foo/bar/Foo.java").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java").build()));
-    File javaTestFile1 = new File(baseDir, "src/test/java/foo/bar/FooTest.java");
-    when(fs.inputFiles(FileQuery.onTest().onLanguage(Java.KEY))).thenReturn(
-      (Iterable) Arrays.asList(
-        new InputFileBuilder(javaTestFile1, Charsets.UTF_8, "src/test/java/foo/bar/FooTest.java").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/FooTest.java")
-          .build()));
+  public void should_index_java_files() throws IOException {
+    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
+      newInputFile("src/main/java/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false),
+      newInputFile("src/main/java2/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false),
+      newInputFile("src/test/java/foo/bar/FooTest.java", "", "foo/bar/FooTest.java", "java", true)));
     when(project.getLanguageKey()).thenReturn(Java.KEY);
-    FileIndexer indexer = new FileIndexer(project, fs, new Languages(Java.INSTANCE), sonarIndex, settings);
+    FileIndexer indexer = new FileIndexer(project, fs, new Languages(Java.INSTANCE), sonarIndex, settings, mock(ResourceKeyMigration.class));
     indexer.execute();
 
     verify(sonarIndex).index(JavaFile.create("src/main/java/foo/bar/Foo.java", "foo/bar/Foo.java", false));
@@ -118,17 +113,13 @@ public class FileIndexerTest {
 
   @Test
   public void should_index_cobol_files() throws IOException {
-    File cobolFile1 = new File(baseDir, "src/foo/bar/Foo.cbl");
-    File cobolFile2 = new File(baseDir, "src2/foo/bar/Foo.cbl");
-    when(fs.inputFiles(FileQuery.onSource().onLanguage("cobol"))).thenReturn((Iterable) Arrays.asList(
-      new InputFileBuilder(cobolFile1, Charsets.UTF_8, "src/foo/bar/Foo.cbl").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.cbl").build(),
-      new InputFileBuilder(cobolFile2, Charsets.UTF_8, "src2/foo/bar/Foo.cbl").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.cbl").build()));
-    File cobolTestFile1 = new File(baseDir, "src/test/foo/bar/FooTest.cbl");
-    when(fs.inputFiles(FileQuery.onTest().onLanguage("cobol"))).thenReturn((Iterable) Arrays.asList(
-      new InputFileBuilder(cobolTestFile1, Charsets.UTF_8, "src/test/foo/bar/FooTest.cbl").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/FooTest.cbl").build()));
+    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
+      newInputFile("src/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false),
+      newInputFile("src2/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false),
+      newInputFile("src/test/foo/bar/FooTest.cbl", "", "foo/bar/FooTest.cbl", "cobol", true)));
     when(project.getLanguageKey()).thenReturn("cobol");
 
-    FileIndexer indexer = new FileIndexer(project, fs, new Languages(cobolLanguage), sonarIndex, settings);
+    FileIndexer indexer = new FileIndexer(project, fs, new Languages(cobolLanguage), sonarIndex, settings, mock(ResourceKeyMigration.class));
     indexer.execute();
 
     verify(sonarIndex).index(org.sonar.api.resources.File.create("/src/foo/bar/Foo.cbl", "foo/bar/Foo.cbl", cobolLanguage, false));
@@ -140,14 +131,10 @@ public class FileIndexerTest {
   public void shouldImportSource() throws IOException {
     settings.setProperty(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY, "true");
 
-    File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java");
-    FileUtils.write(javaFile1, "sample code");
-    when(fs.inputFiles(FileQuery.onSource().onLanguage(Java.KEY))).thenReturn((Iterable) Arrays.asList(
-      new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/foo/bar/Foo.java").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java").build()));
-    when(fs.inputFiles(FileQuery.onTest().onLanguage(Java.KEY))).thenReturn(
-      (Iterable) Collections.emptyList());
+    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
+      newInputFile("src/main/java/foo/bar/Foo.java", "sample code", "foo/bar/Foo.java", "java", false)));
     when(project.getLanguageKey()).thenReturn(Java.KEY);
-    FileIndexer indexer = new FileIndexer(project, fs, new Languages(Java.INSTANCE), sonarIndex, settings);
+    FileIndexer indexer = new FileIndexer(project, fs, new Languages(Java.INSTANCE), sonarIndex, settings, mock(ResourceKeyMigration.class));
     indexer.execute();
 
     Resource sonarFile = JavaFile.create("src/main/java/foo/bar/Foo.java", "foo/bar/Foo.java", false);
@@ -155,6 +142,16 @@ public class FileIndexerTest {
     verify(sonarIndex).setSource(sonarFile, "sample code");
   }
 
+  private DefaultInputFile newInputFile(String path, String content, String sourceRelativePath, String languageKey, boolean unitTest) throws IOException {
+    File file = new File(baseDir, path);
+    FileUtils.write(file, content);
+    return new InputFileBuilder(file, Charsets.UTF_8, path)
+      .attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, sourceRelativePath)
+      .attribute(InputFile.ATTRIBUTE_LANGUAGE, languageKey)
+      .attribute(InputFile.ATTRIBUTE_TYPE, unitTest ? InputFile.TYPE_TEST : InputFile.TYPE_SOURCE)
+      .build();
+  }
+
   @Test
   public void should_use_mac_roman_charset_for_reading_source_files() throws Exception {
     String encoding = "MacRoman";
@@ -182,12 +179,13 @@ public class FileIndexerTest {
 
     File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java");
     FileUtils.write(javaFile1, "\uFEFFpublic class Test", Charsets.UTF_8);
-    when(fs.inputFiles(FileQuery.onSource().onLanguage(Java.KEY))).thenReturn((Iterable) Arrays.asList(
-      new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/foo/bar/Foo.java").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java").build()));
-    when(fs.inputFiles(FileQuery.onTest().onLanguage(Java.KEY))).thenReturn(
-      (Iterable) Collections.emptyList());
+    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
+      new InputFileBuilder(javaFile1, Charset.forName("UTF-8"), "src/main/java/foo/bar/Foo.java")
+        .attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java")
+        .attribute(InputFile.ATTRIBUTE_LANGUAGE, "java")
+        .build()));
     when(project.getLanguageKey()).thenReturn(Java.KEY);
-    FileIndexer indexer = new FileIndexer(project, fs, new Languages(Java.INSTANCE), sonarIndex, settings);
+    FileIndexer indexer = new FileIndexer(project, fs, new Languages(Java.INSTANCE), sonarIndex, settings, mock(ResourceKeyMigration.class));
     indexer.execute();
 
     Resource sonarFile = JavaFile.create("src/main/java/foo/bar/Foo.java", "foo/bar/Foo.java", false);
@@ -206,15 +204,15 @@ public class FileIndexerTest {
 
     File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java");
     FileUtils.copyFile(getFile(testFile), javaFile1);
-    when(fs.inputFiles(FileQuery.onSource().onLanguage(Java.KEY)))
+    when(fs.inputFiles(FileQuery.all()))
       .thenReturn(
         (Iterable) Arrays.asList(
-          new InputFileBuilder(javaFile1, Charset.forName(encoding), "src/main/java/foo/bar/Foo.java").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java")
+          new InputFileBuilder(javaFile1, Charset.forName(encoding), "src/main/java/foo/bar/Foo.java")
+            .attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java")
+            .attribute(InputFile.ATTRIBUTE_LANGUAGE, "java")
             .build()));
-    when(fs.inputFiles(FileQuery.onTest().onLanguage(Java.KEY))).thenReturn(
-      (Iterable) Collections.emptyList());
     when(project.getLanguageKey()).thenReturn(Java.KEY);
-    FileIndexer indexer = new FileIndexer(project, fs, new Languages(Java.INSTANCE), sonarIndex, settings);
+    FileIndexer indexer = new FileIndexer(project, fs, new Languages(Java.INSTANCE), sonarIndex, settings, mock(ResourceKeyMigration.class));
     indexer.execute();
 
     Resource sonarFile = JavaFile.create("/src/main/java/foo/bar/Foo.java", "foo/bar/Foo.java", false);
index fee6de33350be0ccd053ff8d1f6540f328b16c27..6ca27edcd8b79bb1fcdfc49b36f3e317fc78e7c7 100644 (file)
@@ -17,7 +17,7 @@
 
   <projects id="1002" scope="DIR" qualifier="DIR" kee="foo:src/main/java/org/foo" root_id="1001"
             name="src/main/java/org/foo" long_name="src/main/java/org/foo" description="[null]"
-            enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/main/java/org/foo" deprecated_kee="foo:org.foo" />
+            enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/main/java/org/foo" deprecated_kee="[null]" />
 
   <snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="3001" project_id="1001" parent_snapshot_id="[null]" root_project_id="1001" root_snapshot_id="[null]"
              scope="PRJ" qualifier="TRK" created_at="2010-12-25 00:00:00.00" build_date="2010-12-25 00:00:00.00" version="[null]" path=""
index 745203dabf1c37263f4d7f220c52255d71a0f51e..a7107a2871abe168033e5cc3d7151dca5db53c95 100644 (file)
@@ -17,7 +17,7 @@
 
   <projects id="1002" scope="PRJ" qualifier="LIB" kee="junit:junit" root_id="[null]"
             name="junit:junit" long_name="junit:junit" description="[null]"
-            enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" deprecated_kee="junit:junit" />
+            enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" deprecated_kee="[null]" />
 
   <snapshots purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="3001" project_id="1001" parent_snapshot_id="[null]" root_project_id="1001" root_snapshot_id="[null]"
              scope="PRJ" qualifier="TRK" created_at="2010-12-25 00:00:00.00" build_date="2010-12-25 00:00:00.00" version="[null]" path=""
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/index/ResourceKeyMigrationTest/shouldMigrateResourceKeys-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/index/ResourceKeyMigrationTest/shouldMigrateResourceKeys-result.xml
new file mode 100644 (file)
index 0000000..3dacd66
--- /dev/null
@@ -0,0 +1,65 @@
+<dataset>
+
+  <!-- other project already migrated -->
+  <projects id="1000" scope="PRJ" qualifier="TRK" kee="my:key" root_id="[null]"
+            name="Other project" long_name="Other" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="my:key" />
+
+  <!-- Root project not migrated -->
+  <projects id="1001" scope="PRJ" qualifier="TRK" kee="root" root_id="[null]"
+            name="Root" long_name="Root" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <!-- PHP module -->
+  <projects id="1002" scope="PRJ" qualifier="BRC" kee="a" root_id="1001"
+            name="A" long_name="A" description="[null]"
+            enabled="true" language="php" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <!-- Java module -->
+  <projects id="1003" scope="PRJ" qualifier="BRC" kee="b" root_id="1001"
+            name="B" long_name="B" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <!-- Java resources -->
+  <projects id="1004" scope="DIR" qualifier="DIR" kee="b:src/main/java/org/foo" root_id="1003"
+            name="org/foo" long_name="org/foo" description="[null]"
+            enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="b:org/foo" />
+
+  <projects id="1005" scope="FIL" qualifier="CLA" kee="b:src/main/java/org/foo/Bar.java" root_id="1003"
+            name="Bar" long_name="org.foo.Bar" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="b:org.foo.Bar" />
+
+  <projects id="1006" scope="FIL" qualifier="UTS" kee="b:src/test/java/org/foo/BarTest.java" root_id="1003"
+            name="BarTest" long_name="org.foo.BarTest" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="b:org.foo.BarTest" />
+
+  <projects id="1007" scope="DIR" qualifier="DIR" kee="b:src/main/java" root_id="1003"
+          name="[root]" long_name="[root]" description="[null]"
+          enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="b:[root]" />
+
+  <projects id="1008" scope="FIL" qualifier="CLA" kee="b:src/main/java/RootBar.java" root_id="1003"
+            name="RootBar" long_name="RootBar" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="b:[default].RootBar" />
+
+
+  <!-- PHP resources -->
+  <projects id="1009" scope="DIR" qualifier="DIR" kee="a:org/foo" root_id="1002"
+            name="org/foo" long_name="org/foo" description="[null]"
+            enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="a:org/foo" />
+
+  <projects id="1010" scope="FIL" qualifier="FIL" kee="a:org/foo/Bar.php" root_id="1002"
+            name="Bar.php" long_name="Bar.php" description="[null]"
+            enabled="true" language="php" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="a:org/foo/Bar.php" />
+
+  <projects id="1011" scope="FIL" qualifier="UTS" kee="a:test/org/foo/BarTest.php" root_id="1002"
+            name="BarTest.php" long_name="BarTest.php" description="[null]"
+            enabled="true" language="php" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="a:org/foo/BarTest.php" />
+
+  <projects id="1012" scope="DIR" qualifier="DIR" kee="a:/" root_id="1002"
+          name="[root]" long_name="[root]" description="[null]"
+          enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="a:[root]" />
+
+  <projects id="1013" scope="FIL" qualifier="FIL" kee="a:RootBar.php" root_id="1002"
+            name="RootBar.php" long_name="RootBar.php" description="[null]"
+            enabled="true" language="php" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="a:RootBar.php" />
+</dataset>
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/index/ResourceKeyMigrationTest/shouldMigrateResourceKeys.xml b/sonar-batch/src/test/resources/org/sonar/batch/index/ResourceKeyMigrationTest/shouldMigrateResourceKeys.xml
new file mode 100644 (file)
index 0000000..4cfae50
--- /dev/null
@@ -0,0 +1,65 @@
+<dataset>
+
+  <!-- other project already migrated -->
+  <projects id="1000" scope="PRJ" qualifier="TRK" kee="my:key" root_id="[null]"
+            name="Other project" long_name="Other" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="my:key" />
+
+  <!-- Root project not migrated -->
+  <projects id="1001" scope="PRJ" qualifier="TRK" kee="root" root_id="[null]"
+            name="Root" long_name="Root" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <!-- PHP module -->
+  <projects id="1002" scope="PRJ" qualifier="BRC" kee="a" root_id="1001"
+            name="A" long_name="A" description="[null]"
+            enabled="true" language="php" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <!-- Java module -->
+  <projects id="1003" scope="PRJ" qualifier="BRC" kee="b" root_id="1001"
+            name="B" long_name="B" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <!-- Java resources -->
+  <projects id="1004" scope="DIR" qualifier="DIR" kee="b:org/foo" root_id="1003"
+            name="org/foo" long_name="org/foo" description="[null]"
+            enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <projects id="1005" scope="FIL" qualifier="CLA" kee="b:org.foo.Bar" root_id="1003"
+            name="Bar" long_name="org.foo.Bar" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <projects id="1006" scope="FIL" qualifier="UTS" kee="b:org.foo.BarTest" root_id="1003"
+            name="BarTest" long_name="org.foo.BarTest" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <projects id="1007" scope="DIR" qualifier="DIR" kee="b:[root]" root_id="1003"
+          name="[root]" long_name="[root]" description="[null]"
+          enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <projects id="1008" scope="FIL" qualifier="CLA" kee="b:[default].RootBar" root_id="1003"
+            name="RootBar" long_name="RootBar" description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+
+  <!-- PHP resources -->
+  <projects id="1009" scope="DIR" qualifier="DIR" kee="a:org/foo" root_id="1002"
+            name="org/foo" long_name="org/foo" description="[null]"
+            enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <projects id="1010" scope="FIL" qualifier="FIL" kee="a:org/foo/Bar.php" root_id="1002"
+            name="Bar.php" long_name="Bar.php" description="[null]"
+            enabled="true" language="php" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <projects id="1011" scope="FIL" qualifier="UTS" kee="a:org/foo/BarTest.php" root_id="1002"
+            name="BarTest.php" long_name="BarTest.php" description="[null]"
+            enabled="true" language="php" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <projects id="1012" scope="DIR" qualifier="DIR" kee="a:[root]" root_id="1002"
+          name="[root]" long_name="[root]" description="[null]"
+          enabled="true" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+
+  <projects id="1013" scope="FIL" qualifier="FIL" kee="a:RootBar.php" root_id="1002"
+            name="RootBar.php" long_name="RootBar.php" description="[null]"
+            enabled="true" language="php" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]" />
+</dataset>
index d8ba9b5c648f80190e890dd9edf3046ab6504360..a17b51d22f3cd77db4865f62b7e8b8a56a1eba5c 100644 (file)
@@ -55,19 +55,6 @@ public final class ComponentKeys {
     return key;
   }
 
-  public static String createDeprecatedEffectiveKey(Project project, Resource resource) {
-    String key = resource.getKey();
-    if (!StringUtils.equals(Scopes.PROJECT, resource.getScope())) {
-      // not a project nor a library
-      key = new StringBuilder(ResourceModel.KEY_SIZE)
-        .append(project.getKey())
-        .append(':')
-        .append(resource.getDeprecatedKey())
-        .toString();
-    }
-    return key;
-  }
-
   /**
    * <p>Test if given parameter is valid for a project/module. Valid format is:</p>
    * <ul>
index e2d0d0a4745c3a01e1c0b80976c14f3e6aa0d09b..ef9389a5a272d73f89390ca654a2ae355cd806d0 100644 (file)
@@ -41,6 +41,7 @@
   <resultMap id="resourceResultMap" type="Resource">
     <id property="id" column="id"/>
     <result property="key" column="kee"/>
+    <result property="deprecatedKey" column="deprecated_kee"/>
     <result property="path" column="path"/>
     <result property="name" column="name"/>
     <result property="longName" column="long_name"/>
index 42391a2cb2ad67b5fd8216018646b6f8033512d0..04b29175341d23b1db067d9a1615f80ae597d081 100644 (file)
@@ -35,7 +35,6 @@ public class ComponentKeysTest {
 
     Directory dir = Directory.create("src/org/foo", "org/foo");
     assertThat(ComponentKeys.createEffectiveKey(project, dir)).isEqualTo("my_project:src/org/foo");
-    assertThat(ComponentKeys.createDeprecatedEffectiveKey(project, dir)).isEqualTo("my_project:org/foo");
 
     Library library = new Library("junit:junit", "4.7");
     assertThat(ComponentKeys.createEffectiveKey(project, library)).isEqualTo("junit:junit");
index e3e97d5f8acf61d3210c6065aea7b3a1157ce572..1650c324fc61ecabd6ab94b04f7ed60ccd3eff7b 100644 (file)
@@ -380,8 +380,7 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable {
     ResourceModel model = new ResourceModel();
     model.setEnabled(Boolean.TRUE);
     model.setDescription(resource.getDescription());
-    model.setKey(resource.getKey());
-    model.setDeprecatedKey(resource.getDeprecatedKey());
+    model.setKey(resource.getEffectiveKey());
     model.setPath(resource.getPath());
     if (resource.getLanguage() != null) {
       model.setLanguageKey(resource.getLanguage().getKey());
index cedd0097937a6ddcf7a3703e3cb3fc7ca9243fac..770a58e93407533e93fe12fdb8e775671a22f388 100644 (file)
@@ -87,8 +87,8 @@ public class JavaFile extends Resource {
    * @deprecated since 4.2 use {@link #create(String, String, boolean)}
    */
   @Deprecated
-  public JavaFile(String key) {
-    this(key, false);
+  public JavaFile(String deprecatedKey) {
+    this(deprecatedKey, false);
   }
 
   /**
@@ -98,11 +98,11 @@ public class JavaFile extends Resource {
    * @deprecated since 4.2 use {@link #create(String, String, boolean)}
    */
   @Deprecated
-  public JavaFile(String key, boolean unitTest) {
-    if (key == null) {
+  public JavaFile(String deprecatedKey, boolean unitTest) {
+    if (deprecatedKey == null) {
       throw new IllegalArgumentException("Java filename can not be null");
     }
-    String realKey = StringUtils.trim(key);
+    String realKey = StringUtils.trim(deprecatedKey);
     this.unitTest = unitTest;
 
     if (realKey.contains(".")) {
index 7c89db07838e23fc6f1784ffdb38c23a2159958b..610fe1669570b37c853ef1dc332f7f56a1b22efb 100644 (file)
@@ -86,7 +86,6 @@ public class Project extends Resource implements Component {
     setKey(key);
     setDeprecatedKey(key);
     setEffectiveKey(key);
-    setDeprecatedEffectiveKey(key);
   }
 
   public Project(String key, String branch, String name) {
@@ -99,7 +98,6 @@ public class Project extends Resource implements Component {
     }
     setDeprecatedKey(getKey());
     setEffectiveKey(getKey());
-    setDeprecatedEffectiveKey(getKey());
     this.branch = branch;
   }
 
index 02383db58696962437e43fa5565211df8c288ee1..d3b521094ba24ef5b01ea318d0e699fac1f887f3 100644 (file)
@@ -132,8 +132,6 @@ public abstract class Resource implements Serializable {
 
   private String effectiveKey = null;
 
-  private String deprecatedEffectiveKey = null;
-
   private boolean isExcluded = false;
 
   /**
@@ -264,21 +262,6 @@ public abstract class Resource implements Serializable {
     return this;
   }
 
-  /**
-   * Internal use only
-   */
-  public String getDeprecatedEffectiveKey() {
-    return deprecatedEffectiveKey;
-  }
-
-  /**
-   * Internal use only
-   */
-  public final Resource setDeprecatedEffectiveKey(String deprecatedEffectiveKey) {
-    this.deprecatedEffectiveKey = deprecatedEffectiveKey;
-    return this;
-  }
-
   /**
    * @deprecated since 2.6 should use SensorContext#isExcluded(resource). It will make inheritance of Resource easier.
    */
index c8dd3e3b37795e8b8b6830ce23f93ae741b07d4d..95dbfb0cf12eb6b603a8797cac9ecbe715fc9c23 100644 (file)
@@ -52,6 +52,13 @@ public class FileQuery {
     return query;
   }
 
+  /**
+   * @since 4.2
+   */
+  public static FileQuery all() {
+    return on();
+  }
+
   public static FileQuery onSource() {
     return on(FileType.SOURCE);
   }