diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-01-21 14:32:24 +0100 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-01-21 14:32:24 +0100 |
commit | 08cb4444e0341652a4bf34133485ac405fb1ec50 (patch) | |
tree | bfefc7453a2ad73be491cdeaa10c3b1bd45bd060 | |
parent | 1ab2475003835b71ff44b3652691c538059db699 (diff) | |
download | sonarqube-08cb4444e0341652a4bf34133485ac405fb1ec50.tar.gz sonarqube-08cb4444e0341652a4bf34133485ac405fb1ec50.zip |
SONAR-2127 API: do not automatically create hierarchy of resource tree
35 files changed, 789 insertions, 303 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java index 1f7d5e5982f..da1415f6fde 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java @@ -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; } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java index 836d23613e8..310b19f04ef 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java @@ -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()); } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java index 4e6ddddf74e..68e686f61c8 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java @@ -20,13 +20,14 @@ 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) { diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java index 8170bb55dfe..22574d4a1b7 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java @@ -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); diff --git a/sonar-batch/pom.xml b/sonar-batch/pom.xml index b39f5e60004..fd1ae8dffb2 100644 --- a/sonar-batch/pom.xml +++ b/sonar-batch/pom.xml @@ -23,6 +23,10 @@ </dependency> <dependency> <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-java-api</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-plugin-api</artifactId> </dependency> <dependency> @@ -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> diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java index 24c70220e9d..a924fba8ac1 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java @@ -19,23 +19,21 @@ */ 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) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java index ee3ad649957..eb374de1094 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java @@ -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; + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/Bucket.java b/sonar-batch/src/main/java/org/sonar/batch/index/Bucket.java index 0969f089333..5a19f6ba97d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/Bucket.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/Bucket.java @@ -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) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java index 8f7a9f1e872..b63bef696fd 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java @@ -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; + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java index 942dd3aa127..ea019c5ee4c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java @@ -19,13 +19,12 @@ */ 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; } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java index 3634307178f..640503ecdd8 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java @@ -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()); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java index 9b536333674..5cc2b1aa3e5 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/EventPersister.java @@ -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(); + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/LinkPersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/LinkPersister.java index 123b363658b..66ec62ce999 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/LinkPersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/LinkPersister.java @@ -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) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java index 39737571315..ec8ca8c925e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java @@ -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()); diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/PersistenceManager.java b/sonar-batch/src/main/java/org/sonar/batch/index/PersistenceManager.java index f9aebeb5e75..caffd0dac07 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/PersistenceManager.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/PersistenceManager.java @@ -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 index 00000000000..c2f30edd2eb --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/index/ResourceNotPersistedException.java @@ -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()); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java index 644c3261b21..dad3c8f5428 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java @@ -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); diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/SourcePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/SourcePersister.java index 4480ab4bef5..1b1857c7fc9 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/SourcePersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/SourcePersister.java @@ -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() { diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java index 67a0e4e36d6..25f6bcb6cc1 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java @@ -19,25 +19,124 @@ */ 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 index 00000000000..48458f63a1c --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultPersistenceManagerTest.java @@ -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)); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java index bfd8a913dc6..ec61785d170 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java @@ -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"); } - + } diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java index 90d597908c5..13a299b38b3 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java @@ -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)); diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/SourcePersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/SourcePersisterTest.java index d92fdb8adf7..cc92ff24a4c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/SourcePersisterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/SourcePersisterTest.java @@ -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 } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java index f32e3e951ff..b11a96f5655 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java @@ -19,11 +19,6 @@ */ 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 : '" diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java index ae0f10862c4..07b58dc1a13 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java @@ -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); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java index de6d6e1f670..8811492b955 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SonarIndex.java @@ -19,41 +19,102 @@ */ 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 */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java index ebf2b745c42..b2135800217 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Directory.java @@ -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 index 00000000000..8cbd6dce026 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DuplicatedSourceException.java @@ -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)); + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java index e8d2b02cafc..24b7d32b6b8 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/File.java @@ -19,12 +19,12 @@ */ 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; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Library.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Library.java index 1681a06b108..61f85842340 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Library.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Library.java @@ -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 diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java index e4f14394dfa..9890eeb830d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java @@ -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 */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Qualifiers.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Qualifiers.java index f5f87b2161a..bb1c77e99ac 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Qualifiers.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Qualifiers.java @@ -19,13 +19,35 @@ */ 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"; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Scopes.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Scopes.java index fc8a29f2bbb..001fbd96e5e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Scopes.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Scopes.java @@ -20,7 +20,10 @@ 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 diff --git a/sonar-server/pom.xml b/sonar-server/pom.xml index 54873a7cd3c..a90ae860b18 100644 --- a/sonar-server/pom.xml +++ b/sonar-server/pom.xml @@ -29,6 +29,11 @@ </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> </dependency> <dependency> diff --git a/tests/integration/tests/pom.xml b/tests/integration/tests/pom.xml index 36a218cb59e..4f6f2790741 100644 --- a/tests/integration/tests/pom.xml +++ b/tests/integration/tests/pom.xml @@ -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> |