]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3024 Introduce a path attribute on resource to allow distinguish files
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 8 Jan 2014 16:38:52 +0000 (17:38 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Wed, 8 Jan 2014 16:51:06 +0000 (17:51 +0100)
that would have the same key with old key pattern

47 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/phases/FileIndexer.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/phases/SensorsExecutor.java
sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.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/phases/FileIndexerTest.java [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shared.xml
sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shouldRemoveRootIndexIfResourceIsProject-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shouldRemoveRootIndexIfResourceIsProject.xml
sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shouldSaveCopyProject-result.xml
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/DefaultResourcePersisterTest/shouldSaveNewMultiModulesProject-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shouldSaveNewProject-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shouldUpdateExistingResource-result.xml
sonar-batch/src/test/resources/org/sonar/batch/index/DefaultResourcePersisterTest/shouldUpdateExistingResource.xml
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
sonar-core/src/main/java/org/sonar/core/resource/ResourceDto.java
sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
sonar-core/src/main/resources/org/sonar/core/resource/ResourceMapper.xml
sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java
sonar-core/src/test/java/org/sonar/core/user/AuthorDaoTest.java
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteHistoricalDataOfDirectoriesAndFiles-result.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDeleteHistoricalDataOfDirectoriesAndFiles.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot-result.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject-result.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldPurgeProject.xml
sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/insert-result.xml
sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update-result.xml
sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/update.xml
sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shared.xml
sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKey-result.xml
sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldBulkUpdateKeyOnOnlyOneSubmodule-result.xml
sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules-result.xml
sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldNotUpdateAllSubmodules.xml
sonar-core/src/test/resources/org/sonar/core/resource/ResourceKeyUpdaterDaoTest/shouldUpdateKey-result.xml
sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.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
sonar-server/src/main/webapp/WEB-INF/db/migrate/486_add_resource_path_column.rb [new file with mode: 0644]

index 5efdabe3da964443c8eda2bdc10b34a8feb86731..b0ef29a709ed2aaee3d70b4cd472c156c1088981 100644 (file)
@@ -28,12 +28,23 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.Event;
 import org.sonar.api.batch.SonarIndex;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.design.Dependency;
-import org.sonar.api.measures.*;
-import org.sonar.api.resources.*;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.MeasuresFilter;
+import org.sonar.api.measures.MeasuresFilters;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.ProjectLink;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+import org.sonar.api.resources.Scopes;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.Violation;
+import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.api.utils.SonarException;
 import org.sonar.api.violations.ViolationQuery;
 import org.sonar.batch.DefaultResourceCreationLock;
@@ -44,7 +55,14 @@ import org.sonar.batch.issue.ModuleIssues;
 import org.sonar.core.component.ComponentKeys;
 import org.sonar.core.component.ScanGraph;
 
-import java.util.*;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 public class DefaultIndex extends SonarIndex {
 
@@ -69,7 +87,7 @@ public class DefaultIndex extends SonarIndex {
   private ModuleIssues moduleIssues;
 
   public DefaultIndex(PersistenceManager persistence, DefaultResourceCreationLock lock, ProjectTree projectTree, MetricFinder metricFinder,
-                      ScanGraph graph, DeprecatedViolations deprecatedViolations) {
+    ScanGraph graph, DeprecatedViolations deprecatedViolations) {
     this.persistence = persistence;
     this.lock = lock;
     this.projectTree = projectTree;
@@ -91,15 +109,20 @@ public class DefaultIndex extends SonarIndex {
     persistence.saveProject(rootProject, null);
     currentProject = rootProject;
 
-    for (Project project : rootProject.getModules()) {
-      addProject(project);
+    for (Project module : rootProject.getModules()) {
+      addModule(rootProject, module);
     }
   }
 
-  private void addProject(Project project) {
-    addResource(project);
-    for (Project module : project.getModules()) {
-      addProject(module);
+  private void addModule(Project parent, Project module) {
+    ProjectDefinition parentDefinition = projectTree.getProjectDefinition(parent);
+    java.io.File parentBaseDir = parentDefinition.getBaseDir();
+    ProjectDefinition moduleDefinition = projectTree.getProjectDefinition(module);
+    java.io.File moduleBaseDir = moduleDefinition.getBaseDir();
+    module.setPath(new PathResolver().relativePath(parentBaseDir, moduleBaseDir));
+    addResource(module);
+    for (Project submodule : module.getModules()) {
+      addModule(module, submodule);
     }
   }
 
@@ -371,7 +394,6 @@ public class DefaultIndex extends SonarIndex {
     moduleIssues.initAndAddViolation(violation);
   }
 
-
   //
   //
   //
index ac2ad1c546cadbd9878933f554e9a60a2bd7dc91..abe1e4915eff239237b908acde90d2e1e76862da 100644 (file)
@@ -25,10 +25,16 @@ import org.apache.commons.lang.StringUtils;
 import org.sonar.api.database.DatabaseSession;
 import org.sonar.api.database.model.ResourceModel;
 import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.*;
+import org.sonar.api.resources.Library;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+import org.sonar.api.resources.Scopes;
 import org.sonar.api.security.ResourcePermissions;
 import org.sonar.api.utils.SonarException;
 
+import javax.annotation.Nullable;
 import javax.persistence.NonUniqueResultException;
 import javax.persistence.Query;
 
@@ -79,7 +85,7 @@ public final class DefaultResourcePersister implements ResourcePersister {
     // temporary hack
     project.setEffectiveKey(project.getKey());
 
-    ResourceModel model = findOrCreateModel(project);
+    ResourceModel model = findOrCreateModel(null, project);
     // ugly, only for projects
     model.setLanguageKey(project.getLanguageKey());
 
@@ -162,7 +168,7 @@ public final class DefaultResourcePersister implements ResourcePersister {
   }
 
   private Snapshot persistLibrary(Project project, Library library) {
-    ResourceModel model = findOrCreateModel(library);
+    ResourceModel model = findOrCreateModel(null, library);
     model = session.save(model);
     // TODO to be removed
     library.setId(model.getId());
@@ -204,13 +210,14 @@ public final class DefaultResourcePersister implements ResourcePersister {
    * Everything except project and library
    */
   private Snapshot persistFileOrDirectory(Project project, Resource resource, Resource parentReference) {
-    ResourceModel model = findOrCreateModel(resource);
-    Snapshot projectSnapshot = snapshotsByResource.get(project);
-    model.setRootId(projectSnapshot.getResourceId());
+    Snapshot moduleSnapshot = snapshotsByResource.get(project);
+    Integer moduleId = moduleSnapshot.getResourceId();
+    ResourceModel model = findOrCreateModel(moduleId, resource);
+    model.setRootId(moduleId);
     model = session.save(model);
     resource.setId(model.getId());
 
-    Snapshot parentSnapshot = (Snapshot) ObjectUtils.defaultIfNull(getSnapshot(parentReference), projectSnapshot);
+    Snapshot parentSnapshot = (Snapshot) ObjectUtils.defaultIfNull(getSnapshot(parentReference), moduleSnapshot);
     Snapshot snapshot = new Snapshot(model, parentSnapshot);
     snapshot.setBuildDate(new Date());
     snapshot = session.save(snapshot);
@@ -242,10 +249,17 @@ public final class DefaultResourcePersister implements ResourcePersister {
     }
   }
 
-  private ResourceModel findOrCreateModel(Resource resource) {
+  /**
+   * @param rootModuleId can be null and in this case resource will be searched using deprecated key instead of path
+   */
+  private ResourceModel findOrCreateModel(@Nullable Integer rootModuleId, Resource resource) {
     ResourceModel model;
     try {
-      model = session.getSingleResult(ResourceModel.class, "key", resource.getEffectiveKey());
+      if (rootModuleId != null && StringUtils.isNotBlank(resource.getPath())) {
+        model = session.getSingleResult(ResourceModel.class, "rootId", rootModuleId, "path", resource.getPath());
+      } else {
+        model = session.getSingleResult(ResourceModel.class, "key", resource.getEffectiveKey());
+      }
       if (model == null) {
         model = createModel(resource);
 
@@ -264,6 +278,7 @@ public final class DefaultResourcePersister implements ResourcePersister {
     model.setEnabled(Boolean.TRUE);
     model.setDescription(resource.getDescription());
     model.setKey(resource.getEffectiveKey());
+    model.setPath(resource.getPath());
     if (resource.getLanguage() != null) {
       model.setLanguageKey(resource.getLanguage().getKey());
     }
@@ -295,9 +310,9 @@ public final class DefaultResourcePersister implements ResourcePersister {
         Qualifiers.MODULE.equals(resource.getQualifier())
         && Qualifiers.PROJECT.equals(model.getQualifier())) {
         throw new SonarException(
-            String.format("The project '%s' is already defined in SonarQube but not as a module of project '%s'. "
-              + "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.",
-                resource.getKey(), resource.getParent().getKey(), resource.getKey(), resource.getParent().getKey()));
+          String.format("The project '%s' is already defined in SonarQube but not as a module of project '%s'. "
+            + "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.",
+            resource.getKey(), resource.getParent().getKey(), resource.getKey(), resource.getParent().getKey()));
       }
       model.setScope(resource.getScope());
       model.setQualifier(resource.getQualifier());
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/FileIndexer.java b/sonar-batch/src/main/java/org/sonar/batch/phases/FileIndexer.java
new file mode 100644 (file)
index 0000000..ebcf828
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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.phases;
+
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.InstantiationStrategy;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.resources.Java;
+import org.sonar.api.resources.JavaFile;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.scan.filesystem.FileQuery;
+import org.sonar.api.scan.filesystem.internal.InputFile;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
+
+/**
+ * Index all files/directories of the module in SQ database.
+ * @since 4.2
+ */
+@InstantiationStrategy(InstantiationStrategy.PER_PROJECT)
+public class FileIndexer implements BatchComponent {
+
+  private Project module;
+  private DefaultModuleFileSystem fs;
+
+  private Languages languages;
+
+  public FileIndexer(Project module, DefaultModuleFileSystem fs, Languages languages) {
+    this.module = module;
+    this.fs = fs;
+    this.languages = languages;
+  }
+
+  public void execute(SensorContext context) {
+    String languageKey = module.getLanguageKey();
+    indexFiles(fs.inputFiles(FileQuery.onSource().onLanguage(languageKey)), false, context, languageKey);
+    indexFiles(fs.inputFiles(FileQuery.onTest().onLanguage(languageKey)), true, context, languageKey);
+  }
+
+  private void indexFiles(Iterable<InputFile> files, boolean unitTest, SensorContext context, String languageKey) {
+    for (InputFile inputFile : files) {
+      Resource sonarFile;
+      if (Java.KEY.equals(languageKey)) {
+        sonarFile = JavaFile.fromRelativePath(inputFile.attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH), unitTest);
+      } else {
+        sonarFile = new org.sonar.api.resources.File(languages.get(languageKey),
+          inputFile.attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH));
+      }
+      if (sonarFile != null) {
+        sonarFile.setPath(inputFile.path());
+        context.index(sonarFile);
+      }
+    }
+  }
+}
index c4c4fcb09d2bc039278e7bab9e8e96f2a313c4bc..f337007fe7f1bdcedc7adafd041415aa61beefbe 100644 (file)
@@ -47,9 +47,10 @@ public class SensorsExecutor implements BatchComponent {
   private BatchExtensionDictionnary selector;
   private final DatabaseSession session;
   private final SensorMatcher sensorMatcher;
+  private final FileIndexer fileIndexer;
 
   public SensorsExecutor(BatchExtensionDictionnary selector, Project project, DefaultModuleFileSystem fs, MavenPluginExecutor mavenExecutor, EventBus eventBus,
-      DatabaseSession session, SensorMatcher sensorMatcher) {
+    DatabaseSession session, SensorMatcher sensorMatcher, FileIndexer fileIndexer) {
     this.selector = selector;
     this.mavenExecutor = mavenExecutor;
     this.eventBus = eventBus;
@@ -57,12 +58,15 @@ public class SensorsExecutor implements BatchComponent {
     this.fs = fs;
     this.session = session;
     this.sensorMatcher = sensorMatcher;
+    this.fileIndexer = fileIndexer;
   }
 
   public void execute(SensorContext context) {
     Collection<Sensor> sensors = selector.select(Sensor.class, project, true, sensorMatcher);
     eventBus.fireEvent(new SensorsPhaseEvent(Lists.newArrayList(sensors), true));
 
+    fileIndexer.execute(context);
+
     for (Sensor sensor : sensors) {
       // SONAR-2965 In case the sensor takes too much time we close the session to not face a timeout
       session.commitAndClose();
index 293ad2c065f8be4a75a47825298090513443a0d5..e2699fe0572a68e9bfe2ee13d15b44ee8a978972 100644 (file)
@@ -28,7 +28,13 @@ import org.sonar.api.platform.ComponentContainer;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.resources.Project;
 import org.sonar.api.scan.filesystem.FileExclusions;
-import org.sonar.batch.*;
+import org.sonar.batch.DefaultProjectClasspath;
+import org.sonar.batch.DefaultSensorContext;
+import org.sonar.batch.DefaultTimeMachine;
+import org.sonar.batch.ProfileProvider;
+import org.sonar.batch.ProjectTree;
+import org.sonar.batch.ResourceFilters;
+import org.sonar.batch.ViolationFilters;
 import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
 import org.sonar.batch.bootstrap.ExtensionInstaller;
 import org.sonar.batch.bootstrap.ExtensionMatcher;
@@ -40,9 +46,19 @@ import org.sonar.batch.index.ResourcePersister;
 import org.sonar.batch.issue.IssuableFactory;
 import org.sonar.batch.issue.IssueFilters;
 import org.sonar.batch.issue.ModuleIssues;
+import org.sonar.batch.phases.FileIndexer;
 import org.sonar.batch.phases.PhaseExecutor;
 import org.sonar.batch.phases.PhasesTimeProfiler;
-import org.sonar.batch.scan.filesystem.*;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
+import org.sonar.batch.scan.filesystem.DeprecatedFileFilters;
+import org.sonar.batch.scan.filesystem.ExclusionFilters;
+import org.sonar.batch.scan.filesystem.FileHashes;
+import org.sonar.batch.scan.filesystem.FileIndex;
+import org.sonar.batch.scan.filesystem.FileSystemLogger;
+import org.sonar.batch.scan.filesystem.LanguageRecognizer;
+import org.sonar.batch.scan.filesystem.ModuleFileSystemInitializer;
+import org.sonar.batch.scan.filesystem.ProjectFileSystemAdapter;
+import org.sonar.batch.scan.filesystem.RemoteFileHashes;
 import org.sonar.batch.scan.report.ComponentSelectorFactory;
 import org.sonar.batch.scan.report.JsonReport;
 import org.sonar.core.component.ScanPerspectives;
@@ -93,6 +109,7 @@ public class ModuleScanContainer extends ComponentContainer {
       FileHashes.class,
       RemoteFileHashes.class,
       FileIndex.class,
+      FileIndexer.class,
       LanguageRecognizer.class,
       FileSystemLogger.class,
       DefaultProjectClasspath.class,
index cd039e17d9abd776af66891033a4e7ad55900e99..2b31f72d2a8964c34e8c394dc116709c2a7f461b 100644 (file)
@@ -22,14 +22,22 @@ package org.sonar.batch.index;
 import org.apache.commons.lang.StringUtils;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.ResourceFilter;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.config.Settings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.MeasuresFilters;
 import org.sonar.api.measures.MetricFinder;
 import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.*;
+import org.sonar.api.resources.Directory;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Java;
+import org.sonar.api.resources.Library;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RuleFinder;
 import org.sonar.api.rules.Violation;
@@ -42,6 +50,8 @@ import org.sonar.batch.issue.DeprecatedViolations;
 import org.sonar.batch.issue.ModuleIssues;
 import org.sonar.core.component.ScanGraph;
 
+import java.io.IOException;
+
 import static com.google.common.collect.Lists.newArrayList;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Matchers.anyString;
@@ -50,22 +60,43 @@ import static org.mockito.Mockito.when;
 
 public class DefaultIndexTest {
 
+  @org.junit.Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
   private DefaultIndex index = null;
   private DeprecatedViolations deprecatedViolations;
   private DefaultResourceCreationLock lock;
   private Rule rule;
   private RuleFinder ruleFinder;
 
+  private Project project;
+
+  private Project moduleA;
+
+  private Project moduleB;
+
+  private Project moduleB1;
+
   @Before
-  public void createIndex() {
+  public void createIndex() throws IOException {
     deprecatedViolations = mock(DeprecatedViolations.class);
     lock = new DefaultResourceCreationLock(new Settings());
     MetricFinder metricFinder = mock(MetricFinder.class);
     when(metricFinder.findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC);
     ruleFinder = mock(RuleFinder.class);
 
-    index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder, mock(ScanGraph.class), deprecatedViolations);
-    Project project = new Project("project");
+    ProjectTree projectTree = mock(ProjectTree.class);
+    index = new DefaultIndex(mock(PersistenceManager.class), lock, projectTree, metricFinder, mock(ScanGraph.class), deprecatedViolations);
+
+    java.io.File baseDir = temp.newFolder();
+    project = new Project("project");
+    when(projectTree.getProjectDefinition(project)).thenReturn(ProjectDefinition.create().setBaseDir(baseDir));
+    moduleA = new Project("moduleA").setParent(project);
+    when(projectTree.getProjectDefinition(moduleA)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleA")));
+    moduleB = new Project("moduleB").setParent(project);
+    when(projectTree.getProjectDefinition(moduleB)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB")));
+    moduleB1 = new Project("moduleB1").setParent(moduleB);
+    when(projectTree.getProjectDefinition(moduleB1)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB/moduleB1")));
 
     ResourceFilter filter = new ResourceFilter() {
 
@@ -77,7 +108,7 @@ public class DefaultIndexTest {
     rule = Rule.create("repoKey", "ruleKey", "Rule");
     rule.setId(1);
     rulesProfile.activateRule(rule, null);
-    index.setCurrentProject(project, new ResourceFilters(new ResourceFilter[]{filter}), mock(ModuleIssues.class));
+    index.setCurrentProject(project, new ResourceFilters(new ResourceFilter[] {filter}), mock(ModuleIssues.class));
     index.doStart(project);
   }
 
@@ -241,6 +272,14 @@ public class DefaultIndexTest {
     assertThat(index.getViolations(ViolationQuery.create().forResource(file).setSwitchMode(ViolationQuery.SwitchMode.ON))).hasSize(1);
   }
 
+  @Test
+  public void shouldComputePathOfIndexedModules() {
+    assertThat(index.getResource(project).getPath()).isNull();
+    assertThat(index.getResource(moduleA).getPath()).isEqualTo("/moduleA");
+    assertThat(index.getResource(moduleB).getPath()).isEqualTo("/moduleB");
+    assertThat(index.getResource(moduleB1).getPath()).isEqualTo("/moduleB1");
+  }
+
   @Test(expected = IllegalArgumentException.class)
   public void testGetViolationsWithQueryWithNoResource() {
     index.getViolations(ViolationQuery.create());
index 68cba62d50b395ddd7d56da6fe24a5b05394dc68..6bf3829f4423972add970520ee85069ecf5e0a5b 100644 (file)
@@ -72,14 +72,17 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
     moduleA = newProject("a", "java");
     moduleA.setName("A").setAnalysisDate(format.parse("25/12/2010"));
     moduleA.setParent(multiModuleProject);
+    moduleA.setPath("/moduleA");
 
     moduleB = newProject("b", "java");
     moduleB.setName("B").setAnalysisDate(format.parse("25/12/2010"));
     moduleB.setParent(multiModuleProject);
+    moduleB.setPath("/moduleB");
 
     moduleB1 = newProject("b1", "java");
     moduleB1.setName("B1").setAnalysisDate(format.parse("25/12/2010"));
     moduleB1.setParent(moduleB);
+    moduleB1.setPath("/moduleB1");
   }
 
   @Test
@@ -141,7 +144,19 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
 
     ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class), snapshotCache, resourceCache);
     persister.saveProject(singleProject, null);
-    persister.saveResource(singleProject, new JavaPackage("org.foo").setEffectiveKey("foo:org.foo"));
+    persister.saveResource(singleProject, new JavaPackage("org.foo").setEffectiveKey("foo:org.foo").setPath("/src/main/java/org/foo"));
+
+    // check that the directory is attached to the project
+    checkTables("shouldSaveNewDirectory", new String[] {"build_date", "created_at"}, "projects", "snapshots");
+  }
+
+  @Test
+  public void shouldSaveNewDirectoryAndNormalizePath() {
+    setupData("shared");
+
+    ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class), snapshotCache, resourceCache);
+    persister.saveProject(singleProject, null);
+    persister.saveResource(singleProject, new JavaPackage("org.foo").setEffectiveKey("foo:org.foo").setPath("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/phases/FileIndexerTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/FileIndexerTest.java
new file mode 100644 (file)
index 0000000..0928252
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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.phases;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.resources.AbstractLanguage;
+import org.sonar.api.resources.Java;
+import org.sonar.api.resources.JavaFile;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.resources.Project;
+import org.sonar.api.scan.filesystem.FileQuery;
+import org.sonar.api.scan.filesystem.internal.InputFile;
+import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class FileIndexerTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Test
+  public void should_index_java_files() throws IOException {
+    File baseDir = temp.newFolder();
+    DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
+    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, "src/main/java/foo/bar/Foo.java").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java").build(),
+      new InputFileBuilder(javaFile2, "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, "src/test/java/foo/bar/FooTest.java").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/FooTest.java").build()));
+    Project project = mock(Project.class);
+    when(project.getLanguageKey()).thenReturn(Java.KEY);
+    FileIndexer indexer = new FileIndexer(project, fs, new Languages(Java.INSTANCE));
+    SensorContext sensorContext = mock(SensorContext.class);
+    indexer.execute(sensorContext);
+
+    verify(sensorContext).index(new JavaFile("foo.bar.Foo", false).setPath("/src/main/java/foo/bar/Foo.java"));
+    verify(sensorContext).index(new JavaFile("foo.bar.Foo", false).setPath("/src/main/java2/foo/bar/Foo.java"));
+    verify(sensorContext).index(new JavaFile("foo.bar.FooTest", true).setPath("/src/test/java/foo/bar/FooTest.java"));
+  }
+
+  @Test
+  public void should_index_cobol_files() throws IOException {
+    File baseDir = temp.newFolder();
+    DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
+    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, "src/foo/bar/Foo.cbl").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.cbl").build(),
+      new InputFileBuilder(cobolFile2, "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, "src/test/foo/bar/FooTest.cbl").attribute(InputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/FooTest.cbl").build()));
+    Project project = mock(Project.class);
+    when(project.getLanguageKey()).thenReturn("cobol");
+    FileIndexer indexer = new FileIndexer(project, fs, new Languages(new AbstractLanguage("cobol") {
+      @Override
+      public String[] getFileSuffixes() {
+        return new String[] {"cbl"};
+      }
+    }));
+    SensorContext sensorContext = mock(SensorContext.class);
+    indexer.execute(sensorContext);
+
+    verify(sensorContext).index(new org.sonar.api.resources.File("foo/bar/Foo.cbl").setPath("/src/foo/bar/Foo.cbl"));
+    verify(sensorContext).index(new org.sonar.api.resources.File("foo/bar/Foo.cbl").setPath("/src2/foo/bar/Foo.cbl"));
+    verify(sensorContext).index(new org.sonar.api.resources.File("foo/bar/FooTest.cbl").setPath("/src/test/foo/bar/FooTest.cbl"));
+  }
+
+}
index 813a604bf6e78377504e6334b0c8617937820bb0..2c2a08fa2d0108ad4f8b006b4d506f1660b57648 100644 (file)
@@ -3,7 +3,7 @@
   <!-- other project -->
   <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]" created_at="[null]"/>
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[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="3000" project_id="1000" parent_snapshot_id="[null]" root_project_id="1000" root_snapshot_id="[null]"
              scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" build_date="2008-11-01 13:58:00.00" version="[null]" path=""
index bc7fc1c6f0af0cdc81c3aab351e7fd274812eed9..36c622aec03ac8c166f3773c68d08b730c5aaaa6 100644 (file)
@@ -2,7 +2,7 @@
 
   <projects id="1001" scope="PRJ" qualifier="TRK" kee="foo" root_id="[null]"
             name="Foo" long_name="Foo" description="some description"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- old snapshot -->
   <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]"
@@ -14,4 +14,4 @@
              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=""
              status="U" islast="false" depth="0" />
 
-</dataset>
\ No newline at end of file
+</dataset>
index 8b4092b1e967f9870271a3ad134e4926c39d307a..1f6a485baa5b095485496bcc0266067b506c5440 100644 (file)
@@ -3,10 +3,10 @@
   <!-- This project has a root_id which should be set to NULL (SONAR-1700) -->
   <projects id="1001" scope="PRJ" qualifier="TRK" kee="foo" root_id="12345"
             name="name" long_name="long name" description="description"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[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-23 00:00:00.00" build_date="2010-12-23 00:00:00.00" version="[null]" path=""
              status="U" islast="false" depth="0" />
 
-</dataset>
\ No newline at end of file
+</dataset>
index e5169508831108715beee75f5495b386e43bfd53..c4cc6d2ff4a1e2b2551beb6e0b35345d3dc1fac2 100644 (file)
@@ -3,7 +3,7 @@
   <!-- other project -->
   <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]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[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="3000" project_id="1000" parent_snapshot_id="[null]" root_project_id="1000" root_snapshot_id="[null]"
              scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" build_date="2008-11-01 13:58:00.00" version="[null]" path=""
@@ -13,7 +13,7 @@
   <!-- new project -->
   <projects id="1001" scope="PRJ" qualifier="TRK" kee="foo" root_id="[null]"
             name="Foo" long_name="Foo" description="some description"
-            enabled="true" language="java" copy_resource_id="10" person_id="[null]" />
+            enabled="true" language="java" copy_resource_id="10" person_id="[null]" path="[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 bfa0198e5b9e9a64b19e36c24eff183a9e70402b..9fc216c25c0ac584c9ecda6b70d62be1b4627f5d 100644 (file)
@@ -3,7 +3,7 @@
   <!-- other project -->
   <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]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[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="3000" project_id="1000" parent_snapshot_id="[null]" root_project_id="1000" root_snapshot_id="[null]"
              scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" build_date="2008-11-01 13:58:00.00" version="[null]" path=""
   <!-- new project -->
   <projects id="1001" scope="PRJ" qualifier="TRK" kee="foo" root_id="[null]"
             name="Foo" long_name="Foo" description="some description"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <projects id="1002" scope="DIR" qualifier="PAC" kee="foo:org.foo" root_id="1001"
             name="org.foo" long_name="org.foo" description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="/src/main/java/org/foo" />
 
   <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=""
@@ -27,4 +27,4 @@
              scope="DIR" qualifier="PAC" created_at="2010-12-25 00:00:00.00" build_date="2010-12-25 00:00:00.00" version="[null]" path="3001."
              status="U" islast="false" depth="1"/>
 
-</dataset>
\ No newline at end of file
+</dataset>
index 7c4ab1f4008f444e4a5234cd2f8f18ed5f6b334f..52fb16bf0b98b2345f302d07860f39044bec83d2 100644 (file)
@@ -3,7 +3,7 @@
   <!-- other project -->
   <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]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[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="3000" project_id="1000" parent_snapshot_id="[null]" root_project_id="1000" root_snapshot_id="[null]"
              scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" build_date="2008-11-01 13:58:00.00" version="[null]" path=""
@@ -13,7 +13,7 @@
   <!-- new project -->
   <projects id="1001" scope="PRJ" qualifier="TRK" kee="foo" root_id="[null]"
             name="Foo" long_name="Foo" description="some description"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <projects id="1002" scope="PRJ" qualifier="LIB" kee="junit:junit" root_id="[null]"
             name="junit:junit" long_name="junit:junit" description="[null]"
@@ -31,4 +31,4 @@
              scope="PRJ" qualifier="LIB" created_at="2010-12-25 00:00:00.00" build_date="2010-12-25 00:00:00.00" version="3.2" path=""
              status="P" islast="false" depth="0" />
 
-</dataset>
\ No newline at end of file
+</dataset>
index a36b177dafb6d8edd453ee7bbf911486e2fb535a..7a122621b183183e302c23eff1dcf7275bf5d2bf 100644 (file)
@@ -3,7 +3,7 @@
   <!-- other project -->
   <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]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[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="3000" project_id="1000" parent_snapshot_id="[null]" root_project_id="1000" root_snapshot_id="[null]"
              scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" build_date="2008-11-01 13:58:00.00" version="[null]" path=""
   <!-- new project -->
   <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]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <projects id="1002" scope="PRJ" qualifier="BRC" kee="a" root_id="1001"
             name="A" long_name="A" description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="/moduleA" />
 
   <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]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="/moduleB" />
 
   <projects id="1004" scope="PRJ" qualifier="BRC" kee="b1" root_id="1001"
             name="B1" long_name="B1" description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="/moduleB1" />
 
 
   <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" root_project_id="1001" parent_snapshot_id="[null]"  root_snapshot_id="[null]"
@@ -45,4 +45,4 @@
              status="U" islast="false" depth="2" />
 
 
-</dataset>
\ No newline at end of file
+</dataset>
index 9f7c802b57efcf8fe760008b0ecb77d74c05690c..518d992a4a8fe49b2f87887ea74ae4be261a5510 100644 (file)
@@ -3,7 +3,7 @@
   <!-- other project -->
   <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]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[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="3000" project_id="1000" parent_snapshot_id="[null]" root_project_id="1000" root_snapshot_id="[null]"
              scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" build_date="2008-11-01 13:58:00.00" version="[null]" path=""
   <!-- new project -->
   <projects id="1001" scope="PRJ" qualifier="TRK" kee="foo" root_id="[null]"
             name="Foo" long_name="Foo" description="some description"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[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=""
              status="U" islast="false" depth="0" />
 
-</dataset>
\ No newline at end of file
+</dataset>
index 4fe4bcf5894f62f27fc71c624297150c76e42d2c..a668b5f34577c172fc169f3535a89ee3f708e9f2 100644 (file)
@@ -2,7 +2,7 @@
 
   <projects id="1001" scope="PRJ" qualifier="TRK" kee="foo" root_id="[null]"
             name="new name" long_name="new name" description="new description"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- old snapshot -->
   <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]"
@@ -14,4 +14,4 @@
              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=""
              status="U" islast="false" depth="0" />
 
-</dataset>
\ No newline at end of file
+</dataset>
index 23570debd77fe68aafd5e5a790d5907fb1c0984a..9146bc2749eb022273ee0f22c6895b1a621646bf 100644 (file)
@@ -2,10 +2,10 @@
 
   <projects id="1001" scope="PRJ" qualifier="TRK" kee="foo" root_id="[null]"
             name="old name" long_name="old name" description="old description"
-            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" />
+            enabled="true" language="java" copy_resource_id="[null]" person_id="[null]" path="[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-23 00:00:00.00" build_date="2010-12-23 00:00:00.00" version="[null]" path=""
              status="U" islast="false" depth="0" />
 
-</dataset>
\ No newline at end of file
+</dataset>
index 24595450626096f242731566ee032df84b6cd274..411d46fcf794de380ffd095a557519e6c784e1a0 100644 (file)
@@ -33,7 +33,7 @@ import java.util.List;
  */
 public class DatabaseVersion implements BatchComponent, ServerComponent {
 
-  public static final int LAST_VERSION = 485;
+  public static final int LAST_VERSION = 486;
 
   public static enum Status {
     UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL
index cbf8cd69121e4b43ef4e8948a821e19d57314a8b..eeae6e4d05376739a75d3f02d6ca491537807d30 100644 (file)
@@ -28,6 +28,7 @@ public class ResourceDto {
   private String name;
   private String longName;
   private Long rootId;
+  private String path;
   private String scope;
   private String qualifier;
   private boolean enabled = true;
@@ -73,6 +74,15 @@ public class ResourceDto {
     return this;
   }
 
+  public String getPath() {
+    return path;
+  }
+
+  public ResourceDto setPath(String s) {
+    this.path = s;
+    return this;
+  }
+
   public String getLongName() {
     return longName;
   }
index c122d2ded634bba2223c7c9e0d3af93840f93ec2..d4192efcb7d6cf19dbfadee462dd4e63445db5fc 100644 (file)
@@ -197,6 +197,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('482');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('483');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('484');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('485');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('486');
 
 INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
 ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
index cef8abb9bf6db442d275ea6468af560d3bffc132..1b14ac144700a906393489771a83778ff23a30e5 100644 (file)
@@ -264,6 +264,7 @@ CREATE TABLE "PROJECTS" (
   "SCOPE" VARCHAR(3),
   "QUALIFIER" VARCHAR(10),
   "KEE" VARCHAR(400),
+  "PATH" VARCHAR(2000),
   "ROOT_ID" INTEGER,
   "LANGUAGE" VARCHAR(20),
   "COPY_RESOURCE_ID" INTEGER,
index af2115f0ea87fcc8bc8f2500b6f6fe46be7249b6..f1ad0f06c26de07afcf5c6e8856a8c97563d91c2 100644 (file)
@@ -40,6 +40,7 @@
   <resultMap id="resourceResultMap" type="Resource">
     <id property="id" column="id"/>
     <result property="key" column="kee"/>
+    <result property="path" column="path"/>
     <result property="name" column="name"/>
     <result property="longName" column="long_name"/>
     <result property="rootId" column="root_id"/>
 
   <insert id="insert" parameterType="Resource" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
     insert into projects
-    (name, long_name, description, scope, qualifier, kee, language, root_id, copy_resource_id, person_id, enabled, created_at)
+    (name, long_name, description, scope, qualifier, kee, path, language, root_id, copy_resource_id, person_id, enabled, created_at)
     values (
     #{name}, #{longName}, #{description}, #{scope}, #{qualifier},
-    #{key}, #{language}, #{rootId}, #{copyResourceId},
+    #{key}, #{path}, #{language}, #{rootId}, #{copyResourceId},
     #{personId}, #{enabled}, #{createdAt}
     )
   </insert>
 
   <update id="update" parameterType="Resource">
     update projects set name=#{name}, long_name=#{longName}, description=#{description},
-    scope=#{scope}, qualifier=#{qualifier}, kee=#{key},
+    scope=#{scope}, qualifier=#{qualifier}, kee=#{key}, path=#{path},
     language=#{language}, root_id=#{rootId}, copy_resource_id=#{copyResourceId},
     person_id=#{personId}, enabled=#{enabled} where id=#{id}
   </update>
index b0d66aa7df1bdd36e88ef3711f7ef3525ef639ea..bc8bd0a7c9d36d0e7406979ee48becdb1a86e541 100644 (file)
@@ -100,13 +100,13 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   public void getResources_filter_by_qualifier() {
     setupData("fixture");
 
-    List<ResourceDto> resources = dao.getResources(ResourceQuery.create().setQualifiers(new String[]{"TRK", "BRC"}));
+    List<ResourceDto> resources = dao.getResources(ResourceQuery.create().setQualifiers(new String[] {"TRK", "BRC"}));
     assertThat(resources).onProperty("qualifier").containsOnly("TRK", "BRC");
 
-    resources = dao.getResources(ResourceQuery.create().setQualifiers(new String[]{"XXX"}));
+    resources = dao.getResources(ResourceQuery.create().setQualifiers(new String[] {"XXX"}));
     assertThat(resources).isEmpty();
 
-    resources = dao.getResources(ResourceQuery.create().setQualifiers(new String[]{}));
+    resources = dao.getResources(ResourceQuery.create().setQualifiers(new String[] {}));
     assertThat(resources).hasSize(4);
   }
 
@@ -135,13 +135,13 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   public void getResourceIds_filter_by_qualifier() {
     setupData("fixture");
 
-    List<Long> ids = dao.getResourceIds(ResourceQuery.create().setQualifiers(new String[]{"TRK", "BRC"}));
+    List<Long> ids = dao.getResourceIds(ResourceQuery.create().setQualifiers(new String[] {"TRK", "BRC"}));
     assertThat(ids).containsOnly(1L, 2L);
 
-    ids = dao.getResourceIds(ResourceQuery.create().setQualifiers(new String[]{"XXX"}));
+    ids = dao.getResourceIds(ResourceQuery.create().setQualifiers(new String[] {"XXX"}));
     assertThat(ids).isEmpty();
 
-    ids = dao.getResourceIds(ResourceQuery.create().setQualifiers(new String[]{}));
+    ids = dao.getResourceIds(ResourceQuery.create().setQualifiers(new String[] {}));
     assertThat(ids).hasSize(4);
   }
 
@@ -171,7 +171,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
     setupData("fixture");
 
     List<Long> hugeNbOfIds = newArrayList();
-    for (long i=0; i<4500; i++) {
+    for (long i = 0; i < 4500; i++) {
       hugeNbOfIds.add(i);
     }
     Collection<Component> results = dao.findByIds(hugeNbOfIds);
@@ -215,6 +215,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
     ResourceDto project = new ResourceDto()
       .setKey("org.struts:struts").setScope(Scopes.PROJECT).setQualifier(Qualifiers.PROJECT)
       .setName("Struts").setLongName("Apache Struts").setLanguage("java").setDescription("MVC Framework")
+      .setPath("/foo/bar")
       .setId(1L);
 
     dao.insertOrUpdate(project);
@@ -229,7 +230,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
 
     ResourceDto file1 = new ResourceDto()
       .setKey("org.struts:struts:org.struts.Action").setScope(Scopes.FILE).setQualifier(Qualifiers.FILE)
-      .setLanguage("java").setName("Action").setLongName("org.struts.Action");
+      .setLanguage("java").setName("Action").setLongName("org.struts.Action").setPath("/foo/bar");
     ResourceDto file2 = new ResourceDto()
       .setKey("org.struts:struts:org.struts.Filter").setScope(Scopes.FILE).setQualifier(Qualifiers.FILE)
       .setLanguage("java").setName("Filter").setLongName("org.struts.Filter");
@@ -238,7 +239,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
 
     assertThat(file1.getId()).isNotNull();
     assertThat(file2.getId()).isNotNull();
-    checkTables("insert", new String[]{"created_at"}, "projects");
+    checkTables("insert", new String[] {"created_at"}, "projects");
 
     // SONAR-3636 : created_at must be fed when inserting a new entry in the 'projects' table
     ResourceDto fileLoadedFromDB = dao.getResource(file1.getId());
@@ -267,7 +268,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_find_children_component_ids_for_unsecured_project(){
+  public void should_find_children_component_ids_for_unsecured_project() {
     setupData("fixture");
 
     assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("org.struts:struts"), null, "user")).hasSize(4);
@@ -280,7 +281,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_find_children_component_ids_for_secured_project_for_user(){
+  public void should_find_children_component_ids_for_secured_project_for_user() {
     setupData("should_find_children_component_ids_for_secured_project_for_user");
 
     assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("org.struts:struts"), 100, "user")).hasSize(4);
@@ -293,7 +294,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_find_children_component_ids_for_secured_project_for_group(){
+  public void should_find_children_component_ids_for_secured_project_for_group() {
     setupData("should_find_children_component_ids_for_secured_project_for_group");
 
     assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("org.struts:struts"), 100, "user")).hasSize(4);
@@ -306,7 +307,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_find_component_by_key(){
+  public void should_find_component_by_key() {
     setupData("fixture");
 
     assertThat(dao.findByKey("org.struts:struts")).isNotNull();
@@ -315,7 +316,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_find_component_by_id(){
+  public void should_find_component_by_id() {
     setupData("fixture");
 
     assertThat(dao.findById(1L)).isNotNull();
@@ -324,20 +325,20 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_select_projects_by_qualifiers(){
+  public void should_select_projects_by_qualifiers() {
     setupData("fixture-including-ghost-projects-and-technical-project");
 
     List<Component> components = dao.selectProjectsByQualifiers(newArrayList("TRK"));
     assertThat(components).hasSize(1);
     assertThat(components.get(0).key()).isEqualTo("org.struts:struts");
-    assertThat(((ComponentDto)components.get(0)).getId()).isEqualTo(1L);
+    assertThat(((ComponentDto) components.get(0)).getId()).isEqualTo(1L);
 
     assertThat(dao.selectProjectsIncludingNotCompletedOnesByQualifiers(newArrayList("unknown"))).isEmpty();
     assertThat(dao.selectProjectsIncludingNotCompletedOnesByQualifiers(Collections.<String>emptyList())).isEmpty();
   }
 
   @Test
-  public void should_select_projects_including_not_finished_by_qualifiers(){
+  public void should_select_projects_including_not_finished_by_qualifiers() {
     setupData("fixture-including-ghost-projects-and-technical-project");
 
     List<Component> components = dao.selectProjectsIncludingNotCompletedOnesByQualifiers(newArrayList("TRK"));
@@ -348,7 +349,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_select_ghosts_projects_by_qualifiers(){
+  public void should_select_ghosts_projects_by_qualifiers() {
     setupData("fixture-including-ghost-projects-and-technical-project");
 
     List<Component> components = dao.selectGhostsProjects(newArrayList("TRK"));
@@ -360,7 +361,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_select_provisioned_projects_by_qualifiers(){
+  public void should_select_provisioned_projects_by_qualifiers() {
     setupData("fixture-including-ghost-projects-and-technical-project");
 
     List<ResourceDto> components = dao.selectProvisionedProjects(newArrayList("TRK"));
@@ -372,7 +373,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   }
 
   @Test
-  public void should_select_provisioned_project_by_key(){
+  public void should_select_provisioned_project_by_key() {
     setupData("fixture-including-ghost-projects-and-technical-project");
 
     String key = "org.sample:sample";
@@ -380,7 +381,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
     assertThat(dao.selectProvisionedProject("unknown")).isNull();
   }
 
-  private List<String> getKeys(final List<Component> components){
+  private List<String> getKeys(final List<Component> components) {
     return newArrayList(Iterables.transform(components, new Function<Component, String>() {
       @Override
       public String apply(@Nullable Component input) {
index ff2c102b20b72d867cfb51c6dd3ffdd991649105..5d8176e038308089a56544582dd42167e3c66178 100644 (file)
@@ -55,7 +55,7 @@ public class AuthorDaoTest extends AbstractDaoTestCase {
 
     dao.insertAuthor("godin", 13L);
 
-    checkTables("shouldInsertAuthor", new String[]{"created_at", "updated_at"}, "authors");
+    checkTables("shouldInsertAuthor", new String[] {"created_at", "updated_at"}, "authors");
   }
 
   @Test
@@ -75,7 +75,7 @@ public class AuthorDaoTest extends AbstractDaoTestCase {
     dao.insertAuthorAndDeveloper(login, resourceDto);
 
     checkTables("shouldInsertAuthorAndDeveloper",
-      new String[]{"created_at", "updated_at", "copy_resource_id", "description", "enabled", "kee", "language", "long_name", "person_id", "root_id", "scope"},
+      new String[] {"created_at", "updated_at", "copy_resource_id", "description", "enabled", "kee", "path", "language", "long_name", "person_id", "root_id", "scope"},
       "authors", "projects");
   }
 
@@ -89,7 +89,7 @@ public class AuthorDaoTest extends AbstractDaoTestCase {
     } catch (RuntimeException ex) {
     }
 
-    checkTables("shouldPreventAuthorsDuplication", new String[]{"created_at", "updated_at"}, "authors");
+    checkTables("shouldPreventAuthorsDuplication", new String[] {"created_at", "updated_at"}, "authors");
   }
 
   @Test
@@ -106,7 +106,7 @@ public class AuthorDaoTest extends AbstractDaoTestCase {
     }
 
     checkTables("shouldPreventAuthorsAndDevelopersDuplication",
-      new String[]{"created_at", "updated_at", "copy_resource_id", "description", "enabled", "kee", "language", "long_name", "person_id", "root_id", "scope"},
+      new String[] {"created_at", "updated_at", "copy_resource_id", "description", "enabled", "kee", "path", "language", "long_name", "person_id", "root_id", "scope"},
       "authors", "projects");
   }
 }
index 83f1ff3676ed0b16de6e5277ddf5e4731a1ea7b7..3d2063f3797c3f9be68e6fc4ca540f3a48a3eca1 100644 (file)
@@ -9,17 +9,17 @@ What has been changed : purge_status=1 on snapshot 4 (PRJ) and snapshots 5 and 6
   <!-- the project -->
   <projects id="1" enabled="[true]" root_id="[null]" created_at="[null]"
             long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- the directory -->
   <projects id="2" enabled="[true]" root_id="1" created_at="[null]"
             long_name="[null]" scope="DIR" qualifier="DIR" kee="project:my/dir" name="my/dir"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- the file -->
   <projects id="3" enabled="[true]" root_id="1" created_at="[null]"
             long_name="[null]" scope="FIL" qualifier="FIL" kee="project:my/dir/File.java" name="my/dir/File.java"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- do not purge last snapshots -->
   <snapshots id="1"
@@ -85,4 +85,4 @@ What has been changed : purge_status=1 on snapshot 4 (PRJ) and snapshots 5 and 6
              <!--period5_mode="[null]" period5_param="[null]" period5_date="[null]"-->
              <!--depth="[null]" scope="FIL" qualifier="FIL" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>-->
 
-</dataset>
\ No newline at end of file
+</dataset>
index a3445a40a64c2eab8cd57967a01f2389f395a066..292bc88e7c869963de21b0a475c9489baaf5e13b 100644 (file)
@@ -3,17 +3,17 @@
   <!-- the project -->
   <projects id="1" enabled="[true]" root_id="[null]" created_at="[null]"
             long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"/>
 
   <!-- the directory -->
   <projects id="2" enabled="[true]" root_id="1" created_at="[null]"
             long_name="[null]" scope="DIR" qualifier="DIR" kee="project:my/dir" name="my/dir"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- the file -->
   <projects id="3" enabled="[true]" root_id="1" created_at="[null]"
             long_name="[null]" scope="FIL" qualifier="FIL" kee="project:my/dir/File.java" name="my/dir/File.java"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- do not purge last snapshots -->
   <snapshots id="1"
@@ -79,4 +79,4 @@
              period5_mode="[null]" period5_param="[null]" period5_date="[null]"
              depth="[null]" scope="FIL" qualifier="FIL" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
 
-</dataset>
\ No newline at end of file
+</dataset>
index 96c616fb46f646b56b2b6ad993731d697453ab5c..0b1651d2ae25bbaa606a6eedc3c08d67d1245d8a 100644 (file)
@@ -10,17 +10,17 @@ What has been changed :
   <!-- the project -->
   <projects id="1" enabled="[false]" root_id="[null]" created_at="[null]"
             long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- the directory -->
   <projects id="2" enabled="[false]" root_id="1" created_at="[null]"
             long_name="[null]" scope="DIR" qualifier="DIR" kee="project:my/dir" name="my/dir"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- the file -->
   <projects id="3" enabled="[false]" root_id="1" created_at="[null]"
             long_name="[null]" scope="FIL" qualifier="FIL" kee="project:my/dir/File.java" name="my/dir/File.java"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <snapshots id="1"
              project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
@@ -53,4 +53,4 @@ What has been changed :
              period5_mode="[null]" period5_param="[null]" period5_date="[null]"
              depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
 
-</dataset>
\ No newline at end of file
+</dataset>
index b943a8f0ea6a586e1ad79a9fd04a557c58ad71ae..61e32cc1f089633d9d0f475da54d2fb98577941b 100644 (file)
@@ -3,17 +3,17 @@
   <!-- the project -->
   <projects id="1" enabled="[true]" root_id="[null]" created_at="[null]"
             long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- the directory -->
   <projects id="2" enabled="[true]" root_id="1" created_at="[null]"
             long_name="[null]" scope="DIR" qualifier="DIR" kee="project:my/dir" name="my/dir"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <!-- the file -->
   <projects id="3" enabled="[true]" root_id="1" created_at="[null]"
             long_name="[null]" scope="FIL" qualifier="FIL" kee="project:my/dir/File.java" name="my/dir/File.java"
-            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
   <snapshots id="1"
              project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
@@ -46,4 +46,4 @@
              period5_mode="[null]" period5_param="[null]" period5_date="[null]"
              depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
 
-</dataset>
\ No newline at end of file
+</dataset>
index d80268aff4e984a2aaf89b254a1592c1fdb3ca8c..9844d9648851a0f3f3b915e6d719bfa0c69e802c 100644 (file)
@@ -3,7 +3,7 @@
   <!-- the project -->
   <projects id="1" enabled="[true]" created_at="[null]"
             long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
-            root_id="[null]" description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            root_id="[null]" description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
 
   <!-- snapshot already purged -->
@@ -40,4 +40,4 @@
              period5_mode="[null]" period5_param="[null]" period5_date="[null]"
              depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
 
-</dataset>
\ No newline at end of file
+</dataset>
index 23490655cbed0cca1cc41792cc670c55bf7f36aa..7ab36ca2e6c5585c4e8b6d4c056501911d7083e2 100644 (file)
@@ -3,7 +3,7 @@
   <!-- the project -->
   <projects id="1" enabled="[true]" created_at="[null]"
             long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project"
-            root_id="[null]" description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" />
+            root_id="[null]" description="[null]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" />
 
 
   <!-- snapshot already purged -->
@@ -40,4 +40,4 @@
              period5_mode="[null]" period5_param="[null]" period5_date="[null]"
              depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00" version="[null]" path="[null]"/>
 
-</dataset>
\ No newline at end of file
+</dataset>
index 27016ad3471555274d68fbeb683ee3906335e5c6..aeadd58b98330b924123d928d973c9bb7d9e00be 100644 (file)
@@ -2,10 +2,10 @@
 
   <projects id="1" root_id="[null]" scope="FIL" qualifier="FIL" kee="org.struts:struts:org.struts.Action" name="Action"
             description="[null]" long_name="org.struts.Action"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" />
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="/foo/bar" />
 
   <projects id="2" root_id="[null]" scope="FIL" qualifier="FIL" kee="org.struts:struts:org.struts.Filter" name="Filter"
             description="[null]" long_name="org.struts.Filter"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" />
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]" />
 
 </dataset>
index 4a59dd793f1dbca42c5cb609afc5945d4181fcb5..60bc0572238848732db50abfeb5bb20bbaec9720 100644 (file)
@@ -2,6 +2,6 @@
 
   <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
             description="MVC Framework" long_name="Apache Struts"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="/foo/bar"/>
 
 </dataset>
index dcd5ae6480bd52d1606462a1972e1b646fab9b09..fdd155a71a6fc07f74964094a784dfd700d6c22a 100644 (file)
@@ -2,6 +2,6 @@
 
   <projects id="1" root_id="200" scope="PRJ" qualifier="TRK" kee="old key" name="old name"
             description="old name" long_name="old long name"
-            enabled="[false]" language="old" copy_resource_id="2" person_id="3" created_at="[null]"/>
+            enabled="[false]" language="old" copy_resource_id="2" person_id="3" created_at="[null]" path="/old/foo/bar"/>
 
 </dataset>
index 4613c167d3185f200073f538d1311778fad0e5ec..7a1469afe6b3d1c2a6e9e3eae237161891f13d94 100644 (file)
@@ -3,48 +3,48 @@
   <!-- root project -->
   <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
             description="[null]" long_name="Apache Struts"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** First sub project **************** -->
   <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
             scope="PRJ" qualifier="BRC" long_name="Struts Core"
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="org.struts:struts-core:org.struts"
               name="org.struts" root_id="2"
               description="[null]"
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="CLA" kee="org.struts:struts-core:org.struts.RequestContext"
             name="RequestContext" root_id="2"
             description="[null]"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Second sub project **************** -->
   <projects id="5" root_id="1" kee="org.struts:struts-ui" name="Struts UI"
             scope="PRJ" qualifier="BRC" long_name="Struts UI"
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="6" scope="DIR" qualifier="PAC" kee="org.struts:struts-ui:org.struts"
               name="org.struts" root_id="5"
               description="[null]"
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="7" scope="FIL" qualifier="CLA" kee="org.struts:struts-ui:org.struts.RequestContext"
             name="RequestContext" root_id="5"
             description="[null]"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Another independent project **************** -->
   <projects id="8" root_id="[null]" kee="foo:struts-core" name="Foo Struts Core"
             scope="PRJ" qualifier="BRC" long_name="Foo Struts Core"
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 </dataset>
index b9fc934e5465a6d89a51994f057e5cd8609146ad..85e3d646568e472d92e8e7b1d8d7e2b6e448efb0 100644 (file)
@@ -3,48 +3,48 @@
   <!-- root project -->
   <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.apache.struts:struts" name="Struts"
             description="[null]" long_name="Apache Struts"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** First sub project **************** -->
   <projects id="2" root_id="1" kee="org.apache.struts:struts-core" name="Struts Core"
             scope="PRJ" qualifier="BRC" long_name="Struts Core"
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="org.apache.struts:struts-core:org.struts"
               name="org.struts" root_id="2"
               description="[null]"
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="CLA" kee="org.apache.struts:struts-core:org.struts.RequestContext"
             name="RequestContext" root_id="2"
             description="[null]"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Second sub project **************** -->
   <projects id="5" root_id="1" kee="org.apache.struts:struts-ui" name="Struts UI"
             scope="PRJ" qualifier="BRC" long_name="Struts UI"
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="6" scope="DIR" qualifier="PAC" kee="org.apache.struts:struts-ui:org.struts"
               name="org.struts" root_id="5"
               description="[null]"
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="7" scope="FIL" qualifier="CLA" kee="org.apache.struts:struts-ui:org.struts.RequestContext"
             name="RequestContext" root_id="5"
             description="[null]"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Another independent project **************** -->
   <projects id="8" root_id="[null]" kee="foo:struts-core" name="Foo Struts Core"
             scope="PRJ" qualifier="BRC" long_name="Foo Struts Core"
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 </dataset>
index 71ed68a61aeaf8f2b642a0069e6da805dc1e4b6b..4d5611bdabda500d77e858e11914c245ce958f00 100644 (file)
@@ -3,48 +3,48 @@
   <!-- root project -->
   <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
             description="[null]" long_name="Apache Struts"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** First sub project **************** -->
   <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
             scope="PRJ" qualifier="BRC" long_name="Struts Core"
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="org.struts:struts-core:org.struts"
               name="org.struts" root_id="2"
               description="[null]"
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="CLA" kee="org.struts:struts-core:org.struts.RequestContext"
             name="RequestContext" root_id="2"
             description="[null]"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Second sub project **************** -->
   <projects id="5" root_id="1" kee="org.struts:struts-web" name="Struts UI"
             scope="PRJ" qualifier="BRC" long_name="Struts UI"
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="6" scope="DIR" qualifier="PAC" kee="org.struts:struts-web:org.struts"
               name="org.struts" root_id="5"
               description="[null]"
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="7" scope="FIL" qualifier="CLA" kee="org.struts:struts-web:org.struts.RequestContext"
             name="RequestContext" root_id="5"
             description="[null]"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Another independent project **************** -->
   <projects id="8" root_id="[null]" kee="foo:struts-core" name="Foo Struts Core"
             scope="PRJ" qualifier="BRC" long_name="Foo Struts Core"
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 </dataset>
index 54bf43d58021be6d210af471779de0a72b7e5ece..0da70e1fed9ba240a4faeb639e40cac91900e022 100644 (file)
@@ -2,43 +2,43 @@
 
   <!-- root project -->
   <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.apache.struts:struts" name="Struts"
-            description="[null]" long_name="Apache Struts" 
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" long_name="Apache Struts"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** First sub project **************** -->
   <projects id="2" root_id="1" kee="org.apache.struts:struts-core" name="Struts Core"
-            scope="PRJ" qualifier="BRC" long_name="Struts Core" 
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            scope="PRJ" qualifier="BRC" long_name="Struts Core"
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="org.apache.struts:struts-core:org.struts"
               name="org.struts" root_id="2"
-              description="[null]" 
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              description="[null]"
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="CLA" kee="org.apache.struts:struts-core:org.struts.RequestContext"
             name="RequestContext" root_id="2"
-            description="[null]" 
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Second sub project THAT HAS A DIFFERENT GROUP ID => MUST NOT BE UPDATED **************** -->
   <projects id="5" root_id="1" kee="foo:struts-ui" name="Struts UI"
-            scope="PRJ" qualifier="BRC" long_name="Struts UI" 
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            scope="PRJ" qualifier="BRC" long_name="Struts UI"
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="6" scope="DIR" qualifier="PAC" kee="foo:struts-ui:org.struts"
               name="org.struts" root_id="5"
-              description="[null]" 
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              description="[null]"
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="7" scope="FIL" qualifier="CLA" kee="foo:struts-ui:org.struts.RequestContext"
             name="RequestContext" root_id="5"
-            description="[null]" 
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 </dataset>
index 93f747e9d72c87fe38653469b8a51dc1ab89a7a1..8b075699918e42bc87544d127fe6faaaddd03bef 100644 (file)
@@ -2,43 +2,43 @@
 
   <!-- root project -->
   <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
-            description="[null]" long_name="Apache Struts" 
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" long_name="Apache Struts"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** First sub project **************** -->
   <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
-            scope="PRJ" qualifier="BRC" long_name="Struts Core" 
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            scope="PRJ" qualifier="BRC" long_name="Struts Core"
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="org.struts:struts-core:org.struts"
               name="org.struts" root_id="2"
-              description="[null]" 
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              description="[null]"
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="CLA" kee="org.struts:struts-core:org.struts.RequestContext"
             name="RequestContext" root_id="2"
-            description="[null]" 
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Second sub project THAT HAS A DIFFERENT GROUP ID => MUST NOT BE UPDATED **************** -->
   <projects id="5" root_id="1" kee="foo:struts-ui" name="Struts UI"
-            scope="PRJ" qualifier="BRC" long_name="Struts UI" 
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            scope="PRJ" qualifier="BRC" long_name="Struts UI"
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="6" scope="DIR" qualifier="PAC" kee="foo:struts-ui:org.struts"
               name="org.struts" root_id="5"
-              description="[null]" 
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              description="[null]"
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="7" scope="FIL" qualifier="CLA" kee="foo:struts-ui:org.struts.RequestContext"
             name="RequestContext" root_id="5"
-            description="[null]" 
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 </dataset>
index 178b172ddd0aa7d6558dba2164fd78ee30fb8869..894780b152a0e39aed8cdb23e72e839da5d227fc 100644 (file)
@@ -2,51 +2,51 @@
 
   <!-- root project -->
   <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
-            description="[null]" long_name="Apache Struts" 
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]" long_name="Apache Struts"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** First sub project **************** -->
   <!-- ONLY THIS PROJECT MUST HAVE BEEN UPDATED            -->
   <!--                                                     -->
   <projects id="2" root_id="1" kee="struts:core" name="Struts Core"
-            scope="PRJ" qualifier="BRC" long_name="Struts Core" 
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/>
+            scope="PRJ" qualifier="BRC" long_name="Struts Core"
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="struts:core:org.struts"
               name="org.struts" root_id="2"
-              description="[null]" 
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              description="[null]"
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="CLA" kee="struts:core:org.struts.RequestContext"
             name="RequestContext" root_id="2"
-            description="[null]" 
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Second sub project **************** -->
   <projects id="5" root_id="1" kee="org.struts:struts-ui" name="Struts UI"
-            scope="PRJ" qualifier="BRC" long_name="Struts UI" 
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            scope="PRJ" qualifier="BRC" long_name="Struts UI"
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- directory -->
   <projects long_name="org.struts" id="6" scope="DIR" qualifier="PAC" kee="org.struts:struts-ui:org.struts"
               name="org.struts" root_id="5"
-              description="[null]" 
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+              description="[null]"
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="7" scope="FIL" qualifier="CLA" kee="org.struts:struts-ui:org.struts.RequestContext"
             name="RequestContext" root_id="5"
-            description="[null]" 
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            description="[null]"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 
   <!-- **************** Another independent project **************** -->
   <projects id="8" root_id="[null]" kee="foo:struts-core" name="Foo Struts Core"
-            scope="PRJ" qualifier="BRC" long_name="Foo Struts Core" 
-            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]"/>
+            scope="PRJ" qualifier="BRC" long_name="Foo Struts Core"
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" created_at="[null]" path="[null]"/>
 
 </dataset>
index 657ed1d3afa59cc3bf9e038f52408443f58edbd7..e37f0714b222f34710007d47a93e2ced612eb20a 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.database.BaseIdentifiable;
 import org.sonar.api.resources.ProjectLink;
 import org.sonar.api.resources.Resource;
 
+import javax.annotation.Nullable;
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
 import javax.persistence.Entity;
@@ -54,6 +55,7 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable {
   public static final int DESCRIPTION_COLUMN_SIZE = 2000;
   public static final int NAME_COLUMN_SIZE = 256;
   public static final int KEY_SIZE = 400;
+  public static final int PATH_SIZE = 2000;
 
   @Column(name = "name", updatable = true, nullable = true, length = NAME_COLUMN_SIZE)
   private String name;
@@ -82,6 +84,9 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable {
   @Column(name = "root_id", updatable = true, nullable = true)
   private Integer rootId;
 
+  @Column(name = "path", updatable = true, nullable = true, length = PATH_SIZE)
+  private String path;
+
   @Column(name = "copy_resource_id", updatable = true, nullable = true)
   private Integer copyResourceId;
 
@@ -103,6 +108,10 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable {
     this.createdAt = new Date();
   }
 
+  public ResourceModel(String scope, String key, String qualifier, Integer rootId, String name) {
+    this(scope, key, qualifier, rootId, null, name);
+  }
+
   /**
    * <p>Creates a resource model</p>
    *
@@ -110,14 +119,16 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable {
    * @param key       the rule key. This is the name of the resource, including the path
    * @param qualifier the resource qualifier
    * @param rootId    the rootId for the resource
+   * @param path      the path of the resource
    * @param name      the short name of the resource
    */
-  public ResourceModel(String scope, String key, String qualifier, Integer rootId, String name) {
+  public ResourceModel(String scope, String key, String qualifier, Integer rootId, @Nullable String path, String name) {
     // call this to have the "createdAt" field initialized
     this();
     this.scope = scope;
     this.key = key;
     this.rootId = rootId;
+    this.path = path;
     this.name = name;
     this.qualifier = qualifier;
   }
@@ -257,6 +268,18 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable {
     this.rootId = rootId;
   }
 
+  public String getPath() {
+    return path;
+  }
+
+  public ResourceModel setPath(@Nullable String path) {
+    if (path != null && path.length() > PATH_SIZE) {
+      throw new IllegalArgumentException("Resource path is too long, max is " + PATH_SIZE + " characters. Got : " + path);
+    }
+    this.path = path;
+    return this;
+  }
+
   public String getQualifier() {
     return qualifier;
   }
@@ -282,43 +305,58 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable {
       return true;
     }
     ResourceModel other = (ResourceModel) obj;
-    return new EqualsBuilder()
-        .append(key, other.key)
+    if (StringUtils.isNotBlank(path)) {
+      return new EqualsBuilder()
+        .append(path, other.path)
         .append(enabled, other.enabled)
         .append(rootId, other.rootId)
         .isEquals();
+    }
+    return new EqualsBuilder()
+      .append(key, other.key)
+      .append(enabled, other.enabled)
+      .append(rootId, other.rootId)
+      .isEquals();
   }
 
   @Override
   public int hashCode() {
-    return new HashCodeBuilder(17, 37)
-        .append(key)
+    if (StringUtils.isNotBlank(path)) {
+      return new HashCodeBuilder(17, 37)
+        .append(path)
         .append(enabled)
         .append(rootId)
         .toHashCode();
+    }
+    return new HashCodeBuilder(17, 37)
+      .append(key)
+      .append(enabled)
+      .append(rootId)
+      .toHashCode();
   }
 
   @Override
   public String toString() {
     return new ToStringBuilder(this)
-        .append("id", getId())
-        .append("key", key)
-        .append("scope", scope)
-        .append("qualifier", qualifier)
-        .append("name", name)
-        .append("longName", longName)
-        .append("lang", languageKey)
-        .append("enabled", enabled)
-        .append("rootId", rootId)
-        .append("copyResourceId", copyResourceId)
-        .append("personId", personId)
-        .append("createdAt", createdAt)
-        .toString();
+      .append("id", getId())
+      .append("key", key)
+      .append("scope", scope)
+      .append("qualifier", qualifier)
+      .append("name", name)
+      .append("longName", longName)
+      .append("lang", languageKey)
+      .append("enabled", enabled)
+      .append("rootId", rootId)
+      .append("path", path)
+      .append("copyResourceId", copyResourceId)
+      .append("personId", personId)
+      .append("createdAt", createdAt)
+      .toString();
   }
 
   @Override
   public Object clone() {
-    ResourceModel clone = new ResourceModel(getScope(), getKey(), getQualifier(), getRootId(), getName());
+    ResourceModel clone = new ResourceModel(getScope(), getKey(), getQualifier(), getRootId(), getPath(), getName());
     clone.setDescription(getDescription());
     clone.setEnabled(getEnabled());
     clone.setProjectLinks(getProjectLinks());
@@ -338,6 +376,7 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable {
     model.setEnabled(Boolean.TRUE);
     model.setDescription(resource.getDescription());
     model.setKey(resource.getKey());
+    model.setPath(resource.getPath());
     if (resource.getLanguage() != null) {
       model.setLanguageKey(resource.getLanguage().getKey());
     }
index b770527dec435f7d7ea05ac29de84aac64fef03f..98f9c386bf8b88a4f2a56e6552f0cffab2df2bc7 100644 (file)
@@ -98,8 +98,9 @@ public class Directory extends Resource {
   @Override
   public String toString() {
     return new ToStringBuilder(this)
-        .append("key", getKey())
-        .append("language", language)
-        .toString();
+      .append("key", getKey())
+      .append("path", getPath())
+      .append("language", language)
+      .toString();
   }
 }
index 3e743c1e336ff3261fd4cbe0e3c88dbab1634e3c..7b0fa721d6216465f7628b0ed34ad251e31485ff 100644 (file)
@@ -101,6 +101,10 @@ public class File extends Resource {
   public Directory getParent() {
     if (parent == null) {
       parent = new Directory(directoryKey);
+      String filePath = getPath();
+      if (StringUtils.isNotBlank(filePath)) {
+        parent.setPath(StringUtils.substringBeforeLast(filePath, Directory.SEPARATOR));
+      }
     }
     return parent;
   }
@@ -187,8 +191,9 @@ public class File extends Resource {
   /**
    * Sets the language of the file
    */
-  public void setLanguage(Language language) {
+  public File setLanguage(Language language) {
     this.language = language;
+    return this;
   }
 
   /**
@@ -217,6 +222,7 @@ public class File extends Resource {
   public String toString() {
     return new ToStringBuilder(this)
       .append("key", getKey())
+      .append("path", getPath())
       .append("dir", directoryKey)
       .append("filename", filename)
       .append("language", language)
index 40927c844d9d1b7633d92a6be112bb13f898c1aa..d3cbf2f88ad6544cf3dd2a8f01269e1b9983931c 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.api.resources;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.ToStringBuilder;
 import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.api.utils.WildcardPattern;
 
@@ -33,6 +34,7 @@ import java.util.List;
  */
 public class JavaFile extends Resource {
 
+  private static final String JAVA_SUFFIX = ".java";
   private String filename;
   private String longName;
   private String packageKey;
@@ -110,6 +112,10 @@ public class JavaFile extends Resource {
   public JavaPackage getParent() {
     if (parent == null) {
       parent = new JavaPackage(packageKey);
+      String filePath = getPath();
+      if (StringUtils.isNotBlank(filePath)) {
+        parent.setPath(StringUtils.substringBeforeLast(filePath, Directory.SEPARATOR));
+      }
     }
     return parent;
 
@@ -176,8 +182,8 @@ public class JavaFile extends Resource {
   @Override
   public boolean matchFilePattern(String antPattern) {
     String fileKey = getKey();
-    if (!fileKey.endsWith(".java")) {
-      fileKey += ".java";
+    if (!fileKey.endsWith(JAVA_SUFFIX)) {
+      fileKey += JAVA_SUFFIX;
     }
     // Add wildcard extension if not provided
     if ((antPattern.contains("/") && StringUtils.substringAfterLast(antPattern, "/").indexOf('.') < 0) || antPattern.indexOf('.') < 0) {
@@ -191,6 +197,21 @@ public class JavaFile extends Resource {
     return matcher.match(fileKey);
   }
 
+  public static JavaFile fromIOFile(File file, Project module, boolean unitTest) {
+    if (file == null || !StringUtils.endsWithIgnoreCase(file.getName(), JAVA_SUFFIX)) {
+      return null;
+    }
+    PathResolver.RelativePath relativePath = new PathResolver().relativePath(
+      unitTest ? module.getFileSystem().getTestDirs() : module.getFileSystem().getSourceDirs(),
+      file);
+    if (relativePath != null) {
+      JavaFile sonarFile = fromRelativePath(relativePath.path(), unitTest);
+      sonarFile.setPath(new PathResolver().relativePath(module.getFileSystem().getBasedir(), file));
+      return sonarFile;
+    }
+    return null;
+  }
+
   public static JavaFile fromRelativePath(String relativePath, boolean unitTest) {
     if (relativePath != null) {
       String pacname = null;
@@ -213,7 +234,7 @@ public class JavaFile extends Resource {
    * @return the JavaFile created if exists, null otherwise
    */
   public static JavaFile fromIOFile(File file, List<File> sourceDirs, boolean unitTest) {
-    if (file == null || !StringUtils.endsWithIgnoreCase(file.getName(), ".java")) {
+    if (file == null || !StringUtils.endsWithIgnoreCase(file.getName(), JAVA_SUFFIX)) {
       return null;
     }
     PathResolver.RelativePath relativePath = new PathResolver().relativePath(sourceDirs, file);
@@ -235,7 +256,11 @@ public class JavaFile extends Resource {
 
   @Override
   public String toString() {
-    return getKey();
+    return new ToStringBuilder(this)
+      .append("key", getKey())
+      .append("path", getPath())
+      .append("filename", filename)
+      .toString();
   }
 
 }
index 05e30d3013591d750dd915a96712ab732522b0bf..6588de10201bd42a387fd2eb9352ec5ed356afdc 100644 (file)
  */
 package org.sonar.api.resources;
 
+import org.apache.commons.lang.StringUtils;
+
+import javax.annotation.Nullable;
+
 import java.io.Serializable;
 
 /**
  * The interface to implement to create a resource in Sonar
- * 
+ *
  * @since 1.10
  */
 public abstract class Resource implements Serializable {
@@ -122,6 +126,8 @@ public abstract class Resource implements Serializable {
 
   private String key = null;
 
+  private String path = null;
+
   private String effectiveKey = null;
 
   private boolean isExcluded = false;
@@ -182,7 +188,7 @@ public abstract class Resource implements Serializable {
 
   /**
    * Check resource against an Ant pattern, like mypackag?/*Foo.java. It's used for example to match resource exclusions.
-   * 
+   *
    * @param antPattern Ant-like pattern (with **, * and ?). It includes file suffixes.
    * @return true if the resource matches the Ant pattern
    */
@@ -200,6 +206,29 @@ public abstract class Resource implements Serializable {
     return this;
   }
 
+  public String getPath() {
+    return path;
+  }
+
+  public Resource setPath(@Nullable String path) {
+    this.path = normalize(path);
+    return this;
+  }
+
+  private String normalize(@Nullable String path) {
+    if (path == null) {
+      return null;
+    }
+    String normalizedPath = path;
+    if (!normalizedPath.startsWith(Directory.SEPARATOR)) {
+      normalizedPath = Directory.SEPARATOR + normalizedPath;
+    }
+    if (normalizedPath.length() > 1 && normalizedPath.endsWith(Directory.SEPARATOR)) {
+      normalizedPath = normalizedPath.substring(0, normalizedPath.length() - 1);
+    }
+    return normalizedPath;
+  }
+
   public String getEffectiveKey() {
     return effectiveKey;
   }
@@ -240,7 +269,10 @@ public abstract class Resource implements Serializable {
     }
 
     Resource resource = (Resource) o;
-    return key.equals(resource.key);
+    if (StringUtils.isBlank(path)) {
+      return key.equals(resource.key);
+    }
+    return path.equals(resource.path);
 
   }
 
index 256a2f9aa958f80dcb977958dd864586c961c3fb..c8dd3e3b37795e8b8b6830ce23f93ae741b07d4d 100644 (file)
@@ -24,9 +24,11 @@ import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Sets;
+import org.apache.commons.lang.builder.EqualsBuilder;
 import org.sonar.api.scan.filesystem.internal.InputFile;
 
 import javax.annotation.Nullable;
+
 import java.io.FileFilter;
 import java.util.Arrays;
 import java.util.Collection;
@@ -38,6 +40,10 @@ import java.util.Set;
  */
 public class FileQuery {
 
+  private final ListMultimap<String, String> attributes = ArrayListMultimap.create();
+  private final Set<String> inclusions = Sets.newHashSet();
+  private final Set<String> exclusions = Sets.newHashSet();
+
   public static FileQuery on(FileType... types) {
     FileQuery query = new FileQuery();
     for (FileType type : types) {
@@ -54,10 +60,6 @@ public class FileQuery {
     return on(FileType.TEST);
   }
 
-  private final ListMultimap<String, String> attributes = ArrayListMultimap.create();
-  private final Set<String> inclusions = Sets.newHashSet();
-  private final Set<String> exclusions = Sets.newHashSet();
-
   private FileQuery() {
   }
 
@@ -114,5 +116,24 @@ public class FileQuery {
   public FileQuery withFilters(FileFilter... filters) {
     throw new UnsupportedOperationException("TODO");
   }
-}
 
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (obj == this) {
+      return true;
+    }
+    if (obj.getClass() != getClass()) {
+      return false;
+    }
+    FileQuery rhs = (FileQuery) obj;
+    return new EqualsBuilder()
+      .append(attributes, rhs.attributes)
+      .append(exclusions, rhs.exclusions)
+      .append(inclusions, rhs.inclusions)
+      .isEquals();
+  }
+
+}
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/486_add_resource_path_column.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/486_add_resource_path_column.rb
new file mode 100644 (file)
index 0000000..6ae9514
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+#
+# SonarQube 4.2
+# SONAR-926
+#
+class AddResourcePathColumn < ActiveRecord::Migration
+
+  def self.up
+      add_column 'projects', :path, :string, :null => true, :limit => 2000
+  end
+end