]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2127 API: do not automatically create hierarchy of resource tree
authorsimonbrandhof <simon.brandhof@gmail.com>
Fri, 21 Jan 2011 13:32:24 +0000 (14:32 +0100)
committersimonbrandhof <simon.brandhof@gmail.com>
Fri, 21 Jan 2011 13:32:24 +0000 (14:32 +0100)
35 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java
sonar-batch/pom.xml
sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java
sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java
sonar-batch/src/main/java/org/sonar/batch/index/Bucket.java
sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java
sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java
sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java
sonar-batch/src/main/java/org/sonar/batch/index/LinkPersister.java
sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java
sonar-batch/src/main/java/org/sonar/batch/index/PersistenceManager.java
sonar-batch/src/main/java/org/sonar/batch/index/ResourceNotPersistedException.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java
sonar-batch/src/main/java/org/sonar/batch/index/SourcePersister.java
sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
sonar-batch/src/test/java/org/sonar/batch/index/DefaultPersistenceManagerTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java
sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java
sonar-batch/src/test/java/org/sonar/batch/index/SourcePersisterTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/DuplicatedSourceException.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Library.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Qualifiers.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Scopes.java
sonar-server/pom.xml
tests/integration/tests/pom.xml

index 1f7d5e5982fa97ee7aefb22a15bc8488806178fa..da1415f6fde46e74c4cf281e06f3a485a1f2a47c 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.plugins.core.timemachine;
 
 import com.google.common.collect.*;
+import org.apache.commons.lang.StringUtils;
 import org.sonar.api.batch.Decorator;
 import org.sonar.api.batch.DecoratorContext;
 import org.sonar.api.batch.DependedUpon;
@@ -28,6 +29,7 @@ import org.sonar.api.measures.*;
 import org.sonar.api.resources.Project;
 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.RulePriority;
 import org.sonar.api.rules.Violation;
@@ -72,7 +74,9 @@ public class NewViolationsDecorator implements Decorator {
   }
 
   private boolean shouldDecorateResource(Resource resource, DecoratorContext context) {
-    return !ResourceUtils.isUnitTestClass(resource) && context.getMeasure(CoreMetrics.NEW_VIOLATIONS) == null;
+    return
+        (StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope()) || StringUtils.equals(Scopes.FILE, resource.getScope()))
+            && !ResourceUtils.isUnitTestClass(resource) && context.getMeasure(CoreMetrics.NEW_VIOLATIONS) == null;
   }
 
 
index 836d23613e86f7adf7417b3886e66e3ad6d0db7a..310b19f04efe7ea668edb5e60fade7dd0a97b32c 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.plugins.core.timemachine;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
 import org.sonar.api.batch.*;
 import org.sonar.api.measures.Measure;
@@ -30,6 +31,7 @@ import org.sonar.api.measures.MetricFinder;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.resources.ResourceUtils;
+import org.sonar.api.resources.Scopes;
 import org.sonar.batch.components.TimeMachineConfiguration;
 
 import java.util.List;
@@ -114,6 +116,6 @@ public class TendencyDecorator implements Decorator {
   }
 
   private boolean shouldDecorateResource(Resource resource) {
-    return ResourceUtils.isSet(resource) || ResourceUtils.isSpace(resource);
+    return StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope());
   }
 }
index 4e6ddddf74ef33fa8280ff9946dd5c7e0e474f38..68e686f61c8785452a7a8371319af16d933045b3 100644 (file)
 package org.sonar.plugins.core.timemachine;
 
 import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
 import org.sonar.api.batch.*;
 import org.sonar.api.database.model.MeasureModel;
 import org.sonar.api.measures.*;
 import org.sonar.api.qualitymodel.Characteristic;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
+import org.sonar.api.resources.Scopes;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.batch.components.PastMeasuresLoader;
 import org.sonar.batch.components.PastSnapshot;
@@ -73,7 +74,7 @@ public class VariationDecorator implements Decorator {
 
   static boolean shouldCalculateVariations(Resource resource) {
     // measures on files are currently purged, so past measures are not available on files
-    return !ResourceUtils.isEntity(resource);
+    return StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope());
   }
 
   private void calculateVariation(Resource resource, DecoratorContext context, PastSnapshot pastSnapshot) {
index 8170bb55dfe9545634f40971d5e61dec67ba48cf..22574d4a1b7a231843ea0ca4c5da8e6149975e5b 100644 (file)
@@ -31,6 +31,7 @@ import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.measures.RuleMeasure;
+import org.sonar.api.resources.File;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.rules.Rule;
@@ -79,7 +80,7 @@ public class NewViolationsDecoratorTest {
     when(timeMachineConfiguration.getProjectPastSnapshots()).thenReturn(Arrays.asList(pastSnapshot, pastSnapshot2));
 
     context = mock(DecoratorContext.class);
-    resource = mock(Resource.class);
+    resource = new File("com/foo/bar");
     when(context.getResource()).thenReturn(resource);
 
     decorator = new NewViolationsDecorator(timeMachineConfiguration);
index b39f5e600040c96c8a2aff95305351d84446fd17..fd1ae8dffb2c46ffaf48cf8bd9e0010524a61bfb 100644 (file)
       <groupId>org.codehaus.sonar</groupId>
       <artifactId>sonar-deprecated</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.codehaus.sonar</groupId>
+      <artifactId>sonar-java-api</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.codehaus.sonar</groupId>
       <artifactId>sonar-plugin-api</artifactId>
@@ -52,6 +56,8 @@
       <groupId>commons-lang</groupId>
       <artifactId>commons-lang</artifactId>
     </dependency>
+
+    <!-- unit tests -->
     <dependency>
       <groupId>org.codehaus.sonar</groupId>
       <artifactId>sonar-testing-harness</artifactId>
index 24c70220e9dd21dff316c3f908f6de7ccca79b8b..a924fba8ac10e072f105cb786f6a06398f856dd4 100644 (file)
  */
 package org.sonar.batch;
 
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
 import org.sonar.api.batch.Event;
 import org.sonar.api.batch.SensorContext;
 import org.sonar.api.design.Dependency;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.MeasuresFilter;
 import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.ProjectLink;
-import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.*;
 import org.sonar.api.rules.Violation;
 import org.sonar.batch.index.DefaultIndex;
 
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
 public class DefaultSensorContext implements SensorContext {
 
   private DefaultIndex index;
@@ -50,6 +48,30 @@ public class DefaultSensorContext implements SensorContext {
     return project;
   }
 
+  public boolean index(Resource resource) {
+    return index.index(resource);
+  }
+
+  public boolean index(Resource resource, Resource parentReference) {
+    return index.index(resource, parentReference);
+  }
+
+  public boolean isExcluded(Resource reference) {
+    return index.isExcluded(reference);
+  }
+
+  public boolean isIndexed(Resource reference) {
+    return index.isIndexed(reference);
+  }
+
+  public Resource getParent(Resource reference) {
+    return index.getParent(reference);
+  }
+
+  public Collection<Resource> getChildren(Resource reference) {
+    return index.getChildren(reference);
+  }
+
   public Measure getMeasure(Metric metric) {
     return index.getMeasure(project, metric);
   }
@@ -78,6 +100,10 @@ public class DefaultSensorContext implements SensorContext {
     return null;
   }
 
+  public boolean saveResource(Resource resource, Resource parentReference) {
+    return index.index(resource, parentReference);
+  }
+
   public Resource getResource(Resource resource) {
     return index.getResource(resource);
   }
@@ -129,8 +155,8 @@ public class DefaultSensorContext implements SensorContext {
     return index.getOutgoingEdges(resourceOrProject(from));
   }
 
-  public void saveSource(Resource resource, String source) {
-    index.setSource(resource, source);
+  public boolean saveSource(Resource reference, String source) throws DuplicatedSourceException {
+    return index.setSource(reference, source);
   }
 
   public void saveLink(ProjectLink link) {
index ee3ad649957fc33ece55325200999c34a27e3636..eb374de1094de3ef861d4f17b0a63761e0a1f5ad 100644 (file)
@@ -30,6 +30,7 @@ import org.sonar.api.measures.MetricFinder;
 import org.sonar.api.resources.Resource;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -61,8 +62,10 @@ public class PastMeasuresLoader implements BatchExtension {
   }
 
   public List<MeasureModel> getPastMeasures(Resource resource, Snapshot projectSnapshot) {
-    // assume that the resource has already been saved
-    return getPastMeasures(resource.getId(), projectSnapshot);
+    if (isPersisted(resource)) {
+      return getPastMeasures(resource.getId(), projectSnapshot);
+    }
+    return Collections.emptyList();
   }
 
   public List<MeasureModel> getPastMeasures(int resourceId, Snapshot projectSnapshot) {
@@ -78,4 +81,8 @@ public class PastMeasuresLoader implements BatchExtension {
         .setParameter("status", Snapshot.STATUS_PROCESSED)
         .getResultList();
   }
+
+  private boolean isPersisted(Resource resource) {
+    return resource.getId()!=null;
+  }
 }
index 0969f0893339380579e7808d4fd646f72db5fe68..5a19f6ba97d301960eba19e82391d10622d7b8f4 100644 (file)
@@ -50,18 +50,20 @@ public final class Bucket {
     return resource;
   }
 
-  public void setParent(Bucket parent) {
+  public Bucket setParent(Bucket parent) {
     this.parent = parent;
     if (parent != null) {
       parent.addChild(this);
     }
+    return this;
   }
 
-  private void addChild(Bucket child) {
+  private Bucket addChild(Bucket child) {
     if (children == null) {
       children = Lists.newArrayList();
     }
     children.add(child);
+    return this;
   }
 
   private void removeChild(Bucket child) {
index 8f7a9f1e8727c456bab803df5ba74c87a9da4d17..b63bef696fd0ab4aefe6acbeadca671b00fa2078 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.batch.index;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
+import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -75,9 +76,13 @@ public final class DefaultIndex extends SonarIndex {
 
   public void start() {
     Project rootProject = projectTree.getRootProject();
+    doStart(rootProject);
+  }
+
+  void doStart(Project rootProject) {
     Bucket bucket = new Bucket(rootProject);
     buckets.put(rootProject, bucket);
-    persistence.saveProject(rootProject);
+    persistence.saveProject(rootProject, null);
     currentProject = rootProject;
 
     for (Project project : rootProject.getModules()) {
@@ -131,93 +136,6 @@ public final class DefaultIndex extends SonarIndex {
     lock.unlock();
   }
 
-  /**
-   * Does nothing if the resource is already registered.
-   */
-  public Resource addResource(Resource resource) {
-    Bucket bucket = getOrAddBucket(resource);
-    return bucket != null ? bucket.getResource() : null;
-  }
-
-  public Resource getResource(Resource resource) {
-    Bucket bucket = buckets.get(resource);
-    if (bucket != null) {
-      return bucket.getResource();
-    }
-    return null;
-  }
-
-  private Bucket getOrAddBucket(Resource resource) {
-    Bucket bucket = buckets.get(resource);
-    if (bucket != null) {
-      return bucket;
-    }
-
-    if (lock.isLocked() && !ResourceUtils.isLibrary(resource)) {
-      LOG.warn("The following resource has not been registered before saving data: " + resource);
-    }
-
-    resource.setEffectiveKey(calculateResourceEffectiveKey(currentProject, resource));
-    bucket = new Bucket(resource);
-    Bucket parentBucket = null;
-    Resource parent = resource.getParent();
-    if (parent != null) {
-      parentBucket = getOrAddBucket(parent);
-    } else if (!ResourceUtils.isLibrary(resource)) {
-      parentBucket = buckets.get(currentProject);
-    }
-    bucket.setParent(parentBucket);
-    buckets.put(resource, bucket);
-
-    boolean excluded = checkExclusion(resource, parentBucket);
-    if (!excluded) {
-      persistence.saveResource(currentProject, resource);
-    }
-    return bucket;
-  }
-
-  static String calculateResourceEffectiveKey(Project project, Resource resource) {
-    String effectiveKey = resource.getKey();
-    if (!StringUtils.equals(Resource.SCOPE_SET, resource.getScope())) {
-      // not a project nor a library
-      effectiveKey = new StringBuilder(ResourceModel.KEY_SIZE)
-          .append(project.getKey())
-          .append(':')
-          .append(resource.getKey())
-          .toString();
-    }
-    return effectiveKey;
-  }
-
-  private boolean checkExclusion(Resource resource, Bucket parent) {
-    boolean excluded = (parent != null && parent.isExcluded()) || (resourceFilters != null && resourceFilters.isExcluded(resource));
-    resource.setExcluded(excluded);
-    return excluded;
-  }
-
-  public List<Resource> getChildren(Resource resource) {
-    return getChildren(resource, false);
-  }
-
-  public List<Resource> getChildren(Resource resource, boolean includeExcludedResources) {
-    List<Resource> children = Lists.newArrayList();
-    Bucket bucket = buckets.get(resource);
-    if (bucket != null) {
-      for (Bucket childBucket : bucket.getChildren()) {
-        if (includeExcludedResources || !childBucket.isExcluded())
-          children.add(childBucket.getResource());
-      }
-    }
-    return children;
-  }
-
-  public Resource getParent(Resource resource) {
-    Bucket bucket = buckets.get(resource);
-    if (bucket != null && bucket.getParent() != null) {
-      return bucket.getParent().getResource();
-    }
-    return null;
-  }
 
   public Measure getMeasure(Resource resource, Metric metric) {
     Bucket bucket = buckets.get(resource);
@@ -239,8 +157,8 @@ public final class DefaultIndex extends SonarIndex {
    * the measure is updated if it's already registered.
    */
   public Measure addMeasure(Resource resource, Measure measure) {
-    Bucket bucket = getOrAddBucket(resource);
-    if (!bucket.isExcluded()) {
+    Bucket bucket = doIndex(resource);
+    if (bucket != null && !bucket.isExcluded()) {
       Metric metric = metricFinder.findByKey(measure.getMetricKey());
       if (metric == null) {
         throw new SonarException("Unknown metric: " + measure.getMetricKey());
@@ -250,7 +168,7 @@ public final class DefaultIndex extends SonarIndex {
         bucket.addMeasure(measure);
       }
       if (measure.getPersistenceMode().useDatabase()) {
-        persistence.saveMeasure(currentProject, resource, measure);
+        persistence.saveMeasure(resource, measure);
       }
 
       // TODO keep database measures in cache but remove data
@@ -258,13 +176,6 @@ public final class DefaultIndex extends SonarIndex {
     return measure;
   }
 
-  public void setSource(Resource resource, String source) {
-    Bucket bucket = getOrAddBucket(resource);
-    if (!bucket.isExcluded()) {
-      persistence.setSource(currentProject, resource, source);
-    }
-  }
-
   //
   //
   //
@@ -291,8 +202,8 @@ public final class DefaultIndex extends SonarIndex {
   }
 
   boolean registerDependency(Dependency dependency) {
-    Bucket fromBucket = getOrAddBucket(dependency.getFrom());
-    Bucket toBucket = getOrAddBucket(dependency.getTo());
+    Bucket fromBucket = doIndex(dependency.getFrom());
+    Bucket toBucket = doIndex(dependency.getTo());
 
     if (fromBucket != null && !fromBucket.isExcluded() && toBucket != null && !toBucket.isExcluded()) {
       dependencies.add(dependency);
@@ -389,7 +300,7 @@ public final class DefaultIndex extends SonarIndex {
     if (resource == null) {
       violation.setResource(currentProject);
     }
-    bucket = getOrAddBucket(violation.getResource());
+    bucket = doIndex(violation.getResource());
     if (!bucket.isExcluded()) {
       boolean isIgnored = !force && violationFilters != null && violationFilters.isIgnored(violation);
       if (!isIgnored) {
@@ -451,7 +362,149 @@ public final class DefaultIndex extends SonarIndex {
   public Event addEvent(Resource resource, String name, String description, String category, Date date) {
     Event event = new Event(name, description, category);
     event.setDate(date);
-    persistence.saveEvent(currentProject, resource, event);
+    persistence.saveEvent(resource, event);
     return null;
   }
+
+  public boolean setSource(Resource reference, String source) {
+    boolean result = false;
+    if (isIndexed(reference)) {
+      persistence.setSource(reference, source);
+      result = true;
+    }
+    return result;
+  }
+
+
+  /**
+   * Does nothing if the resource is already registered.
+   */
+  public Resource addResource(Resource resource) {
+    Bucket bucket = doIndex(resource);
+    return bucket != null ? bucket.getResource() : null;
+  }
+
+  public <R extends Resource> R getResource(R reference) {
+    Bucket bucket = buckets.get(reference);
+    if (bucket != null) {
+      return (R)bucket.getResource();
+    }
+    return null;
+  }
+
+  static String createUID(Project project, Resource resource) {
+    String uid = resource.getKey();
+    if (!StringUtils.equals(Resource.SCOPE_SET, resource.getScope())) {
+      // not a project nor a library
+      uid = new StringBuilder(ResourceModel.KEY_SIZE)
+          .append(project.getKey())
+          .append(':')
+          .append(resource.getKey())
+          .toString();
+    }
+    return uid;
+  }
+
+  private boolean checkExclusion(Resource resource, Bucket parent) {
+    boolean excluded = (parent != null && parent.isExcluded()) || (resourceFilters != null && resourceFilters.isExcluded(resource));
+    resource.setExcluded(excluded);
+    return excluded;
+  }
+
+  public List<Resource> getChildren(Resource resource) {
+    return getChildren(resource, false);
+  }
+
+
+  public List<Resource> getChildren(Resource resource, boolean acceptExcluded) {
+    List<Resource> children = Lists.newLinkedList();
+    Bucket bucket = getBucket(resource, acceptExcluded);
+    if (bucket != null) {
+      for (Bucket childBucket : bucket.getChildren()) {
+        if (acceptExcluded || !childBucket.isExcluded())
+          children.add(childBucket.getResource());
+      }
+    }
+    return children;
+  }
+
+  public Resource getParent(Resource resource) {
+    Bucket bucket = getBucket(resource, false);
+    if (bucket != null && bucket.getParent() != null) {
+      return bucket.getParent().getResource();
+    }
+    return null;
+  }
+
+  public boolean index(Resource resource) {
+    Bucket bucket = doIndex(resource);
+    return bucket != null && !bucket.isExcluded();
+  }
+
+  private Bucket doIndex(Resource resource) {
+    if (resource.getParent() != null) {
+      // SONAR-2127 backward-compatibility - create automatically parent of files
+      doIndex(resource.getParent(), currentProject);
+    }
+    return doIndex(resource, resource.getParent());
+  }
+
+  public boolean index(Resource resource, Resource parentReference) {
+    Bucket bucket = doIndex(resource, parentReference);
+    return bucket != null && !bucket.isExcluded();
+  }
+
+  private Bucket doIndex(Resource resource, Resource parentReference) {
+    Bucket bucket = buckets.get(resource);
+    if (bucket != null) {
+      return bucket;
+    }
+
+    if (lock.isLocked() && !ResourceUtils.isLibrary(resource)) {
+      LOG.warn("Resource will be ignored in next Sonar versions, index is locked: " + resource);
+    }
+
+    Resource parent = null;
+    if (!ResourceUtils.isLibrary(resource)) {
+      // a library has no parent
+      parent = (Resource) ObjectUtils.defaultIfNull(parentReference, currentProject);
+    }
+
+    Bucket parentBucket = getBucket(parent, true);
+    if (parentBucket==null && parent!=null) {
+      LOG.warn("Resource ignored, parent is not indexed: " + resource);
+      return null;
+    }
+
+    resource.setEffectiveKey(createUID(currentProject, resource));
+    bucket = new Bucket(resource).setParent(parentBucket);
+    buckets.put(resource, bucket);
+
+    boolean excluded = checkExclusion(resource, parentBucket);
+    if (!excluded) {
+      persistence.saveResource(currentProject, resource, (parentBucket!=null ? parentBucket.getResource() : null));
+    }
+    return bucket;
+  }
+
+
+  public boolean isExcluded(Resource reference) {
+    Bucket bucket = getBucket(reference, true);
+    return bucket != null && bucket.isExcluded();
+  }
+
+  public boolean isIndexed(Resource reference) {
+    return getBucket(reference, false) != null;
+  }
+
+  private Bucket getBucket(Resource resource, boolean acceptExcluded) {
+    Bucket bucket = null;
+    if (resource != null) {
+      bucket = buckets.get(resource);
+      if (!acceptExcluded && bucket != null && bucket.isExcluded()) {
+        bucket = null;
+      }
+    }
+    return bucket;
+  }
 }
index 942dd3aa127ad02a5693263e1262981569e99869..ea019c5ee4c1698d90faaa2e8a4efce787f18f1d 100644 (file)
  */
 package org.sonar.batch.index;
 
+import org.apache.commons.lang.StringUtils;
 import org.sonar.api.batch.Event;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.design.Dependency;
 import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.ProjectLink;
-import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.*;
 
 import java.util.List;
 
@@ -62,24 +61,31 @@ public final class DefaultPersistenceManager implements PersistenceManager {
     measurePersister.dump();
   }
 
-  public void saveProject(Project project) {
-    resourcePersister.saveProject(project);
+  public void saveProject(Project project, Project parent) {
+    resourcePersister.saveProject(project, parent);
   }
 
-  public Snapshot saveResource(Project project, Resource resource) {
-    return resourcePersister.saveResource(project, resource);
+  public Snapshot saveResource(Project project, Resource resource, Resource parent) {
+    if (isPersistable(resource)) {
+      return resourcePersister.saveResource(project, resource, parent);
+    }
+    return null;
   }
 
-  public void setSource(Project project, Resource resource, String source) {
-    sourcePersister.saveSource(project, resource, source);
+  public void setSource(Resource file, String source) {
+    sourcePersister.saveSource(file, source);
   }
 
-  public void saveMeasure(Project project, Resource resource, Measure measure) {
-    measurePersister.saveMeasure(project, resource, measure);
+  public void saveMeasure(Resource resource, Measure measure) {
+    if (isPersistable(resource)) {
+      measurePersister.saveMeasure(resource, measure);
+    }
   }
 
   public void saveDependency(Project project, Dependency dependency, Dependency parentDependency) {
-    dependencyPersister.saveDependency(project, dependency, parentDependency);
+    if (isPersistable(dependency.getFrom()) && isPersistable(dependency.getTo())) {
+      dependencyPersister.saveDependency(project, dependency, parentDependency);
+    }
   }
 
   public void saveLink(Project project, ProjectLink link) {
@@ -98,7 +104,18 @@ public final class DefaultPersistenceManager implements PersistenceManager {
     eventPersister.deleteEvent(event);
   }
 
-  public void saveEvent(Project project, Resource resource, Event event) {
-    eventPersister.saveEvent(project, resource, event);
+  public void saveEvent(Resource resource, Event event) {
+    if (isPersistable(resource)) {
+      eventPersister.saveEvent(resource, event);
+    }
+  }
+
+  static boolean isPersistable(Resource resource) {
+    if (resource != null) {
+      return resource instanceof File || resource instanceof Directory || resource instanceof Library || resource instanceof Project ||
+          // for deprecated resources
+          StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope()) || StringUtils.equals(Scopes.FILE, resource.getScope());
+    }
+    return false;
   }
 }
index 3634307178f688b558643db8e65287d8cf8c157d..640503ecdd8191b4fde02e737932f26b52a61ace 100644 (file)
@@ -33,7 +33,6 @@ import org.sonar.api.utils.SonarException;
 
 import javax.persistence.NonUniqueResultException;
 import javax.persistence.Query;
-
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -48,29 +47,22 @@ public final class DefaultResourcePersister implements ResourcePersister {
     this.session = session;
   }
 
-  public Snapshot saveProject(Project project) {
+  public Snapshot saveProject(Project project, Project parent) {
     Snapshot snapshot = snapshotsByResource.get(project);
     if (snapshot == null) {
-      snapshot = doSaveProject(project);
+      snapshot = persistProject(project, parent);
+      addToCache(project, snapshot);
     }
     return snapshot;
   }
 
-  public Snapshot getSnapshot(Resource resource) {
-    if (resource != null) {
-      return snapshotsByResource.get(resource);
+  private void addToCache(Resource resource, Snapshot snapshot) {
+    if (snapshot != null) {
+      snapshotsByResource.put(resource, snapshot);
     }
-    return null;
   }
 
-  /**
-   * just for unit tests
-   */
-  Map<Resource, Snapshot> getSnapshotsByResource() {
-    return snapshotsByResource;
-  }
-
-  private Snapshot doSaveProject(Project project) {
+  private Snapshot persistProject(Project project, Project parent) {
     // temporary hack
     project.setEffectiveKey(project.getKey());
 
@@ -78,7 +70,7 @@ public final class DefaultResourcePersister implements ResourcePersister {
     model.setLanguageKey(project.getLanguageKey());// ugly, only for projects
 
     Snapshot parentSnapshot = null;
-    if (project.getParent() != null) {
+    if (parent != null) {
       // assume that the parent project has already been saved
       parentSnapshot = snapshotsByResource.get(project.getParent());
       model.setRootId((Integer) ObjectUtils.defaultIfNull(parentSnapshot.getRootProjectId(), parentSnapshot.getResourceId()));
@@ -91,30 +83,60 @@ public final class DefaultResourcePersister implements ResourcePersister {
     snapshot.setCreatedAt(project.getAnalysisDate());
     snapshot = session.save(snapshot);
     session.commit();
-    snapshotsByResource.put(project, snapshot);
     return snapshot;
   }
 
-  public Snapshot saveResource(Project project, Resource resource) {
-    if (resource == null) {
-      return null;
+  public Snapshot getSnapshot(Resource reference) {
+    return snapshotsByResource.get(reference);
+  }
+
+  public Snapshot getSnapshotOrFail(Resource resource) throws ResourceNotPersistedException {
+    Snapshot snapshot = getSnapshot(resource);
+    if (snapshot == null) {
+      throw new ResourceNotPersistedException(resource);
     }
+    return snapshot;
+  }
+
+  /**
+   * just for unit tests
+   */
+  Map<Resource, Snapshot> getSnapshotsByResource() {
+    return snapshotsByResource;
+  }
+
+
+  public Snapshot saveResource(Project project, Resource resource) {
+    return saveResource(project, resource, null);
+  }
+
+  public Snapshot saveResource(Project project, Resource resource, Resource parent) {
     Snapshot snapshot = snapshotsByResource.get(resource);
     if (snapshot == null) {
-      if (resource instanceof Project) {
-        snapshot = doSaveProject((Project) resource);
+      snapshot = persist(project, resource, parent);
+      addToCache(resource, snapshot);
+    }
+    return snapshot;
+  }
 
-      } else if (resource instanceof Library) {
-        snapshot = doSaveLibrary(project, (Library) resource);
 
-      } else {
-        snapshot = doSaveResource(project, resource);
-      }
+  private Snapshot persist(Project project, Resource resource, Resource parent) {
+    Snapshot snapshot;
+    if (resource instanceof Project) {
+      // should not occur, please use the method saveProject()
+      snapshot = persistProject((Project) resource, project);
+
+    } else if (resource instanceof Library) {
+      snapshot = persistLibrary(project, (Library) resource);
+
+    } else {
+      snapshot = persistFileOrDirectory(project, resource, parent);
     }
     return snapshot;
   }
 
-  private Snapshot doSaveLibrary(Project project, Library library) {
+
+  private Snapshot persistLibrary(Project project, Library library) {
     ResourceModel model = findOrCreateModel(library);
     model = session.save(model);
     library.setId(model.getId()); // TODO to be removed
@@ -131,7 +153,6 @@ public final class DefaultResourcePersister implements ResourcePersister {
       // The qualifier must be LIB, even if the resource is TRK, because this snapshot has no measures.
       snapshot.setQualifier(Resource.QUALIFIER_LIB);
       snapshot = session.save(snapshot);
-      snapshotsByResource.put(library, snapshot);
     }
     session.commit();
     return snapshot;
@@ -154,18 +175,17 @@ public final class DefaultResourcePersister implements ResourcePersister {
   /**
    * Everything except project and library
    */
-  private Snapshot doSaveResource(Project project, Resource resource) {
+  private Snapshot persistFileOrDirectory(Project project, Resource resource, Resource parentReference) {
     ResourceModel model = findOrCreateModel(resource);
     Snapshot projectSnapshot = snapshotsByResource.get(project);
     model.setRootId(projectSnapshot.getResourceId());
     model = session.save(model);
     resource.setId(model.getId()); // TODO to be removed
 
-    Snapshot parentSnapshot = (Snapshot) ObjectUtils.defaultIfNull(getSnapshot(resource.getParent()), projectSnapshot);
+    Snapshot parentSnapshot = (Snapshot) ObjectUtils.defaultIfNull(getSnapshot(parentReference), projectSnapshot);
     Snapshot snapshot = new Snapshot(model, parentSnapshot);
     snapshot = session.save(snapshot);
     session.commit();
-    snapshotsByResource.put(resource, snapshot);
     return snapshot;
   }
 
@@ -186,7 +206,7 @@ public final class DefaultResourcePersister implements ResourcePersister {
     // we keep cache of projects
     for (Iterator<Map.Entry<Resource, Snapshot>> it = snapshotsByResource.entrySet().iterator(); it.hasNext();) {
       Map.Entry<Resource, Snapshot> entry = it.next();
-      if ( !ResourceUtils.isSet(entry.getKey())) {
+      if (!ResourceUtils.isSet(entry.getKey())) {
         it.remove();
       }
     }
@@ -239,7 +259,7 @@ public final class DefaultResourcePersister implements ResourcePersister {
     if (StringUtils.isNotBlank(resource.getDescription())) {
       model.setDescription(resource.getDescription());
     }
-    if ( !ResourceUtils.isLibrary(resource)) {
+    if (!ResourceUtils.isLibrary(resource)) {
       model.setScope(resource.getScope());
       model.setQualifier(resource.getQualifier());
     }
index 9b536333674130af7dd408b94f616d85928e3c81..5cc2b1aa3e586775016fe71a82145adf36aac4ad 100644 (file)
@@ -50,16 +50,15 @@ public final class EventPersister {
     session.commit();
   }
 
-  public void saveEvent(Project project, Resource resource, Event event) {
-    Snapshot snapshot = resourcePersister.saveResource(project, resource);
-    if (snapshot != null) {
-      if (event.getDate()==null) {
-        event.setSnapshot(snapshot);
-      } else {
-        event.setResourceId(snapshot.getResourceId());
-      }
-      session.save(event);
-      session.commit();
+  public void saveEvent(Resource resource, Event event) {
+    Snapshot snapshot = resourcePersister.getSnapshotOrFail(resource);
+    if (event.getDate() == null) {
+      event.setSnapshot(snapshot);
+    } else {
+      event.setResourceId(snapshot.getResourceId());
     }
+    session.save(event);
+    session.commit();
+
   }
 }
index 123b363658b0fc04ff7d7d86d1a92502f1dbdaa6..66ec62ce999b4b23924aa65c3c1058ec1305fcd8 100644 (file)
@@ -35,21 +35,20 @@ public final class LinkPersister {
   }
 
   public void saveLink(Project project, ProjectLink link) {
-    Snapshot snapshot = resourcePersister.getSnapshot(project);
-    if (snapshot != null) {
-      ResourceModel projectDao = session.reattach(ResourceModel.class, snapshot.getResourceId());
-      ProjectLink dbLink = projectDao.getProjectLink(link.getKey());
-      if (dbLink == null) {
-        link.setResource(projectDao);
-        projectDao.getProjectLinks().add(link);
-        session.save(link);
+    Snapshot snapshot = resourcePersister.getSnapshotOrFail(project);
+    ResourceModel projectDao = session.reattach(ResourceModel.class, snapshot.getResourceId());
+    ProjectLink dbLink = projectDao.getProjectLink(link.getKey());
+    if (dbLink == null) {
+      link.setResource(projectDao);
+      projectDao.getProjectLinks().add(link);
+      session.save(link);
 
-      } else {
-        dbLink.copyFieldsFrom(link);
-        session.save(dbLink);
-      }
-      session.commit();
+    } else {
+      dbLink.copyFieldsFrom(link);
+      session.save(dbLink);
     }
+    session.commit();
+
   }
 
   public void deleteLink(Project project, String linkKey) {
index 39737571315dc02b08f0e73c516d0d139e677323..ec8ca8c925e76786400eb8912d81a6b7a8bc18e5 100644 (file)
@@ -57,17 +57,13 @@ public final class MeasurePersister {
     this.delayedMode = delayedMode;
   }
 
-  public void saveMeasure(Project project, Measure measure) {
-    saveMeasure(project, project, measure);
-  }
-
-  public void saveMeasure(Project project, Resource resource, Measure measure) {
+  public void saveMeasure(Resource resource, Measure measure) {
     boolean saveLater = (measure.getPersistenceMode().useMemory() && delayedMode);
     if (saveLater) {
       unsavedMeasuresByResource.put(resource, measure);
 
     } else {
-      Snapshot snapshot = resourcePersister.saveResource(project, resource);
+      Snapshot snapshot = resourcePersister.getSnapshotOrFail(resource);
       if (measure.getId() != null) {
         // update
         MeasureModel model = session.reattach(MeasureModel.class, measure.getId());
index f9aebeb5e75b2dcf10d4379f9709776be484e4d7..caffd0dac07b91b342113cb30cfec0875e07d0ec 100644 (file)
@@ -23,6 +23,7 @@ import org.sonar.api.batch.Event;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.design.Dependency;
 import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.File;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.ProjectLink;
 import org.sonar.api.resources.Resource;
@@ -36,13 +37,13 @@ public interface PersistenceManager {
 
   void dump();
 
-  void saveProject(Project project);
+  void saveProject(Project project, Project parent);
 
-  Snapshot saveResource(Project project, Resource resource);
+  Snapshot saveResource(Project project, Resource resource, Resource parent);
 
-  void setSource(Project project, Resource resource, String source);
+  void setSource(Resource file, String source);
 
-  void saveMeasure(Project project, Resource resource, Measure measure);
+  void saveMeasure(Resource resource, Measure measure);
 
   void saveDependency(Project project, Dependency dependency, Dependency parentDependency);
 
@@ -54,5 +55,5 @@ public interface PersistenceManager {
 
   void deleteEvent(Event event);
 
-  void saveEvent(Project project, Resource resource, Event event);
+  void saveEvent(Resource resource, Event event);
 }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ResourceNotPersistedException.java b/sonar-batch/src/main/java/org/sonar/batch/index/ResourceNotPersistedException.java
new file mode 100644 (file)
index 0000000..c2f30ed
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.index;
+
+import org.sonar.api.resources.Resource;
+import org.sonar.api.utils.SonarException;
+
+/**
+ * @since 2.6
+ */
+public final class ResourceNotPersistedException extends SonarException {
+
+  public ResourceNotPersistedException(Resource resource) {
+    super(resource.toString());
+  }
+
+}
index 644c3261b2103f0cdf256f19291d5d2e30f09ec8..dad3c8f542877e87cbfd44af15567236ff4ae7d6 100644 (file)
@@ -24,14 +24,29 @@ import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
 
 public interface ResourcePersister {
-  Snapshot saveProject(Project project);
+  
+  Snapshot saveProject(Project project, Project parent);
 
-  Snapshot getSnapshot(Resource resource);
+  /**
+   * Persist a resource in database. Returns null if the resource must not be persisted (scope lower than file)
+   */
+  Snapshot saveResource(Project project, Resource resource, Resource parent);
 
+  /**
+   * Persist a resource in database. Returns null if the resource must not be persisted (scope lower than file)
+   */
   Snapshot saveResource(Project project, Resource resource);
 
+  Snapshot getSnapshot(Resource resource);
+
+  /**
+   * @throws ResourceNotPersistedException if the resource is not persisted.
+   */
+  Snapshot getSnapshotOrFail(Resource resource);
+
   /**
-   * The current snapshot which is flagged as "last"
+   * The current snapshot which is flagged as "last", different then the current analysis.
    * @param onlyOlder true if the result must be anterior to the snapshot parameter
    */
   Snapshot getLastSnapshot(Snapshot snapshot, boolean onlyOlder);
index 4480ab4bef5fecbaa1464e146c06c83691cca8a8..1b1857c7fc93e56cf32d1c575d820f4dc5e63709 100644 (file)
@@ -23,9 +23,8 @@ import com.google.common.collect.Sets;
 import org.sonar.api.database.DatabaseSession;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.database.model.SnapshotSource;
-import org.sonar.api.resources.Project;
+import org.sonar.api.resources.DuplicatedSourceException;
 import org.sonar.api.resources.Resource;
-import org.sonar.api.utils.SonarException;
 
 import java.util.Set;
 
@@ -40,17 +39,22 @@ public final class SourcePersister {
     this.resourcePersister = resourcePersister;
   }
 
-  public void saveSource(Project project, Resource resource, String source) {
-    Snapshot snapshot = resourcePersister.saveResource(project, resource);
-    if (snapshot != null) {
-
-      if (savedSnapshotIds.contains(snapshot.getId())) {
-        throw new SonarException("Can not set twice the source of " + resource);
-      }
-      session.save(new SnapshotSource(snapshot.getId(), source));
-      session.commit();
-      savedSnapshotIds.add(snapshot.getId());
+  public void saveSource(Resource resource, String source) {
+    Snapshot snapshot = resourcePersister.getSnapshotOrFail(resource);
+    if (isCached(snapshot)) {
+      throw new DuplicatedSourceException(resource);
     }
+    session.save(new SnapshotSource(snapshot.getId(), source));
+    session.commit();
+    addToCache(snapshot);
+  }
+
+  private boolean isCached(Snapshot snapshot) {
+    return savedSnapshotIds.contains(snapshot.getId());
+  }
+
+  private void addToCache(Snapshot snapshot) {
+    savedSnapshotIds.add(snapshot.getId());
   }
 
   public void clear() {
index 67a0e4e36d6525be0c048a8fb3c68973303c46a8..25f6bcb6cc1bf52d138203643c9a6d479cc6f6c7 100644 (file)
  */
 package org.sonar.batch.index;
 
+import org.apache.commons.lang.StringUtils;
+import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
-import org.sonar.api.resources.JavaPackage;
-import org.sonar.api.resources.Library;
-import org.sonar.api.resources.Project;
+import org.sonar.api.batch.ResourceFilter;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.resources.*;
+import org.sonar.batch.DefaultResourceCreationLock;
+import org.sonar.batch.ProjectTree;
+import org.sonar.batch.ResourceFilters;
+import org.sonar.batch.ViolationFilters;
 
+import static org.hamcrest.Matchers.nullValue;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
 
 public class DefaultIndexTest {
 
+  private DefaultIndex index = null;
+
+  @Before
+  public void createIndex() {
+    index = new DefaultIndex(mock(PersistenceManager.class), new DefaultResourceCreationLock(), mock(ProjectTree.class), mock(MetricFinder.class));
+    Project project = new Project("project");
+
+    ResourceFilter filter = new ResourceFilter() {
+      public boolean isIgnored(Resource resource) {
+        return StringUtils.containsIgnoreCase(resource.getKey(), "excluded");
+      }
+    };
+    index.setCurrentProject(project, new ResourceFilters(new ResourceFilter[]{filter}), new ViolationFilters(), RulesProfile.create());
+    index.doStart(project);
+  }
+
+
   @Test
-  public void shouldCalculateResourceEffectiveKey() {
+  public void shouldCreateUID() {
     Project project = new Project("my_project");
-    assertThat(DefaultIndex.calculateResourceEffectiveKey(project, project), is("my_project"));
+    assertThat(DefaultIndex.createUID(project, project), is("my_project"));
 
     JavaPackage javaPackage = new JavaPackage("org.foo");
-    assertThat(DefaultIndex.calculateResourceEffectiveKey(project, javaPackage), is("my_project:org.foo"));
+    assertThat(DefaultIndex.createUID(project, javaPackage), is("my_project:org.foo"));
 
     Library library = new Library("junit:junit", "4.7");
-    assertThat(DefaultIndex.calculateResourceEffectiveKey(project, library), is("junit:junit"));
+    assertThat(DefaultIndex.createUID(project, library), is("junit:junit"));
+  }
+
+  @Test
+  public void shouldIndexParentOfDeprecatedFiles() {
+    File file = new File("org/foo/Bar.java");
+    assertThat(index.index(file), is(true));
+
+    Directory reference = new Directory("org/foo");
+    assertThat(index.getResource(reference).getName(), is("org/foo"));
+    assertThat(index.isIndexed(reference), is(true));
+    assertThat(index.isExcluded(reference), is(false));
+    assertThat(index.getChildren(reference).size(), is(1));
+    assertThat(index.getParent(reference), is(Project.class));
+  }
+
+  @Test
+  public void shouldIndexTreeOfResources() {
+    Directory directory = new Directory("org/foo");
+    File file = new File("org/foo/Bar.java");
+    file.setLanguage(Java.INSTANCE);
+
+    assertThat(index.index(directory), is(true));
+    assertThat(index.index(file, directory), is(true));
+
+    File fileRef = new File("org/foo/Bar.java");
+    assertThat(index.getResource(fileRef).getKey(), is("org/foo/Bar.java"));
+    assertThat(index.getResource(fileRef).getLanguage(), is((Language) Java.INSTANCE));
+    assertThat(index.isIndexed(fileRef), is(true));
+    assertThat(index.isExcluded(fileRef), is(false));
+    assertThat(index.getChildren(fileRef).size(), is(0));
+    assertThat(index.getParent(fileRef), is(Directory.class));
+  }
+
+  @Test
+  public void shouldIndexLibraryOutsideProjectTree() {
+    Library lib = new Library("junit", "4.8");
+    assertThat(index.index(lib), is(true));
+
+    Library reference = new Library("junit", "4.8");
+    assertThat(index.getResource(reference).getQualifier(), is(Qualifiers.LIBRARY));
+    assertThat(index.isIndexed(reference), is(true));
+    assertThat(index.isExcluded(reference), is(false));
+  }
+
+  @Test
+  public void shouldNotIndexResourceIfParentNotIndexed() {
+    Directory directory = new Directory("org/other");
+    File file = new File("org/foo/Bar.java");
+
+    assertThat(index.index(file, directory), is(false));
+
+    File fileRef = new File("org/foo/Bar.java");
+    assertThat(index.isIndexed(directory), is(false));
+    assertThat(index.isIndexed(fileRef), is(false));
+    assertThat(index.isExcluded(fileRef), is(false));
+    assertThat(index.getChildren(fileRef).size(), is(0));
+    assertThat(index.getParent(fileRef), nullValue());
+  }
+
+
+  @Test
+  @Ignore("TODO: should it be really possible")
+  public void shouldIndexDirectChildOfProject() {
+
+  }
+
+  @Test
+  public void shouldBeExcluded() {
+    File file = new File("org/foo/ExcludedBar.java");
+    assertThat(index.index(file), is(false));
+    assertThat(index.isIndexed(file), is(false));
+    assertThat(index.isExcluded(file), is(true));
   }
 }
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultPersistenceManagerTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultPersistenceManagerTest.java
new file mode 100644 (file)
index 0000000..48458f6
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.index;
+
+import org.junit.Test;
+import org.sonar.api.resources.Directory;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Library;
+import org.sonar.api.resources.Project;
+import org.sonar.java.api.JavaClass;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class DefaultPersistenceManagerTest {
+  
+  @Test
+  public void shouldPersistResoucesWithScopeHigherThanFile() {
+    assertThat(DefaultPersistenceManager.isPersistable(new File("Foo.java")), is(true));
+    assertThat(DefaultPersistenceManager.isPersistable(new Directory("bar/Foo.java")), is(true));
+    assertThat(DefaultPersistenceManager.isPersistable(new Project("foo")), is(true));
+    assertThat(DefaultPersistenceManager.isPersistable(new Library("foo", "1.2")), is(true));
+  }
+
+  @Test
+  public void shouldNotPersistResoucesWithScopeLowerThanFile() {
+    assertThat(DefaultPersistenceManager.isPersistable(JavaClass.createRef("com.foo.Bar")), is(false));
+  }
+}
index bfd8a913dc6385e6af4214560804f067a0d539ee..ec61785d170aa959a5a05ed92883cefc5356c344 100644 (file)
@@ -66,7 +66,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
     setupData("shared");
 
     ResourcePersister persister = new DefaultResourcePersister(getSession());
-    persister.saveProject(singleProject);
+    persister.saveProject(singleProject, null);
 
     checkTables("shouldSaveNewProject", "projects", "snapshots");
   }
@@ -76,10 +76,10 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
     setupData("shared");
 
     ResourcePersister persister = new DefaultResourcePersister(getSession());
-    persister.saveProject(multiModuleProject);
-    persister.saveProject(moduleA);
-    persister.saveProject(moduleB);
-    persister.saveProject(moduleB1);
+    persister.saveProject(multiModuleProject, null);
+    persister.saveProject(moduleA, multiModuleProject);
+    persister.saveProject(moduleB, multiModuleProject);
+    persister.saveProject(moduleB1, moduleB);
 
     checkTables("shouldSaveNewMultiModulesProject", "projects", "snapshots");
   }
@@ -89,7 +89,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
     setupData("shared");
 
     ResourcePersister persister = new DefaultResourcePersister(getSession());
-    persister.saveProject(singleProject);
+    persister.saveProject(singleProject, null);
     persister.saveResource(singleProject, new JavaPackage("org.foo").setEffectiveKey("foo:org.foo"));
 
     // check that the directory is attached to the project
@@ -101,7 +101,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
     setupData("shared");
 
     ResourcePersister persister = new DefaultResourcePersister(getSession());
-    persister.saveProject(singleProject);
+    persister.saveProject(singleProject, null);
     persister.saveResource(singleProject, new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"));
     persister.saveResource(singleProject, new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"));// do nothing, already saved
     persister.saveResource(singleProject, new Library("junit:junit", "3.2").setEffectiveKey("junit:junit"));
@@ -114,8 +114,8 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
     setupData("shared");
 
     DefaultResourcePersister persister = new DefaultResourcePersister(getSession());
-    persister.saveProject(multiModuleProject);
-    persister.saveProject(moduleA);
+    persister.saveProject(multiModuleProject, null);
+    persister.saveProject(moduleA, multiModuleProject);
     persister.saveResource(moduleA, new JavaPackage("org.foo").setEffectiveKey("a:org.foo"));
     persister.saveResource(moduleA, new JavaFile("org.foo.MyClass").setEffectiveKey("a:org.foo.MyClass"));
     persister.clear();
@@ -132,9 +132,9 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
     ResourcePersister persister = new DefaultResourcePersister(getSession());
     singleProject.setName("new name");
     singleProject.setDescription("new description");
-    persister.saveProject(singleProject);
+    persister.saveProject(singleProject, null);
 
     checkTables("shouldUpdateExistingResource", "projects", "snapshots");
   }
+
 }
index 90d597908c5cdf098193abd051ce54064542a581..13a299b38b3df42ebb9cb26b5628305233953735 100644 (file)
@@ -67,9 +67,9 @@ public class MeasurePersisterTest extends AbstractDbUnitTestCase {
     fileSnapshot = getSession().getSingleResult(Snapshot.class, "id", FILE_SNAPSHOT_ID);
     ncloc = getSession().getSingleResult(Metric.class, "key", "ncloc");
     coverage = getSession().getSingleResult(Metric.class, "key", "coverage");
-    when(resourcePersister.saveResource((Project) anyObject(), eq(project))).thenReturn(projectSnapshot);
-    when(resourcePersister.saveResource((Project) anyObject(), eq(aPackage))).thenReturn(packageSnapshot);
-    when(resourcePersister.saveResource((Project) anyObject(), eq(aFile))).thenReturn(fileSnapshot);
+    when(resourcePersister.getSnapshotOrFail(eq(project))).thenReturn(projectSnapshot);
+    when(resourcePersister.getSnapshotOrFail(eq(aPackage))).thenReturn(packageSnapshot);
+    when(resourcePersister.getSnapshotOrFail(eq(aFile))).thenReturn(fileSnapshot);
     when(resourcePersister.getSnapshot(project)).thenReturn(projectSnapshot);
     when(resourcePersister.getSnapshot(aPackage)).thenReturn(packageSnapshot);
     when(resourcePersister.getSnapshot(aFile)).thenReturn(fileSnapshot);
@@ -122,7 +122,7 @@ public class MeasurePersisterTest extends AbstractDbUnitTestCase {
     measurePersister.setDelayedMode(true);
 
     measurePersister.saveMeasure(project, new Measure(ncloc).setValue(1234.0));
-    measurePersister.saveMeasure(project, aPackage, new Measure(ncloc).setValue(50.0));
+    measurePersister.saveMeasure(aPackage, new Measure(ncloc).setValue(50.0));
 
     assertThat(getSession().getResults(MeasureModel.class, "metricId", 1).size(), is(0));
 
@@ -135,7 +135,7 @@ public class MeasurePersisterTest extends AbstractDbUnitTestCase {
     measurePersister.setDelayedMode(true);
 
     measurePersister.saveMeasure(project, new Measure(ncloc).setValue(1234.0).setPersistenceMode(PersistenceMode.DATABASE)); // database only
-    measurePersister.saveMeasure(project, aPackage, new Measure(ncloc).setValue(50.0)); // database + memory
+    measurePersister.saveMeasure(aPackage, new Measure(ncloc).setValue(50.0)); // database + memory
 
     // no dump => the db-only measure is saved
 
@@ -160,7 +160,7 @@ public class MeasurePersisterTest extends AbstractDbUnitTestCase {
   public void shouldNotSaveBestValueMeasuresInDelayedMode() {
     measurePersister.setDelayedMode(true);
 
-    measurePersister.saveMeasure(project, aFile, new Measure(coverage).setValue(100.0));
+    measurePersister.saveMeasure(aFile, new Measure(coverage).setValue(100.0));
 
     assertThat(getSession().getResults(MeasureModel.class, "metricId", COVERAGE_METRIC_ID, "snapshotId", FILE_SNAPSHOT_ID).size(), is(0));
 
index d92fdb8adf740869f86a4ab4947e1f0b6f6efdd9..cc92ff24a4cba246557a4bd8b49a68e57e6baf52 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.batch.index;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.resources.DuplicatedSourceException;
 import org.sonar.api.resources.JavaFile;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
@@ -41,21 +42,20 @@ public class SourcePersisterTest extends AbstractDbUnitTestCase {
     setupData("shared");
     Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", 1000);
     ResourcePersister resourcePersister = mock(ResourcePersister.class);
-    when(resourcePersister.saveResource((Project) anyObject(), (Resource) anyObject())).thenReturn(snapshot);
+    when(resourcePersister.getSnapshotOrFail((Resource) anyObject())).thenReturn(snapshot);
     sourcePersister = new SourcePersister(getSession(), resourcePersister);
   }
 
   @Test
   public void shouldSaveSource() {
-    sourcePersister.saveSource(new Project(""), new JavaFile("org.foo.Bar"), "this is the file content");
+    sourcePersister.saveSource(new JavaFile("org.foo.Bar"), "this is the file content");
     checkTables("shouldSaveSource", "snapshot_sources");
   }
 
-  @Test(expected = SonarException.class)
+  @Test(expected = DuplicatedSourceException.class)
   public void shouldFailIfSourceSavedSeveralTimes() {
-    Project project = new Project("project");
     JavaFile file = new JavaFile("org.foo.Bar");
-    sourcePersister.saveSource(project, file, "this is the file content");
-    sourcePersister.saveSource(project, file, "new content"); // fail
+    sourcePersister.saveSource(file, "this is the file content");
+    sourcePersister.saveSource(file, "new content"); // fail
   }
 }
index f32e3e951ffa5119bbd98e183d33c7287014ad38..b11a96f5655dbc0e09918ea2fccfc03faec69759 100644 (file)
  */
 package org.sonar.api.batch;
 
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.List;
-
 import org.apache.commons.io.FileUtils;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.resources.Language;
@@ -32,6 +27,11 @@ import org.sonar.api.resources.ProjectFileSystem;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.utils.SonarException;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.List;
+
 /**
  * A pre-implementation for a sensor that imports sources
  * 
@@ -88,6 +88,7 @@ public abstract class AbstractSourceImporter implements Sensor {
       if (resource != null) {
         try {
           String source = FileUtils.readFileToString(file, sourcesEncoding.name());
+          context.index(resource);
           context.saveSource(resource, source);
         } catch (IOException e) {
           throw new SonarException("Unable to read and import the source file : '" + file.getAbsolutePath() + "' with the charset : '"
index ae0f10862c4e85cb712c1c6b89ea4b19c518b5a9..07b58dc1a137cd2b40ed79bbcab46987aaa1fbcf 100644 (file)
@@ -23,6 +23,7 @@ import org.sonar.api.design.Dependency;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.MeasuresFilter;
 import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.DuplicatedSourceException;
 import org.sonar.api.resources.ProjectLink;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.rules.Violation;
@@ -37,6 +38,57 @@ import java.util.Set;
  */
 public interface SensorContext {
 
+  /**
+   * Indexes a resource as a direct child of project. This method does nothing and returns true if the resource already indexed.
+   *
+   * @return false if the resource is excluded
+   * @since 2.6
+   */
+  boolean index(Resource resource);
+
+
+  /**
+   * Indexes a resource. This method does nothing if the resource is already indexed.
+   *
+   * @param resource        the resource to index. Not nullable
+   * @param parentReference a reference to the parent. If null, the the resource is indexed as a direct child of project.
+   * @return false if the parent is not indexed or if the resource is excluded
+   * @since 2.6
+   */
+  boolean index(Resource resource, Resource parentReference);
+
+  /**
+   * Returns true if the referenced resource is excluded. An excluded resource is not indexed.
+   * @since 2.6
+   */
+  boolean isExcluded(Resource reference);
+
+  /**
+   * @since 2.6
+   */
+  boolean isIndexed(Resource reference);
+
+  /**
+   * Search for an indexed resource.
+   *
+   * @param reference the resource reference
+   * @return the indexed resource, null if it's not indexed
+   * @since 1.10. Generic types since 2.6.
+   */
+  <R extends Resource> R getResource(R reference);
+
+  /**
+   * @since 2.6
+   */
+  Resource getParent(Resource reference);
+
+  /**
+   * @since 2.6
+   */
+
+  Collection<Resource> getChildren(Resource reference);
+
+
   // ----------- MEASURES ON PROJECT --------------
 
   /**
@@ -68,15 +120,13 @@ public interface SensorContext {
 
   /**
    * Key is updated when saving the resource.
-   * 
+   *
    * @return the key as saved in database. Null if the resource is set as excluded.
+   * @deprecated use the methods index()
    */
+  @Deprecated
   String saveResource(Resource resource);
 
-  /**
-   * @return the resource saved in sonar index
-   */
-  Resource getResource(Resource resource);
 
   /**
    * Find all measures for this project. Never return null.
@@ -105,9 +155,9 @@ public interface SensorContext {
 
   /**
    * Save a coding rule violation.
-   * 
-   * @since 2.5
+   *
    * @param force allows to force creation of violation even if it was supressed by {@link org.sonar.api.rules.ViolationFilter}
+   * @since 2.5
    */
   void saveViolation(Violation violation, boolean force);
 
@@ -137,9 +187,15 @@ public interface SensorContext {
   // ----------- FILE SOURCES --------------
 
   /**
-   * Does nothing if the resource is set as excluded.
+   * Save the source code of a file. The file must be have been indexed before.
+   * Note: the source stream is not closed.
+   *
+   * @return false if the resource is excluded or not indexed
+   * @throws org.sonar.api.resources.DuplicatedSourceException
+   *          if the source has already been set on this resource
+   * @since 1.10. Returns a boolean since 2.6.
    */
-  void saveSource(Resource resource, String source);
+  boolean saveSource(Resource reference, String source) throws DuplicatedSourceException;
 
   // ----------- LINKS --------------
 
@@ -163,18 +219,18 @@ public interface SensorContext {
 
   /**
    * Creates an event for a given date
-   * 
-   * @param name the event name
+   *
+   * @param name        the event name
    * @param description the event description
-   * @param category the event category
-   * @param date the event date
+   * @param category    the event category
+   * @param date        the event date
    * @return the created event
    */
   Event createEvent(Resource resource, String name, String description, String category, Date date);
 
   /**
    * Deletes an event
-   * 
+   *
    * @param event the event to delete
    */
   void deleteEvent(Event event);
index de6d6e1f670c08238b1259d651f587c481e1dc37..8811492b95559b5ae373132da57cc937374bbac4 100644 (file)
  */
 package org.sonar.api.batch;
 
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
 import org.sonar.api.design.Dependency;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.MeasuresFilter;
 import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.DuplicatedSourceException;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.ProjectLink;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.rules.Violation;
 import org.sonar.graph.DirectedGraphAccessor;
 
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
 public abstract class SonarIndex implements DirectedGraphAccessor<Resource, Dependency> {
 
-  public abstract Project getProject();
+  /**
+   * Indexes a resource as a direct child of project. This method does nothing and returns true if the resource already indexed.
+   *
+   * @return false if the resource is excluded
+   * @since 2.6
+   */
+  public abstract boolean index(Resource resource);
+
+
+  /**
+   * Indexes a resource. This method does nothing if the resource is already indexed.
+   *
+   * @param resource        the resource to index. Not nullable
+   * @param parentReference a reference to the indexed parent. If null, the resource is indexed as a direct child of project.
+   * @return false if the parent is not indexed or if the resource is excluded
+   * @since 2.6
+   */
+  public abstract boolean index(Resource resource, Resource parentReference);
 
-  public abstract Resource getResource(Resource resource);
+  /**
+   * Returns true if the referenced resource is excluded. An excluded resource is not indexed.
+   * @since 2.6
+   */
+  public abstract boolean isExcluded(Resource reference);
+
+  /**
+   * @since 2.6
+   */
+  public abstract boolean isIndexed(Resource reference);
+
+  /**
+   * Search for an indexed resource.
+   *
+   * @param reference the resource reference
+   * @return the indexed resource, null if it's not indexed
+   * @since 1.10. Generic types since 2.6.
+   */
+  public abstract <R extends Resource> R getResource(R reference);
+
+  /**
+   * @since 2.6
+   */
+  public abstract Resource getParent(Resource reference);
+
+  /**
+   * @since 2.6
+   */
+
+  public abstract Collection<Resource> getChildren(Resource reference);
+
+  /**
+   * Save the source code of a file. The file must be have been indexed before.
+   * Note: the source stream is not closed.
+   *
+   * @return false if the resource is excluded or not indexed
+   * @throws org.sonar.api.resources.DuplicatedSourceException
+   *          if the source has already been set on this resource
+   */
+  public abstract boolean setSource(Resource reference, String source) throws DuplicatedSourceException;
+
+  public abstract Project getProject();
 
   public final Collection<Resource> getResources() {
     return getVertices();
   }
 
-  public abstract List<Resource> getChildren(Resource resource);
-
+  /**
+   * Indexes the resource.
+   * @return the indexed resource, even if it's excluded
+   * @deprecated since 2.6. Use methods index()
+   */
+  @Deprecated
   public abstract Resource addResource(Resource resource);
 
   public abstract Measure getMeasure(Resource resource, Metric metric);
 
   public abstract <M> M getMeasures(Resource resource, MeasuresFilter<M> filter);
 
-  public abstract void setSource(Resource resource, String source);
-
   /**
    * @since 2.5
    */
index ebf2b745c42017387a82ff2f67c624865cb53565..b21358002177a069fd6dca98ee2097cf959ffb25 100644 (file)
@@ -59,11 +59,11 @@ public class Directory extends Resource {
   }
 
   public String getScope() {
-    return Resource.SCOPE_SPACE;
+    return Scopes.DIRECTORY;
   }
 
   public String getQualifier() {
-    return Resource.QUALIFIER_DIRECTORY;
+    return Qualifiers.DIRECTORY;
   }
 
   public Resource getParent() {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DuplicatedSourceException.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DuplicatedSourceException.java
new file mode 100644 (file)
index 0000000..8cbd6dc
--- /dev/null
@@ -0,0 +1,14 @@
+package org.sonar.api.resources;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.sonar.api.utils.SonarException;
+
+/**
+ * @since 2.6
+ */
+public final class DuplicatedSourceException extends SonarException {
+
+  public DuplicatedSourceException(Resource resource) {
+    super(ObjectUtils.toString(resource));
+  }
+}
index e8d2b02cafccfa70905d76559b8f9b5555df2aae..24b7d32b6b8f49b5a7820f451ceaba77f4b80d99 100644 (file)
  */
 package org.sonar.api.resources;
 
-import java.util.List;
-
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.builder.ToStringBuilder;
 import org.sonar.api.utils.WildcardPattern;
 
+import java.util.List;
+
 /**
  * This class is an implementation of a resource of type FILE
  * 
@@ -32,6 +32,8 @@ import org.sonar.api.utils.WildcardPattern;
  */
 public class File extends Resource<Directory> {
 
+  public static final String SCOPE = Scopes.FILE;
+
   private String directoryKey;
   private String filename;
   private Language language;
index 1681a06b108ede7ae2f3e8a7f676723b3b0e7da7..61f85842340b601144d06d19c279db0706ff76dd 100644 (file)
@@ -21,7 +21,7 @@ package org.sonar.api.resources;
 
 import org.apache.commons.lang.builder.ToStringBuilder;
 
-public class Library extends Resource {
+public final class Library extends Resource {
 
   private String name;
   private String description;
@@ -68,12 +68,12 @@ public class Library extends Resource {
 
   @Override
   public String getScope() {
-    return Resource.SCOPE_SET;
+    return Scopes.PROJECT;
   }
 
   @Override
   public String getQualifier() {
-    return Resource.QUALIFIER_LIB;
+    return Qualifiers.LIBRARY;
   }
 
   @Override
index e4f14394dfa1b51e36ed6a863dcadfcfaccc15ab..9890eeb830d35fdbbc9ee3423305938db516d4e0 100644 (file)
@@ -36,6 +36,8 @@ import java.util.List;
  */
 public class Project extends Resource {
 
+  public static final String SCOPE = Scopes.PROJECT;
+
   /**
    * @deprecated since version 1.11. Constant moved to CoreProperties
    */
index f5f87b2161a846fc21d88ecf31686feaa4abe633..bb1c77e99ac1fc4ed70c845719f7074c7a010b6c 100644 (file)
  */
 package org.sonar.api.resources;
 
+/**
+ * The qualifier determines the exact type of a resource.
+ * Plugins can use their own qualifiers.
+ * @since 2.6
+ */
 public interface Qualifiers {
 
   String VIEW = "VW";
   String SUBVIEW = "SVW";
-  String LIB = "LIB";
+
+  /**
+   * Library, for example a JAR dependency of Java projects.
+   * Scope is Scopes.PROJECT
+   */
+  String LIBRARY = "LIB";
+
+  /**
+   * Single project or root of multi-modules projects
+   * Scope is Scopes.PROJECT
+   */
   String PROJECT = "TRK";
+
+  /**
+   * Module of multi-modules project. It's sometimes called sub-project.
+   * Scope is Scopes.PROJECT
+   */
   String MODULE = "BRC";
+
+
   String PACKAGE = "PAC";
   String DIRECTORY = "DIR";
   String FILE = "FIL";
index fc8a29f2bbbd2236dd1abdb0db5c2c3c1c6d480c..001fbd96e5ef548872411b4f73e42922d8d010c1 100644 (file)
 package org.sonar.api.resources;
 
 /**
- * Resource scopes are not extendable by plugins.
+ * Resource scopes are used to group resources. They relate to persisted resources only (project, directories and files).
+ * They are generally used in UI to display/hide some services or in web services.
+ *
+ * Resource scopes are not extensible by plugins. 
  */
 public interface Scopes {
   /**
@@ -31,23 +34,11 @@ public interface Scopes {
   /**
    * For example directory or Java package. Persisted in database.
    */
-  String NAMESPACE = "DIR";
+  String DIRECTORY = "DIR";
 
   /**
    * For example a Java file. Persisted in database.
    */
   String FILE = "FIL";
 
-  /**
-   * For example a Java class or a Java interface. Not persisted in database.
-   */
-  String TYPE = "TYP";
-
-  /**
-   * For example a Java method. Not persisted in database.
-   */
-  String METHOD = "MET";
-
-  
-  String[] ORDERED_SCOPES = {PROJECT, NAMESPACE, FILE, TYPE, METHOD};
-}
+}
\ No newline at end of file
index 54873a7cd3ce9f25f9bbc76070dc48c520f3068f..a90ae860b18d57a22ed1eaa39705c981888e98ed 100644 (file)
       <groupId>org.codehaus.sonar</groupId>
       <artifactId>sonar-deprecated</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.codehaus.sonar</groupId>
+      <artifactId>sonar-java-api</artifactId>
+    </dependency>
+
     <dependency>
       <groupId>org.codehaus.sonar</groupId>
       <artifactId>sonar-update-center-common</artifactId>
index 36a218cb59e7ef11c9f7b8360a6ab27f9c2593b8..4f6f27907410e189432cc06add349cf91588e645 100644 (file)
@@ -31,7 +31,7 @@
               <clean>true</clean>
             </configuration>
             <goals>
-              <goal>start-war</goal>
+              <goal>start</goal>
             </goals>
           </execution>
           <execution>
@@ -48,7 +48,7 @@
             <id>stop-server</id>
             <phase>post-integration-test</phase>
             <goals>
-              <goal>stop-war</goal>
+              <goal>stop</goal>
             </goals>
           </execution>
         </executions>