From: Julien HENRY Date: Thu, 12 Mar 2015 09:16:10 +0000 (+0100) Subject: SONAR-6273 SONAR-6274 Feed links in compute report and remove links sensor API X-Git-Tag: 5.2-RC1~2596 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c7eba90212ed8130d8f9d8d915c30d9d7574d145;p=sonarqube.git SONAR-6273 SONAR-6274 Feed links in compute report and remove links sensor API --- diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java index 31c78a9d8b7..666a6d1a95e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java @@ -21,23 +21,12 @@ package org.sonar.batch.bootstrap; import com.google.common.collect.Lists; import org.sonar.batch.cpd.CpdComponents; -import org.sonar.batch.design.DirectoryDsmDecorator; -import org.sonar.batch.design.DirectoryTangleIndexDecorator; -import org.sonar.batch.design.FileTangleIndexDecorator; -import org.sonar.batch.design.MavenDependenciesSensor; -import org.sonar.batch.design.ProjectDsmDecorator; -import org.sonar.batch.design.SubProjectDsmDecorator; +import org.sonar.batch.design.*; import org.sonar.batch.issue.tracking.IssueTracking; import org.sonar.batch.maven.MavenProjectBootstrapper; import org.sonar.batch.maven.MavenProjectBuilder; import org.sonar.batch.maven.MavenProjectConverter; -import org.sonar.batch.scan.report.ConsoleReport; -import org.sonar.batch.scan.report.HtmlReport; -import org.sonar.batch.scan.report.IssuesReportBuilder; -import org.sonar.batch.scan.report.JSONReport; -import org.sonar.batch.scan.report.RuleNameProvider; -import org.sonar.batch.scan.report.SourceProvider; -import org.sonar.batch.scan.sensor.ProjectLinksSensor; +import org.sonar.batch.scan.report.*; import org.sonar.batch.scan.sensor.VersionEventsSensor; import org.sonar.batch.scm.ScmConfiguration; import org.sonar.batch.scm.ScmSensor; @@ -71,7 +60,6 @@ public class BatchComponents { ScmSensor.class, LinesSensor.class, - ProjectLinksSensor.class, VersionEventsSensor.class, // Issues tracking diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java index 6558fa59c0b..0e421a788e0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java @@ -37,12 +37,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.Directory; -import org.sonar.api.resources.File; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.ProjectLink; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.Resource; +import org.sonar.api.resources.*; import org.sonar.api.rules.Violation; import org.sonar.api.utils.SonarException; import org.sonar.batch.sensor.DefaultSensorContext; @@ -239,16 +234,6 @@ public class DeprecatedSensorContext extends DefaultSensorContext implements Sen // useless since 4.2. } - @Override - public void saveLink(ProjectLink link) { - index.addLink(link); - } - - @Override - public void deleteLink(String key) { - index.deleteLink(key); - } - @Override public List getEvents(Resource resource) { return index.getEvents(resource); 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 0bec73c2c3e..d2f26e4cecf 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 @@ -90,7 +90,6 @@ public class DefaultIndex extends SonarIndex { private final MeasureCache measureCache; private final ResourceKeyMigration migration; private final DependencyPersister dependencyPersister; - private final LinkPersister linkPersister; private final EventPersister eventPersister; // caches private Project currentProject; @@ -102,11 +101,10 @@ public class DefaultIndex extends SonarIndex { private ModuleIssues moduleIssues; public DefaultIndex(ResourceCache resourceCache, DependencyPersister dependencyPersister, - LinkPersister linkPersister, EventPersister eventPersister, ProjectTree projectTree, MetricFinder metricFinder, + EventPersister eventPersister, ProjectTree projectTree, MetricFinder metricFinder, ResourceKeyMigration migration, MeasureCache measureCache) { this.resourceCache = resourceCache; this.dependencyPersister = dependencyPersister; - this.linkPersister = linkPersister; this.eventPersister = eventPersister; this.projectTree = projectTree; this.metricFinder = metricFinder; @@ -117,7 +115,6 @@ public class DefaultIndex extends SonarIndex { public DefaultIndex(ResourceCache resourceCache, DependencyPersister dependencyPersister, ProjectTree projectTree, MetricFinder metricFinder, MeasureCache measureCache) { this.resourceCache = resourceCache; this.dependencyPersister = dependencyPersister; - this.linkPersister = null; this.eventPersister = null; this.projectTree = projectTree; this.metricFinder = metricFinder; @@ -410,28 +407,6 @@ public class DefaultIndex extends SonarIndex { moduleIssues.initAndAddViolation(violation); } - // - // - // - // LINKS - // - // - // - - @Override - public void addLink(ProjectLink link) { - if (linkPersister != null) { - linkPersister.saveLink(currentProject, link); - } - } - - @Override - public void deleteLink(String key) { - if (linkPersister != null) { - linkPersister.deleteLink(currentProject, key); - } - } - // // // 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 deleted file mode 100644 index 3ab649150ae..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/index/LinkPersister.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.index; - -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.ResourceModel; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.ProjectLink; - -public final class LinkPersister { - private DatabaseSession session; - private ResourceCache resourceCache; - - public LinkPersister(DatabaseSession session, ResourceCache resourcePersister) { - this.session = session; - this.resourceCache = resourcePersister; - } - - public void saveLink(Project project, ProjectLink link) { - BatchResource batchResource = resourceCache.get(project.getEffectiveKey()); - ResourceModel projectDao = session.reattach(ResourceModel.class, batchResource.resource().getId()); - 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(); - - } - - public void deleteLink(Project project, String linkKey) { - BatchResource batchResource = resourceCache.get(project.getEffectiveKey()); - if (batchResource != null) { - ResourceModel model = session.reattach(ResourceModel.class, batchResource.resource().getId()); - ProjectLink dbLink = model.getProjectLink(linkKey); - if (dbLink != null) { - session.remove(dbLink); - model.getProjectLinks().remove(dbLink); - session.commit(); - } - - } - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java index d075a9a6300..181f38b71e5 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java +++ b/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java @@ -19,6 +19,9 @@ */ package org.sonar.batch.report; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.CoreProperties; +import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.resources.Language; import org.sonar.api.resources.Resource; @@ -26,8 +29,10 @@ import org.sonar.api.resources.ResourceUtils; import org.sonar.batch.index.BatchResource; import org.sonar.batch.index.ResourceCache; import org.sonar.batch.protocol.Constants; -import org.sonar.batch.protocol.output.BatchReportWriter; +import org.sonar.batch.protocol.Constants.ComponentLinkType; import org.sonar.batch.protocol.output.BatchReport; +import org.sonar.batch.protocol.output.BatchReport.ComponentLink; +import org.sonar.batch.protocol.output.BatchReportWriter; import javax.annotation.CheckForNull; @@ -86,6 +91,16 @@ public class ComponentsPublisher implements ReportPublisher { for (BatchResource child : batchResource.children()) { builder.addChildRefs(child.batchId()); } + if (ResourceUtils.isProject(r)) { + ProjectDefinition def = reactor.getProject(r.getEffectiveKey()); + ComponentLink.Builder linkBuilder = ComponentLink.newBuilder(); + + writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_HOME_PAGE, ComponentLinkType.HOME); + writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_CI, ComponentLinkType.CI); + writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_ISSUE_TRACKER, ComponentLinkType.ISSUE); + writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_SOURCES, ComponentLinkType.SCM); + writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_SOURCES_DEV, ComponentLinkType.SCM_DEV); + } writer.writeComponent(builder.build()); for (BatchResource child : batchResource.children()) { @@ -93,6 +108,17 @@ public class ComponentsPublisher implements ReportPublisher { } } + private void writeProjectLink(BatchReport.Component.Builder componentBuilder, ProjectDefinition def, ComponentLink.Builder linkBuilder, String linkProp, + ComponentLinkType linkType) { + String link = def.properties().get(linkProp); + if (StringUtils.isNotBlank(link)) { + linkBuilder.setType(linkType); + linkBuilder.setHref(link); + componentBuilder.addLinks(linkBuilder.build()); + linkBuilder.clear(); + } + } + @CheckForNull private String getLanguageKey(Resource r) { Language language = r.getLanguage(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java index 0f457c735d9..2e7a68eb8da 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java @@ -30,17 +30,9 @@ import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.api.scan.filesystem.FileExclusions; import org.sonar.batch.ProjectTree; -import org.sonar.batch.bootstrap.BatchExtensionDictionnary; -import org.sonar.batch.bootstrap.DefaultAnalysisMode; -import org.sonar.batch.bootstrap.ExtensionInstaller; -import org.sonar.batch.bootstrap.ExtensionMatcher; -import org.sonar.batch.bootstrap.ExtensionUtils; +import org.sonar.batch.bootstrap.*; import org.sonar.batch.components.TimeMachineConfiguration; -import org.sonar.batch.debt.DebtDecorator; -import org.sonar.batch.debt.IssueChangelogDebtCalculator; -import org.sonar.batch.debt.NewDebtDecorator; -import org.sonar.batch.debt.SqaleRatingDecorator; -import org.sonar.batch.debt.SqaleRatingSettings; +import org.sonar.batch.debt.*; import org.sonar.batch.deprecated.DeprecatedSensorContext; import org.sonar.batch.deprecated.ResourceFilters; import org.sonar.batch.deprecated.components.DefaultProjectClasspath; @@ -60,41 +52,15 @@ import org.sonar.batch.issue.tracking.InitialOpenIssuesSensor; import org.sonar.batch.issue.tracking.IssueHandlers; import org.sonar.batch.issue.tracking.IssueTrackingDecorator; import org.sonar.batch.language.LanguageDistributionDecorator; -import org.sonar.batch.phases.DatabaseLessPhaseExecutor; -import org.sonar.batch.phases.DatabaseModePhaseExecutor; -import org.sonar.batch.phases.DecoratorsExecutor; -import org.sonar.batch.phases.InitializersExecutor; -import org.sonar.batch.phases.PhaseExecutor; -import org.sonar.batch.phases.PhasesTimeProfiler; -import org.sonar.batch.phases.PostJobsExecutor; -import org.sonar.batch.phases.ProjectInitializer; -import org.sonar.batch.phases.SensorsExecutor; +import org.sonar.batch.phases.*; import org.sonar.batch.qualitygate.GenerateQualityGateEvents; import org.sonar.batch.qualitygate.QualityGateProvider; import org.sonar.batch.qualitygate.QualityGateVerifier; import org.sonar.batch.report.ComponentsPublisher; import org.sonar.batch.report.IssuesPublisher; import org.sonar.batch.report.PublishReportJob; -import org.sonar.batch.rule.ModuleQProfiles; -import org.sonar.batch.rule.QProfileDecorator; -import org.sonar.batch.rule.QProfileEventsDecorator; -import org.sonar.batch.rule.QProfileSensor; -import org.sonar.batch.rule.QProfileVerifier; -import org.sonar.batch.rule.RuleFinderCompatibility; -import org.sonar.batch.rule.RulesProfileProvider; -import org.sonar.batch.scan.filesystem.ComponentIndexer; -import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; -import org.sonar.batch.scan.filesystem.DeprecatedFileFilters; -import org.sonar.batch.scan.filesystem.ExclusionFilters; -import org.sonar.batch.scan.filesystem.FileIndexer; -import org.sonar.batch.scan.filesystem.FileMetadata; -import org.sonar.batch.scan.filesystem.FileSystemLogger; -import org.sonar.batch.scan.filesystem.InputFileBuilderFactory; -import org.sonar.batch.scan.filesystem.LanguageDetectionFactory; -import org.sonar.batch.scan.filesystem.ModuleFileSystemInitializer; -import org.sonar.batch.scan.filesystem.ModuleInputFileCache; -import org.sonar.batch.scan.filesystem.ProjectFileSystemAdapter; -import org.sonar.batch.scan.filesystem.StatusDetectionFactory; +import org.sonar.batch.rule.*; +import org.sonar.batch.scan.filesystem.*; import org.sonar.batch.scan.report.IssuesReports; import org.sonar.batch.sensor.AnalyzerOptimizer; import org.sonar.batch.sensor.DefaultSensorContext; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index eeb15214e81..89b5aed9596 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -185,7 +185,6 @@ public class ProjectScanContainer extends ComponentContainer { private void addDataBaseComponents() { add( EventPersister.class, - LinkPersister.class, MeasurePersister.class, DuplicationPersister.class, ResourcePersister.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/ProjectLinksSensor.java b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/ProjectLinksSensor.java deleted file mode 100644 index c04d0f5cc5e..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/ProjectLinksSensor.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.scan.sensor; - -import org.apache.commons.lang.StringUtils; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.config.Settings; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.ProjectLink; -import org.sonar.core.i18n.DefaultI18n; - -import java.util.Locale; - -public class ProjectLinksSensor implements Sensor { - - private Settings settings; - private DefaultI18n defaultI18n; - private AnalysisMode analysisMode; - - public ProjectLinksSensor(Settings settings, DefaultI18n defaultI18n, AnalysisMode analysisMode) { - this.settings = settings; - this.defaultI18n = defaultI18n; - this.analysisMode = analysisMode; - } - - @Override - public boolean shouldExecuteOnProject(Project project) { - return !analysisMode.isPreview(); - } - - @Override - public void analyse(Project project, SensorContext context) { - handleLink(context, CoreProperties.LINKS_HOME_PAGE); - handleLink(context, CoreProperties.LINKS_CI); - handleLink(context, CoreProperties.LINKS_ISSUE_TRACKER); - handleLink(context, CoreProperties.LINKS_SOURCES); - handleLink(context, CoreProperties.LINKS_SOURCES_DEV); - } - - private void handleLink(SensorContext context, String linkProperty) { - String home = settings.getString(linkProperty); - String linkType = StringUtils.substringAfterLast(linkProperty, "."); - String name = defaultI18n.message(Locale.getDefault(), "project_links." + linkType, linkProperty); - updateLink(context, linkType, name, home); - } - - private void updateLink(SensorContext context, String key, String name, String url) { - if (StringUtils.isBlank(url)) { - context.deleteLink(key); - } else { - context.saveLink(new ProjectLink(key, name, url)); - } - } - - @Override - public String toString() { - return getClass().getSimpleName(); - } -} 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 fe541281e05..0c62cc64ac4 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 @@ -29,13 +29,7 @@ import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilters; import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.resources.Directory; -import org.sonar.api.resources.File; -import org.sonar.api.resources.Java; -import org.sonar.api.resources.Library; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.Resource; +import org.sonar.api.resources.*; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; import org.sonar.batch.ProjectTree; @@ -71,7 +65,7 @@ public class DefaultIndexTest { ProjectTree projectTree = mock(ProjectTree.class); ResourceCache resourceCache = new ResourceCache(); - index = new DefaultIndex(resourceCache, null, null, null, projectTree, metricFinder, + index = new DefaultIndex(resourceCache, null, null, projectTree, metricFinder, mock(ResourceKeyMigration.class), mock(MeasureCache.class)); diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java index fee743895f0..92299c87f20 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java @@ -30,11 +30,7 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.config.Settings; import org.sonar.api.database.model.Snapshot; -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.api.resources.Resource; +import org.sonar.api.resources.*; import org.sonar.api.security.ResourcePermissions; import org.sonar.batch.ProjectTree; import org.sonar.batch.scan.measure.MeasureCache; @@ -225,7 +221,7 @@ public class ResourcePersisterTest extends AbstractDbUnitTestCase { when(projectTree.getProjectDefinition(moduleB)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB"))); when(projectTree.getProjectDefinition(moduleB1)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB/moduleB1"))); - DefaultIndex index = new DefaultIndex(resourceCache, null, null, null, projectTree, mock(MetricFinder.class), + DefaultIndex index = new DefaultIndex(resourceCache, null, null, projectTree, mock(MetricFinder.class), mock(ResourceKeyMigration.class), mock(MeasureCache.class)); diff --git a/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java b/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java index 5bcc75aa6db..d309dd35013 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java @@ -19,9 +19,11 @@ */ package org.sonar.batch.report; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.database.model.Snapshot; @@ -30,9 +32,14 @@ import org.sonar.api.resources.Java; import org.sonar.api.resources.Project; import org.sonar.api.utils.DateUtils; import org.sonar.batch.index.ResourceCache; +import org.sonar.batch.protocol.Constants.ComponentLinkType; +import org.sonar.batch.protocol.output.BatchReport.Component; +import org.sonar.batch.protocol.output.BatchReportReader; import org.sonar.batch.protocol.output.BatchReportWriter; import org.sonar.batch.protocol.output.FileStructure; +import java.io.File; + import static org.assertj.core.api.Assertions.assertThat; public class ComponentsPublisherTest { @@ -40,9 +47,16 @@ public class ComponentsPublisherTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); - ProjectReactor reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo")); - ResourceCache resourceCache = new ResourceCache(); - ComponentsPublisher publisher = new ComponentsPublisher(reactor, resourceCache); + private ProjectReactor reactor; + private ResourceCache resourceCache; + private ComponentsPublisher publisher; + + @Before + public void prepare() { + reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo")); + resourceCache = new ResourceCache(); + publisher = new ComponentsPublisher(reactor, resourceCache); + } @Test public void add_components_to_report() throws Exception { @@ -56,6 +70,7 @@ public class ComponentsPublisherTest { module1.setParent(root); module1.setId(2).setUuid("MODULE_UUID"); resourceCache.add(module1, root).setSnapshot(new Snapshot().setId(12)); + reactor.getRoot().addSubProject(ProjectDefinition.create().setKey("module1")); Directory dir = Directory.create("src"); dir.setEffectiveKey("foo:src"); @@ -77,7 +92,8 @@ public class ComponentsPublisherTest { testFile.setId(6).setUuid("TEST_FILE_UUID"); resourceCache.add(testFile, dir).setSnapshot(new Snapshot().setId(16)); - BatchReportWriter writer = new BatchReportWriter(temp.newFolder()); + File outputDir = temp.newFolder(); + BatchReportWriter writer = new BatchReportWriter(outputDir); publisher.publish(writer); assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue(); @@ -89,5 +105,53 @@ public class ComponentsPublisherTest { // no such reference assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isFalse(); + + BatchReportReader reader = new BatchReportReader(outputDir); + Component rootProtobuf = reader.readComponent(1); + assertThat(rootProtobuf.getLinksCount()).isEqualTo(0); + + } + + @Test + public void add_components_with_links() throws Exception { + // inputs + Project root = new Project("foo").setName("Root project") + .setAnalysisDate(DateUtils.parseDate(("2012-12-12"))); + root.setId(1).setUuid("PROJECT_UUID"); + resourceCache.add(root, null).setSnapshot(new Snapshot().setId(11)); + reactor.getRoot().properties().put(CoreProperties.LINKS_HOME_PAGE, "http://home"); + + Project module1 = new Project("module1").setName("Module1"); + module1.setParent(root); + module1.setId(2).setUuid("MODULE_UUID"); + resourceCache.add(module1, root).setSnapshot(new Snapshot().setId(12)); + ProjectDefinition moduleDef = ProjectDefinition.create().setKey("module1"); + moduleDef.properties().put(CoreProperties.LINKS_CI, "http://ci"); + reactor.getRoot().addSubProject(moduleDef); + + Directory dir = Directory.create("src"); + dir.setEffectiveKey("foo:src"); + dir.setId(3).setUuid("DIR_UUID"); + resourceCache.add(dir, module1).setSnapshot(new Snapshot().setId(13)); + + org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", Java.INSTANCE, false); + file.setEffectiveKey("foo:src/Foo.java"); + file.setId(4).setUuid("FILE_UUID"); + resourceCache.add(file, dir).setSnapshot(new Snapshot().setId(14)); + + File outputDir = temp.newFolder(); + BatchReportWriter writer = new BatchReportWriter(outputDir); + publisher.publish(writer); + + BatchReportReader reader = new BatchReportReader(outputDir); + Component rootProtobuf = reader.readComponent(1); + assertThat(rootProtobuf.getLinksCount()).isEqualTo(1); + assertThat(rootProtobuf.getLinks(0).getType()).isEqualTo(ComponentLinkType.HOME); + assertThat(rootProtobuf.getLinks(0).getHref()).isEqualTo("http://home"); + + Component module1Protobuf = reader.readComponent(2); + assertThat(module1Protobuf.getLinksCount()).isEqualTo(1); + assertThat(module1Protobuf.getLinks(0).getType()).isEqualTo(ComponentLinkType.CI); + assertThat(module1Protobuf.getLinks(0).getHref()).isEqualTo("http://ci"); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/ProjectLinksSensorTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/ProjectLinksSensorTest.java deleted file mode 100644 index 6e44bc572f4..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/ProjectLinksSensorTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.scan.sensor; - -import org.sonar.batch.scan.sensor.ProjectLinksSensor; - -import org.apache.commons.lang.StringUtils; -import org.junit.Test; -import org.mockito.ArgumentMatcher; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.config.Settings; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.ProjectLink; -import org.sonar.core.i18n.DefaultI18n; - -import java.util.Locale; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class ProjectLinksSensorTest { - - @Test - public void testToString() { - assertThat(new ProjectLinksSensor(null, null, null).toString()).isEqualTo("ProjectLinksSensor"); - } - - @Test - public void shouldNotExecuteInPreview() { - Project project = mock(Project.class); - AnalysisMode analysisMode = mock(AnalysisMode.class); - assertThat(new ProjectLinksSensor(null, null, analysisMode).shouldExecuteOnProject(project)).isTrue(); - when(analysisMode.isPreview()).thenReturn(true); - assertThat(new ProjectLinksSensor(null, null, analysisMode).shouldExecuteOnProject(project)).isFalse(); - } - - @Test - public void shouldSaveLinks() { - Settings settings = new Settings(); - settings.setProperty(CoreProperties.LINKS_HOME_PAGE, "http://home"); - DefaultI18n defaultI18n = mock(DefaultI18n.class); - when(defaultI18n.message(Locale.getDefault(), "project_links.homepage", CoreProperties.LINKS_HOME_PAGE)).thenReturn("HOME"); - Project project = mock(Project.class); - SensorContext context = mock(SensorContext.class); - - new ProjectLinksSensor(settings, defaultI18n, null).analyse(project, context); - - verify(context).saveLink(argThat(new MatchLink("homepage", "HOME", "http://home"))); - } - - @Test - public void shouldDeleteLink() { - Settings settings = new Settings(); - settings.setProperty(CoreProperties.LINKS_HOME_PAGE, ""); - DefaultI18n defaultI18n = mock(DefaultI18n.class); - when(defaultI18n.message(Locale.getDefault(), "project_links.homepage", CoreProperties.LINKS_HOME_PAGE)).thenReturn("HOME"); - Project project = mock(Project.class); - SensorContext context = mock(SensorContext.class); - - new ProjectLinksSensor(settings, defaultI18n, null).analyse(project, context); - - verify(context).deleteLink("homepage"); - } - - private class MatchLink extends ArgumentMatcher { - private String key; - private String name; - private String url; - - private MatchLink(String key, String name, String url) { - this.key = key; - this.name = name; - this.url = url; - } - - @Override - public boolean matches(Object o) { - ProjectLink link = (ProjectLink) o; - return StringUtils.equals(link.getHref(), url) && StringUtils.equals(link.getKey(), key) && StringUtils.equals(link.getName(), name); - } - } - -} diff --git a/sonar-core/src/main/resources/META-INF/persistence.xml b/sonar-core/src/main/resources/META-INF/persistence.xml index 099bd1c8c9e..016767d84fb 100644 --- a/sonar-core/src/main/resources/META-INF/persistence.xml +++ b/sonar-core/src/main/resources/META-INF/persistence.xml @@ -17,7 +17,6 @@ org.sonar.api.database.model.ResourceModel org.sonar.api.rules.Rule org.sonar.api.rules.RuleParam - org.sonar.api.resources.ProjectLink org.sonar.api.batch.Event true 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 a9eb2562878..25a7521cdd7 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 @@ -25,7 +25,6 @@ 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.ProjectLink; import org.sonar.api.resources.Resource; import org.sonar.api.rules.Violation; @@ -227,19 +226,6 @@ public interface SensorContext extends org.sonar.api.batch.sensor.SensorContext @Deprecated void saveSource(Resource reference, String source); - // ----------- LINKS -------------- - - /** - * add a link to an external page like project homepage, sources (subversion, ...), continuous integration server... Example : - * context.addLink(new ProjectLink("maven_site, "Maven site", "http://my.maven.com) - */ - void saveLink(ProjectLink link); - - /** - * remove a link. It does not fail if key is unknown. - */ - void deleteLink(String key); - // ----------- EVENTS -------------- /** 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 6714ed9c1bb..a9d32eb7595 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 @@ -24,7 +24,6 @@ import org.sonar.api.design.Dependency; import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilter; 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; @@ -148,10 +147,6 @@ public abstract class SonarIndex implements DirectedGraphAccessor getDependencies(); - public abstract void addLink(ProjectLink link); - - public abstract void deleteLink(String key); - public abstract List getEvents(Resource resource); public abstract void deleteEvent(Event event); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java index 3f0f2469cbb..d8b080cdab4 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/ResourceModel.java @@ -23,18 +23,14 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; -import org.hibernate.annotations.BatchSize; import org.sonar.api.database.BaseIdentifiable; import org.sonar.api.resources.Language; -import org.sonar.api.resources.ProjectLink; import org.sonar.api.resources.Resource; import javax.annotation.Nullable; import javax.persistence.*; -import java.util.ArrayList; import java.util.Date; -import java.util.List; /** * Class to map resource with hibernate model @@ -94,11 +90,6 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { @Column(name = "created_at", updatable = true, nullable = true) private Date createdAt; - @OneToMany(mappedBy = "resource", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}) - @JoinColumn(name = "component_uuid") - @BatchSize(size = 8) - private List projectLinks = new ArrayList(); - @Column(name = "uuid", updatable = false, nullable = true, length = 50) private String uuid; @@ -143,29 +134,6 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { this.qualifier = qualifier; } - /** - * Only available at project level. - */ - public List getProjectLinks() { - return projectLinks; - } - - public void setProjectLinks(List projectLinks) { - this.projectLinks = projectLinks; - } - - /** - * @return a project link given its key if exists, null otherwise - */ - public ProjectLink getProjectLink(String key) { - for (ProjectLink projectLink : projectLinks) { - if (key.equals(projectLink.getKey())) { - return projectLink; - } - } - return null; - } - /** * Only available at project level. */ @@ -405,7 +373,6 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable { clone.setDescription(getDescription()); clone.setDeprecatedKey(getDeprecatedKey()); clone.setEnabled(getEnabled()); - clone.setProjectLinks(getProjectLinks()); clone.setLanguageKey(getLanguageKey()); clone.setCopyResourceId(getCopyResourceId()); clone.setLongName(getLongName()); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectLink.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectLink.java deleted file mode 100644 index 3e4f276571d..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectLink.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.api.resources; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.builder.ReflectionToStringBuilder; -import org.apache.commons.lang.builder.ToStringStyle; -import org.sonar.api.database.BaseIdentifiable; -import org.sonar.api.database.model.ResourceModel; - -import javax.persistence.*; - -/** - * @since 1.10 - */ -@Entity(name = "ProjectLink") -@Table(name = "project_links") -public class ProjectLink extends BaseIdentifiable { - - public static final int NAME_COLUMN_SIZE = 128; - public static final int HREF_COLUMN_SIZE = 2048; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "component_uuid", referencedColumnName = "uuid", updatable = false, nullable = false) - private ResourceModel resource; - - @Column(name = "link_type", updatable = true, nullable = true, length = 20) - private String key; - - @Column(name = "name", updatable = true, nullable = true, length = NAME_COLUMN_SIZE) - private String name; - - @Column(name = "href", updatable = true, nullable = false, length = HREF_COLUMN_SIZE) - private String href; - - public ProjectLink() { - } - - public ProjectLink(String key, String name, String href) { - this.key = key; - setName(name); - setHref(href); - } - - public ResourceModel getResource() { - return resource; - } - - public void setResource(ResourceModel resource) { - this.resource = resource; - } - - public String getName() { - return name; - } - - public final void setName(String name) { - this.name = StringUtils.abbreviate(name, NAME_COLUMN_SIZE); - } - - public String getHref() { - return href; - } - - public final void setHref(String href) { - if (href == null) { - throw new IllegalArgumentException("ProjectLink.href can not be null"); - } - this.href = StringUtils.abbreviate(href, HREF_COLUMN_SIZE); - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ProjectLink that = (ProjectLink) o; - if (!key.equals(that.key)) { - return false; - } - return resource.equals(that.resource); - - } - - @Override - public int hashCode() { - int result = resource != null ? resource.hashCode() : 0; - result = 31 * result + key.hashCode(); - return result; - } - - @Override - public String toString() { - return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString(); - } - - public void copyFieldsFrom(ProjectLink link) { - this.name = link.getName(); - this.href = link.getHref(); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectLinkTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectLinkTest.java deleted file mode 100644 index b193513f8ea..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectLinkTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.api.resources; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class ProjectLinkTest { - - ProjectLink link = new ProjectLink(); - - @Test - public void testSetName() { - link.setName(overFillString(ProjectLink.NAME_COLUMN_SIZE)); - assertAbbreviated(ProjectLink.NAME_COLUMN_SIZE, link.getName()); - } - - @Test - public void testSetHref() { - link.setHref(overFillString(ProjectLink.HREF_COLUMN_SIZE)); - assertAbbreviated(ProjectLink.HREF_COLUMN_SIZE, link.getHref()); - } - - @Test - public void testConstructor() { - link = new ProjectLink("home", - overFillString(ProjectLink.NAME_COLUMN_SIZE), - overFillString(ProjectLink.HREF_COLUMN_SIZE)); - assertAbbreviated(ProjectLink.NAME_COLUMN_SIZE, link.getName()); - assertAbbreviated(ProjectLink.HREF_COLUMN_SIZE, link.getHref()); - } - - private String overFillString(int maxSize) { - StringBuilder overFilled = new StringBuilder(); - for (int i = 0; i < 50 + maxSize; i++) { - overFilled.append("x"); - } - return overFilled.toString(); - } - - private void assertAbbreviated(int maxSize, String value) { - assertEquals(maxSize, value.length()); - assertEquals('.', value.charAt(maxSize - 1)); - } -}