]> source.dussan.org Git - sonarqube.git/commitdiff
[SONAR-1957] Add ViolationQuery on SonarIndex and DecoratorContext
authorFabrice Bellingard <bellingard@gmail.com>
Mon, 18 Apr 2011 14:04:44 +0000 (16:04 +0200)
committerFabrice Bellingard <bellingard@gmail.com>
Wed, 20 Apr 2011 06:57:57 +0000 (08:57 +0200)
APIs

sonar-batch/src/main/java/org/sonar/batch/DefaultDecoratorContext.java
sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/DecoratorContext.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java
sonar-plugin-api/src/main/java/org/sonar/api/violations/ViolationQuery.java [new file with mode: 0644]

index fde3c9099d4a47744b59dc9b08c8822bfa10a495..4ca401c310ab4ded8a586a40dc21f8db48d8b203 100644 (file)
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * 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;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
-import com.google.common.collect.Lists;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.Event;
-import org.sonar.api.batch.SonarIndex;
-import org.sonar.api.design.Dependency;
-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.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.rules.Violation;
-
-public class DefaultDecoratorContext implements DecoratorContext {
-
-  private SonarIndex index;
-  private Resource resource;
-  private boolean readOnly = false;
-
-  private List<DecoratorContext> childrenContexts;
-
-  public DefaultDecoratorContext(Resource resource,
-                                 SonarIndex index,
-                                 List<DecoratorContext> childrenContexts) {
-    this.index = index;
-    this.resource = resource;
-    this.childrenContexts = childrenContexts;
-  }
-
-  public DefaultDecoratorContext setReadOnly(boolean b) {
-    readOnly = b;
-    childrenContexts = null;
-    return this;
-  }
-
-  public Project getProject() {
-    return index.getProject();
-  }
-
-  public List<DecoratorContext> getChildren() {
-    checkReadOnly("getModules");
-    return childrenContexts;
-  }
-
-  private void checkReadOnly(String methodName) {
-    if (readOnly) {
-      throw new IllegalStateException("Method DecoratorContext." + methodName + "() can not be executed on children.");
-    }
-  }
-
-  public <M> M getMeasures(MeasuresFilter<M> filter) {
-    return index.getMeasures(resource, filter);
-  }
-
-  public Measure getMeasure(Metric metric) {
-    return index.getMeasure(resource, metric);
-  }
-
-  public Collection<Measure> getChildrenMeasures(MeasuresFilter filter) {
-    List<Measure> result = Lists.newArrayList();
-    for (DecoratorContext childContext : childrenContexts) {
-      Object childResult = childContext.getMeasures(filter);
-      if (childResult != null) {
-        if (childResult instanceof Collection) {
-          result.addAll((Collection) childResult);
-        } else {
-          result.add((Measure) childResult);
-        }
-      }
-    }
-    return result;
-  }
-
-  public Collection<Measure> getChildrenMeasures(Metric metric) {
-    return getChildrenMeasures(MeasuresFilters.metric(metric));
-  }
-
-  public Resource getResource() {
-    return resource;
-  }
-
-  public DecoratorContext saveMeasure(Measure measure) {
-    checkReadOnly("saveMeasure");
-    index.addMeasure(resource, measure);
-    return this;
-  }
-
-  public DecoratorContext saveMeasure(Metric metric, Double value) {
-    checkReadOnly("saveMeasure");
-    index.addMeasure(resource, new Measure(metric, value));
-    return this;
-  }
-
-  public List<Violation> getViolations() {
-    return index.getViolations(resource);
-  }
-
-  public Dependency saveDependency(Dependency dependency) {
-    checkReadOnly("addDependency");
-    return index.addDependency(dependency);
-  }
-
-  public Set<Dependency> getDependencies() {
-    return index.getDependencies();
-  }
-
-  public Collection<Dependency> getIncomingDependencies() {
-    return index.getIncomingEdges(resource);
-  }
-
-  public Collection<Dependency> getOutgoingDependencies() {
-    return index.getOutgoingEdges(resource);
-  }
-
-  public List<Event> getEvents() {
-    return index.getEvents(resource);
-  }
-
-  public Event createEvent(String name, String description, String category, Date date) {
-    return index.addEvent(resource, name, description, category, date);
-  }
-
-  public void deleteEvent(Event event) {
-    index.deleteEvent(event);
-  }
-
-  public DefaultDecoratorContext saveViolation(Violation violation, boolean force) {
-    if (violation.getResource() == null) {
-      violation.setResource(resource);
-    }
-    index.addViolation(violation, force);
-    return this;
-  }
-
-  public DefaultDecoratorContext saveViolation(Violation violation) {
-    return saveViolation(violation, false);
-  }
-}
+/*\r
+ * Sonar, open source software quality management tool.\r
+ * Copyright (C) 2008-2011 SonarSource\r
+ * mailto:contact AT sonarsource DOT com\r
+ *\r
+ * Sonar is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 3 of the License, or (at your option) any later version.\r
+ *\r
+ * Sonar is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with Sonar; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02\r
+ */\r
+package org.sonar.batch;\r
+\r
+import java.util.Collection;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import com.google.common.collect.Lists;\r
+import org.sonar.api.batch.DecoratorContext;\r
+import org.sonar.api.batch.Event;\r
+import org.sonar.api.batch.SonarIndex;\r
+import org.sonar.api.design.Dependency;\r
+import org.sonar.api.measures.Measure;\r
+import org.sonar.api.measures.MeasuresFilter;\r
+import org.sonar.api.measures.MeasuresFilters;\r
+import org.sonar.api.measures.Metric;\r
+import org.sonar.api.resources.Project;\r
+import org.sonar.api.resources.Resource;\r
+import org.sonar.api.rules.Violation;\r
+import org.sonar.api.violations.ViolationQuery;\r
+\r
+public class DefaultDecoratorContext implements DecoratorContext {\r
+\r
+  private SonarIndex index;\r
+  private Resource resource;\r
+  private boolean readOnly = false;\r
+\r
+  private List<DecoratorContext> childrenContexts;\r
+\r
+  public DefaultDecoratorContext(Resource resource,\r
+                                 SonarIndex index,\r
+                                 List<DecoratorContext> childrenContexts) {\r
+    this.index = index;\r
+    this.resource = resource;\r
+    this.childrenContexts = childrenContexts;\r
+  }\r
+\r
+  public DefaultDecoratorContext setReadOnly(boolean b) {\r
+    readOnly = b;\r
+    childrenContexts = null;\r
+    return this;\r
+  }\r
+\r
+  public Project getProject() {\r
+    return index.getProject();\r
+  }\r
+\r
+  public List<DecoratorContext> getChildren() {\r
+    checkReadOnly("getModules");\r
+    return childrenContexts;\r
+  }\r
+\r
+  private void checkReadOnly(String methodName) {\r
+    if (readOnly) {\r
+      throw new IllegalStateException("Method DecoratorContext." + methodName + "() can not be executed on children.");\r
+    }\r
+  }\r
+\r
+  public <M> M getMeasures(MeasuresFilter<M> filter) {\r
+    return index.getMeasures(resource, filter);\r
+  }\r
+\r
+  public Measure getMeasure(Metric metric) {\r
+    return index.getMeasure(resource, metric);\r
+  }\r
+\r
+  public Collection<Measure> getChildrenMeasures(MeasuresFilter filter) {\r
+    List<Measure> result = Lists.newArrayList();\r
+    for (DecoratorContext childContext : childrenContexts) {\r
+      Object childResult = childContext.getMeasures(filter);\r
+      if (childResult != null) {\r
+        if (childResult instanceof Collection) {\r
+          result.addAll((Collection) childResult);\r
+        } else {\r
+          result.add((Measure) childResult);\r
+        }\r
+      }\r
+    }\r
+    return result;\r
+  }\r
+\r
+  public Collection<Measure> getChildrenMeasures(Metric metric) {\r
+    return getChildrenMeasures(MeasuresFilters.metric(metric));\r
+  }\r
+\r
+  public Resource getResource() {\r
+    return resource;\r
+  }\r
+\r
+  public DecoratorContext saveMeasure(Measure measure) {\r
+    checkReadOnly("saveMeasure");\r
+    index.addMeasure(resource, measure);\r
+    return this;\r
+  }\r
+\r
+  public DecoratorContext saveMeasure(Metric metric, Double value) {\r
+    checkReadOnly("saveMeasure");\r
+    index.addMeasure(resource, new Measure(metric, value));\r
+    return this;\r
+  }\r
+\r
+  /**\r
+  * {@inheritDoc}\r
+  */\r
+  public List<Violation> getViolations(ViolationQuery violationQuery) {\r
+    return index.getViolations(violationQuery);\r
+  }\r
+  \r
+  /**\r
+  * {@inheritDoc}\r
+  */\r
+  public List<Violation> getViolations() {\r
+    return index.getViolations(resource);\r
+  }\r
+\r
+  public Dependency saveDependency(Dependency dependency) {\r
+    checkReadOnly("addDependency");\r
+    return index.addDependency(dependency);\r
+  }\r
+\r
+  public Set<Dependency> getDependencies() {\r
+    return index.getDependencies();\r
+  }\r
+\r
+  public Collection<Dependency> getIncomingDependencies() {\r
+    return index.getIncomingEdges(resource);\r
+  }\r
+\r
+  public Collection<Dependency> getOutgoingDependencies() {\r
+    return index.getOutgoingEdges(resource);\r
+  }\r
+\r
+  public List<Event> getEvents() {\r
+    return index.getEvents(resource);\r
+  }\r
+\r
+  public Event createEvent(String name, String description, String category, Date date) {\r
+    return index.addEvent(resource, name, description, category, date);\r
+  }\r
+\r
+  public void deleteEvent(Event event) {\r
+    index.deleteEvent(event);\r
+  }\r
+\r
+  public DefaultDecoratorContext saveViolation(Violation violation, boolean force) {\r
+    if (violation.getResource() == null) {\r
+      violation.setResource(resource);\r
+    }\r
+    index.addViolation(violation, force);\r
+    return this;\r
+  }\r
+\r
+  public DefaultDecoratorContext saveViolation(Violation violation) {\r
+    return saveViolation(violation, false);\r
+  }\r
+}\r
index 484ab7ce54f6c4c7b7b316897cbe4b06f26752cf..b8f42c96040f2f882e1e7bf7032d53803024b859 100644 (file)
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * 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 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;
-import org.sonar.api.batch.Event;
-import org.sonar.api.batch.SonarIndex;
-import org.sonar.api.database.model.ResourceModel;
-import org.sonar.api.design.Dependency;
-import org.sonar.api.measures.*;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.*;
-import org.sonar.api.rules.ActiveRule;
-import org.sonar.api.rules.Violation;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.DefaultResourceCreationLock;
-import org.sonar.batch.ProjectTree;
-import org.sonar.batch.ResourceFilters;
-import org.sonar.batch.ViolationFilters;
-
-import java.util.*;
-
-public class DefaultIndex extends SonarIndex {
-
-  private static final Logger LOG = LoggerFactory.getLogger(DefaultIndex.class);
-
-  private RulesProfile profile;
-  private PersistenceManager persistence;
-  private DefaultResourceCreationLock lock;
-  private MetricFinder metricFinder;
-
-  // filters
-  private ViolationFilters violationFilters;
-  private ResourceFilters resourceFilters;
-
-  // caches
-  private Project currentProject;
-  private Map<Resource, Bucket> buckets = Maps.newHashMap();
-  private Set<Dependency> dependencies = Sets.newHashSet();
-  private Map<Resource, Map<Resource, Dependency>> outgoingDependenciesByResource = Maps.newHashMap();
-  private Map<Resource, Map<Resource, Dependency>> incomingDependenciesByResource = Maps.newHashMap();
-  private ProjectTree projectTree;
-
-  public DefaultIndex(PersistenceManager persistence, DefaultResourceCreationLock lock, ProjectTree projectTree, MetricFinder metricFinder) {
-    this.persistence = persistence;
-    this.lock = lock;
-    this.projectTree = projectTree;
-    this.metricFinder = metricFinder;
-  }
-
-  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, null);
-    currentProject = rootProject;
-
-    for (Project project : rootProject.getModules()) {
-      addProject(project);
-    }
-  }
-
-  private void addProject(Project project) {
-    addResource(project);
-    for (Project module : project.getModules()) {
-      addProject(module);
-    }
-  }
-
-  public Project getProject() {
-    return currentProject;
-  }
-
-  public void setCurrentProject(Project project, ResourceFilters resourceFilters, ViolationFilters violationFilters, RulesProfile profile) {
-    this.currentProject = project;
-
-    // the following components depend on the current project, so they need to be reloaded.
-    this.resourceFilters = resourceFilters;
-    this.violationFilters = violationFilters;
-    this.profile = profile;
-  }
-
-  /**
-   * Keep only project stuff
-   */
-  public void clear() {
-    Iterator<Map.Entry<Resource, Bucket>> it = buckets.entrySet().iterator();
-    while (it.hasNext()) {
-      Map.Entry<Resource, Bucket> entry = it.next();
-      Resource resource = entry.getKey();
-      if (!ResourceUtils.isSet(resource)) {
-        entry.getValue().clear();
-        it.remove();
-      }
-    }
-
-    Set<Dependency> projectDependencies = getDependenciesBetweenProjects();
-    dependencies.clear();
-    incomingDependenciesByResource.clear();
-    outgoingDependenciesByResource.clear();
-    for (Dependency projectDependency : projectDependencies) {
-      projectDependency.setId(null);
-      registerDependency(projectDependency);
-    }
-
-    lock.unlock();
-  }
-
-  public Measure getMeasure(Resource resource, Metric metric) {
-    Bucket bucket = buckets.get(resource);
-    if (bucket != null) {
-      Measure measure = bucket.getMeasures(MeasuresFilters.metric(metric));
-      if (measure != null) {
-        return persistence.reloadMeasure(measure);
-      }
-    }
-    return null;
-  }
-
-  public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {
-    Bucket bucket = buckets.get(resource);
-    if (bucket != null) {
-      // TODO the data measures which are not kept in memory are not reloaded yet. Use getMeasure().
-      return bucket.getMeasures(filter);
-    }
-    return null;
-  }
-
-  /**
-   * the measure is updated if it's already registered.
-   */
-  public Measure addMeasure(Resource resource, Measure measure) {
-    Bucket bucket = checkIndexed(resource);
-    if (bucket != null && !bucket.isExcluded()) {
-      Metric metric = metricFinder.findByKey(measure.getMetricKey());
-      if (metric == null) {
-        throw new SonarException("Unknown metric: " + measure.getMetricKey());
-      }
-      measure.setMetric(metric);
-      bucket.addMeasure(measure);
-
-      if (measure.getPersistenceMode().useDatabase()) {
-        persistence.saveMeasure(resource, measure);
-      }
-    }
-    return measure;
-  }
-
-  //
-  //
-  //
-  // DEPENDENCIES
-  //
-  //
-  //
-
-  public Dependency addDependency(Dependency dependency) {
-    Dependency existingDep = getEdge(dependency.getFrom(), dependency.getTo());
-    if (existingDep != null) {
-      return existingDep;
-    }
-
-    Dependency parentDependency = dependency.getParent();
-    if (parentDependency != null) {
-      addDependency(parentDependency);
-    }
-
-    if (registerDependency(dependency)) {
-      persistence.saveDependency(currentProject, dependency, parentDependency);
-    }
-    return dependency;
-  }
-
-  boolean registerDependency(Dependency dependency) {
-    Bucket fromBucket = doIndex(dependency.getFrom());
-    Bucket toBucket = doIndex(dependency.getTo());
-
-    if (fromBucket != null && !fromBucket.isExcluded() && toBucket != null && !toBucket.isExcluded()) {
-      dependencies.add(dependency);
-      registerOutgoingDependency(dependency);
-      registerIncomingDependency(dependency);
-      return true;
-    }
-    return false;
-  }
-
-  private void registerOutgoingDependency(Dependency dependency) {
-    Map<Resource, Dependency> outgoingDeps = outgoingDependenciesByResource.get(dependency.getFrom());
-    if (outgoingDeps == null) {
-      outgoingDeps = new HashMap<Resource, Dependency>();
-      outgoingDependenciesByResource.put(dependency.getFrom(), outgoingDeps);
-    }
-    outgoingDeps.put(dependency.getTo(), dependency);
-  }
-
-  private void registerIncomingDependency(Dependency dependency) {
-    Map<Resource, Dependency> incomingDeps = incomingDependenciesByResource.get(dependency.getTo());
-    if (incomingDeps == null) {
-      incomingDeps = new HashMap<Resource, Dependency>();
-      incomingDependenciesByResource.put(dependency.getTo(), incomingDeps);
-    }
-    incomingDeps.put(dependency.getFrom(), dependency);
-  }
-
-  public Set<Dependency> getDependencies() {
-    return dependencies;
-  }
-
-  public Dependency getEdge(Resource from, Resource to) {
-    Map<Resource, Dependency> map = outgoingDependenciesByResource.get(from);
-    if (map != null) {
-      return map.get(to);
-    }
-    return null;
-  }
-
-  public boolean hasEdge(Resource from, Resource to) {
-    return getEdge(from, to) != null;
-  }
-
-  public Set<Resource> getVertices() {
-    return buckets.keySet();
-  }
-
-  public Collection<Dependency> getOutgoingEdges(Resource from) {
-    Map<Resource, Dependency> deps = outgoingDependenciesByResource.get(from);
-    if (deps != null) {
-      return deps.values();
-    }
-    return Collections.emptyList();
-  }
-
-  public Collection<Dependency> getIncomingEdges(Resource to) {
-    Map<Resource, Dependency> deps = incomingDependenciesByResource.get(to);
-    if (deps != null) {
-      return deps.values();
-    }
-    return Collections.emptyList();
-  }
-
-  Set<Dependency> getDependenciesBetweenProjects() {
-    Set<Dependency> result = Sets.newLinkedHashSet();
-    for (Dependency dependency : dependencies) {
-      if (ResourceUtils.isSet(dependency.getFrom()) || ResourceUtils.isSet(dependency.getTo())) {
-        result.add(dependency);
-      }
-    }
-    return result;
-  }
-
-  //
-  //
-  //
-  // VIOLATIONS
-  //
-  //
-  //
-
-  public List<Violation> getViolations(Resource resource) {
-    Bucket bucket = buckets.get(resource);
-    if (bucket == null) {
-      return Collections.emptyList();
-    }
-    return bucket.getViolations();
-  }
-
-  public void addViolation(Violation violation, boolean force) {
-    Resource resource = violation.getResource();
-    if (resource == null) {
-      violation.setResource(currentProject);
-    } else if (!Scopes.isHigherThanOrEquals(resource, Scopes.FILE)) {
-      throw new IllegalArgumentException("Violations are only supported on files, directories and project");
-    }
-
-    if (violation.getRule() == null) {
-      LOG.warn("Rule is null, ignoring violation {}", violation);
-      return;
-    }
-
-    Bucket bucket = checkIndexed(resource);
-    if (bucket != null && !bucket.isExcluded()) {
-      boolean isIgnored = !force && violationFilters != null && violationFilters.isIgnored(violation);
-      if (!isIgnored) {
-        ActiveRule activeRule = profile.getActiveRule(violation.getRule());
-        if (activeRule == null) {
-          if (currentProject.getReuseExistingRulesConfig()) {
-            violation.setSeverity(violation.getRule().getSeverity());
-            doAddViolation(violation, bucket);
-
-          } else {
-            LoggerFactory.getLogger(getClass()).debug("Rule is not activated, ignoring violation {}", violation);
-          }
-
-        } else {
-          violation.setSeverity(activeRule.getSeverity());
-          doAddViolation(violation, bucket);
-        }
-      }
-    }
-  }
-
-  private void doAddViolation(Violation violation, Bucket bucket) {
-    bucket.addViolation(violation);
-  }
-
-  //
-  //
-  //
-  // LINKS
-  //
-  //
-  //
-
-  public void addLink(ProjectLink link) {
-    persistence.saveLink(currentProject, link);
-  }
-
-  public void deleteLink(String key) {
-    persistence.deleteLink(currentProject, key);
-  }
-
-  //
-  //
-  //
-  // EVENTS
-  //
-  //
-  //
-
-  public List<Event> getEvents(Resource resource) {
-    // currently events are not cached in memory
-    return persistence.getEvents(resource);
-  }
-
-  public void deleteEvent(Event event) {
-    persistence.deleteEvent(event);
-  }
-
-  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(resource, event);
-    return null;
-  }
-
-  public void setSource(Resource reference, String source) {
-    Bucket bucket = checkIndexed(reference);
-    if (bucket != null && !bucket.isExcluded()) {
-      persistence.setSource(reference, source);
-    }
-  }
-
-  /**
-   * 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(Scopes.PROJECT, 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) {
-      doIndex(resource.getParent());
-    }
-    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;
-    }
-
-    checkLock(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;
-  }
-
-  private void checkLock(Resource resource) {
-    if (lock.isLocked() && !ResourceUtils.isLibrary(resource)) {
-      if (lock.isFailWhenLocked()) {
-        throw new SonarException("Index is locked, resource can not be indexed: " + resource);
-      }
-    }
-  }
-
-  private Bucket checkIndexed(Resource resource) {
-    Bucket bucket = getBucket(resource, true);
-    if (bucket == null) {
-      if (lock.isLocked()) {
-        if (lock.isFailWhenLocked()) {
-          throw new ResourceNotIndexedException(resource);
-        }
-        LOG.warn("Resource will be ignored in next Sonar versions, index is locked: " + resource);
-      }
-      if (Scopes.isDirectory(resource) || Scopes.isFile(resource)) {
-        bucket = doIndex(resource);
-      } else if (!lock.isLocked()) {
-        LOG.warn("Resource will be ignored in next Sonar versions, it must be indexed before adding data: " + resource);
-      }
-    }
-    return bucket;
-  }
-
-  public boolean isExcluded(Resource reference) {
-    Bucket bucket = getBucket(reference, true);
-    return bucket != null && bucket.isExcluded();
-  }
-
-  public boolean isIndexed(Resource reference, boolean acceptExcluded) {
-    return getBucket(reference, acceptExcluded) != 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;
-  }
-}
+/*\r
+ * Sonar, open source software quality management tool.\r
+ * Copyright (C) 2008-2011 SonarSource\r
+ * mailto:contact AT sonarsource DOT com\r
+ *\r
+ * Sonar is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 3 of the License, or (at your option) any later version.\r
+ *\r
+ * Sonar is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with Sonar; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02\r
+ */\r
+package org.sonar.batch.index;\r
+\r
+import com.google.common.collect.Lists;\r
+import com.google.common.collect.Maps;\r
+import com.google.common.collect.Sets;\r
+import org.apache.commons.lang.ObjectUtils;\r
+import org.apache.commons.lang.StringUtils;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.sonar.api.batch.Event;\r
+import org.sonar.api.batch.SonarIndex;\r
+import org.sonar.api.database.model.ResourceModel;\r
+import org.sonar.api.design.Dependency;\r
+import org.sonar.api.measures.*;\r
+import org.sonar.api.profiles.RulesProfile;\r
+import org.sonar.api.resources.*;\r
+import org.sonar.api.rules.ActiveRule;\r
+import org.sonar.api.rules.Violation;\r
+import org.sonar.api.utils.SonarException;\r
+import org.sonar.api.violations.ViolationQuery;\r
+import org.sonar.batch.DefaultResourceCreationLock;\r
+import org.sonar.batch.ProjectTree;\r
+import org.sonar.batch.ResourceFilters;\r
+import org.sonar.batch.ViolationFilters;\r
+\r
+import java.util.*;\r
+\r
+public class DefaultIndex extends SonarIndex {\r
+\r
+  private static final Logger LOG = LoggerFactory.getLogger(DefaultIndex.class);\r
+\r
+  private RulesProfile profile;\r
+  private PersistenceManager persistence;\r
+  private DefaultResourceCreationLock lock;\r
+  private MetricFinder metricFinder;\r
+\r
+  // filters\r
+  private ViolationFilters violationFilters;\r
+  private ResourceFilters resourceFilters;\r
+\r
+  // caches\r
+  private Project currentProject;\r
+  private Map<Resource, Bucket> buckets = Maps.newHashMap();\r
+  private Set<Dependency> dependencies = Sets.newHashSet();\r
+  private Map<Resource, Map<Resource, Dependency>> outgoingDependenciesByResource = Maps.newHashMap();\r
+  private Map<Resource, Map<Resource, Dependency>> incomingDependenciesByResource = Maps.newHashMap();\r
+  private ProjectTree projectTree;\r
+\r
+  public DefaultIndex(PersistenceManager persistence, DefaultResourceCreationLock lock, ProjectTree projectTree, MetricFinder metricFinder) {\r
+    this.persistence = persistence;\r
+    this.lock = lock;\r
+    this.projectTree = projectTree;\r
+    this.metricFinder = metricFinder;\r
+  }\r
+\r
+  public void start() {\r
+    Project rootProject = projectTree.getRootProject();\r
+    doStart(rootProject);\r
+  }\r
+\r
+  void doStart(Project rootProject) {\r
+    Bucket bucket = new Bucket(rootProject);\r
+    buckets.put(rootProject, bucket);\r
+    persistence.saveProject(rootProject, null);\r
+    currentProject = rootProject;\r
+\r
+    for (Project project : rootProject.getModules()) {\r
+      addProject(project);\r
+    }\r
+  }\r
+\r
+  private void addProject(Project project) {\r
+    addResource(project);\r
+    for (Project module : project.getModules()) {\r
+      addProject(module);\r
+    }\r
+  }\r
+\r
+  public Project getProject() {\r
+    return currentProject;\r
+  }\r
+\r
+  public void setCurrentProject(Project project, ResourceFilters resourceFilters, ViolationFilters violationFilters, RulesProfile profile) {\r
+    this.currentProject = project;\r
+\r
+    // the following components depend on the current project, so they need to be reloaded.\r
+    this.resourceFilters = resourceFilters;\r
+    this.violationFilters = violationFilters;\r
+    this.profile = profile;\r
+  }\r
+\r
+  /**\r
+   * Keep only project stuff\r
+   */\r
+  public void clear() {\r
+    Iterator<Map.Entry<Resource, Bucket>> it = buckets.entrySet().iterator();\r
+    while (it.hasNext()) {\r
+      Map.Entry<Resource, Bucket> entry = it.next();\r
+      Resource resource = entry.getKey();\r
+      if (!ResourceUtils.isSet(resource)) {\r
+        entry.getValue().clear();\r
+        it.remove();\r
+      }\r
+    }\r
+\r
+    Set<Dependency> projectDependencies = getDependenciesBetweenProjects();\r
+    dependencies.clear();\r
+    incomingDependenciesByResource.clear();\r
+    outgoingDependenciesByResource.clear();\r
+    for (Dependency projectDependency : projectDependencies) {\r
+      projectDependency.setId(null);\r
+      registerDependency(projectDependency);\r
+    }\r
+\r
+    lock.unlock();\r
+  }\r
+\r
+  public Measure getMeasure(Resource resource, Metric metric) {\r
+    Bucket bucket = buckets.get(resource);\r
+    if (bucket != null) {\r
+      Measure measure = bucket.getMeasures(MeasuresFilters.metric(metric));\r
+      if (measure != null) {\r
+        return persistence.reloadMeasure(measure);\r
+      }\r
+    }\r
+    return null;\r
+  }\r
+\r
+  public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {\r
+    Bucket bucket = buckets.get(resource);\r
+    if (bucket != null) {\r
+      // TODO the data measures which are not kept in memory are not reloaded yet. Use getMeasure().\r
+      return bucket.getMeasures(filter);\r
+    }\r
+    return null;\r
+  }\r
+\r
+  /**\r
+   * the measure is updated if it's already registered.\r
+   */\r
+  public Measure addMeasure(Resource resource, Measure measure) {\r
+    Bucket bucket = checkIndexed(resource);\r
+    if (bucket != null && !bucket.isExcluded()) {\r
+      Metric metric = metricFinder.findByKey(measure.getMetricKey());\r
+      if (metric == null) {\r
+        throw new SonarException("Unknown metric: " + measure.getMetricKey());\r
+      }\r
+      measure.setMetric(metric);\r
+      bucket.addMeasure(measure);\r
+\r
+      if (measure.getPersistenceMode().useDatabase()) {\r
+        persistence.saveMeasure(resource, measure);\r
+      }\r
+    }\r
+    return measure;\r
+  }\r
+\r
+  //\r
+  //\r
+  //\r
+  // DEPENDENCIES\r
+  //\r
+  //\r
+  //\r
+\r
+  public Dependency addDependency(Dependency dependency) {\r
+    Dependency existingDep = getEdge(dependency.getFrom(), dependency.getTo());\r
+    if (existingDep != null) {\r
+      return existingDep;\r
+    }\r
+\r
+    Dependency parentDependency = dependency.getParent();\r
+    if (parentDependency != null) {\r
+      addDependency(parentDependency);\r
+    }\r
+\r
+    if (registerDependency(dependency)) {\r
+      persistence.saveDependency(currentProject, dependency, parentDependency);\r
+    }\r
+    return dependency;\r
+  }\r
+\r
+  boolean registerDependency(Dependency dependency) {\r
+    Bucket fromBucket = doIndex(dependency.getFrom());\r
+    Bucket toBucket = doIndex(dependency.getTo());\r
+\r
+    if (fromBucket != null && !fromBucket.isExcluded() && toBucket != null && !toBucket.isExcluded()) {\r
+      dependencies.add(dependency);\r
+      registerOutgoingDependency(dependency);\r
+      registerIncomingDependency(dependency);\r
+      return true;\r
+    }\r
+    return false;\r
+  }\r
+\r
+  private void registerOutgoingDependency(Dependency dependency) {\r
+    Map<Resource, Dependency> outgoingDeps = outgoingDependenciesByResource.get(dependency.getFrom());\r
+    if (outgoingDeps == null) {\r
+      outgoingDeps = new HashMap<Resource, Dependency>();\r
+      outgoingDependenciesByResource.put(dependency.getFrom(), outgoingDeps);\r
+    }\r
+    outgoingDeps.put(dependency.getTo(), dependency);\r
+  }\r
+\r
+  private void registerIncomingDependency(Dependency dependency) {\r
+    Map<Resource, Dependency> incomingDeps = incomingDependenciesByResource.get(dependency.getTo());\r
+    if (incomingDeps == null) {\r
+      incomingDeps = new HashMap<Resource, Dependency>();\r
+      incomingDependenciesByResource.put(dependency.getTo(), incomingDeps);\r
+    }\r
+    incomingDeps.put(dependency.getFrom(), dependency);\r
+  }\r
+\r
+  public Set<Dependency> getDependencies() {\r
+    return dependencies;\r
+  }\r
+\r
+  public Dependency getEdge(Resource from, Resource to) {\r
+    Map<Resource, Dependency> map = outgoingDependenciesByResource.get(from);\r
+    if (map != null) {\r
+      return map.get(to);\r
+    }\r
+    return null;\r
+  }\r
+\r
+  public boolean hasEdge(Resource from, Resource to) {\r
+    return getEdge(from, to) != null;\r
+  }\r
+\r
+  public Set<Resource> getVertices() {\r
+    return buckets.keySet();\r
+  }\r
+\r
+  public Collection<Dependency> getOutgoingEdges(Resource from) {\r
+    Map<Resource, Dependency> deps = outgoingDependenciesByResource.get(from);\r
+    if (deps != null) {\r
+      return deps.values();\r
+    }\r
+    return Collections.emptyList();\r
+  }\r
+\r
+  public Collection<Dependency> getIncomingEdges(Resource to) {\r
+    Map<Resource, Dependency> deps = incomingDependenciesByResource.get(to);\r
+    if (deps != null) {\r
+      return deps.values();\r
+    }\r
+    return Collections.emptyList();\r
+  }\r
+\r
+  Set<Dependency> getDependenciesBetweenProjects() {\r
+    Set<Dependency> result = Sets.newLinkedHashSet();\r
+    for (Dependency dependency : dependencies) {\r
+      if (ResourceUtils.isSet(dependency.getFrom()) || ResourceUtils.isSet(dependency.getTo())) {\r
+        result.add(dependency);\r
+      }\r
+    }\r
+    return result;\r
+  }\r
+\r
+  //\r
+  //\r
+  //\r
+  // VIOLATIONS\r
+  //\r
+  //\r
+  //\r
+\r
+  /**\r
+   * {@inheritDoc}\r
+   */\r
+  public List<Violation> getViolations(ViolationQuery violationQuery) {\r
+    Resource resource = violationQuery.getResource();\r
+    if (resource == null) {\r
+      throw new IllegalArgumentException("A resource must be set on the ViolationQuery in order to search for violations.");\r
+    }\r
+    Bucket bucket = buckets.get(resource);\r
+    if (bucket == null) {\r
+      return Collections.emptyList();\r
+    }\r
+    List<Violation> filteredViolations = Lists.newArrayList();\r
+    boolean ignoreSwitchedOff = violationQuery.ignoreSwitchedOff();\r
+    for (Violation violation : bucket.getViolations()) {\r
+      if ( ignoreSwitchedOff && violation.isSwitchedOff()) {\r
+        continue;\r
+      }\r
+      filteredViolations.add(violation);\r
+    }\r
+    return filteredViolations;\r
+  }\r
+\r
+  public void addViolation(Violation violation, boolean force) {\r
+    Resource resource = violation.getResource();\r
+    if (resource == null) {\r
+      violation.setResource(currentProject);\r
+    } else if (!Scopes.isHigherThanOrEquals(resource, Scopes.FILE)) {\r
+      throw new IllegalArgumentException("Violations are only supported on files, directories and project");\r
+    }\r
+\r
+    if (violation.getRule() == null) {\r
+      LOG.warn("Rule is null, ignoring violation {}", violation);\r
+      return;\r
+    }\r
+\r
+    Bucket bucket = checkIndexed(resource);\r
+    if (bucket != null && !bucket.isExcluded()) {\r
+      boolean isIgnored = !force && violationFilters != null && violationFilters.isIgnored(violation);\r
+      if (!isIgnored) {\r
+        ActiveRule activeRule = profile.getActiveRule(violation.getRule());\r
+        if (activeRule == null) {\r
+          if (currentProject.getReuseExistingRulesConfig()) {\r
+            violation.setSeverity(violation.getRule().getSeverity());\r
+            doAddViolation(violation, bucket);\r
+\r
+          } else {\r
+            LoggerFactory.getLogger(getClass()).debug("Rule is not activated, ignoring violation {}", violation);\r
+          }\r
+\r
+        } else {\r
+          violation.setSeverity(activeRule.getSeverity());\r
+          doAddViolation(violation, bucket);\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  private void doAddViolation(Violation violation, Bucket bucket) {\r
+    bucket.addViolation(violation);\r
+  }\r
+\r
+  //\r
+  //\r
+  //\r
+  // LINKS\r
+  //\r
+  //\r
+  //\r
+\r
+  public void addLink(ProjectLink link) {\r
+    persistence.saveLink(currentProject, link);\r
+  }\r
+\r
+  public void deleteLink(String key) {\r
+    persistence.deleteLink(currentProject, key);\r
+  }\r
+\r
+  //\r
+  //\r
+  //\r
+  // EVENTS\r
+  //\r
+  //\r
+  //\r
+\r
+  public List<Event> getEvents(Resource resource) {\r
+    // currently events are not cached in memory\r
+    return persistence.getEvents(resource);\r
+  }\r
+\r
+  public void deleteEvent(Event event) {\r
+    persistence.deleteEvent(event);\r
+  }\r
+\r
+  public Event addEvent(Resource resource, String name, String description, String category, Date date) {\r
+    Event event = new Event(name, description, category);\r
+    event.setDate(date);\r
+    persistence.saveEvent(resource, event);\r
+    return null;\r
+  }\r
+\r
+  public void setSource(Resource reference, String source) {\r
+    Bucket bucket = checkIndexed(reference);\r
+    if (bucket != null && !bucket.isExcluded()) {\r
+      persistence.setSource(reference, source);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Does nothing if the resource is already registered.\r
+   */\r
+  public Resource addResource(Resource resource) {\r
+    Bucket bucket = doIndex(resource);\r
+    return bucket != null ? bucket.getResource() : null;\r
+  }\r
+\r
+  public <R extends Resource> R getResource(R reference) {\r
+    Bucket bucket = buckets.get(reference);\r
+    if (bucket != null) {\r
+      return (R) bucket.getResource();\r
+    }\r
+    return null;\r
+  }\r
+\r
+  static String createUID(Project project, Resource resource) {\r
+    String uid = resource.getKey();\r
+    if (!StringUtils.equals(Scopes.PROJECT, resource.getScope())) {\r
+      // not a project nor a library\r
+      uid = new StringBuilder(ResourceModel.KEY_SIZE)\r
+          .append(project.getKey())\r
+          .append(':')\r
+          .append(resource.getKey())\r
+          .toString();\r
+    }\r
+    return uid;\r
+  }\r
+\r
+  private boolean checkExclusion(Resource resource, Bucket parent) {\r
+    boolean excluded = (parent != null && parent.isExcluded()) || (resourceFilters != null && resourceFilters.isExcluded(resource));\r
+    resource.setExcluded(excluded);\r
+    return excluded;\r
+  }\r
+\r
+  public List<Resource> getChildren(Resource resource) {\r
+    return getChildren(resource, false);\r
+  }\r
+\r
+  public List<Resource> getChildren(Resource resource, boolean acceptExcluded) {\r
+    List<Resource> children = Lists.newLinkedList();\r
+    Bucket bucket = getBucket(resource, acceptExcluded);\r
+    if (bucket != null) {\r
+      for (Bucket childBucket : bucket.getChildren()) {\r
+        if (acceptExcluded || !childBucket.isExcluded()) {\r
+          children.add(childBucket.getResource());\r
+        }\r
+      }\r
+    }\r
+    return children;\r
+  }\r
+\r
+  public Resource getParent(Resource resource) {\r
+    Bucket bucket = getBucket(resource, false);\r
+    if (bucket != null && bucket.getParent() != null) {\r
+      return bucket.getParent().getResource();\r
+    }\r
+    return null;\r
+  }\r
+\r
+  public boolean index(Resource resource) {\r
+    Bucket bucket = doIndex(resource);\r
+    return bucket != null && !bucket.isExcluded();\r
+  }\r
+\r
+  private Bucket doIndex(Resource resource) {\r
+    if (resource.getParent() != null) {\r
+      doIndex(resource.getParent());\r
+    }\r
+    return doIndex(resource, resource.getParent());\r
+  }\r
+\r
+  public boolean index(Resource resource, Resource parentReference) {\r
+    Bucket bucket = doIndex(resource, parentReference);\r
+    return bucket != null && !bucket.isExcluded();\r
+  }\r
+\r
+  private Bucket doIndex(Resource resource, Resource parentReference) {\r
+    Bucket bucket = buckets.get(resource);\r
+    if (bucket != null) {\r
+      return bucket;\r
+    }\r
+\r
+    checkLock(resource);\r
+\r
+    Resource parent = null;\r
+    if (!ResourceUtils.isLibrary(resource)) {\r
+      // a library has no parent\r
+      parent = (Resource) ObjectUtils.defaultIfNull(parentReference, currentProject);\r
+    }\r
+\r
+    Bucket parentBucket = getBucket(parent, true);\r
+    if (parentBucket == null && parent != null) {\r
+      LOG.warn("Resource ignored, parent is not indexed: " + resource);\r
+      return null;\r
+    }\r
+\r
+    resource.setEffectiveKey(createUID(currentProject, resource));\r
+    bucket = new Bucket(resource).setParent(parentBucket);\r
+    buckets.put(resource, bucket);\r
+\r
+    boolean excluded = checkExclusion(resource, parentBucket);\r
+    if (!excluded) {\r
+      persistence.saveResource(currentProject, resource, (parentBucket != null ? parentBucket.getResource() : null));\r
+    }\r
+    return bucket;\r
+  }\r
+\r
+  private void checkLock(Resource resource) {\r
+    if (lock.isLocked() && !ResourceUtils.isLibrary(resource)) {\r
+      if (lock.isFailWhenLocked()) {\r
+        throw new SonarException("Index is locked, resource can not be indexed: " + resource);\r
+      }\r
+    }\r
+  }\r
+\r
+  private Bucket checkIndexed(Resource resource) {\r
+    Bucket bucket = getBucket(resource, true);\r
+    if (bucket == null) {\r
+      if (lock.isLocked()) {\r
+        if (lock.isFailWhenLocked()) {\r
+          throw new ResourceNotIndexedException(resource);\r
+        }\r
+        LOG.warn("Resource will be ignored in next Sonar versions, index is locked: " + resource);\r
+      }\r
+      if (Scopes.isDirectory(resource) || Scopes.isFile(resource)) {\r
+        bucket = doIndex(resource);\r
+      } else if (!lock.isLocked()) {\r
+        LOG.warn("Resource will be ignored in next Sonar versions, it must be indexed before adding data: " + resource);\r
+      }\r
+    }\r
+    return bucket;\r
+  }\r
+\r
+  public boolean isExcluded(Resource reference) {\r
+    Bucket bucket = getBucket(reference, true);\r
+    return bucket != null && bucket.isExcluded();\r
+  }\r
+\r
+  public boolean isIndexed(Resource reference, boolean acceptExcluded) {\r
+    return getBucket(reference, acceptExcluded) != null;\r
+  }\r
+\r
+  private Bucket getBucket(Resource resource, boolean acceptExcluded) {\r
+    Bucket bucket = null;\r
+    if (resource != null) {\r
+      bucket = buckets.get(resource);\r
+      if (!acceptExcluded && bucket != null && bucket.isExcluded()) {\r
+        bucket = null;\r
+      }\r
+    }\r
+    return bucket;\r
+  }\r
+}\r
index 39080fe6a5b1063fb7b3bbfa31aad2844a246002..6457cf2cc431b3fa5a01bbe2cd2dcc96c212f7e5 100644 (file)
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * 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 static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.apache.commons.lang.StringUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.batch.ResourceFilter;
-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.rules.Rule;
-import org.sonar.api.rules.Violation;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.DefaultResourceCreationLock;
-import org.sonar.batch.ProjectTree;
-import org.sonar.batch.ResourceFilters;
-import org.sonar.batch.ViolationFilters;
-
-public class DefaultIndexTest {
-
-  private DefaultIndex index = null;
-  private DefaultResourceCreationLock lock;
-
-  @Before
-  public void createIndex() {
-    lock = new DefaultResourceCreationLock();
-    MetricFinder metricFinder = mock(MetricFinder.class);
-    when(metricFinder.findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC);
-
-    index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder);
-    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 shouldCreateUID() {
-    Project project = new Project("my_project");
-    assertThat(DefaultIndex.createUID(project, project), is("my_project"));
-
-    JavaPackage javaPackage = new JavaPackage("org.foo");
-    assertThat(DefaultIndex.createUID(project, javaPackage), is("my_project:org.foo"));
-
-    Library library = new Library("junit:junit", "4.7");
-    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, true), 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, true), 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, true), 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, true), is(false));
-    assertThat(index.isIndexed(fileRef, true), is(false));
-    assertThat(index.isExcluded(fileRef), is(false));
-    assertThat(index.getChildren(fileRef).size(), is(0));
-    assertThat(index.getParent(fileRef), nullValue());
-  }
-
-  /**
-   * Only a warning is logged when index is locked.
-   */
-  @Test
-  public void shouldIndexEvenIfLocked() {
-    lock.lock();
-
-    Directory dir = new Directory("org/foo");
-    assertThat(index.index(dir), is(true));
-    assertThat(index.isIndexed(dir, true), is(true));
-  }
-
-  @Test(expected = SonarException.class)
-  public void shouldFailIfIndexingAndLocked() {
-    lock.setFailWhenLocked(true);
-    lock.lock();
-
-    Directory dir = new Directory("org/foo");
-    index.index(dir);
-  }
-
-  @Test
-  public void shouldBeExcluded() {
-    File file = new File("org/foo/ExcludedBar.java");
-    assertThat(index.index(file), is(false));
-    assertThat(index.isIndexed(file, true), is(true));
-    assertThat(index.isIndexed(file, false), is(false));
-    assertThat(index.isExcluded(file), is(true));
-  }
-
-  @Test
-  public void shouldIndexResourceWhenAddingMeasure() {
-    Resource dir = new Directory("org/foo");
-    index.addMeasure(dir, new Measure("ncloc").setValue(50.0));
-
-    assertThat(index.isIndexed(dir, true), is(true));
-    assertThat(index.getMeasures(dir, MeasuresFilters.metric("ncloc")).getIntValue(), is(50));
-  }
-
-  /**
-   * See http://jira.codehaus.org/browse/SONAR-2107
-   */
-  @Test
-  public void shouldNotFailWhenSavingViolationOnNullRule() {
-    File file = new File("org/foo/Bar.java");
-    Violation violation = Violation.create((Rule) null, file);
-    index.addViolation(violation);
-
-    assertThat(index.getViolations(file).size(), is(0));
-  }
-}
+/*\r
+ * Sonar, open source software quality management tool.\r
+ * Copyright (C) 2008-2011 SonarSource\r
+ * mailto:contact AT sonarsource DOT com\r
+ *\r
+ * Sonar is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 3 of the License, or (at your option) any later version.\r
+ *\r
+ * Sonar is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with Sonar; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02\r
+ */\r
+package org.sonar.batch.index;\r
+\r
+import static org.hamcrest.Matchers.nullValue;\r
+import static org.hamcrest.core.Is.is;\r
+import static org.junit.Assert.assertThat;\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.when;\r
+\r
+import org.apache.commons.lang.StringUtils;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.sonar.api.batch.ResourceFilter;\r
+import org.sonar.api.measures.CoreMetrics;\r
+import org.sonar.api.measures.Measure;\r
+import org.sonar.api.measures.MeasuresFilters;\r
+import org.sonar.api.measures.MetricFinder;\r
+import org.sonar.api.profiles.RulesProfile;\r
+import org.sonar.api.resources.Directory;\r
+import org.sonar.api.resources.File;\r
+import org.sonar.api.resources.Java;\r
+import org.sonar.api.resources.JavaPackage;\r
+import org.sonar.api.resources.Language;\r
+import org.sonar.api.resources.Library;\r
+import org.sonar.api.resources.Project;\r
+import org.sonar.api.resources.Qualifiers;\r
+import org.sonar.api.resources.Resource;\r
+import org.sonar.api.rules.Rule;\r
+import org.sonar.api.rules.Violation;\r
+import org.sonar.api.utils.SonarException;\r
+import org.sonar.api.violations.ViolationQuery;\r
+import org.sonar.batch.DefaultResourceCreationLock;\r
+import org.sonar.batch.ProjectTree;\r
+import org.sonar.batch.ResourceFilters;\r
+import org.sonar.batch.ViolationFilters;\r
+\r
+public class DefaultIndexTest {\r
+\r
+  private DefaultIndex index = null;\r
+  private DefaultResourceCreationLock lock;\r
+  private Rule rule;\r
+\r
+  @Before\r
+  public void createIndex() {\r
+    lock = new DefaultResourceCreationLock();\r
+    MetricFinder metricFinder = mock(MetricFinder.class);\r
+    when(metricFinder.findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC);\r
+\r
+    index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder);\r
+    Project project = new Project("project");\r
+\r
+    ResourceFilter filter = new ResourceFilter() {\r
+\r
+      public boolean isIgnored(Resource resource) {\r
+        return StringUtils.containsIgnoreCase(resource.getKey(), "excluded");\r
+      }\r
+    };\r
+    RulesProfile rulesProfile = RulesProfile.create();\r
+    rule = Rule.create("repoKey", "ruleKey", "Rule");\r
+    rulesProfile.activateRule(rule, null);\r
+    index.setCurrentProject(project, new ResourceFilters(new ResourceFilter[] { filter }), new ViolationFilters(), rulesProfile);\r
+    index.doStart(project);\r
+  }\r
+\r
+  @Test\r
+  public void shouldCreateUID() {\r
+    Project project = new Project("my_project");\r
+    assertThat(DefaultIndex.createUID(project, project), is("my_project"));\r
+\r
+    JavaPackage javaPackage = new JavaPackage("org.foo");\r
+    assertThat(DefaultIndex.createUID(project, javaPackage), is("my_project:org.foo"));\r
+\r
+    Library library = new Library("junit:junit", "4.7");\r
+    assertThat(DefaultIndex.createUID(project, library), is("junit:junit"));\r
+  }\r
+\r
+  @Test\r
+  public void shouldIndexParentOfDeprecatedFiles() {\r
+    File file = new File("org/foo/Bar.java");\r
+    assertThat(index.index(file), is(true));\r
+\r
+    Directory reference = new Directory("org/foo");\r
+    assertThat(index.getResource(reference).getName(), is("org/foo"));\r
+    assertThat(index.isIndexed(reference, true), is(true));\r
+    assertThat(index.isExcluded(reference), is(false));\r
+    assertThat(index.getChildren(reference).size(), is(1));\r
+    assertThat(index.getParent(reference), is(Project.class));\r
+  }\r
+\r
+  @Test\r
+  public void shouldIndexTreeOfResources() {\r
+    Directory directory = new Directory("org/foo");\r
+    File file = new File("org/foo/Bar.java");\r
+    file.setLanguage(Java.INSTANCE);\r
+\r
+    assertThat(index.index(directory), is(true));\r
+    assertThat(index.index(file, directory), is(true));\r
+\r
+    File fileRef = new File("org/foo/Bar.java");\r
+    assertThat(index.getResource(fileRef).getKey(), is("org/foo/Bar.java"));\r
+    assertThat(index.getResource(fileRef).getLanguage(), is((Language) Java.INSTANCE));\r
+    assertThat(index.isIndexed(fileRef, true), is(true));\r
+    assertThat(index.isExcluded(fileRef), is(false));\r
+    assertThat(index.getChildren(fileRef).size(), is(0));\r
+    assertThat(index.getParent(fileRef), is(Directory.class));\r
+  }\r
+\r
+  @Test\r
+  public void shouldIndexLibraryOutsideProjectTree() {\r
+    Library lib = new Library("junit", "4.8");\r
+    assertThat(index.index(lib), is(true));\r
+\r
+    Library reference = new Library("junit", "4.8");\r
+    assertThat(index.getResource(reference).getQualifier(), is(Qualifiers.LIBRARY));\r
+    assertThat(index.isIndexed(reference, true), is(true));\r
+    assertThat(index.isExcluded(reference), is(false));\r
+  }\r
+\r
+  @Test\r
+  public void shouldNotIndexResourceIfParentNotIndexed() {\r
+    Directory directory = new Directory("org/other");\r
+    File file = new File("org/foo/Bar.java");\r
+\r
+    assertThat(index.index(file, directory), is(false));\r
+\r
+    File fileRef = new File("org/foo/Bar.java");\r
+    assertThat(index.isIndexed(directory, true), is(false));\r
+    assertThat(index.isIndexed(fileRef, true), is(false));\r
+    assertThat(index.isExcluded(fileRef), is(false));\r
+    assertThat(index.getChildren(fileRef).size(), is(0));\r
+    assertThat(index.getParent(fileRef), nullValue());\r
+  }\r
+\r
+  /**\r
+   * Only a warning is logged when index is locked.\r
+   */\r
+  @Test\r
+  public void shouldIndexEvenIfLocked() {\r
+    lock.lock();\r
+\r
+    Directory dir = new Directory("org/foo");\r
+    assertThat(index.index(dir), is(true));\r
+    assertThat(index.isIndexed(dir, true), is(true));\r
+  }\r
+\r
+  @Test(expected = SonarException.class)\r
+  public void shouldFailIfIndexingAndLocked() {\r
+    lock.setFailWhenLocked(true);\r
+    lock.lock();\r
+\r
+    Directory dir = new Directory("org/foo");\r
+    index.index(dir);\r
+  }\r
+\r
+  @Test\r
+  public void shouldBeExcluded() {\r
+    File file = new File("org/foo/ExcludedBar.java");\r
+    assertThat(index.index(file), is(false));\r
+    assertThat(index.isIndexed(file, true), is(true));\r
+    assertThat(index.isIndexed(file, false), is(false));\r
+    assertThat(index.isExcluded(file), is(true));\r
+  }\r
+\r
+  @Test\r
+  public void shouldIndexResourceWhenAddingMeasure() {\r
+    Resource dir = new Directory("org/foo");\r
+    index.addMeasure(dir, new Measure("ncloc").setValue(50.0));\r
+\r
+    assertThat(index.isIndexed(dir, true), is(true));\r
+    assertThat(index.getMeasures(dir, MeasuresFilters.metric("ncloc")).getIntValue(), is(50));\r
+  }\r
+\r
+  /**\r
+   * See http://jira.codehaus.org/browse/SONAR-2107\r
+   */\r
+  @Test\r
+  public void shouldNotFailWhenSavingViolationOnNullRule() {\r
+    File file = new File("org/foo/Bar.java");\r
+    Violation violation = Violation.create((Rule) null, file);\r
+    index.addViolation(violation);\r
+\r
+    assertThat(index.getViolations(file).size(), is(0));\r
+  }\r
+\r
+  @Test\r
+  public void testGetViolations() {\r
+    File file = new File("org/foo/Bar.java");\r
+    Violation violation1 = Violation.create(rule, file);\r
+    index.addViolation(violation1);\r
+    Violation violation2 = Violation.create(rule, file);\r
+    violation2.setSwitchedOff(true);\r
+    index.addViolation(violation2);\r
+    Violation violation3 = Violation.create(rule, file);\r
+    violation3.setSwitchedOff(true);\r
+    index.addViolation(violation3);\r
+\r
+    assertThat(index.getViolations(file).size(), is(1));\r
+  }\r
+\r
+  @Test\r
+  public void testGetViolationsWithQuery() {\r
+    File file = new File("org/foo/Bar.java");\r
+    Violation violation1 = Violation.create(rule, file);\r
+    index.addViolation(violation1);\r
+    Violation violation2 = Violation.create(rule, file);\r
+    violation2.setSwitchedOff(true);\r
+    index.addViolation(violation2);\r
+    Violation violation3 = Violation.create(rule, file);\r
+    violation3.setSwitchedOff(true);\r
+    index.addViolation(violation3);\r
+\r
+    assertThat(index.getViolations(ViolationQuery.create().forResource(file).ignoreSwitchedOff(false)).size(), is(3));\r
+  }\r
+\r
+  @Test(expected = IllegalArgumentException.class)\r
+  public void testGetViolationsWithQueryWithNoResource() {\r
+    index.getViolations(ViolationQuery.create());\r
+  }\r
+\r
+}\r
index 8ee17e565b8ef22502a1513f2acc922c1f9cb9b2..af59b924da7c8a74abe0cbfff07a488016cb3897 100644 (file)
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * 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.api.batch;
-
-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.Resource;
-import org.sonar.api.rules.Violation;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
-/**
- * @since 1.10
- */
-public interface DecoratorContext {
-
-  /**
-   * @return the project in which the decorator is
-   */
-  Project getProject();
-
-  /**
-   * @return the resource that is currently decorated
-   */
-  Resource getResource();
-
-  /**
-   * Child contexts are read only
-   */
-  List<DecoratorContext> getChildren();
-
-  // MEASURES
-
-  /**
-   * Find a measure for the resource
-   */
-  Measure getMeasure(Metric metric);
-
-  /**
-   * Never return null.
-   */
-  <M> M getMeasures(MeasuresFilter<M> filter);
-
-  /**
-   * Never return null.
-   */
-  Collection<Measure> getChildrenMeasures(MeasuresFilter filter);
-
-  /**
-   * @return the resource children measures for the given metric
-   */
-  Collection<Measure> getChildrenMeasures(Metric metric);
-
-  /**
-   * Add a measure on the current resource. It can not be executed from children contexts.
-   * 
-   * @return the same context
-   */
-  DecoratorContext saveMeasure(Measure measure);
-
-  /**
-   * Add a measure on the current resource. It can not be executed from children contexts.
-   * 
-   * @return the current object
-   */
-  DecoratorContext saveMeasure(Metric metric, Double value);
-
-  // DEPENDENCIES
-
-  Dependency saveDependency(Dependency dependency);
-
-  Set<Dependency> getDependencies();
-
-  Collection<Dependency> getIncomingDependencies();
-
-  Collection<Dependency> getOutgoingDependencies();
-
-  // RULES
-
-  /**
-   * Read-only rule violations.
-   */
-  List<Violation> getViolations();
-
-  /**
-   * Save a coding rule violation. The decorator which calls this method must be depended upon BatchBarriers.END_OF_VIOLATIONS_GENERATION.
-   * 
-   * @since 2.5
-   * @param force allows to force creation of violation even if it was suppressed by {@link org.sonar.api.rules.ViolationFilter}
-   */
-  DecoratorContext saveViolation(Violation violation, boolean force);
-
-  /**
-   * Save a coding rule violation. The decorator which calls this method must be depended upon BatchBarriers.END_OF_VIOLATIONS_GENERATION.
-   */
-  DecoratorContext saveViolation(Violation violation);
-
-  // EVENTS
-
-  /**
-   * @return the list of events associated to the current resource
-   */
-  List<Event> getEvents();
-
-  /**
-   * Creates an event for a given date
-   * 
-   * @param name the event name
-   * @param description the event description
-   * @param category the event category
-   * @param date the event date
-   * @return the created event
-   */
-  Event createEvent(String name, String description, String category, Date date);
-
-  /**
-   * Deletes an event
-   * 
-   * @param event the event to delete
-   */
-  void deleteEvent(Event event);
-
-}
+/*\r
+ * Sonar, open source software quality management tool.\r
+ * Copyright (C) 2008-2011 SonarSource\r
+ * mailto:contact AT sonarsource DOT com\r
+ *\r
+ * Sonar is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 3 of the License, or (at your option) any later version.\r
+ *\r
+ * Sonar is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with Sonar; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02\r
+ */\r
+package org.sonar.api.batch;\r
+\r
+import org.sonar.api.design.Dependency;\r
+import org.sonar.api.measures.Measure;\r
+import org.sonar.api.measures.MeasuresFilter;\r
+import org.sonar.api.measures.Metric;\r
+import org.sonar.api.resources.Project;\r
+import org.sonar.api.resources.Resource;\r
+import org.sonar.api.rules.Violation;\r
+import org.sonar.api.violations.ViolationQuery;\r
+\r
+import java.util.Collection;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+/**\r
+ * @since 1.10\r
+ */\r
+public interface DecoratorContext {\r
+\r
+  /**\r
+   * @return the project in which the decorator is\r
+   */\r
+  Project getProject();\r
+\r
+  /**\r
+   * @return the resource that is currently decorated\r
+   */\r
+  Resource getResource();\r
+\r
+  /**\r
+   * Child contexts are read only\r
+   */\r
+  List<DecoratorContext> getChildren();\r
+\r
+  // MEASURES\r
+\r
+  /**\r
+   * Find a measure for the resource\r
+   */\r
+  Measure getMeasure(Metric metric);\r
+\r
+  /**\r
+   * Never return null.\r
+   */\r
+  <M> M getMeasures(MeasuresFilter<M> filter);\r
+\r
+  /**\r
+   * Never return null.\r
+   */\r
+  Collection<Measure> getChildrenMeasures(MeasuresFilter filter);\r
+\r
+  /**\r
+   * @return the resource children measures for the given metric\r
+   */\r
+  Collection<Measure> getChildrenMeasures(Metric metric);\r
+\r
+  /**\r
+   * Add a measure on the current resource. It can not be executed from children contexts.\r
+   * \r
+   * @return the same context\r
+   */\r
+  DecoratorContext saveMeasure(Measure measure);\r
+\r
+  /**\r
+   * Add a measure on the current resource. It can not be executed from children contexts.\r
+   * \r
+   * @return the current object\r
+   */\r
+  DecoratorContext saveMeasure(Metric metric, Double value);\r
+\r
+  // DEPENDENCIES\r
+\r
+  Dependency saveDependency(Dependency dependency);\r
+\r
+  Set<Dependency> getDependencies();\r
+\r
+  Collection<Dependency> getIncomingDependencies();\r
+\r
+  Collection<Dependency> getOutgoingDependencies();\r
+\r
+  // RULES\r
+\r
+  /**\r
+   * Returns the violations that match the {@link ViolationQuery} parameters.\r
+   * \r
+   * @since 2.8\r
+   * @param violationQuery\r
+   *          the request parameters specified as a {@link ViolationQuery}\r
+   * @return the list of violations that match those parameters\r
+   */\r
+  public abstract List<Violation> getViolations(ViolationQuery violationQuery);\r
+\r
+  /**\r
+   * Returns all the active (= non switched-off) violations found on the current resource.\r
+   * \r
+   * @return the list of violations\r
+   */\r
+  List<Violation> getViolations();\r
+\r
+  /**\r
+   * Save a coding rule violation. The decorator which calls this method must be depended upon BatchBarriers.END_OF_VIOLATIONS_GENERATION.\r
+   * \r
+   * @since 2.5\r
+   * @param force allows to force creation of violation even if it was suppressed by {@link org.sonar.api.rules.ViolationFilter}\r
+   */\r
+  DecoratorContext saveViolation(Violation violation, boolean force);\r
+\r
+  /**\r
+   * Save a coding rule violation. The decorator which calls this method must be depended upon BatchBarriers.END_OF_VIOLATIONS_GENERATION.\r
+   */\r
+  DecoratorContext saveViolation(Violation violation);\r
+\r
+  // EVENTS\r
+\r
+  /**\r
+   * @return the list of events associated to the current resource\r
+   */\r
+  List<Event> getEvents();\r
+\r
+  /**\r
+   * Creates an event for a given date\r
+   * \r
+   * @param name the event name\r
+   * @param description the event description\r
+   * @param category the event category\r
+   * @param date the event date\r
+   * @return the created event\r
+   */\r
+  Event createEvent(String name, String description, String category, Date date);\r
+\r
+  /**\r
+   * Deletes an event\r
+   * \r
+   * @param event the event to delete\r
+   */\r
+  void deleteEvent(Event event);\r
+\r
+}\r
index 02bb82d115324ffb07809d5fac84eca849552d74..f2a09f9a6ce07cdf3c916f81d45a0140bb412fb2 100644 (file)
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * 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.api.batch;
-
-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> {
-
-  /**
-   * Indexes a resource as a direct child of project. This method does nothing and returns true if the resource already indexed.
-   * If the method resource.getParent() does not return null, then this parent will be indexed too.
-   *
-   * @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);
-
-  /**
-   * 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, boolean acceptExcluded);
-
-  /**
-   * 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 void setSource(Resource reference, String source) throws DuplicatedSourceException;
-
-  public abstract Project getProject();
-
-  public final Collection<Resource> getResources() {
-    return getVertices();
-  }
-
-  /**
-   * 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);
-
-  /**
-   * @since 2.7
-   */
-  public abstract List<Violation> getViolations(Resource resource);
-
-  /**
-   * @since 2.5
-   */
-  public abstract void addViolation(Violation violation, boolean force);
-
-  public final void addViolation(Violation violation) {
-    addViolation(violation, false);
-  }
-
-  /**
-   * Warning: the resource is automatically indexed for backward-compatibility, but it should be explictly
-   * indexed before. Next versions will deactivate this automatic indexation.
-   *
-   * @throws SonarException if the metric is unknown.
-   */
-  public abstract Measure addMeasure(Resource resource, Measure measure);
-
-  public abstract Dependency addDependency(Dependency dependency);
-
-  public abstract Set<Dependency> getDependencies();
-
-  public abstract void addLink(ProjectLink link);
-
-  public abstract void deleteLink(String key);
-
-  public abstract List<Event> getEvents(Resource resource);
-
-  public abstract void deleteEvent(Event event);
-
-  public abstract Event addEvent(Resource resource, String name, String description, String category, Date date);
-
-  public final Collection<Dependency> getOutgoingDependencies(Resource from) {
-    return getOutgoingEdges(from);
-  }
-
-  public final Collection<Dependency> getIncomingDependencies(Resource to) {
-    return getIncomingEdges(to);
-  }
-}
+/*\r
+ * Sonar, open source software quality management tool.\r
+ * Copyright (C) 2008-2011 SonarSource\r
+ * mailto:contact AT sonarsource DOT com\r
+ *\r
+ * Sonar is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 3 of the License, or (at your option) any later version.\r
+ *\r
+ * Sonar is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with Sonar; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02\r
+ */\r
+package org.sonar.api.batch;\r
+\r
+import org.sonar.api.design.Dependency;\r
+import org.sonar.api.measures.Measure;\r
+import org.sonar.api.measures.MeasuresFilter;\r
+import org.sonar.api.measures.Metric;\r
+import org.sonar.api.resources.DuplicatedSourceException;\r
+import org.sonar.api.resources.Project;\r
+import org.sonar.api.resources.ProjectLink;\r
+import org.sonar.api.resources.Resource;\r
+import org.sonar.api.rules.Violation;\r
+import org.sonar.api.violations.ViolationQuery;\r
+import org.sonar.graph.DirectedGraphAccessor;\r
+\r
+import java.util.Collection;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+public abstract class SonarIndex implements DirectedGraphAccessor<Resource, Dependency> {\r
+\r
+  /**\r
+   * Indexes a resource as a direct child of project. This method does nothing and returns true if the resource already indexed.\r
+   * If the method resource.getParent() does not return null, then this parent will be indexed too.\r
+   *\r
+   * @return false if the resource is excluded\r
+   * @since 2.6\r
+   */\r
+  public abstract boolean index(Resource resource);\r
+\r
+\r
+  /**\r
+   * Indexes a resource. This method does nothing if the resource is already indexed.\r
+   *\r
+   * @param resource        the resource to index. Not nullable\r
+   * @param parentReference a reference to the indexed parent. If null, the resource is indexed as a direct child of project.\r
+   * @return false if the parent is not indexed or if the resource is excluded\r
+   * @since 2.6\r
+   */\r
+  public abstract boolean index(Resource resource, Resource parentReference);\r
+\r
+  /**\r
+   * Returns true if the referenced resource is excluded. An excluded resource is not indexed.\r
+   * @since 2.6\r
+   */\r
+  public abstract boolean isExcluded(Resource reference);\r
+\r
+  /**\r
+   * @since 2.6\r
+   */\r
+  public abstract boolean isIndexed(Resource reference, boolean acceptExcluded);\r
+\r
+  /**\r
+   * Search for an indexed resource.\r
+   *\r
+   * @param reference the resource reference\r
+   * @return the indexed resource, null if it's not indexed\r
+   * @since 1.10. Generic types since 2.6.\r
+   */\r
+  public abstract <R extends Resource> R getResource(R reference);\r
+\r
+  /**\r
+   * @since 2.6\r
+   */\r
+  public abstract Resource getParent(Resource reference);\r
+\r
+  /**\r
+   * @since 2.6\r
+   */\r
+\r
+  public abstract Collection<Resource> getChildren(Resource reference);\r
+\r
+  /**\r
+   * Save the source code of a file. The file must be have been indexed before.\r
+   * Note: the source stream is not closed.\r
+   *\r
+   * @return false if the resource is excluded or not indexed\r
+   * @throws org.sonar.api.resources.DuplicatedSourceException\r
+   *          if the source has already been set on this resource\r
+   */\r
+  public abstract void setSource(Resource reference, String source) throws DuplicatedSourceException;\r
+\r
+  public abstract Project getProject();\r
+\r
+  public final Collection<Resource> getResources() {\r
+    return getVertices();\r
+  }\r
+\r
+  /**\r
+   * Indexes the resource.\r
+   * @return the indexed resource, even if it's excluded\r
+   * @deprecated since 2.6. Use methods index()\r
+   */\r
+  @Deprecated\r
+  public abstract Resource addResource(Resource resource);\r
+\r
+  public abstract Measure getMeasure(Resource resource, Metric metric);\r
+\r
+  public abstract <M> M getMeasures(Resource resource, MeasuresFilter<M> filter);\r
+\r
+  /**\r
+   * Returns the violations that match the {@link ViolationQuery} parameters.\r
+   * \r
+   * @since 2.8\r
+   * @param violationQuery\r
+   *          the request parameters specified as a {@link ViolationQuery}\r
+   * @return the list of violations that match those parameters\r
+   */\r
+  public abstract List<Violation> getViolations(ViolationQuery violationQuery);\r
+\r
+  /**\r
+   * Returns all the active (= non switched-off) violations found on the given resource. Equivalent to\r
+   * {@link #getViolations(ViolationQuery)} called with <code>ViolationQuery.create().forResource(resource).ignoreSwitchedOff(true)</code>\r
+   * as a parameter.\r
+   * \r
+   * @since 2.7\r
+   * @param the\r
+   *          resource on which violations are searched\r
+   * @return the list of violations\r
+   */\r
+  public final List<Violation> getViolations(Resource resource) {\r
+    return getViolations(ViolationQuery.create().forResource(resource).ignoreSwitchedOff(true));\r
+  }\r
+\r
+  /**\r
+   * @since 2.5\r
+   */\r
+  public abstract void addViolation(Violation violation, boolean force);\r
+\r
+  public final void addViolation(Violation violation) {\r
+    addViolation(violation, false);\r
+  }\r
+\r
+  /**\r
+   * Warning: the resource is automatically indexed for backward-compatibility, but it should be explictly\r
+   * indexed before. Next versions will deactivate this automatic indexation.\r
+   *\r
+   * @throws SonarException if the metric is unknown.\r
+   */\r
+  public abstract Measure addMeasure(Resource resource, Measure measure);\r
+\r
+  public abstract Dependency addDependency(Dependency dependency);\r
+\r
+  public abstract Set<Dependency> getDependencies();\r
+\r
+  public abstract void addLink(ProjectLink link);\r
+\r
+  public abstract void deleteLink(String key);\r
+\r
+  public abstract List<Event> getEvents(Resource resource);\r
+\r
+  public abstract void deleteEvent(Event event);\r
+\r
+  public abstract Event addEvent(Resource resource, String name, String description, String category, Date date);\r
+\r
+  public final Collection<Dependency> getOutgoingDependencies(Resource from) {\r
+    return getOutgoingEdges(from);\r
+  }\r
+\r
+  public final Collection<Dependency> getIncomingDependencies(Resource to) {\r
+    return getIncomingEdges(to);\r
+  }\r
+}\r
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/violations/ViolationQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/violations/ViolationQuery.java
new file mode 100644 (file)
index 0000000..e9f5ebd
--- /dev/null
@@ -0,0 +1,89 @@
+/*\r
+ * Sonar, open source software quality management tool.\r
+ * Copyright (C) 2008-2011 SonarSource\r
+ * mailto:contact AT sonarsource DOT com\r
+ *\r
+ * Sonar is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 3 of the License, or (at your option) any later version.\r
+ *\r
+ * Sonar is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with Sonar; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02\r
+ */\r
+package org.sonar.api.violations;\r
+\r
+import org.sonar.api.resources.Resource;\r
+\r
+/**\r
+ * Class that allows to query the Sonar index about violations.\r
+ * \r
+ * @since 2.8\r
+ */\r
+public final class ViolationQuery {\r
+\r
+  private boolean ignoreSwitchedOff;\r
+  private Resource resource;\r
+\r
+  /**\r
+   * Use the factory method <code>create()</code>\r
+   */\r
+  ViolationQuery() {\r
+  }\r
+\r
+  /**\r
+   * Creates a new {@link ViolationQuery} object.\r
+   * \r
+   * @return the new query\r
+   */\r
+  public static ViolationQuery create() {\r
+    return new ViolationQuery();\r
+  }\r
+\r
+  /**\r
+   * Specifies if the query should returned switched-off violations or not.\r
+   * \r
+   * @param ignore\r
+   *          if true, the query will return only active violations.\r
+   * @return the current violation query\r
+   */\r
+  public ViolationQuery ignoreSwitchedOff(boolean ignore) {\r
+    this.ignoreSwitchedOff = ignore;\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Tells if the query should returned switched-off violations or not.\r
+   * \r
+   * @return\r
+   */\r
+  public boolean ignoreSwitchedOff() {\r
+    return ignoreSwitchedOff;\r
+  }\r
+\r
+  /**\r
+   * Specifies the resource which violations are search from.\r
+   * \r
+   * @param resource\r
+   *          the resource\r
+   */\r
+  public ViolationQuery forResource(Resource resource) {\r
+    this.resource = resource;\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Returns the resource which violations are search from.\r
+   * \r
+   * @return the resource\r
+   */\r
+  public Resource getResource() {\r
+    return resource;\r
+  }\r
+}\r