diff options
148 files changed, 1978 insertions, 1469 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index a87d01690a6..b8770197f47 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -20,36 +20,84 @@ package org.sonar.plugins.core; import com.google.common.collect.ImmutableList; -import org.sonar.api.*; +import org.sonar.api.CoreProperties; +import org.sonar.api.Properties; +import org.sonar.api.Property; +import org.sonar.api.PropertyType; +import org.sonar.api.SonarPlugin; import org.sonar.api.checks.NoSonarFilter; -import org.sonar.api.config.PropertyDefinition; -import org.sonar.api.resources.Qualifiers; -import org.sonar.batch.components.PastSnapshotFinder; -import org.sonar.batch.debt.IssueChangelogDebtCalculator; -import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; import org.sonar.core.timemachine.Periods; import org.sonar.plugins.core.batch.IndexProjectPostJob; import org.sonar.plugins.core.charts.DistributionAreaChart; import org.sonar.plugins.core.charts.DistributionBarChart; import org.sonar.plugins.core.charts.XradarChart; import org.sonar.plugins.core.colorizers.JavaColorizerFormat; -import org.sonar.plugins.core.dashboards.*; -import org.sonar.plugins.core.issue.*; -import org.sonar.plugins.core.issue.notification.*; +import org.sonar.plugins.core.dashboards.GlobalDefaultDashboard; +import org.sonar.plugins.core.dashboards.ProjectDefaultDashboard; +import org.sonar.plugins.core.dashboards.ProjectHotspotDashboard; +import org.sonar.plugins.core.dashboards.ProjectIssuesDashboard; +import org.sonar.plugins.core.dashboards.ProjectTimeMachineDashboard; +import org.sonar.plugins.core.issue.CountFalsePositivesDecorator; +import org.sonar.plugins.core.issue.CountUnresolvedIssuesDecorator; +import org.sonar.plugins.core.issue.InitialOpenIssuesSensor; +import org.sonar.plugins.core.issue.InitialOpenIssuesStack; +import org.sonar.plugins.core.issue.IssueHandlers; +import org.sonar.plugins.core.issue.IssueTracking; +import org.sonar.plugins.core.issue.IssueTrackingDecorator; +import org.sonar.plugins.core.issue.IssuesDensityDecorator; +import org.sonar.plugins.core.issue.WeightedIssuesDecorator; +import org.sonar.plugins.core.issue.notification.ChangesOnMyIssueNotificationDispatcher; +import org.sonar.plugins.core.issue.notification.IssueChangesEmailTemplate; +import org.sonar.plugins.core.issue.notification.NewFalsePositiveNotificationDispatcher; +import org.sonar.plugins.core.issue.notification.NewIssuesEmailTemplate; +import org.sonar.plugins.core.issue.notification.NewIssuesNotificationDispatcher; +import org.sonar.plugins.core.issue.notification.SendIssueNotificationsPostJob; import org.sonar.plugins.core.measurefilters.MyFavouritesFilter; import org.sonar.plugins.core.measurefilters.ProjectFilter; import org.sonar.plugins.core.notifications.alerts.NewAlerts; import org.sonar.plugins.core.security.ApplyProjectRolesDecorator; -import org.sonar.plugins.core.sensors.*; -import org.sonar.plugins.core.technicaldebt.DebtDecorator; -import org.sonar.plugins.core.technicaldebt.NewDebtDecorator; -import org.sonar.plugins.core.timemachine.*; +import org.sonar.plugins.core.sensors.BranchCoverageDecorator; +import org.sonar.plugins.core.sensors.CommentDensityDecorator; +import org.sonar.plugins.core.sensors.CoverageDecorator; +import org.sonar.plugins.core.sensors.CoverageMeasurementFilter; +import org.sonar.plugins.core.sensors.DirectoriesDecorator; +import org.sonar.plugins.core.sensors.FileHashSensor; +import org.sonar.plugins.core.sensors.FilesDecorator; +import org.sonar.plugins.core.sensors.ItBranchCoverageDecorator; +import org.sonar.plugins.core.sensors.ItCoverageDecorator; +import org.sonar.plugins.core.sensors.ItLineCoverageDecorator; +import org.sonar.plugins.core.sensors.LineCoverageDecorator; +import org.sonar.plugins.core.sensors.ManualMeasureDecorator; +import org.sonar.plugins.core.sensors.OverallBranchCoverageDecorator; +import org.sonar.plugins.core.sensors.OverallCoverageDecorator; +import org.sonar.plugins.core.sensors.OverallLineCoverageDecorator; +import org.sonar.plugins.core.sensors.ProfileEventsSensor; +import org.sonar.plugins.core.sensors.ProjectLinksSensor; +import org.sonar.plugins.core.sensors.UnitTestDecorator; +import org.sonar.plugins.core.sensors.VersionEventsSensor; +import org.sonar.plugins.core.timemachine.NewCoverageAggregator; +import org.sonar.plugins.core.timemachine.NewCoverageFileAnalyzer; +import org.sonar.plugins.core.timemachine.NewItCoverageFileAnalyzer; +import org.sonar.plugins.core.timemachine.NewOverallCoverageFileAnalyzer; +import org.sonar.plugins.core.timemachine.TendencyDecorator; +import org.sonar.plugins.core.timemachine.TimeMachineConfigurationPersister; +import org.sonar.plugins.core.timemachine.VariationDecorator; import org.sonar.plugins.core.web.TestsViewer; import org.sonar.plugins.core.widgets.*; -import org.sonar.plugins.core.widgets.issues.*; -import org.sonar.plugins.core.widgets.measures.*; +import org.sonar.plugins.core.widgets.issues.ActionPlansWidget; +import org.sonar.plugins.core.widgets.issues.FalsePositiveIssuesWidget; +import org.sonar.plugins.core.widgets.issues.IssueFilterWidget; +import org.sonar.plugins.core.widgets.issues.IssuesWidget; +import org.sonar.plugins.core.widgets.issues.MyUnresolvedIssuesWidget; +import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesPerAssigneeWidget; +import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesStatusesWidget; +import org.sonar.plugins.core.widgets.measures.MeasureFilterAsBubbleChartWidget; +import org.sonar.plugins.core.widgets.measures.MeasureFilterAsCloudWidget; +import org.sonar.plugins.core.widgets.measures.MeasureFilterAsHistogramWidget; +import org.sonar.plugins.core.widgets.measures.MeasureFilterAsPieChartWidget; +import org.sonar.plugins.core.widgets.measures.MeasureFilterListWidget; +import org.sonar.plugins.core.widgets.measures.MeasureFilterTreemapWidget; -import java.util.Arrays; import java.util.List; @Properties({ @@ -292,11 +340,6 @@ public final class CorePlugin extends SonarPlugin { NewFalsePositiveNotificationDispatcher.class, NewFalsePositiveNotificationDispatcher.newMetadata(), - // technical debt - DebtDecorator.class, - NewDebtDecorator.class, - IssueChangelogDebtCalculator.class, - // batch ProfileEventsSensor.class, ProjectLinksSensor.class, @@ -334,64 +377,7 @@ public final class CorePlugin extends SonarPlugin { NewAlerts.class, NewAlerts.newMetadata()); - extensions.addAll(ExclusionProperties.definitions()); - extensions.addAll(IssueExclusionsConfiguration.getPropertyDefinitions()); - extensions.addAll(CoverageMeasurementFilter.getPropertyDefinitions()); - extensions.addAll(PastSnapshotFinder.getPropertyDefinitions()); - extensions.addAll(DebtDecorator.definitions()); - extensions.addAll(propertyDefinitions()); - return extensions.build(); } - static List<PropertyDefinition> propertyDefinitions() { - return Arrays.asList( - PropertyDefinition.builder(CoreProperties.CORE_VIOLATION_LOCALE_PROPERTY) - .defaultValue("en") - .name("Locale used for issue messages") - .description("Deprecated property. Keep default value for backward compatibility.") - .hidden() - .build(), - PropertyDefinition.builder(CoreProperties.CORE_ALLOW_USERS_TO_SIGNUP_PROPERTY) - .defaultValue("" + CoreProperties.CORE_ALLOW_USERS_TO_SIGNUP_DEAULT_VALUE) - .name("Allow users to sign up online") - .description("Users can sign up online.") - .type(PropertyType.BOOLEAN) - .category(CoreProperties.CATEGORY_SECURITY) - .build(), - - PropertyDefinition.builder(CoreProperties.CORE_DEFAULT_GROUP) - .defaultValue(CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE) - .name("Default user group") - .description("Any new users will automatically join this group.") - .category(CoreProperties.CATEGORY_SECURITY) - .build(), - - PropertyDefinition.builder(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY) - .defaultValue("" + CoreProperties.CORE_IMPORT_SOURCES_DEFAULT_VALUE) - .name("Import sources") - .description("Set to false if sources should not be imported and therefore not available in the Web UI (e.g. for security reasons).") - .type(PropertyType.BOOLEAN) - .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) - .category(CoreProperties.CATEGORY_SECURITY) - .build(), - - PropertyDefinition.builder(CoreProperties.CORE_FORCE_AUTHENTICATION_PROPERTY) - .defaultValue("" + CoreProperties.CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE) - .name("Force user authentication") - .description("Forcing user authentication stops un-logged users to access SonarQube.") - .type(PropertyType.BOOLEAN) - .category(CoreProperties.CATEGORY_SECURITY) - .build(), - - PropertyDefinition.builder(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION) - .defaultValue(Boolean.toString(false)) - .name("Prevent automatic project creation") - .description("Set to true to prevent automatic project creation at first analysis and force project provisioning.") - .type(PropertyType.BOOLEAN) - .category(CoreProperties.CATEGORY_SECURITY) - .build() - ); - } - } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilter.java index e2bcea80dce..eeda60396a9 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilter.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilter.java @@ -23,34 +23,26 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.ImmutableSet; -import org.sonar.api.CoreProperties; -import org.sonar.api.PropertyType; -import org.sonar.api.config.PropertyDefinition; import org.sonar.api.config.Settings; import org.sonar.api.measures.Measure; import org.sonar.api.measures.Metric; -import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Resource; import org.sonar.api.utils.WildcardPattern; import org.sonar.core.measure.MeasurementFilter; import java.util.Collection; import java.util.Iterator; -import java.util.List; public class CoverageMeasurementFilter implements MeasurementFilter { - public static final String PROPERTY_COVERAGE_EXCLUSIONS = "sonar.coverage.exclusions"; - public static final String PROPERTY_COVERAGE_INCLUSIONS = "sonar.coverage.inclusions"; - private final Settings settings; private final ImmutableSet<Metric> coverageMetrics; private Collection<WildcardPattern> resourcePatterns; public CoverageMeasurementFilter(Settings settings, - CoverageDecorator coverageDecorator, - LineCoverageDecorator lineCoverageDecorator, - BranchCoverageDecorator branchCoverageDecorator) { + CoverageDecorator coverageDecorator, + LineCoverageDecorator lineCoverageDecorator, + BranchCoverageDecorator branchCoverageDecorator) { this.settings = settings; this.coverageMetrics = ImmutableSet.<Metric>builder() .addAll(coverageDecorator.generatedMetrics()) @@ -88,22 +80,10 @@ public class CoverageMeasurementFilter implements MeasurementFilter { @VisibleForTesting final void initPatterns() { - Builder<WildcardPattern> builder = ImmutableList.<WildcardPattern>builder(); - for (String pattern : settings.getStringArray(PROPERTY_COVERAGE_EXCLUSIONS)) { + Builder<WildcardPattern> builder = ImmutableList.builder(); + for (String pattern : settings.getStringArray("sonar.coverage.exclusions")) { builder.add(WildcardPattern.create(pattern)); } resourcePatterns = builder.build(); } - - public static List<PropertyDefinition> getPropertyDefinitions() { - return ImmutableList.of( - PropertyDefinition.builder(PROPERTY_COVERAGE_EXCLUSIONS) - .category(CoreProperties.CATEGORY_EXCLUSIONS) - .subCategory(CoreProperties.SUBCATEGORY_COVERAGE_EXCLUSIONS) - .type(PropertyType.STRING) - .multiValues(true) - .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) - .build() - ); - } } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/ExclusionPropertiesTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/ExclusionPropertiesTest.java deleted file mode 100644 index 42aed67cb00..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/ExclusionPropertiesTest.java +++ /dev/null @@ -1,36 +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.plugins.core; - -import org.junit.Test; -import org.sonar.api.CoreProperties; -import org.sonar.api.config.PropertyDefinition; - -import static org.fest.assertions.Assertions.assertThat; - -public class ExclusionPropertiesTest { - @Test - public void definitions() throws Exception { - assertThat(ExclusionProperties.definitions().size()).isGreaterThan(0); - for (PropertyDefinition definition : ExclusionProperties.definitions()) { - assertThat(definition.category()).isEqualTo(CoreProperties.CATEGORY_EXCLUSIONS); - } - } -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilterTest.java index 8254fb28094..072dea5844e 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilterTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilterTest.java @@ -27,6 +27,7 @@ import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.resources.File; import org.sonar.api.resources.Resource; +import org.sonar.core.config.ExclusionProperties; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -40,7 +41,7 @@ public class CoverageMeasurementFilterTest { @Before public void createFilter() { - settings = new Settings(new PropertyDefinitions(CoverageMeasurementFilter.getPropertyDefinitions())); + settings = new Settings(new PropertyDefinitions(ExclusionProperties.all())); filter = new CoverageMeasurementFilter(settings, new CoverageDecorator(), new LineCoverageDecorator(), new BranchCoverageDecorator()); } @@ -57,7 +58,7 @@ public class CoverageMeasurementFilterTest { Measure coverageMeasure = mock(Measure.class); when(coverageMeasure.getMetric()).thenReturn(CoreMetrics.LINES_TO_COVER); - settings.setProperty(CoverageMeasurementFilter.PROPERTY_COVERAGE_EXCLUSIONS, "src/org/polop/*"); + settings.setProperty("sonar.coverage.exclusions", "src/org/polop/*"); filter.initPatterns(); assertThat(filter.accept(resource, coverageMeasure)).isFalse(); } @@ -68,7 +69,7 @@ public class CoverageMeasurementFilterTest { Measure coverageMeasure = mock(Measure.class); when(coverageMeasure.getMetric()).thenReturn(CoreMetrics.COVERAGE); - settings.setProperty(CoverageMeasurementFilter.PROPERTY_COVERAGE_EXCLUSIONS, "src/org/other/*"); + settings.setProperty("sonar.coverage.exclusions", "src/org/other/*"); filter.initPatterns(); assertThat(filter.accept(resource, coverageMeasure)).isTrue(); } diff --git a/plugins/sonar-l10n-en-plugin/pom.xml b/plugins/sonar-l10n-en-plugin/pom.xml deleted file mode 100644 index 66bdabc0e8e..00000000000 --- a/plugins/sonar-l10n-en-plugin/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar</artifactId> - <version>4.4-SNAPSHOT</version> - <relativePath>../..</relativePath> - </parent> - - <groupId>org.codehaus.sonar.plugins</groupId> - <artifactId>sonar-l10n-en-plugin</artifactId> - <packaging>sonar-plugin</packaging> - <name>SonarQube :: Plugins :: English Pack</name> - - <dependencies> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.easytesting</groupId> - <artifactId>fest-assert</artifactId> - <scope>test</scope> - </dependency> - - </dependencies> - - <build> - <plugins> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>native2ascii-maven-plugin</artifactId> - <version>1.0-beta-1</version> - <executions> - <execution> - <goals> - <goal>native2ascii</goal> - </goals> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <configuration> - <pluginName>English Pack</pluginName> - <pluginClass>org.sonar.plugins.l10n.EnglishPackPlugin</pluginClass> - <pluginDescription><![CDATA[Language pack for English]]></pluginDescription> - </configuration> - </plugin> - </plugins> - </build> -</project> diff --git a/plugins/sonar-l10n-en-plugin/src/main/java/org/sonar/plugins/l10n/EnglishPackPlugin.java b/plugins/sonar-l10n-en-plugin/src/main/java/org/sonar/plugins/l10n/EnglishPackPlugin.java deleted file mode 100644 index 1a774bda931..00000000000 --- a/plugins/sonar-l10n-en-plugin/src/main/java/org/sonar/plugins/l10n/EnglishPackPlugin.java +++ /dev/null @@ -1,32 +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.plugins.l10n; - -import org.sonar.api.SonarPlugin; - -import java.util.Collections; -import java.util.List; - -public final class EnglishPackPlugin extends SonarPlugin { - - public List getExtensions() { - return Collections.emptyList(); - } -} diff --git a/plugins/sonar-maven-batch-plugin/pom.xml b/plugins/sonar-maven-batch-plugin/pom.xml deleted file mode 100644 index d82188f54a8..00000000000 --- a/plugins/sonar-maven-batch-plugin/pom.xml +++ /dev/null @@ -1,76 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar</artifactId> - <version>4.4-SNAPSHOT</version> - <relativePath>../..</relativePath> - </parent> - - <groupId>org.codehaus.sonar.plugins</groupId> - <artifactId>sonar-maven-batch-plugin</artifactId> - <packaging>sonar-plugin</packaging> - <name>SonarQube :: Maven Batch Plugin</name> - - <properties> - <maven.version>3.0</maven.version> - </properties> - - <dependencies> - <dependency> - <groupId>com.google.code.findbugs</groupId> - <artifactId>jsr305</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-batch</artifactId> - <version>${project.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-plugin-api</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.apache.maven</groupId> - <artifactId>maven-plugin-api</artifactId> - <version>${maven.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.apache.maven</groupId> - <artifactId>maven-core</artifactId> - <version>${maven.version}</version> - <scope>provided</scope> - </dependency> - - <!-- unit tests --> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-testing-harness</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-all</artifactId> - <scope>test</scope> - </dependency> - </dependencies> - - <build> - <plugins> - - <plugin> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-packaging-maven-plugin</artifactId> - <configuration> - <pluginName>Maven Batch Plugin</pluginName> - <pluginClass>org.sonar.plugins.maven.MavenBatchPlugin</pluginClass> - </configuration> - </plugin> - </plugins> - </build> -</project> diff --git a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenBatchPlugin.java b/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenBatchPlugin.java deleted file mode 100644 index 64375e5f696..00000000000 --- a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenBatchPlugin.java +++ /dev/null @@ -1,32 +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.plugins.maven; - -import com.google.common.collect.ImmutableList; -import org.sonar.api.SonarPlugin; - -import java.util.List; - -public final class MavenBatchPlugin extends SonarPlugin { - - public List getExtensions() { - return ImmutableList.of(MavenProjectBootstrapper.class, DefaultMavenPluginExecutor.class, MavenProjectConverter.class, MavenProjectBuilder.class); - } -} @@ -34,9 +34,7 @@ <module>plugins/sonar-dbcleaner-plugin</module> <module>plugins/sonar-cpd-plugin</module> <module>plugins/sonar-design-plugin</module> - <module>plugins/sonar-l10n-en-plugin</module> <module>plugins/sonar-email-notifications-plugin</module> - <module>plugins/sonar-maven-batch-plugin</module> <module>plugins/sonar-xoo-plugin</module> </modules> diff --git a/sonar-application/assembly.xml b/sonar-application/assembly.xml index d99cf5fedb4..8010c915144 100644 --- a/sonar-application/assembly.xml +++ b/sonar-application/assembly.xml @@ -13,13 +13,20 @@ <excludes> <exclude>org.codehaus.sonar:sonar-server</exclude> <exclude>mysql:mysql-connector-java</exclude> - <exclude>com.h2database:h2</exclude> <exclude>postgresql:postgresql</exclude> <exclude>net.sourceforge.jtds:jtds</exclude> <exclude>org.codehaus.sonar.plugins:*</exclude> <exclude>org.codehaus.sonar-plugins.*:*</exclude> + <exclude>org.codehaus.sonar:sonar-batch-maven-compat</exclude> </excludes> </dependencySet> + <dependencySet> + <outputDirectory>lib/batch</outputDirectory> + <useTransitiveDependencies>false</useTransitiveDependencies> + <includes> + <include>org.codehaus.sonar:sonar-batch-maven-compat</include> + </includes> + </dependencySet> <!-- Plugins --> <dependencySet> <outputDirectory>lib/core-plugins</outputDirectory> @@ -53,14 +60,6 @@ <scope>runtime</scope> </dependencySet> <dependencySet> - <outputDirectory>extensions/jdbc-driver/h2/</outputDirectory> - <includes> - <include>com.h2database:h2</include> - </includes> - <unpack>false</unpack> - <scope>runtime</scope> - </dependencySet> - <dependencySet> <outputDirectory>extensions/jdbc-driver/postgresql/</outputDirectory> <includes> <include>postgresql:postgresql</include> diff --git a/sonar-application/pom.xml b/sonar-application/pom.xml index 3bceb25828e..83058a4ead5 100644 --- a/sonar-application/pom.xml +++ b/sonar-application/pom.xml @@ -17,15 +17,27 @@ <dependencies> <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + <dependency> <groupId>com.google.code.findbugs</groupId> <artifactId>jsr305</artifactId> <scope>provided</scope> </dependency> <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> @@ -46,6 +58,12 @@ <artifactId>logback-core</artifactId> </dependency> <dependency> + <groupId>${pom.groupId}</groupId> + <artifactId>sonar-batch-maven-compat</artifactId> + <version>${pom.version}</version> + <scope>runtime</scope> + </dependency> + <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> </dependency> @@ -75,11 +93,6 @@ <scope>runtime</scope> </dependency> <dependency> - <groupId>com.h2database</groupId> - <artifactId>h2</artifactId> - <scope>runtime</scope> - </dependency> - <dependency> <groupId>net.sourceforge.jtds</groupId> <artifactId>jtds</artifactId> <scope>runtime</scope> @@ -134,13 +147,6 @@ </dependency> <dependency> <groupId>org.codehaus.sonar.plugins</groupId> - <artifactId>sonar-l10n-en-plugin</artifactId> - <version>${project.version}</version> - <type>sonar-plugin</type> - <scope>runtime</scope> - </dependency> - <dependency> - <groupId>org.codehaus.sonar.plugins</groupId> <artifactId>sonar-email-notifications-plugin</artifactId> <version>${project.version}</version> <type>sonar-plugin</type> @@ -159,13 +165,6 @@ <scope>runtime</scope> </dependency> <dependency> - <groupId>org.codehaus.sonar.plugins</groupId> - <artifactId>sonar-maven-batch-plugin</artifactId> - <version>${project.version}</version> - <type>sonar-plugin</type> - <scope>runtime</scope> - </dependency> - <dependency> <groupId>org.sonatype.jsw-binaries</groupId> <artifactId>jsw-binaries</artifactId> <version>3.2.3.6</version> @@ -201,12 +200,6 @@ <artifactId>http-request</artifactId> <scope>test</scope> </dependency> - <dependency> - <groupId>com.google.guava</groupId> - <artifactId>guava</artifactId> - <scope>test</scope> - </dependency> - </dependencies> <build> @@ -259,8 +252,8 @@ <configuration> <rules> <requireFilesSize> - <minsize>55000000</minsize> - <maxsize>75000000</maxsize> + <minsize>80000000</minsize> + <maxsize>88000000</maxsize> <files> <file>${project.build.directory}/sonarqube-${project.version}.zip</file> </files> diff --git a/sonar-application/src/main/assembly/conf/sonar.properties b/sonar-application/src/main/assembly/conf/sonar.properties index 6c058aa3227..65954622bb9 100644 --- a/sonar-application/src/main/assembly/conf/sonar.properties +++ b/sonar-application/src/main/assembly/conf/sonar.properties @@ -82,7 +82,7 @@ sonar.jdbc.timeBetweenEvictionRunsMillis=30000 # Web context. When set, it must start with forward slash (for example /sonarqube). # The default value is root context (empty value). -#sonar.web.context= +#sonar.web.context=/ # TCP port for incoming HTTP connections. Disabled when value is -1. #sonar.web.port=9000 diff --git a/sonar-application/src/main/assembly/conf/wrapper.conf b/sonar-application/src/main/assembly/conf/wrapper.conf index 9353b41cd83..d53aa251978 100644 --- a/sonar-application/src/main/assembly/conf/wrapper.conf +++ b/sonar-application/src/main/assembly/conf/wrapper.conf @@ -33,11 +33,10 @@ wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp # needed starting from 1 wrapper.java.classpath.1=../../lib/*.jar wrapper.java.classpath.2=../../conf -wrapper.java.classpath.3=../../extensions/jdbc-driver/h2/*.jar -wrapper.java.classpath.4=../../extensions/jdbc-driver/mysql/*.jar -wrapper.java.classpath.5=../../extensions/jdbc-driver/oracle/*.jar -wrapper.java.classpath.6=../../extensions/jdbc-driver/postgresql/*.jar -wrapper.java.classpath.7=../../extensions/jdbc-driver/mssql/*.jar +wrapper.java.classpath.3=../../extensions/jdbc-driver/mysql/*.jar +wrapper.java.classpath.4=../../extensions/jdbc-driver/oracle/*.jar +wrapper.java.classpath.5=../../extensions/jdbc-driver/postgresql/*.jar +wrapper.java.classpath.6=../../extensions/jdbc-driver/mssql/*.jar # Java Library Path (location of Wrapper.DLL or libwrapper.so) wrapper.java.library.path.1=./lib diff --git a/sonar-application/src/main/java/org/sonar/application/AesCipher.java b/sonar-application/src/main/java/org/sonar/application/AesCipher.java new file mode 100644 index 00000000000..e778b0ebc18 --- /dev/null +++ b/sonar-application/src/main/java/org/sonar/application/AesCipher.java @@ -0,0 +1,138 @@ +/* + * 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.application; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Throwables; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; + +import javax.annotation.Nullable; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import java.io.File; +import java.io.IOException; +import java.security.Key; +import java.security.SecureRandom; + +final class AesCipher extends Cipher { + + // Can't be increased because of Java 6 policy files : + // https://confluence.terena.org/display/~visser/No+256+bit+ciphers+for+Java+apps + // http://java.sun.com/javase/6/webnotes/install/jre/README + public static final int KEY_SIZE_IN_BITS = 128; + + private static final String CRYPTO_KEY = "AES"; + + /** + * Duplication from CoreProperties.ENCRYPTION_SECRET_KEY_PATH + */ + static final String ENCRYPTION_SECRET_KEY_PATH = "sonar.secretKeyPath"; + + private String pathToSecretKey; + + AesCipher(@Nullable String pathToSecretKey) { + this.pathToSecretKey = pathToSecretKey; + } + + @Override + String encrypt(String clearText) { + try { + javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CRYPTO_KEY); + cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, loadSecretFile()); + return new String(Base64.encodeBase64(cipher.doFinal(clearText.getBytes("UTF-8")))); + } catch (Exception e) { + throw Throwables.propagate(e); + } + } + + @Override + String decrypt(String encryptedText) { + try { + javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CRYPTO_KEY); + cipher.init(javax.crypto.Cipher.DECRYPT_MODE, loadSecretFile()); + byte[] cipherData = cipher.doFinal(Base64.decodeBase64(StringUtils.trim(encryptedText))); + return new String(cipherData); + } catch (Exception e) { + throw Throwables.propagate(e); + } + } + + /** + * This method checks the existence of the file, but not the validity of the contained key. + */ + boolean hasSecretKey() { + String path = getPathToSecretKey(); + if (StringUtils.isNotBlank(path)) { + File file = new File(path); + return file.exists() && file.isFile(); + } + return false; + } + + private Key loadSecretFile() throws IOException { + String path = getPathToSecretKey(); + return loadSecretFileFromFile(path); + } + + @VisibleForTesting + Key loadSecretFileFromFile(@Nullable String path) throws IOException { + if (StringUtils.isBlank(path)) { + throw new IllegalStateException("Secret key not found. Please set the property " + ENCRYPTION_SECRET_KEY_PATH); + } + File file = new File(path); + if (!file.exists() || !file.isFile()) { + throw new IllegalStateException("The property " + ENCRYPTION_SECRET_KEY_PATH + " does not link to a valid file: " + path); + } + String s = FileUtils.readFileToString(file); + if (StringUtils.isBlank(s)) { + throw new IllegalStateException("No secret key in the file: " + path); + } + return new SecretKeySpec(Base64.decodeBase64(StringUtils.trim(s)), CRYPTO_KEY); + } + + String generateRandomSecretKey() { + try { + KeyGenerator keyGen = KeyGenerator.getInstance(CRYPTO_KEY); + keyGen.init(KEY_SIZE_IN_BITS, new SecureRandom()); + SecretKey secretKey = keyGen.generateKey(); + return new String(Base64.encodeBase64(secretKey.getEncoded())); + + } catch (Exception e) { + throw new IllegalStateException("Fail to generate secret key", e); + } + } + + @VisibleForTesting + String getPathToSecretKey() { + if (StringUtils.isBlank(pathToSecretKey)) { + pathToSecretKey = new File(FileUtils.getUserDirectoryPath(), ".sonar/sonar-secret.txt").getPath(); + } + return pathToSecretKey; + } + + public void setPathToSecretKey(@Nullable String pathToSecretKey) { + this.pathToSecretKey = pathToSecretKey; + } +} diff --git a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/MavenBatchPluginTest.java b/sonar-application/src/main/java/org/sonar/application/Base64Cipher.java index 0504cb99f3f..5abbeb85ac2 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/MavenBatchPluginTest.java +++ b/sonar-application/src/main/java/org/sonar/application/Base64Cipher.java @@ -17,18 +17,19 @@ * 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.plugins.maven; -import org.junit.Test; +package org.sonar.application; -import static org.fest.assertions.Assertions.assertThat; +import org.apache.commons.codec.binary.Base64; -public class MavenBatchPluginTest { - - @Test - public void testGetExtensions() { - MavenBatchPlugin plugin = new MavenBatchPlugin(); - assertThat(plugin.getExtensions()).hasSize(4); +final class Base64Cipher extends Cipher { + @Override + String encrypt(String clearText) { + return new String(Base64.encodeBase64(clearText.getBytes())); } + @Override + String decrypt(String encryptedText) { + return new String(Base64.decodeBase64(encryptedText)); + } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/technicaldebt/package-info.java b/sonar-application/src/main/java/org/sonar/application/Cipher.java index defa4e01d36..44abfbb3176 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/technicaldebt/package-info.java +++ b/sonar-application/src/main/java/org/sonar/application/Cipher.java @@ -17,7 +17,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -@ParametersAreNonnullByDefault -package org.sonar.plugins.core.technicaldebt; -import javax.annotation.ParametersAreNonnullByDefault; +package org.sonar.application; + +abstract class Cipher { + abstract String encrypt(String clearText); + abstract String decrypt(String encryptedText); +} diff --git a/sonar-core/src/main/java/org/sonar/core/config/ConfigurationUtils.java b/sonar-application/src/main/java/org/sonar/application/ConfigurationUtils.java index d3875f78846..a5a563a168c 100644 --- a/sonar-core/src/main/java/org/sonar/core/config/ConfigurationUtils.java +++ b/sonar-application/src/main/java/org/sonar/application/ConfigurationUtils.java @@ -17,60 +17,25 @@ * 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.core.config; +package org.sonar.application; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang.text.StrSubstitutor; -import javax.annotation.WillClose; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; import java.util.Enumeration; import java.util.Map; import java.util.Properties; -/** - * @since 2.12 - */ public final class ConfigurationUtils { private ConfigurationUtils() { + // Utility class } - public static void copyProperties(Properties from, Map<String, String> to) { - for (Map.Entry<Object, Object> entry : from.entrySet()) { - String key = (String) entry.getKey(); - to.put(key, entry.getValue().toString()); - } - } - - public static Properties openProperties(File file) throws IOException { - FileInputStream input = FileUtils.openInputStream(file); - return readInputStream(input); - } - - /** - * Note that the input stream is closed in this method. - */ - public static Properties readInputStream(@WillClose InputStream input) throws IOException { - try { - Properties p = new Properties(); - p.load(input); - return p; - - } finally { - IOUtils.closeQuietly(input); - } - } - - public static Properties interpolateEnvVariables(Properties properties) { + static Properties interpolateEnvVariables(Properties properties) { return interpolateVariables(properties, System.getenv()); } - public static Properties interpolateVariables(Properties properties, Map<String, String> variables) { + static Properties interpolateVariables(Properties properties, Map<String, String> variables) { Properties result = new Properties(); Enumeration keys = properties.keys(); while (keys.hasMoreElements()) { diff --git a/sonar-application/src/main/java/org/sonar/application/EmbeddedTomcat.java b/sonar-application/src/main/java/org/sonar/application/EmbeddedTomcat.java index ddb1efad898..a677f8bcf11 100644 --- a/sonar-application/src/main/java/org/sonar/application/EmbeddedTomcat.java +++ b/sonar-application/src/main/java/org/sonar/application/EmbeddedTomcat.java @@ -65,6 +65,7 @@ class EmbeddedTomcat { tomcat.getHost().setDeployOnStartup(true); Props props = Props.create(env); + Logging.configure(tomcat, env, props); Connectors.configure(tomcat, props); Webapp.configure(tomcat, env, props); diff --git a/sonar-application/src/main/java/org/sonar/application/Encryption.java b/sonar-application/src/main/java/org/sonar/application/Encryption.java new file mode 100644 index 00000000000..60e732fc716 --- /dev/null +++ b/sonar-application/src/main/java/org/sonar/application/Encryption.java @@ -0,0 +1,66 @@ +/* + * 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.application; + +import com.google.common.collect.ImmutableMap; + +import javax.annotation.Nullable; + +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @since 3.0 + */ +public final class Encryption { + + private static final String BASE64_ALGORITHM = "b64"; + + private static final String AES_ALGORITHM = "aes"; + private final AesCipher aesCipher; + + private final Map<String, Cipher> ciphers; + private static final Pattern ENCRYPTED_PATTERN = Pattern.compile("\\{(.*?)\\}(.*)"); + + public Encryption(@Nullable String pathToSecretKey) { + aesCipher = new AesCipher(pathToSecretKey); + ciphers = ImmutableMap.of( + BASE64_ALGORITHM, new Base64Cipher(), + AES_ALGORITHM, aesCipher); + } + public boolean isEncrypted(String value) { + return value.indexOf('{') == 0 && value.indexOf('}') > 1; + } + + public String decrypt(String encryptedText) { + Matcher matcher = ENCRYPTED_PATTERN.matcher(encryptedText); + if (matcher.matches()) { + Cipher cipher = ciphers.get(matcher.group(1).toLowerCase(Locale.ENGLISH)); + if (cipher != null) { + return cipher.decrypt(matcher.group(2)); + } + } + return encryptedText; + } + +} diff --git a/sonar-application/src/main/java/org/sonar/application/Props.java b/sonar-application/src/main/java/org/sonar/application/Props.java index 7b33d918cc6..dbe24636d0e 100644 --- a/sonar-application/src/main/java/org/sonar/application/Props.java +++ b/sonar-application/src/main/java/org/sonar/application/Props.java @@ -22,16 +22,14 @@ package org.sonar.application; import org.apache.commons.io.IOUtils; import javax.annotation.Nullable; + import java.io.File; -import java.io.FileNotFoundException; import java.io.FileReader; -import java.io.IOException; +import java.util.Map; import java.util.Properties; -/** - * TODO support env substitution and encryption - */ class Props { + private final Properties props; Props(Properties props) { @@ -80,8 +78,18 @@ class Props { FileReader reader = null; try { reader = new FileReader(propsFile); + + // order is important : the last override the first p.load(reader); + p.putAll(System.getenv()); p.putAll(System.getProperties()); + + p = ConfigurationUtils.interpolateEnvVariables(p); + p = decrypt(p); + + // Set all properties as system properties to pass them to PlatformServletContextListener + System.setProperties(p); + return new Props(p); } catch (Exception e) { @@ -91,4 +99,19 @@ class Props { IOUtils.closeQuietly(reader); } } + + static Properties decrypt(Properties properties) { + Encryption encryption = new Encryption(properties.getProperty(AesCipher.ENCRYPTION_SECRET_KEY_PATH)); + Properties result = new Properties(); + + for (Map.Entry<Object, Object> entry : properties.entrySet()) { + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + if (encryption.isEncrypted(value)) { + value = encryption.decrypt(value); + } + result.setProperty(key, value); + } + return result; + } } diff --git a/sonar-application/src/test/java/org/sonar/application/AesCipherTest.java b/sonar-application/src/test/java/org/sonar/application/AesCipherTest.java new file mode 100644 index 00000000000..9f097093105 --- /dev/null +++ b/sonar-application/src/test/java/org/sonar/application/AesCipherTest.java @@ -0,0 +1,186 @@ +/* + * 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.application; + +import com.google.common.io.Resources; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import javax.crypto.BadPaddingException; + +import java.io.File; +import java.security.InvalidKeyException; +import java.security.Key; + +import static org.fest.assertions.Assertions.assertThat; +import static org.fest.assertions.Fail.fail; + + +public class AesCipherTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void generateRandomSecretKey() { + AesCipher cipher = new AesCipher(null); + + String key = cipher.generateRandomSecretKey(); + + assertThat(StringUtils.isNotBlank(key)).isTrue(); + assertThat(Base64.isArrayByteBase64(key.getBytes())).isTrue(); + } + + @Test + public void encrypt() throws Exception { + AesCipher cipher = new AesCipher(pathToSecretKey()); + + String encryptedText = cipher.encrypt("this is a secret"); + + assertThat(StringUtils.isNotBlank(encryptedText)).isTrue(); + assertThat(Base64.isArrayByteBase64(encryptedText.getBytes())).isTrue(); + } + + @Test + public void encrypt_bad_key() throws Exception { + thrown.expect(RuntimeException.class); + thrown.expectMessage("Invalid AES key"); + + AesCipher cipher = new AesCipher(getPath("bad_secret_key.txt")); + + cipher.encrypt("this is a secret"); + } + + @Test + public void decrypt() throws Exception { + AesCipher cipher = new AesCipher(pathToSecretKey()); + + // the following value has been encrypted with the key /org/sonar/api/config/AesCipherTest/aes_secret_key.txt + String clearText = cipher.decrypt("9mx5Zq4JVyjeChTcVjEide4kWCwusFl7P2dSVXtg9IY="); + + assertThat(clearText).isEqualTo("this is a secret"); + } + + @Test + public void decrypt_bad_key() throws Exception { + AesCipher cipher = new AesCipher(getPath("bad_secret_key.txt")); + + try { + cipher.decrypt("9mx5Zq4JVyjeChTcVjEide4kWCwusFl7P2dSVXtg9IY="); + fail(); + + } catch (RuntimeException e) { + assertThat(e.getCause()).isInstanceOf(InvalidKeyException.class); + } + } + + @Test + public void decrypt_other_key() throws Exception { + AesCipher cipher = new AesCipher(getPath("other_secret_key.txt")); + + try { + // text encrypted with another key + cipher.decrypt("9mx5Zq4JVyjeChTcVjEide4kWCwusFl7P2dSVXtg9IY="); + fail(); + + } catch (RuntimeException e) { + assertThat(e.getCause()).isInstanceOf(BadPaddingException.class); + } + } + + @Test + public void encryptThenDecrypt() throws Exception { + AesCipher cipher = new AesCipher(pathToSecretKey()); + + assertThat(cipher.decrypt(cipher.encrypt("foo"))).isEqualTo("foo"); + } + + @Test + public void testDefaultPathToSecretKey() { + AesCipher cipher = new AesCipher(null); + + String path = cipher.getPathToSecretKey(); + + assertThat(StringUtils.isNotBlank(path)).isTrue(); + assertThat(new File(path).getName()).isEqualTo("sonar-secret.txt"); + } + + @Test + public void loadSecretKeyFromFile() throws Exception { + AesCipher cipher = new AesCipher(null); + Key secretKey = cipher.loadSecretFileFromFile(pathToSecretKey()); + assertThat(secretKey.getAlgorithm()).isEqualTo("AES"); + assertThat(secretKey.getEncoded().length).isGreaterThan(10); + } + + @Test + public void loadSecretKeyFromFile_trim_content() throws Exception { + String path = getPath("non_trimmed_secret_key.txt"); + AesCipher cipher = new AesCipher(null); + + Key secretKey = cipher.loadSecretFileFromFile(path); + + assertThat(secretKey.getAlgorithm()).isEqualTo("AES"); + assertThat(secretKey.getEncoded().length).isGreaterThan(10); + } + + @Test + public void loadSecretKeyFromFile_file_does_not_exist() throws Exception { + thrown.expect(IllegalStateException.class); + + AesCipher cipher = new AesCipher(null); + cipher.loadSecretFileFromFile("/file/does/not/exist"); + } + + @Test + public void loadSecretKeyFromFile_no_property() throws Exception { + thrown.expect(IllegalStateException.class); + + AesCipher cipher = new AesCipher(null); + cipher.loadSecretFileFromFile(null); + } + + @Test + public void hasSecretKey() throws Exception { + AesCipher cipher = new AesCipher(pathToSecretKey()); + + assertThat(cipher.hasSecretKey()).isTrue(); + } + + @Test + public void doesNotHaveSecretKey() throws Exception { + AesCipher cipher = new AesCipher("/my/twitter/id/is/SimonBrandhof"); + + assertThat(cipher.hasSecretKey()).isFalse(); + } + + private static String getPath(String file){ + return Resources.getResource(AesCipherTest.class, "AesCipherTest/" + file).getPath(); + } + + private static String pathToSecretKey() throws Exception { + return getPath("aes_secret_key.txt"); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/core/config/ConfigurationUtilsTest.java b/sonar-application/src/test/java/org/sonar/application/ConfigurationUtilsTest.java index 92452b2338e..29a722b9fad 100644 --- a/sonar-core/src/test/java/org/sonar/core/config/ConfigurationUtilsTest.java +++ b/sonar-application/src/test/java/org/sonar/application/ConfigurationUtilsTest.java @@ -17,7 +17,7 @@ * 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.core.config; +package org.sonar.application; import com.google.common.collect.Maps; import org.junit.Test; @@ -52,22 +52,4 @@ public class ConfigurationUtilsTest { assertThat(input.getProperty("do_not_change"), is("${SONAR_JDBC_URL}")); } - @Test - public void shouldCopyProperties() { - Properties input = new Properties(); - input.setProperty("hello", "world"); - input.setProperty("foo", "bar"); - Map<String, String> output = Maps.newHashMap(); - - ConfigurationUtils.copyProperties(input, output); - - assertThat(output.size(), is(2)); - assertThat(output.get("hello"), is("world")); - assertThat(output.get("foo"), is("bar")); - - // input is not changed - assertThat(input.size(), is(2)); - assertThat(input.getProperty("hello"), is("world")); - assertThat(input.getProperty("foo"), is("bar")); - } } diff --git a/sonar-application/src/test/java/org/sonar/application/EncryptionTest.java b/sonar-application/src/test/java/org/sonar/application/EncryptionTest.java new file mode 100644 index 00000000000..85b3c568a35 --- /dev/null +++ b/sonar-application/src/test/java/org/sonar/application/EncryptionTest.java @@ -0,0 +1,59 @@ +/* + * 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.application; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class EncryptionTest { + + @Test + public void isEncrypted() { + Encryption encryption = new Encryption(null); + assertThat(encryption.isEncrypted("{aes}ADASDASAD"), is(true)); + assertThat(encryption.isEncrypted("{b64}ADASDASAD"), is(true)); + assertThat(encryption.isEncrypted("{abc}ADASDASAD"), is(true)); + + assertThat(encryption.isEncrypted("{}"), is(false)); + assertThat(encryption.isEncrypted("{foo"), is(false)); + assertThat(encryption.isEncrypted("foo{aes}"), is(false)); + } + + @Test + public void decrypt() { + Encryption encryption = new Encryption(null); + assertThat(encryption.decrypt("{b64}Zm9v"), is("foo")); + } + + @Test + public void decrypt_unknown_algorithm() { + Encryption encryption = new Encryption(null); + assertThat(encryption.decrypt("{xxx}Zm9v"), is("{xxx}Zm9v")); + } + + @Test + public void decrypt_uncrypted_text() { + Encryption encryption = new Encryption(null); + assertThat(encryption.decrypt("foo"), is("foo")); + } +} diff --git a/sonar-application/src/test/java/org/sonar/application/PropsTest.java b/sonar-application/src/test/java/org/sonar/application/PropsTest.java index 92091740301..46ca5e8dd26 100644 --- a/sonar-application/src/test/java/org/sonar/application/PropsTest.java +++ b/sonar-application/src/test/java/org/sonar/application/PropsTest.java @@ -19,6 +19,7 @@ */ package org.sonar.application; +import com.google.common.io.Resources; import org.apache.commons.io.FilenameUtils; import org.junit.Test; @@ -31,6 +32,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class PropsTest { + @Test public void of() throws Exception { Properties p = new Properties(); @@ -99,8 +101,10 @@ public class PropsTest { @Test public void load_file_and_system_properties() throws Exception { + System.setProperty("hello", "bar"); + Env env = mock(Env.class); - File propsFile = new File(getClass().getResource("/org/sonar/application/PropsTest/sonar.properties").toURI()); + File propsFile = new File(Resources.getResource(getClass(), "PropsTest/sonar.properties").getFile()); when(env.file("conf/sonar.properties")).thenReturn(propsFile); Props props = Props.create(env); @@ -109,7 +113,11 @@ public class PropsTest { assertThat(props.of("java.version")).isNotNull(); // system properties override file properties + assertThat(props.of("hello")).isEqualTo("bar"); assertThat(props.of("java.io.tmpdir")).isNotEmpty().isNotEqualTo("/should/be/overridden"); + + assertThat(System.getProperty("foo")).isEqualTo("bar"); + assertThat(System.getProperty("hello")).isEqualTo("bar"); } @Test diff --git a/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/aes_secret_key.txt b/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/aes_secret_key.txt new file mode 100644 index 00000000000..65b98c522da --- /dev/null +++ b/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/aes_secret_key.txt @@ -0,0 +1 @@ +0PZz+G+f8mjr3sPn4+AhHg==
\ No newline at end of file diff --git a/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/bad_secret_key.txt b/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/bad_secret_key.txt new file mode 100644 index 00000000000..b33e179e5c8 --- /dev/null +++ b/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/bad_secret_key.txt @@ -0,0 +1 @@ +badbadbad==
\ No newline at end of file diff --git a/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/non_trimmed_secret_key.txt b/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/non_trimmed_secret_key.txt new file mode 100644 index 00000000000..ab83e4adc03 --- /dev/null +++ b/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/non_trimmed_secret_key.txt @@ -0,0 +1,3 @@ + + 0PZz+G+f8mjr3sPn4+AhHg== + diff --git a/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/other_secret_key.txt b/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/other_secret_key.txt new file mode 100644 index 00000000000..23f5ecf5104 --- /dev/null +++ b/sonar-application/src/test/resources/org/sonar/application/AesCipherTest/other_secret_key.txt @@ -0,0 +1 @@ +IBxEUxZ41c8XTxyaah1Qlg==
\ No newline at end of file diff --git a/sonar-application/src/test/resources/org/sonar/application/PropsTest/sonar.properties b/sonar-application/src/test/resources/org/sonar/application/PropsTest/sonar.properties index b73be15411b..5c06e58a32e 100644 --- a/sonar-application/src/test/resources/org/sonar/application/PropsTest/sonar.properties +++ b/sonar-application/src/test/resources/org/sonar/application/PropsTest/sonar.properties @@ -1,2 +1,3 @@ +hello: world foo=bar java.io.tmpdir=/should/be/overridden diff --git a/sonar-batch-maven-compat/pom.xml b/sonar-batch-maven-compat/pom.xml index 4951028aa44..a19f029a522 100644 --- a/sonar-batch-maven-compat/pom.xml +++ b/sonar-batch-maven-compat/pom.xml @@ -14,10 +14,14 @@ <dependencies> <dependency> + <groupId>${pom.groupId}</groupId> + <artifactId>sonar-batch</artifactId> + <version>${pom.version}</version> + </dependency> + <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-project</artifactId> <version>2.0.7</version> - <scope>compile</scope> <exclusions> <exclusion> <groupId>org.codehaus.plexus</groupId> @@ -43,20 +47,4 @@ </plugin> </plugins> </build> - - <profiles> - <profile> - <id>release</id> - <build> - <plugins> - <plugin> - <artifactId>maven-deploy-plugin</artifactId> - <configuration> - <skip>true</skip> - </configuration> - </plugin> - </plugins> - </build> - </profile> - </profiles> </project> diff --git a/sonar-batch/pom.xml b/sonar-batch/pom.xml index 3965e7ced3f..e0c8a4389d0 100644 --- a/sonar-batch/pom.xml +++ b/sonar-batch/pom.xml @@ -7,7 +7,6 @@ <version>4.4-SNAPSHOT</version> </parent> - <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-batch</artifactId> <name>SonarQube :: Batch</name> @@ -40,6 +39,16 @@ <dependency> <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-plugin-api</artifactId> + <exclusions> + <exclusion> + <groupId>jfree</groupId> + <artifactId>jcommon</artifactId> + </exclusion> + <exclusion> + <groupId>jfree</groupId> + <artifactId>jfreechat</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.codehaus.sonar</groupId> @@ -52,11 +61,13 @@ <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> + <version>3.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-core</artifactId> + <version>3.0</version> <scope>provided</scope> </dependency> <dependency> 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 new file mode 100644 index 00000000000..02c98554fa6 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java @@ -0,0 +1,47 @@ +/* + * 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.bootstrap; + +import com.google.common.collect.Lists; +import org.sonar.batch.debt.DebtDecorator; +import org.sonar.batch.debt.IssueChangelogDebtCalculator; +import org.sonar.batch.debt.NewDebtDecorator; +import org.sonar.batch.maven.DefaultMavenPluginExecutor; +import org.sonar.batch.maven.MavenProjectBootstrapper; +import org.sonar.batch.maven.MavenProjectBuilder; +import org.sonar.batch.maven.MavenProjectConverter; +import org.sonar.core.config.CorePropertyDefinitions; + +import java.util.Collection; +import java.util.List; + +public class BatchComponents { + public static Collection all() { + List components = Lists.newArrayList( + // Maven + MavenProjectBootstrapper.class, DefaultMavenPluginExecutor.class, MavenProjectConverter.class, MavenProjectBuilder.class, + + // Debt + IssueChangelogDebtCalculator.class, DebtDecorator.class, NewDebtDecorator.class + ); + components.addAll(CorePropertyDefinitions.all()); + return components; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java index 584ecce1cad..2e2b09da23c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java @@ -36,11 +36,7 @@ import org.sonar.core.plugins.RemotePlugin; import java.io.File; import java.text.MessageFormat; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Sets.newHashSet; @@ -49,7 +45,6 @@ public class BatchPluginRepository implements PluginRepository { private static final Logger LOG = LoggerFactory.getLogger(BatchPluginRepository.class); private static final String CORE_PLUGIN = "core"; - private static final String ENGLISH_PACK_PLUGIN = "l10nen"; private PluginDownloader pluginDownloader; private Map<String, Plugin> pluginsByKey; @@ -164,7 +159,7 @@ public class BatchPluginRepository implements PluginRepository { } boolean accepts(String pluginKey) { - if (CORE_PLUGIN.equals(pluginKey) || ENGLISH_PACK_PLUGIN.equals(pluginKey)) { + if (CORE_PLUGIN.equals(pluginKey)) { return true; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java index 039cc1c210c..bb2b2e431f2 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java @@ -44,6 +44,13 @@ public class ExtensionInstaller { public ExtensionInstaller install(ComponentContainer container, ExtensionMatcher matcher) { boolean preview = analysisMode.isPreview(); + + // core components + for (Object o : BatchComponents.all()) { + doInstall(container, matcher, null, preview, o); + } + + // plugin extensions for (Map.Entry<PluginMetadata, Plugin> entry : pluginRepository.getPluginsByMetadata().entrySet()) { PluginMetadata metadata = entry.getKey(); Plugin plugin = entry.getValue(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java index 614841858ca..437fd62ff55 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java @@ -20,11 +20,14 @@ package org.sonar.batch.bootstrap; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.utils.SonarException; import org.sonar.home.cache.FileCache; +import javax.annotation.CheckForNull; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -58,22 +61,23 @@ public class JdbcDriverHolder { try { LOG.info("Install JDBC driver"); String[] nameAndHash = downloadJdbcDriverIndex(); - String filename = nameAndHash[0]; - String hash = nameAndHash[1]; - - File jdbcDriver = fileCache.get(filename, hash, new FileCache.Downloader() { - public void download(String filename, File toFile) throws IOException { - String url = "/deploy/" + filename; - if (LOG.isDebugEnabled()) { - LOG.debug("Download {} to {}", url, toFile.getAbsolutePath()); - } else { - LOG.info("Download {}", filename); + if (nameAndHash != null) { + String filename = nameAndHash[0]; + String hash = nameAndHash[1]; + + File jdbcDriver = fileCache.get(filename, hash, new FileCache.Downloader() { + public void download(String filename, File toFile) throws IOException { + String url = "/deploy/" + filename; + if (LOG.isDebugEnabled()) { + LOG.debug("Download {} to {}", url, toFile.getAbsolutePath()); + } else { + LOG.info("Download {}", filename); + } + serverClient.download(url, toFile); } - serverClient.download(url, toFile); - } - }); - - classLoader = initClassloader(jdbcDriver); + }); + classLoader = initClassloader(jdbcDriver); + } } catch (SonarException e) { throw e; } catch (Exception e) { @@ -134,11 +138,16 @@ public class JdbcDriverHolder { } } + @CheckForNull private String[] downloadJdbcDriverIndex() { String url = "/deploy/jdbc-driver.txt"; try { LOG.debug("Download index of jdbc-driver"); String indexContent = serverClient.request(url); + // File is empty when H2 is used + if (Strings.isNullOrEmpty(indexContent)) { + return null; + } return indexContent.split("\\|"); } catch (Exception e) { throw new SonarException("Fail to download jdbc-driver index: " + url, e); diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerMetadata.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerMetadata.java index cf664e315df..01d2b5915c1 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerMetadata.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerMetadata.java @@ -27,6 +27,7 @@ import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; +import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -70,6 +71,21 @@ public class ServerMetadata extends Server implements BatchComponent { } @Override + public File getRootDir() { + return null; + } + + @Override + public File getDeployDir() { + return null; + } + + @Override + public String getContextPath() { + return null; + } + + @Override public String getURL() { return client.getURL(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java index c5992b6475a..d823a0650cf 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java @@ -24,6 +24,7 @@ import org.sonar.api.config.Settings; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.task.Task; +import org.sonar.api.task.TaskComponent; import org.sonar.api.task.TaskDefinition; import org.sonar.api.task.TaskExtension; import org.sonar.api.utils.SonarException; @@ -55,7 +56,7 @@ public class TaskContainer extends ComponentContainer { private void installTaskExtensions() { getComponentByType(ExtensionInstaller.class).install(this, new ExtensionMatcher() { public boolean accept(Object extension) { - return ExtensionUtils.isType(extension, TaskExtension.class); + return ExtensionUtils.isType(extension, TaskComponent.class); } }); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinder.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinder.java index 88de3031103..541a63a6bd7 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinder.java @@ -20,24 +20,19 @@ package org.sonar.batch.components; import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; import org.apache.commons.configuration.Configuration; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchExtension; import org.sonar.api.CoreProperties; -import org.sonar.api.config.PropertyDefinition; import org.sonar.api.config.Settings; import org.sonar.api.database.model.Snapshot; -import org.sonar.api.resources.Qualifiers; import javax.annotation.Nullable; - import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; public class PastSnapshotFinder implements BatchExtension { @@ -196,60 +191,4 @@ public class PastSnapshotFinder implements BatchExtension { } } - public static List<PropertyDefinition> getPropertyDefinitions() { - return ImmutableList.of( - PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 1) - .name("Period 1") - .description("Period used to compare measures and track new violations. Values are : <ul class='bullet'><li>Number of days before " + - "analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, for example 2010-12-25</li><li>'previous_analysis' to " + - "compare to previous analysis</li><li>'previous_version' to compare to the previous version in the project history</li></ul>" + - "<p>When specifying a number of days or a date, the snapshot selected for comparison is " + - " the first one available inside the corresponding time range. </p>" + - "<p>Changing this property only takes effect after subsequent project inspections.<p/>") - .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_1) - .category(CoreProperties.CATEGORY_GENERAL) - .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) - .build(), - - PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 2) - .name("Period 2") - .description("See the property 'Period 1'") - .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2) - .category(CoreProperties.CATEGORY_GENERAL) - .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) - .build(), - - PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 3) - .name("Period 3") - .description("See the property 'Period 1'") - .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_3) - .category(CoreProperties.CATEGORY_GENERAL) - .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) - .build(), - - PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 4) - .name("Period 4") - .description("Period used to compare measures and track new violations. This property is specific to the project. Values are : " + - "<ul class='bullet'><li>Number of days before analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, " + - "for example 2010-12-25</li><li>'previous_analysis' to compare to previous analysis</li>" + - "<li>'previous_version' to compare to the previous version in the project history</li><li>A version, for example 1.2</li></ul>" + - "<p>When specifying a number of days or a date, the snapshot selected for comparison is the first one available inside the corresponding time range. </p>" + - "<p>Changing this property only takes effect after subsequent project inspections.<p/>") - .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_4) - .onlyOnQualifiers(Qualifiers.PROJECT) - .category(CoreProperties.CATEGORY_GENERAL) - .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) - .build(), - - PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 5) - .name("Period 5") - .description("See the property 'Period 4'") - .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5) - .onlyOnQualifiers(Qualifiers.PROJECT) - .category(CoreProperties.CATEGORY_GENERAL) - .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) - .build() - ); - } - } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/technicaldebt/DebtDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/debt/DebtDecorator.java index 2caf164d9c2..71e9cc36a1c 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/technicaldebt/DebtDecorator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/debt/DebtDecorator.java @@ -18,21 +18,26 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.plugins.core.technicaldebt; +package org.sonar.batch.debt; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import org.sonar.api.CoreProperties; -import org.sonar.api.PropertyType; -import org.sonar.api.batch.*; +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorBarriers; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.DependsUpon; import org.sonar.api.batch.rule.Rule; import org.sonar.api.batch.rule.Rules; import org.sonar.api.component.ResourcePerspectives; -import org.sonar.api.config.PropertyDefinition; import org.sonar.api.issue.Issuable; import org.sonar.api.issue.Issue; import org.sonar.api.issue.internal.DefaultIssue; -import org.sonar.api.measures.*; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasuresFilters; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.PersistenceMode; +import org.sonar.api.measures.RuleMeasure; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.resources.ResourceUtils; @@ -43,7 +48,6 @@ import org.sonar.api.technicaldebt.batch.TechnicalDebtModel; import javax.annotation.CheckForNull; import javax.annotation.Nullable; - import java.util.Arrays; import java.util.List; import java.util.Map; @@ -185,18 +189,6 @@ public final class DebtDecorator implements Decorator { return context.getMeasure(CoreMetrics.TECHNICAL_DEBT) == null; } - public static List<PropertyDefinition> definitions() { - return ImmutableList.of( - PropertyDefinition.builder(CoreProperties.HOURS_IN_DAY) - .name("Number of working hours in a day") - .type(PropertyType.INTEGER) - .defaultValue("8") - .category(CoreProperties.CATEGORY_TECHNICAL_DEBT) - .deprecatedKey("sqale.hoursInDay") - .build() - ); - } - private static class SumMap<E> { private Map<E, Long> sumByKeys; diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/technicaldebt/NewDebtDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/debt/NewDebtDecorator.java index f5f7062a584..fe738d63de8 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/technicaldebt/NewDebtDecorator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/debt/NewDebtDecorator.java @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.plugins.core.technicaldebt; +package org.sonar.batch.debt; import com.google.common.collect.ImmutableList; import org.sonar.api.batch.*; diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/AbstractPatternInitializer.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/AbstractPatternInitializer.java index 03d218b3a3b..e29fc5aaa30 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/AbstractPatternInitializer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/AbstractPatternInitializer.java @@ -19,8 +19,6 @@ */ package org.sonar.batch.issue.ignore.pattern; -import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; - import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; @@ -67,8 +65,8 @@ public abstract class AbstractPatternInitializer implements BatchExtension { String patternConf = StringUtils.defaultIfBlank(settings.getString(getMulticriteriaConfigurationKey()), ""); for (String id : StringUtils.split(patternConf, ',')) { String propPrefix = getMulticriteriaConfigurationKey() + "." + id + "."; - String resourceKeyPattern = settings.getString(propPrefix + IssueExclusionsConfiguration.RESOURCE_KEY); - String ruleKeyPattern = settings.getString(propPrefix + IssueExclusionsConfiguration.RULE_KEY); + String resourceKeyPattern = settings.getString(propPrefix + "resourceKey"); + String ruleKeyPattern = settings.getString(propPrefix + "ruleKey"); String lineRange = "*"; String[] fields = new String[] { resourceKeyPattern, ruleKeyPattern, lineRange }; PatternDecoder.checkRegularLineConstraints(StringUtils.join(fields, ","), fields); diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializer.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializer.java index 79b176b4721..75882be5422 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializer.java @@ -20,12 +20,11 @@ package org.sonar.batch.issue.ignore.pattern; -import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; - import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import org.sonar.api.config.Settings; +import org.sonar.core.config.IssueExclusionProperties; import java.util.List; @@ -45,7 +44,7 @@ public class IssueExclusionPatternInitializer extends AbstractPatternInitializer @Override protected String getMulticriteriaConfigurationKey() { - return IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY; + return "sonar.issue.ignore" + ".multicriteria"; } public PatternMatcher getPatternMatcher() { @@ -54,7 +53,7 @@ public class IssueExclusionPatternInitializer extends AbstractPatternInitializer @Override public void initializePatternsForPath(String relativePath, String componentKey) { - for (IssuePattern pattern: getMulticriteriaPatterns()) { + for (IssuePattern pattern : getMulticriteriaPatterns()) { if (pattern.matchResource(relativePath)) { getPatternMatcher().addPatternForComponent(componentKey, pattern); } @@ -70,12 +69,12 @@ public class IssueExclusionPatternInitializer extends AbstractPatternInitializer protected final void loadFileContentPatterns() { // Patterns Block blockPatterns = Lists.newArrayList(); - String patternConf = StringUtils.defaultIfBlank(getSettings().getString(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY), ""); + String patternConf = StringUtils.defaultIfBlank(getSettings().getString(IssueExclusionProperties.PATTERNS_BLOCK_KEY), ""); for (String id : StringUtils.split(patternConf, ',')) { - String propPrefix = IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + "." + id + "."; - String beginBlockRegexp = getSettings().getString(propPrefix + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP); - String endBlockRegexp = getSettings().getString(propPrefix + IssueExclusionsConfiguration.END_BLOCK_REGEXP); - String[] fields = new String[] { beginBlockRegexp, endBlockRegexp }; + String propPrefix = IssueExclusionProperties.PATTERNS_BLOCK_KEY + "." + id + "."; + String beginBlockRegexp = getSettings().getString(propPrefix + IssueExclusionProperties.BEGIN_BLOCK_REGEXP); + String endBlockRegexp = getSettings().getString(propPrefix + IssueExclusionProperties.END_BLOCK_REGEXP); + String[] fields = new String[]{beginBlockRegexp, endBlockRegexp}; PatternDecoder.checkDoubleRegexpLineConstraints(StringUtils.join(fields, ","), fields); IssuePattern pattern = new IssuePattern().setBeginBlockRegexp(nullToEmpty(beginBlockRegexp)).setEndBlockRegexp(nullToEmpty(endBlockRegexp)); blockPatterns.add(pattern); @@ -83,10 +82,10 @@ public class IssueExclusionPatternInitializer extends AbstractPatternInitializer // Patterns All File allFilePatterns = Lists.newArrayList(); - patternConf = StringUtils.defaultIfBlank(getSettings().getString(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY), ""); + patternConf = StringUtils.defaultIfBlank(getSettings().getString(IssueExclusionProperties.PATTERNS_ALLFILE_KEY), ""); for (String id : StringUtils.split(patternConf, ',')) { - String propPrefix = IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + "." + id + "."; - String allFileRegexp = getSettings().getString(propPrefix + IssueExclusionsConfiguration.FILE_REGEXP); + String propPrefix = IssueExclusionProperties.PATTERNS_ALLFILE_KEY + "." + id + "."; + String allFileRegexp = getSettings().getString(propPrefix + IssueExclusionProperties.FILE_REGEXP); PatternDecoder.checkWholeFileRegexp(allFileRegexp); IssuePattern pattern = new IssuePattern().setAllFileRegexp(nullToEmpty(allFileRegexp)); allFilePatterns.add(pattern); @@ -102,6 +101,6 @@ public class IssueExclusionPatternInitializer extends AbstractPatternInitializer } public boolean hasFileContentPattern() { - return ! (blockPatterns.isEmpty() && allFilePatterns.isEmpty()); + return !(blockPatterns.isEmpty() && allFilePatterns.isEmpty()); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializer.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializer.java index 5ce390af0be..bf87ad85313 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializer.java @@ -20,8 +20,6 @@ package org.sonar.batch.issue.ignore.pattern; -import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; - import com.google.common.collect.Maps; import org.sonar.api.config.Settings; @@ -38,7 +36,7 @@ public class IssueInclusionPatternInitializer extends AbstractPatternInitializer @Override protected String getMulticriteriaConfigurationKey() { - return IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY; + return "sonar.issue.enforce" + ".multicriteria"; } @Override diff --git a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/DefaultMavenPluginExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/maven/DefaultMavenPluginExecutor.java index fc5eef968b4..fb0a1a56a20 100644 --- a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/DefaultMavenPluginExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/maven/DefaultMavenPluginExecutor.java @@ -17,7 +17,7 @@ * 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.plugins.maven; +package org.sonar.batch.maven; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ReactorManager; @@ -33,7 +33,6 @@ import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import org.sonar.batch.scan.maven.MavenPluginExecutor; import javax.annotation.Nullable; - import java.lang.reflect.Method; import java.util.Arrays; diff --git a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenProjectBootstrapper.java b/sonar-batch/src/main/java/org/sonar/batch/maven/MavenProjectBootstrapper.java index 1bb3ea37d21..3cd1f9d5c7f 100644 --- a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenProjectBootstrapper.java +++ b/sonar-batch/src/main/java/org/sonar/batch/maven/MavenProjectBootstrapper.java @@ -17,7 +17,7 @@ * 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.plugins.maven; +package org.sonar.batch.maven; import org.apache.maven.execution.MavenSession; import org.apache.maven.project.MavenProject; diff --git a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenProjectBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/maven/MavenProjectBuilder.java index 3d9ebb12c2f..7cbf3efc5f2 100644 --- a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenProjectBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/maven/MavenProjectBuilder.java @@ -17,7 +17,7 @@ * 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.plugins.maven; +package org.sonar.batch.maven; import org.apache.maven.execution.MavenSession; import org.apache.maven.project.MavenProject; diff --git a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenProjectConverter.java b/sonar-batch/src/main/java/org/sonar/batch/maven/MavenProjectConverter.java index 3162b095361..2ef3fe6fa54 100644 --- a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenProjectConverter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/maven/MavenProjectConverter.java @@ -17,7 +17,7 @@ * 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.plugins.maven; +package org.sonar.batch.maven; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; @@ -40,7 +40,6 @@ import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import org.sonar.java.api.JavaUtils; import javax.annotation.Nullable; - import java.io.File; import java.io.IOException; import java.util.Arrays; diff --git a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/maven/package-info.java index 4e7cfd86137..b595cf0548f 100644 --- a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/package-info.java +++ b/sonar-batch/src/main/java/org/sonar/batch/maven/package-info.java @@ -22,7 +22,7 @@ * This package is a part of bootstrap process, so we should take care about backward compatibility. */ @ParametersAreNonnullByDefault -package org.sonar.plugins.maven; +package org.sonar.batch.maven; import javax.annotation.ParametersAreNonnullByDefault; 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 835aa9be91f..5180a498752 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 @@ -19,6 +19,7 @@ */ package org.sonar.batch.scan; +import org.sonar.api.BatchComponent; import org.sonar.batch.qualitygate.GenerateQualityGateEvents; import org.slf4j.Logger; @@ -158,7 +159,7 @@ public class ModuleScanContainer extends ComponentContainer { ExtensionInstaller installer = getComponentByType(ExtensionInstaller.class); installer.install(this, new ExtensionMatcher() { public boolean accept(Object extension) { - if (ExtensionUtils.isType(extension, BatchExtension.class) && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_PROJECT)) { + if (ExtensionUtils.isType(extension, BatchComponent.class) && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_PROJECT)) { // Special use-case: the extension point ProjectBuilder is used in a Maven environment to define some // new sub-projects without pom. // Example : C# plugin adds sub-projects at runtime, even if they are not defined in root pom. 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 dee73ecd6c7..e4eacf6aa8d 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 @@ -20,6 +20,7 @@ package org.sonar.batch.scan; import com.google.common.annotations.VisibleForTesting; +import org.sonar.api.BatchComponent; import org.sonar.api.BatchExtension; import org.sonar.api.CoreProperties; import org.sonar.api.batch.InstantiationStrategy; @@ -201,7 +202,7 @@ public class ProjectScanContainer extends ComponentContainer { static class BatchExtensionFilter implements ExtensionMatcher { public boolean accept(Object extension) { - return ExtensionUtils.isType(extension, BatchExtension.class) + return ExtensionUtils.isType(extension, BatchComponent.class) && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_BATCH); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java index b1a4eb2a999..0592c2158d4 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java @@ -158,15 +158,6 @@ public class BatchPluginRepositoryTest { assertThat(filter.accepts("core")).isTrue(); } - // English Pack plugin should never be blacklisted as it is mandatory for the I18nManager on batch side - @Test - public void englishPackPluginShouldNeverBeInBlackList() { - Settings settings = new Settings() - .setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "l10nen,findbugs"); - BatchPluginRepository.PluginFilter filter = new BatchPluginRepository.PluginFilter(settings, mode); - assertThat(filter.accepts("l10nen")).isTrue(); - } - @Test public void check_white_list_with_black_list() { Settings settings = new Settings() diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java index aece0a8f370..3d3dcad38db 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java @@ -19,6 +19,7 @@ */ package org.sonar.batch.bootstrap; +import com.google.common.io.Resources; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -32,9 +33,7 @@ import java.io.File; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class JdbcDriverHolderTest { @@ -59,10 +58,10 @@ public class JdbcDriverHolderTest { } @Test - public void should_extend_classloader_with_jdbc_driver() throws Exception { + public void extend_classloader_with_jdbc_driver() throws Exception { FileCache cache = mock(FileCache.class); - File fakeDriver = new File(getClass().getResource("/org/sonar/batch/bootstrap/JdbcDriverHolderTest/jdbc-driver.jar").toURI()); + File fakeDriver = new File(Resources.getResource(JdbcDriverHolderTest.class, "JdbcDriverHolderTest/jdbc-driver.jar").getFile()); when(cache.get(eq("ojdbc14.jar"), eq("fakemd5"), any(FileCache.Downloader.class))).thenReturn(fakeDriver); /* jdbc-driver.jar has just one file /foo/foo.txt */ @@ -85,7 +84,22 @@ public class JdbcDriverHolderTest { } @Test - public void should_be_disabled_if_preview() { + public void do_nothing_when_jdbc_driver_file_is_empty() throws Exception { + FileCache cache = mock(FileCache.class); + + ServerClient server = mock(ServerClient.class); + when(server.request("/deploy/jdbc-driver.txt")).thenReturn(""); + + JdbcDriverHolder holder = new JdbcDriverHolder(cache, mode, server); + holder.start(); + + verify(server, never()).download(anyString(), any(File.class)); + verifyZeroInteractions(cache); + assertThat(holder.getClassLoader()).isNull(); + } + + @Test + public void be_disabled_if_preview() { FileCache cache = mock(FileCache.class); when(mode.isPreview()).thenReturn(true); ServerClient server = mock(ServerClient.class); diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/technicaldebt/DebtDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/DebtDecoratorTest.java index 2aac5804446..fc82ece746c 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/technicaldebt/DebtDecoratorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/debt/DebtDecoratorTest.java @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.plugins.core.technicaldebt; +package org.sonar.batch.debt; import com.google.common.collect.Lists; import org.apache.commons.lang.ObjectUtils; @@ -38,7 +38,11 @@ import org.sonar.api.component.ResourcePerspectives; import org.sonar.api.issue.Issuable; import org.sonar.api.issue.Issue; import org.sonar.api.issue.internal.DefaultIssue; -import org.sonar.api.measures.*; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasuresFilter; +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; @@ -55,7 +59,12 @@ import java.util.Collections; import static com.google.common.collect.Lists.newArrayList; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class DebtDecoratorTest { @@ -275,15 +284,10 @@ public class DebtDecoratorTest { DecoratorContext context = mock(DecoratorContext.class); when(context.getResource()).thenReturn(new File("foo")); - decorator.saveCharacteristicMeasure(context, (Characteristic) null, 0.0, true); + decorator.saveCharacteristicMeasure(context, null, 0.0, true); verify(context, never()).saveMeasure(new Measure(CoreMetrics.TECHNICAL_DEBT)); } - @Test - public void check_definitions() { - assertThat(DebtDecorator.definitions()).hasSize(1); - } - private DefaultIssue createIssue(String ruleKey, String repositoryKey) { return new DefaultIssue().setRuleKey(RuleKey.of(repositoryKey, ruleKey)); } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/technicaldebt/NewDebtDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/NewDebtDecoratorTest.java index a9391f96da2..a80a19feac1 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/technicaldebt/NewDebtDecoratorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/debt/NewDebtDecoratorTest.java @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.plugins.core.technicaldebt; +package org.sonar.batch.debt; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.time.DateUtils; @@ -45,6 +45,7 @@ import org.sonar.api.utils.Duration; import org.sonar.batch.components.Period; import org.sonar.batch.components.TimeMachineConfiguration; import org.sonar.batch.debt.IssueChangelogDebtCalculator; +import org.sonar.batch.debt.NewDebtDecorator; import java.util.Date; diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IssueExclusionsConfigurationTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IssueExclusionsConfigurationTest.java deleted file mode 100644 index 79849ba1358..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IssueExclusionsConfigurationTest.java +++ /dev/null @@ -1,33 +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.issue.ignore; - -import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; - -import org.junit.Test; -import static org.fest.assertions.Assertions.assertThat; - -public class IssueExclusionsConfigurationTest { - @Test - public void justForCoverage() { - assertThat(IssueExclusionsConfiguration.getPropertyDefinitions()).hasSize(4); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java index f478c284184..a0707867019 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java @@ -20,14 +20,14 @@ package org.sonar.batch.issue.ignore.pattern; -import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; -import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer; import org.junit.Before; import org.junit.Test; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; import org.sonar.api.utils.SonarException; +import org.sonar.core.config.IssueExclusionProperties; + import static org.fest.assertions.Assertions.assertThat; public class IssueExclusionPatternInitializerTest { @@ -38,7 +38,7 @@ public class IssueExclusionPatternInitializerTest { @Before public void init() { - settings = new Settings(new PropertyDefinitions(IssueExclusionsConfiguration.getPropertyDefinitions())); + settings = new Settings(new PropertyDefinitions(IssueExclusionProperties.all())); patternsInitializer = new IssueExclusionPatternInitializer(settings); } @@ -51,11 +51,11 @@ public class IssueExclusionPatternInitializerTest { @Test public void shouldHavePatternsBasedOnMulticriteriaPattern() { - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1,2"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Bar.java"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "*"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Hello.java"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RULE_KEY, "checkstyle:MagicNumber"); + settings.setProperty("sonar.issue.ignore" + ".multicriteria", "1,2"); + settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "resourceKey", "org/foo/Bar.java"); + settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "ruleKey", "*"); + settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".2." + "resourceKey", "org/foo/Hello.java"); + settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".2." + "ruleKey", "checkstyle:MagicNumber"); patternsInitializer.initPatterns(); assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue(); @@ -77,29 +77,29 @@ public class IssueExclusionPatternInitializerTest { @Test(expected = SonarException.class) public void shouldLogInvalidResourceKey() { - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, ""); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "*"); + settings.setProperty("sonar.issue.ignore" + ".multicriteria", "1"); + settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "resourceKey", ""); + settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "ruleKey", "*"); patternsInitializer.initPatterns(); } @Test(expected = SonarException.class) public void shouldLogInvalidRuleKey() { - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "*"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, ""); + settings.setProperty("sonar.issue.ignore" + ".multicriteria", "1"); + settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "resourceKey", "*"); + settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "ruleKey", ""); patternsInitializer.initPatterns(); } @Test public void shouldReturnBlockPattern() { - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY, "1,2,3"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "// SONAR-OFF"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "// SONAR-ON"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".2." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "// FOO-OFF"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".2." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "// FOO-ON"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "// IGNORE-TO-EOF"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, ""); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY, "1,2,3"); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionProperties.BEGIN_BLOCK_REGEXP, "// SONAR-OFF"); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionProperties.END_BLOCK_REGEXP, "// SONAR-ON"); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".2." + IssueExclusionProperties.BEGIN_BLOCK_REGEXP, "// FOO-OFF"); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".2." + IssueExclusionProperties.END_BLOCK_REGEXP, "// FOO-ON"); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionProperties.BEGIN_BLOCK_REGEXP, "// IGNORE-TO-EOF"); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionProperties.END_BLOCK_REGEXP, ""); patternsInitializer.loadFileContentPatterns(); assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue(); @@ -112,17 +112,17 @@ public class IssueExclusionPatternInitializerTest { @Test(expected = SonarException.class) public void shouldLogInvalidStartBlockPattern() { - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY, "1"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, ""); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "// SONAR-ON"); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY, "1"); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionProperties.BEGIN_BLOCK_REGEXP, ""); + settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionProperties.END_BLOCK_REGEXP, "// SONAR-ON"); patternsInitializer.loadFileContentPatterns(); } @Test public void shouldReturnAllFilePattern() { - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY, "1,2"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionsConfiguration.FILE_REGEXP, "@SONAR-IGNORE-ALL"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + ".2." + IssueExclusionsConfiguration.FILE_REGEXP, "//FOO-IGNORE-ALL"); + settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY, "1,2"); + settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionProperties.FILE_REGEXP, "@SONAR-IGNORE-ALL"); + settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY + ".2." + IssueExclusionProperties.FILE_REGEXP, "//FOO-IGNORE-ALL"); patternsInitializer.loadFileContentPatterns(); assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue(); @@ -135,8 +135,8 @@ public class IssueExclusionPatternInitializerTest { @Test(expected = SonarException.class) public void shouldLogInvalidAllFilePattern() { - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY, "1"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionsConfiguration.FILE_REGEXP, ""); + settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY, "1"); + settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionProperties.FILE_REGEXP, ""); patternsInitializer.loadFileContentPatterns(); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java index ed93e89c8e7..eae28d70c05 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java @@ -20,13 +20,12 @@ package org.sonar.batch.issue.ignore.pattern; -import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; -import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer; - import org.junit.Before; import org.junit.Test; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; +import org.sonar.core.config.IssueExclusionProperties; + import static org.fest.assertions.Assertions.assertThat; public class IssueInclusionPatternInitializerTest { @@ -37,7 +36,7 @@ public class IssueInclusionPatternInitializerTest { @Before public void init() { - settings = new Settings(new PropertyDefinitions(IssueExclusionsConfiguration.getPropertyDefinitions())); + settings = new Settings(new PropertyDefinitions(IssueExclusionProperties.all())); patternsInitializer = new IssueInclusionPatternInitializer(settings); } @@ -49,11 +48,11 @@ public class IssueInclusionPatternInitializerTest { @Test public void shouldHavePatternsBasedOnMulticriteriaPattern() { - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY, "1,2"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Bar.java"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "*"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Hello.java"); - settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RULE_KEY, "checkstyle:MagicNumber"); + settings.setProperty("sonar.issue.enforce" + ".multicriteria", "1,2"); + settings.setProperty("sonar.issue.enforce" + ".multicriteria" + ".1." + "resourceKey", "org/foo/Bar.java"); + settings.setProperty("sonar.issue.enforce" + ".multicriteria" + ".1." + "ruleKey", "*"); + settings.setProperty("sonar.issue.enforce" + ".multicriteria" + ".2." + "resourceKey", "org/foo/Hello.java"); + settings.setProperty("sonar.issue.enforce" + ".multicriteria" + ".2." + "ruleKey", "checkstyle:MagicNumber"); patternsInitializer.initPatterns(); assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue(); diff --git a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/DefaultMavenPluginExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/maven/DefaultMavenPluginExecutorTest.java index fcaa0bf34b5..75897a2abb3 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/DefaultMavenPluginExecutorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/maven/DefaultMavenPluginExecutorTest.java @@ -17,7 +17,7 @@ * 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.plugins.maven; +package org.sonar.batch.maven; import org.apache.maven.project.MavenProject; import org.junit.Test; diff --git a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/MavenProjectBootstrapperTest.java b/sonar-batch/src/test/java/org/sonar/batch/maven/MavenProjectBootstrapperTest.java index 9c7cb4ecde8..f4f7ea66051 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/MavenProjectBootstrapperTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/maven/MavenProjectBootstrapperTest.java @@ -17,7 +17,7 @@ * 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.plugins.maven; +package org.sonar.batch.maven; import org.apache.maven.execution.MavenSession; import org.apache.maven.project.MavenProject; diff --git a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/MavenProjectConverterTest.java b/sonar-batch/src/test/java/org/sonar/batch/maven/MavenProjectConverterTest.java index 6cc799f029c..be1fd2cfe3e 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/MavenProjectConverterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/maven/MavenProjectConverterTest.java @@ -17,7 +17,7 @@ * 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.plugins.maven; +package org.sonar.batch.maven; import org.apache.commons.io.FileUtils; import org.apache.maven.model.Model; @@ -119,10 +119,10 @@ public class MavenProjectConverterTest { @Test public void moduleNameShouldEqualArtifactId() throws Exception { - File rootDir = TestUtils.getResource("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/"); - MavenProject parent = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/pom.xml", true); - MavenProject module1 = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module1/pom.xml", false); - MavenProject module2 = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module2/pom.xml", false); + File rootDir = TestUtils.getResource("/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/"); + MavenProject parent = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/pom.xml", true); + MavenProject module1 = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module1/pom.xml", false); + MavenProject module2 = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module2/pom.xml", false); ProjectDefinition rootDef = converter.configure(Arrays.asList(parent, module1, module2), parent); @@ -140,10 +140,10 @@ public class MavenProjectConverterTest { @Test public void moduleNameDifferentThanArtifactId() throws Exception { - File rootDir = TestUtils.getResource("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/"); - MavenProject parent = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/pom.xml", true); - MavenProject module1 = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path1/pom.xml", false); - MavenProject module2 = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path2/pom.xml", false); + File rootDir = TestUtils.getResource("/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/"); + MavenProject parent = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/pom.xml", true); + MavenProject module1 = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path1/pom.xml", false); + MavenProject module2 = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path2/pom.xml", false); ProjectDefinition rootDef = converter.configure(Arrays.asList(parent, module1, module2), parent); @@ -161,9 +161,9 @@ public class MavenProjectConverterTest { @Test public void should_find_module_with_maven_project_file_naming_different_from_pom_xml() throws Exception { - File rootDir = TestUtils.getResource("/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/"); - MavenProject parent = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/pom.xml", true); - MavenProject module = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom_having_different_name.xml", false); + File rootDir = TestUtils.getResource("/org/sonar/batch/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/"); + MavenProject parent = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/pom.xml", true); + MavenProject module = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom_having_different_name.xml", false); ProjectDefinition rootDef = converter.configure(Arrays.asList(parent, module), parent); @@ -181,8 +181,8 @@ public class MavenProjectConverterTest { @Test public void testSingleProjectWithoutModules() throws Exception { - File rootDir = TestUtils.getResource("/org/sonar/plugins/maven/MavenProjectConverterTest/singleProjectWithoutModules/"); - MavenProject pom = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/singleProjectWithoutModules/pom.xml", true); + File rootDir = TestUtils.getResource("/org/sonar/batch/maven/MavenProjectConverterTest/singleProjectWithoutModules/"); + MavenProject pom = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/singleProjectWithoutModules/pom.xml", true); ProjectDefinition rootDef = converter.configure(Arrays.asList(pom), pom); @@ -194,7 +194,7 @@ public class MavenProjectConverterTest { @Test public void shouldConvertLinksToProperties() throws Exception { - MavenProject pom = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/projectWithLinks/pom.xml", true); + MavenProject pom = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/projectWithLinks/pom.xml", true); ProjectDefinition rootDef = converter.configure(Arrays.asList(pom), pom); @@ -208,7 +208,7 @@ public class MavenProjectConverterTest { @Test public void shouldNotConvertLinksToPropertiesIfPropertyAlreadyDefined() throws Exception { - MavenProject pom = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml", true); + MavenProject pom = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml", true); ProjectDefinition rootDef = converter.configure(Arrays.asList(pom), pom); @@ -226,7 +226,7 @@ public class MavenProjectConverterTest { @Test public void shouldLoadSourceEncoding() throws Exception { - MavenProject pom = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/sourceEncoding/pom.xml", true); + MavenProject pom = loadPom("/org/sonar/batch/maven/MavenProjectConverterTest/sourceEncoding/pom.xml", true); ProjectDefinition rootDef = converter.configure(Arrays.asList(pom), pom); diff --git a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/SonarMavenProjectBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/maven/SonarMavenProjectBuilderTest.java index a39798c1c85..16cbd06bc1e 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/java/org/sonar/plugins/maven/SonarMavenProjectBuilderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/maven/SonarMavenProjectBuilderTest.java @@ -17,7 +17,7 @@ * 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.plugins.maven; +package org.sonar.batch.maven; import org.apache.maven.execution.MavenSession; import org.apache.maven.project.MavenProject; diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom.xml index 7b49562c2e0..7b49562c2e0 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom_having_different_name.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom_having_different_name.xml index 7b49562c2e0..7b49562c2e0 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom_having_different_name.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom_having_different_name.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/pom.xml index 9d2244eb148..9d2244eb148 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path1/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path1/pom.xml index 470f2d1f6e5..470f2d1f6e5 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path1/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path1/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path2/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path2/pom.xml index 88101678e0f..88101678e0f 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path2/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path2/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/pom.xml index afd92c0dbee..afd92c0dbee 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module1/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module1/pom.xml index 470f2d1f6e5..470f2d1f6e5 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module1/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module1/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module2/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module2/pom.xml index 88101678e0f..88101678e0f 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module2/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module2/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/pom.xml index cc73a43ec08..cc73a43ec08 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/projectWithLinks/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/projectWithLinks/pom.xml index 460e8967e5c..460e8967e5c 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/projectWithLinks/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/projectWithLinks/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml index 5b024e5c4a7..5b024e5c4a7 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/singleProjectWithoutModules/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/singleProjectWithoutModules/pom.xml index ffd40530c5d..ffd40530c5d 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/singleProjectWithoutModules/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/singleProjectWithoutModules/pom.xml diff --git a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/sourceEncoding/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/sourceEncoding/pom.xml index 01bf73cfa9e..01bf73cfa9e 100644 --- a/plugins/sonar-maven-batch-plugin/src/test/resources/org/sonar/plugins/maven/MavenProjectConverterTest/sourceEncoding/pom.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/maven/MavenProjectConverterTest/sourceEncoding/pom.xml diff --git a/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java new file mode 100644 index 00000000000..82bb38e79b6 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java @@ -0,0 +1,117 @@ +/* + * 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.core.config; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import org.sonar.api.CoreProperties; +import org.sonar.api.PropertyType; +import org.sonar.api.config.PropertyDefinition; +import org.sonar.api.resources.Qualifiers; + +import java.util.List; + +public class CorePropertyDefinitions { + + private CorePropertyDefinitions() { + // only static stuff + } + + public static List<PropertyDefinition> all() { + List<PropertyDefinition> defs = Lists.newArrayList(); + defs.addAll(IssueExclusionProperties.all()); + defs.addAll(ExclusionProperties.all()); + defs.addAll(SecurityProperties.all()); + + defs.addAll(ImmutableList.of( + + // DEBT + PropertyDefinition.builder(CoreProperties.HOURS_IN_DAY) + .name("Number of working hours in a day") + .type(PropertyType.INTEGER) + .defaultValue("8") + .category(CoreProperties.CATEGORY_TECHNICAL_DEBT) + .deprecatedKey("sqale.hoursInDay") + .build(), + + // BATCH + + PropertyDefinition.builder(CoreProperties.CORE_VIOLATION_LOCALE_PROPERTY) + .defaultValue("en") + .name("Locale used for issue messages") + .description("Deprecated property. Keep default value for backward compatibility.") + .hidden() + .build(), + + PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 1) + .name("Period 1") + .description("Period used to compare measures and track new violations. Values are : <ul class='bullet'><li>Number of days before " + + "analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, for example 2010-12-25</li><li>'previous_analysis' to " + + "compare to previous analysis</li><li>'previous_version' to compare to the previous version in the project history</li></ul>" + + "<p>When specifying a number of days or a date, the snapshot selected for comparison is " + + " the first one available inside the corresponding time range. </p>" + + "<p>Changing this property only takes effect after subsequent project inspections.<p/>") + .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_1) + .category(CoreProperties.CATEGORY_GENERAL) + .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) + .build(), + + PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 2) + .name("Period 2") + .description("See the property 'Period 1'") + .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2) + .category(CoreProperties.CATEGORY_GENERAL) + .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) + .build(), + + PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 3) + .name("Period 3") + .description("See the property 'Period 1'") + .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_3) + .category(CoreProperties.CATEGORY_GENERAL) + .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) + .build(), + + PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 4) + .name("Period 4") + .description("Period used to compare measures and track new violations. This property is specific to the project. Values are : " + + "<ul class='bullet'><li>Number of days before analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, " + + "for example 2010-12-25</li><li>'previous_analysis' to compare to previous analysis</li>" + + "<li>'previous_version' to compare to the previous version in the project history</li><li>A version, for example 1.2</li></ul>" + + "<p>When specifying a number of days or a date, the snapshot selected for comparison is the first one available inside the corresponding time range. </p>" + + "<p>Changing this property only takes effect after subsequent project inspections.<p/>") + .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_4) + .onlyOnQualifiers(Qualifiers.PROJECT) + .category(CoreProperties.CATEGORY_GENERAL) + .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) + .build(), + + PropertyDefinition.builder(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + 5) + .name("Period 5") + .description("See the property 'Period 4'") + .defaultValue(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5) + .onlyOnQualifiers(Qualifiers.PROJECT) + .category(CoreProperties.CATEGORY_GENERAL) + .subCategory(CoreProperties.SUBCATEGORY_DIFFERENTIAL_VIEWS) + .build() + )); + return defs; + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ExclusionProperties.java b/sonar-core/src/main/java/org/sonar/core/config/ExclusionProperties.java index b169a572965..47756b864d6 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ExclusionProperties.java +++ b/sonar-core/src/main/java/org/sonar/core/config/ExclusionProperties.java @@ -17,23 +17,35 @@ * 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.plugins.core; +package org.sonar.core.config; import com.google.common.collect.ImmutableList; import org.sonar.api.CoreProperties; +import org.sonar.api.PropertyType; import org.sonar.api.config.PropertyDefinition; import org.sonar.api.resources.Qualifiers; import java.util.List; -class ExclusionProperties { +public class ExclusionProperties { private ExclusionProperties() { // only static stuff } - static List<PropertyDefinition> definitions() { + public static List<PropertyDefinition> all() { return ImmutableList.of( + + // COVERAGE + PropertyDefinition.builder("sonar.coverage.exclusions") + .category(CoreProperties.CATEGORY_EXCLUSIONS) + .subCategory(CoreProperties.SUBCATEGORY_COVERAGE_EXCLUSIONS) + .type(PropertyType.STRING) + .multiValues(true) + .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) + .build(), + + // FILES PropertyDefinition.builder(CoreProperties.PROJECT_INCLUSIONS_PROPERTY) .name("Source File Inclusions") .multiValues(true) @@ -97,6 +109,7 @@ class ExclusionProperties { .subCategory(CoreProperties.SUBCATEGORY_FILES_EXCLUSIONS) .onlyOnQualifiers(Qualifiers.PROJECT) .index(1) - .build()); + .build() + ); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/IssueExclusionsConfiguration.java b/sonar-core/src/main/java/org/sonar/core/config/IssueExclusionProperties.java index 18c2f9fa8b4..b98f1cab9be 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/IssueExclusionsConfiguration.java +++ b/sonar-core/src/main/java/org/sonar/core/config/IssueExclusionProperties.java @@ -17,8 +17,7 @@ * 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.issue.ignore; +package org.sonar.core.config; import com.google.common.collect.ImmutableList; import org.sonar.api.CoreProperties; @@ -29,7 +28,7 @@ import org.sonar.api.resources.Qualifiers; import java.util.List; -public final class IssueExclusionsConfiguration { +public final class IssueExclusionProperties { public static final String SUB_CATEGORY_IGNORE_ISSUES = "issues"; @@ -56,14 +55,13 @@ public final class IssueExclusionsConfiguration { public static final String PATTERNS_ALLFILE_KEY = EXCLUSION_KEY_PREFIX + ALLFILE_SUFFIX; public static final String FILE_REGEXP = "fileRegexp"; - static final int LARGE_SIZE = 40; - static final int SMALL_SIZE = 10; + public static final int LARGE_SIZE = 40; - private IssueExclusionsConfiguration() { - // static configuration declaration only + private IssueExclusionProperties() { + // only static } - public static List<PropertyDefinition> getPropertyDefinitions() { + public static List<PropertyDefinition> all() { return ImmutableList.of( PropertyDefinition.builder(PATTERNS_MULTICRITERIA_EXCLUSION_KEY) .category(CoreProperties.CATEGORY_EXCLUSIONS) @@ -84,7 +82,8 @@ public final class IssueExclusionsConfiguration { .description("Pattern to match files which should be ignored.") .type(PropertyType.STRING) .indicativeSize(LARGE_SIZE) - .build()) + .build() + ) .build(), PropertyDefinition.builder(PATTERNS_BLOCK_KEY) .category(CoreProperties.CATEGORY_EXCLUSIONS) @@ -105,7 +104,8 @@ public final class IssueExclusionsConfiguration { .description("If specified, this regular expression is used to determine the end of code blocks to ignore. If not, then block ends at the end of file.") .type(PropertyType.STRING) .indicativeSize(LARGE_SIZE) - .build()) + .build() + ) .build(), PropertyDefinition.builder(PATTERNS_ALLFILE_KEY) .category(CoreProperties.CATEGORY_EXCLUSIONS) @@ -120,7 +120,8 @@ public final class IssueExclusionsConfiguration { .description("If this regular expression is found in a file, then the whole file is ignored.") .type(PropertyType.STRING) .indicativeSize(LARGE_SIZE) - .build()) + .build() + ) .build(), PropertyDefinition.builder(PATTERNS_MULTICRITERIA_INCLUSION_KEY) .category(CoreProperties.CATEGORY_EXCLUSIONS) @@ -141,7 +142,9 @@ public final class IssueExclusionsConfiguration { .description("Pattern used to match files to which the rules should be restricted.") .type(PropertyType.STRING) .indicativeSize(LARGE_SIZE) - .build()) - .build()); + .build() + ) + .build() + ); } } diff --git a/sonar-core/src/main/java/org/sonar/core/config/SecurityProperties.java b/sonar-core/src/main/java/org/sonar/core/config/SecurityProperties.java new file mode 100644 index 00000000000..39157443966 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/config/SecurityProperties.java @@ -0,0 +1,80 @@ +/* + * 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.core.config; + +import com.google.common.collect.ImmutableList; +import org.sonar.api.CoreProperties; +import org.sonar.api.PropertyType; +import org.sonar.api.config.PropertyDefinition; +import org.sonar.api.resources.Qualifiers; + +import java.util.List; + +class SecurityProperties { + + private SecurityProperties() { + // only static stuff + } + + static List<PropertyDefinition> all() { + return ImmutableList.of( + PropertyDefinition.builder(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY) + .defaultValue("" + CoreProperties.CORE_IMPORT_SOURCES_DEFAULT_VALUE) + .name("Import sources") + .description("Set to false if sources should not be imported and therefore not available in the Web UI (e.g. for security reasons).") + .type(PropertyType.BOOLEAN) + .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE) + .category(CoreProperties.CATEGORY_SECURITY) + .build(), + + PropertyDefinition.builder(CoreProperties.CORE_ALLOW_USERS_TO_SIGNUP_PROPERTY) + .defaultValue("" + CoreProperties.CORE_ALLOW_USERS_TO_SIGNUP_DEAULT_VALUE) + .name("Allow users to sign up online") + .description("Users can sign up online.") + .type(PropertyType.BOOLEAN) + .category(CoreProperties.CATEGORY_SECURITY) + .build(), + + PropertyDefinition.builder(CoreProperties.CORE_DEFAULT_GROUP) + .defaultValue(CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE) + .name("Default user group") + .description("Any new users will automatically join this group.") + .category(CoreProperties.CATEGORY_SECURITY) + .build(), + + PropertyDefinition.builder(CoreProperties.CORE_FORCE_AUTHENTICATION_PROPERTY) + .defaultValue("" + CoreProperties.CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE) + .name("Force user authentication") + .description("Forcing user authentication stops un-logged users to access SonarQube.") + .type(PropertyType.BOOLEAN) + .category(CoreProperties.CATEGORY_SECURITY) + .build(), + + PropertyDefinition.builder(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION) + .defaultValue(Boolean.toString(false)) + .name("Prevent automatic project creation") + .description("Set to true to prevent automatic project creation at first analysis and force project provisioning.") + .type(PropertyType.BOOLEAN) + .category(CoreProperties.CATEGORY_SECURITY) + .build() + ); + + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/i18n/DefaultI18n.java b/sonar-core/src/main/java/org/sonar/core/i18n/DefaultI18n.java index 066743f9a6d..4bf009a9a42 100644 --- a/sonar-core/src/main/java/org/sonar/core/i18n/DefaultI18n.java +++ b/sonar-core/src/main/java/org/sonar/core/i18n/DefaultI18n.java @@ -49,7 +49,7 @@ public class DefaultI18n implements I18n, ServerExtension, BatchExtension, Start public static final String BUNDLE_PACKAGE = "org.sonar.l10n."; private PluginRepository pluginRepository; - private I18nClassloader i18nClassloader; + private ClassLoader classloader; private Map<String, String> propertyToBundles; private final ResourceBundle.Control control; private final System2 system2; @@ -81,28 +81,36 @@ public class DefaultI18n implements I18n, ServerExtension, BatchExtension, Start } @VisibleForTesting - void doStart(I18nClassloader classloader) { - this.i18nClassloader = classloader; + void doStart(ClassLoader classloader) { + this.classloader = classloader; propertyToBundles = Maps.newHashMap(); - for (PluginMetadata plugin : pluginRepository.getMetadata()) { - try { - String bundleKey = BUNDLE_PACKAGE + plugin.getKey(); - ResourceBundle bundle = ResourceBundle.getBundle(bundleKey, Locale.ENGLISH, i18nClassloader, control); - Enumeration<String> keys = bundle.getKeys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - propertyToBundles.put(key, bundleKey); - } - } catch (MissingResourceException e) { - // ignore + Collection<PluginMetadata> metadata = pluginRepository.getMetadata(); + if (metadata.isEmpty()) { + addPlugin("core"); + } else { + for (PluginMetadata plugin : pluginRepository.getMetadata()) { + addPlugin(plugin.getKey()); } } LOG.debug(String.format("Loaded %d properties from l10n bundles", propertyToBundles.size())); } + private void addPlugin(String pluginKey){ + try { + String bundleKey = BUNDLE_PACKAGE + pluginKey; + ResourceBundle bundle = ResourceBundle.getBundle(bundleKey, Locale.ENGLISH, this.classloader, control); + Enumeration<String> keys = bundle.getKeys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + propertyToBundles.put(key, bundleKey); + } + } catch (MissingResourceException e) { + // ignore + } + } @Override public void stop() { - i18nClassloader = null; + classloader = null; propertyToBundles = null; } @@ -112,7 +120,7 @@ public class DefaultI18n implements I18n, ServerExtension, BatchExtension, Start String value = null; if (bundleKey != null) { try { - ResourceBundle resourceBundle = ResourceBundle.getBundle(bundleKey, locale, i18nClassloader, control); + ResourceBundle resourceBundle = ResourceBundle.getBundle(bundleKey, locale, classloader, control); value = resourceBundle.getString(key); } catch (MissingResourceException e1) { // ignore @@ -165,7 +173,7 @@ public class DefaultI18n implements I18n, ServerExtension, BatchExtension, Start filePath += "_" + locale.getLanguage(); } filePath += "/" + filename; - InputStream input = i18nClassloader.getResourceAsStream(filePath); + InputStream input = classloader.getResourceAsStream(filePath); if (input != null) { result = readInputStream(filePath, input); } @@ -198,6 +206,6 @@ public class DefaultI18n implements I18n, ServerExtension, BatchExtension, Start } ClassLoader getBundleClassLoader() { - return i18nClassloader; + return classloader; } } diff --git a/sonar-core/src/main/java/org/sonar/core/i18n/I18nClassloader.java b/sonar-core/src/main/java/org/sonar/core/i18n/I18nClassloader.java index 9987fa9800e..d0eb0510763 100644 --- a/sonar-core/src/main/java/org/sonar/core/i18n/I18nClassloader.java +++ b/sonar-core/src/main/java/org/sonar/core/i18n/I18nClassloader.java @@ -30,25 +30,28 @@ import java.util.List; class I18nClassloader extends URLClassLoader { - private ClassLoader[] pluginClassloaders; - - public I18nClassloader(PluginRepository pluginRepository) { - super(new URL[0]); + private static List<ClassLoader> classLoadersFromPlugin(PluginRepository pluginRepository) { List<ClassLoader> list = Lists.newArrayList(); - for (PluginMetadata metadata : pluginRepository.getMetadata()) { Plugin plugin = pluginRepository.getPlugin(metadata.getKey()); list.add(plugin.getClass().getClassLoader()); } + return list; + } + + private ClassLoader[] pluginClassloaders; - this.pluginClassloaders = list.toArray(new ClassLoader[list.size()]); + public I18nClassloader(PluginRepository pluginRepository) { + this(classLoadersFromPlugin(pluginRepository)); } - I18nClassloader(ClassLoader[] pluginClassloaders) { + I18nClassloader(List<ClassLoader> pluginClassloaders) { super(new URL[0]); - this.pluginClassloaders = pluginClassloaders; + pluginClassloaders.add(getClass().getClassLoader()); + this.pluginClassloaders = pluginClassloaders.toArray(new ClassLoader[pluginClassloaders.size()]); } + @Override public URL getResource(String name) { for (ClassLoader pluginClassloader : pluginClassloaders) { URL url = pluginClassloader.getResource(name); diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java b/sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java index 8723ad437dd..9ead96effba 100644 --- a/sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java +++ b/sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java @@ -100,7 +100,7 @@ public class MeasuresDao extends BaseDao { getSession().getEntityManager().merge(dbMetric); } else { - getSession().getEntityManager().persist(metric); + getSession().getEntityManager().persist(new Metric().merge(metric)); } } diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index c9a1ae7140a..c9a1ae7140a 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties diff --git a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/gwt.properties b/sonar-core/src/main/resources/org/sonar/l10n/gwt.properties index 9febb9a1a1f..aaa12a5fa72 100644 --- a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/gwt.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/gwt.properties @@ -17,11 +17,3 @@ libs.expand=Expand all libs.collapse=Collapse all libs.noLibraries=No libraries libs.usageLink=Usages - - -# Unit tests viewer -unittest.duration=Duration -unittest.name=Unit test name -unittest.skipped=skipped -unittest.tests=Tests -unittest.failures=Failures/Errors
\ No newline at end of file diff --git a/plugins/sonar-l10n-en-plugin/src/test/java/org/sonar/plugins/l10n/EnglishPackPluginTest.java b/sonar-core/src/test/java/org/sonar/core/config/CorePropertyDefinitionsTest.java index 1e8ecc6c7af..5f3b028baa7 100644 --- a/plugins/sonar-l10n-en-plugin/src/test/java/org/sonar/plugins/l10n/EnglishPackPluginTest.java +++ b/sonar-core/src/test/java/org/sonar/core/config/CorePropertyDefinitionsTest.java @@ -17,15 +17,19 @@ * 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.plugins.l10n; +package org.sonar.core.config; import org.junit.Test; +import org.sonar.api.config.PropertyDefinition; + +import java.util.List; import static org.fest.assertions.Assertions.assertThat; -public class EnglishPackPluginTest { +public class CorePropertyDefinitionsTest { @Test - public void no_extensions() { - assertThat(new EnglishPackPlugin().getExtensions()).isEmpty(); + public void all() { + List<PropertyDefinition> defs = CorePropertyDefinitions.all(); + assertThat(defs.size()).isGreaterThan(10); } } diff --git a/sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java b/sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java index 66e35d66d28..7fd150b3608 100644 --- a/sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java +++ b/sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java @@ -50,38 +50,45 @@ public class DefaultI18nTest { @Before public void before() { PluginRepository pluginRepository = mock(PluginRepository.class); - List<PluginMetadata> plugins = Arrays.asList(newPlugin("sqale"), newPlugin("frpack"), newPlugin("core"), newPlugin("checkstyle"), newPlugin("other")); + List<PluginMetadata> plugins = Arrays.asList(newPlugin("core"), newPlugin("sqale"), newPlugin("frpack"), newPlugin("checkstyle"), newPlugin("other")); when(pluginRepository.getMetadata()).thenReturn(plugins); - I18nClassloader i18nClassloader = new I18nClassloader(new ClassLoader[]{ - newCoreClassloader(), newFrenchPackClassloader(), newSqaleClassloader(), newCheckstyleClassloader() - }); manager = new DefaultI18n(pluginRepository, system2); - manager.doStart(i18nClassloader); + manager.doStart(getClass().getClassLoader()); } @Test - public void should_introspect_all_available_properties() { - assertThat(manager.getPropertyKeys().contains("by")).isTrue(); - assertThat(manager.getPropertyKeys().contains("only.in.english")).isTrue(); + public void load_core_bundle_when_no_plugin() { + DefaultI18n manager = new DefaultI18n(mock(PluginRepository.class), system2); + manager.doStart(getClass().getClassLoader()); + + assertThat(manager.getPropertyKeys().contains("any")).isTrue(); + assertThat(manager.getPropertyKeys().contains("assignee")).isTrue(); + } + + @Test + public void introspect_all_available_properties() { + assertThat(manager.getPropertyKeys().contains("any")).isTrue(); + // Only in english + assertThat(manager.getPropertyKeys().contains("assignee")).isTrue(); assertThat(manager.getPropertyKeys().contains("sqale.page")).isTrue(); assertThat(manager.getPropertyKeys().contains("unknown")).isFalse(); } @Test - public void should_get_english_labels() { - assertThat(manager.message(Locale.ENGLISH, "by", null)).isEqualTo("By"); + public void get_english_labels() { + assertThat(manager.message(Locale.ENGLISH, "any", null)).isEqualTo("Any"); assertThat(manager.message(Locale.ENGLISH, "sqale.page", null)).isEqualTo("Sqale page title"); assertThat(manager.message(Locale.ENGLISH, "checkstyle.rule1.name", null)).isEqualTo("Rule one"); } // SONAR-2927 @Test - public void should_get_english_labels_when_default_locale_is_not_english() { + public void get_english_labels_when_default_locale_is_not_english() { Locale defaultLocale = Locale.getDefault(); try { Locale.setDefault(Locale.FRENCH); - assertThat(manager.message(Locale.ENGLISH, "by", null)).isEqualTo("By"); + assertThat(manager.message(Locale.ENGLISH, "any", null)).isEqualTo("Any"); assertThat(manager.message(Locale.ENGLISH, "sqale.page", null)).isEqualTo("Sqale page title"); assertThat(manager.message(Locale.ENGLISH, "checkstyle.rule1.name", null)).isEqualTo("Rule one"); } finally { @@ -90,85 +97,61 @@ public class DefaultI18nTest { } @Test - public void should_get_labels_from_french_pack() { + public void get_labels_from_french_pack() { assertThat(manager.message(Locale.FRENCH, "checkstyle.rule1.name", null)).isEqualTo("Rule un"); - assertThat(manager.message(Locale.FRENCH, "by", null)).isEqualTo("Par"); + assertThat(manager.message(Locale.FRENCH, "any", null)).isEqualTo("Tous"); // language pack assertThat(manager.message(Locale.FRENCH, "sqale.page", null)).isEqualTo("Titre de la page Sqale"); } @Test - public void should_get_french_label_if_swiss_country() { + public void get_french_label_if_swiss_country() { Locale swiss = new Locale("fr", "CH"); assertThat(manager.message(swiss, "checkstyle.rule1.name", null)).isEqualTo("Rule un"); - assertThat(manager.message(swiss, "by", null)).isEqualTo("Par"); + assertThat(manager.message(swiss, "any", null)).isEqualTo("Tous"); // language pack assertThat(manager.message(swiss, "sqale.page", null)).isEqualTo("Titre de la page Sqale"); } @Test - public void should_fallback_to_default_locale() { + public void fallback_to_default_locale() { assertThat(manager.message(Locale.CHINA, "checkstyle.rule1.name", null)).isEqualTo("Rule one"); - assertThat(manager.message(Locale.CHINA, "by", null)).isEqualTo("By"); + assertThat(manager.message(Locale.CHINA, "any", null)).isEqualTo("Any"); assertThat(manager.message(Locale.CHINA, "sqale.page", null)).isEqualTo("Sqale page title"); } @Test - public void should_return_default_value_if_missing_key() { + public void return_default_value_if_missing_key() { assertThat(manager.message(Locale.ENGLISH, "unknown", "default")).isEqualTo("default"); assertThat(manager.message(Locale.FRENCH, "unknown", "default")).isEqualTo("default"); } @Test - public void should_accept_empty_labels() { - assertThat(manager.message(Locale.ENGLISH, "empty", "default")).isEqualTo(""); - assertThat(manager.message(Locale.FRENCH, "empty", "default")).isEqualTo(""); - } - - @Test - public void shouldFormatMessageWithParameters() { - assertThat(manager.message(Locale.ENGLISH, "with.parameters", null, "one", "two")).isEqualTo("First is one and second is two"); - } - - @Test - public void shouldUseDefaultLocaleIfMissingValueInLocalizedBundle() { - assertThat(manager.message(Locale.FRENCH, "only.in.english", null)).isEqualTo("Missing in French bundle"); - assertThat(manager.message(Locale.CHINA, "only.in.english", null)).isEqualTo("Missing in French bundle"); + public void format_message_with_parameters() { + assertThat(manager.message(Locale.ENGLISH, "name_too_long_x", null, "10")).isEqualTo("Name is too long (maximum is 10 characters)"); } @Test - public void should_locate_english_file() { - String html = manager.messageFromFile(Locale.ENGLISH, "ArchitectureRule.html", "checkstyle.rule1.name"); - assertThat(html).isEqualTo("This is the architecture rule"); + public void use_default_locale_if_missing_value_in_localized_bundle() { + assertThat(manager.message(Locale.FRENCH, "assignee", null)).isEqualTo("Assignee"); + assertThat(manager.message(Locale.CHINA, "assignee", null)).isEqualTo("Assignee"); } @Test - public void should_return_null_if_file_not_found() { + public void return_null_if_file_not_found() { String html = manager.messageFromFile(Locale.ENGLISH, "UnknownRule.html", "checkstyle.rule1.name"); assertThat(html).isNull(); } @Test - public void should_return_null_if_rule_not_internationalized() { + public void return_null_if_rule_not_internationalized() { String html = manager.messageFromFile(Locale.ENGLISH, "UnknownRule.html", "foo.rule1.name"); assertThat(html).isNull(); } @Test - public void should_locate_french_file() { - String html = manager.messageFromFile(Locale.FRENCH, "ArchitectureRule.html", "checkstyle.rule1.name"); - assertThat(html).isEqualTo("Règle d'architecture"); - } - - @Test - public void should_locate_file_with_missing_locale() { - String html = manager.messageFromFile(Locale.CHINA, "ArchitectureRule.html", "checkstyle.rule1.name"); - assertThat(html).isNull(); - } - - @Test public void get_age_with_duration() { assertThat(manager.age(Locale.ENGLISH, 10)).isEqualTo("less than a minute"); } @@ -195,12 +178,8 @@ public class DefaultI18nTest { assertThat(manager.formatDate(Locale.ENGLISH, DateUtils.parseDateTime("2014-01-22T19:10:03+0100"))).isEqualTo("Jan 22, 2014"); } - static URLClassLoader newCoreClassloader() { - return newClassLoader("/org/sonar/core/i18n/corePlugin/"); - } - static URLClassLoader newCheckstyleClassloader() { - return newClassLoader("/org/sonar/core/i18n/checkstylePlugin/"); + return newClassLoader("/org/sonar/core/i18n/I18nClassloaderTest/"); } /** diff --git a/sonar-core/src/test/java/org/sonar/core/i18n/GwtI18nTest.java b/sonar-core/src/test/java/org/sonar/core/i18n/GwtI18nTest.java index f719ece6297..0f299a7bedc 100644 --- a/sonar-core/src/test/java/org/sonar/core/i18n/GwtI18nTest.java +++ b/sonar-core/src/test/java/org/sonar/core/i18n/GwtI18nTest.java @@ -46,13 +46,13 @@ public class GwtI18nTest { } @Test - public void shouldListAllPropertyKeysAtStartup() { + public void list_all_property_keys_at_startup() { assertThat(i18n.getPropertyKeys().length, Is.is(2)); assertThat(Lists.newArrayList(i18n.getPropertyKeys()), hasItems("one", "two")); } @Test - public void shouldEncodeJavascriptValues() { + public void encode_javascript_values() { String js = i18n.getJsDictionnary(bundle); assertThat(js, containsString("var l10n = {")); assertThat(js, containsString("one\": \"One")); diff --git a/sonar-core/src/test/java/org/sonar/core/i18n/I18nClassloaderTest.java b/sonar-core/src/test/java/org/sonar/core/i18n/I18nClassloaderTest.java index 2a62a129fcf..00a6b3e0372 100644 --- a/sonar-core/src/test/java/org/sonar/core/i18n/I18nClassloaderTest.java +++ b/sonar-core/src/test/java/org/sonar/core/i18n/I18nClassloaderTest.java @@ -19,14 +19,18 @@ */ package org.sonar.core.i18n; +import com.google.common.collect.Lists; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.platform.PluginRepository; +import java.net.URL; import java.net.URLClassLoader; import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; public class I18nClassloaderTest { private I18nClassloader i18nClassloader; @@ -36,32 +40,49 @@ public class I18nClassloaderTest { @Before public void init() { - URLClassLoader sqale = DefaultI18nTest.newSqaleClassloader(); - URLClassLoader checkstyle = DefaultI18nTest.newCheckstyleClassloader(); - - i18nClassloader = new I18nClassloader(new ClassLoader[]{sqale, checkstyle}); + i18nClassloader = new I18nClassloader(mock(PluginRepository.class)); } @Test - public void should_aggregate_plugin_classloaders() { + public void aggregate_plugin_classloaders() { + URLClassLoader checkstyle = newCheckstyleClassloader(); + + I18nClassloader i18nClassloader = new I18nClassloader(Lists.<ClassLoader>newArrayList(checkstyle)); assertThat(i18nClassloader.getResource("org/sonar/l10n/checkstyle.properties")).isNotNull(); assertThat(i18nClassloader.getResource("org/sonar/l10n/checkstyle.properties").getFile()).endsWith("checkstyle.properties"); - assertThat(i18nClassloader.getResource("org/sonar/l10n/checkstyle/ArchitectureRule.html").getFile()).endsWith("ArchitectureRule.html"); } @Test - public void should_return_null_if_resource_not_found() { + public void contain_its_own_classloader() { + assertThat(i18nClassloader.getResource("org/sonar/l10n/core.properties")).isNotNull(); + assertThat(i18nClassloader.getResource("org/sonar/l10n/gwt.properties")).isNotNull(); + } + + @Test + public void return_null_if_resource_not_found() { assertThat(i18nClassloader.getResource("org/unknown.properties")).isNull(); } @Test - public void should_not_support_lookup_of_java_classes() throws ClassNotFoundException { + public void not_support_lookup_of_java_classes() throws ClassNotFoundException { thrown.expect(UnsupportedOperationException.class); i18nClassloader.loadClass("java.lang.String"); } @Test - public void should_override_toString() throws ClassNotFoundException { + public void override_toString() throws ClassNotFoundException { assertThat(i18nClassloader.toString()).isEqualTo("i18n-classloader"); } + + private static URLClassLoader newCheckstyleClassloader() { + return newClassLoader("/org/sonar/core/i18n/I18nClassloaderTest/"); + } + + private static URLClassLoader newClassLoader(String... resourcePaths) { + URL[] urls = new URL[resourcePaths.length]; + for (int index = 0; index < resourcePaths.length; index++) { + urls[index] = DefaultI18nTest.class.getResource(resourcePaths[index]); + } + return new URLClassLoader(urls); + } } diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/I18nClassloaderTest/org/sonar/l10n/checkstyle.properties b/sonar-core/src/test/resources/org/sonar/core/i18n/I18nClassloaderTest/org/sonar/l10n/checkstyle.properties new file mode 100644 index 00000000000..81756045d79 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/i18n/I18nClassloaderTest/org/sonar/l10n/checkstyle.properties @@ -0,0 +1 @@ +rule1.name=Rule one diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/checkstylePlugin/org/sonar/l10n/checkstyle/ArchitectureRule.html b/sonar-core/src/test/resources/org/sonar/core/i18n/checkstylePlugin/org/sonar/l10n/checkstyle/ArchitectureRule.html deleted file mode 100644 index a7cad9049d7..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/i18n/checkstylePlugin/org/sonar/l10n/checkstyle/ArchitectureRule.html +++ /dev/null @@ -1 +0,0 @@ -This is the architecture rule
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/corePlugin/org/sonar/l10n/core.properties b/sonar-core/src/test/resources/org/sonar/core/i18n/corePlugin/org/sonar/l10n/core.properties deleted file mode 100644 index d185db89e91..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/i18n/corePlugin/org/sonar/l10n/core.properties +++ /dev/null @@ -1,9 +0,0 @@ -by=By -empty= -with.parameters=First is {0} and second is {1} -only.in.english=Missing in French bundle -duration.seconds=less than a minute -duration.day=a day -work_duration.x_days={0}d -work_duration.x_hours={0}h -work_duration.x_minutes={0}min diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/frenchPack/org/sonar/l10n/checkstyle_fr/ArchitectureRule.html b/sonar-core/src/test/resources/org/sonar/core/i18n/frenchPack/org/sonar/l10n/checkstyle_fr/ArchitectureRule.html deleted file mode 100644 index 9b12ae071ce..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/i18n/frenchPack/org/sonar/l10n/checkstyle_fr/ArchitectureRule.html +++ /dev/null @@ -1 +0,0 @@ -Règle d'architecture
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/frenchPack/org/sonar/l10n/core_fr.properties b/sonar-core/src/test/resources/org/sonar/core/i18n/frenchPack/org/sonar/l10n/core_fr.properties deleted file mode 100644 index e9ced4039ae..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/i18n/frenchPack/org/sonar/l10n/core_fr.properties +++ /dev/null @@ -1,2 +0,0 @@ -by=Par -empty=
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/checkstylePlugin/org/sonar/l10n/checkstyle.properties b/sonar-core/src/test/resources/org/sonar/l10n/checkstyle.properties index 10fa9295c44..10fa9295c44 100644 --- a/sonar-core/src/test/resources/org/sonar/core/i18n/checkstylePlugin/org/sonar/l10n/checkstyle.properties +++ b/sonar-core/src/test/resources/org/sonar/l10n/checkstyle.properties diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/frenchPack/org/sonar/l10n/checkstyle_fr.properties b/sonar-core/src/test/resources/org/sonar/l10n/checkstyle_fr.properties index b2fc8f9651f..b2fc8f9651f 100644 --- a/sonar-core/src/test/resources/org/sonar/core/i18n/frenchPack/org/sonar/l10n/checkstyle_fr.properties +++ b/sonar-core/src/test/resources/org/sonar/l10n/checkstyle_fr.properties diff --git a/sonar-core/src/test/resources/org/sonar/l10n/core_fr.properties b/sonar-core/src/test/resources/org/sonar/l10n/core_fr.properties new file mode 100644 index 00000000000..9b473d07f5c --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/l10n/core_fr.properties @@ -0,0 +1,2 @@ +any=Tous +empty= diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/sqalePlugin/org/sonar/l10n/sqale.properties b/sonar-core/src/test/resources/org/sonar/l10n/sqale.properties index a8ea9c0553e..a8ea9c0553e 100644 --- a/sonar-core/src/test/resources/org/sonar/core/i18n/sqalePlugin/org/sonar/l10n/sqale.properties +++ b/sonar-core/src/test/resources/org/sonar/l10n/sqale.properties diff --git a/sonar-core/src/test/resources/org/sonar/core/i18n/sqalePlugin/org/sonar/l10n/sqale_fr.properties b/sonar-core/src/test/resources/org/sonar/l10n/sqale_fr.properties index 471d015a11a..471d015a11a 100644 --- a/sonar-core/src/test/resources/org/sonar/core/i18n/sqalePlugin/org/sonar/l10n/sqale_fr.properties +++ b/sonar-core/src/test/resources/org/sonar/l10n/sqale_fr.properties diff --git a/sonar-plugin-api/pom.xml b/sonar-plugin-api/pom.xml index 5f199d70642..09d12366d3f 100644 --- a/sonar-plugin-api/pom.xml +++ b/sonar-plugin-api/pom.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> @@ -191,6 +192,14 @@ </executions> </plugin> </plugins> + + <resources> + <resource> + <!-- Used to set SonarQube version in sq-version.txt file --> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> </build> </project> diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/platform/Server.java b/sonar-plugin-api/src/main/java/org/sonar/api/platform/Server.java index d6c39401c2d..7fd8afd1b1e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/platform/Server.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/platform/Server.java @@ -22,6 +22,7 @@ package org.sonar.api.platform; import org.sonar.api.BatchComponent; import org.sonar.api.ServerComponent; +import java.io.File; import java.util.Date; /** @@ -35,6 +36,12 @@ public abstract class Server implements BatchComponent, ServerComponent { public abstract Date getStartedAt(); + public abstract File getRootDir(); + + public abstract File getDeployDir(); + + public abstract String getContextPath(); + /** * @return the server URL when executed from batch, else null. * @since 2.4 diff --git a/sonar-plugin-api/src/main/resources/sq-version.txt b/sonar-plugin-api/src/main/resources/sq-version.txt new file mode 100644 index 00000000000..ad96e7cf933 --- /dev/null +++ b/sonar-plugin-api/src/main/resources/sq-version.txt @@ -0,0 +1 @@ +${project.version} diff --git a/sonar-server/pom.xml b/sonar-server/pom.xml index 6f037197a80..cda7d4a900b 100644 --- a/sonar-server/pom.xml +++ b/sonar-server/pom.xml @@ -25,14 +25,8 @@ <artifactId>gson</artifactId> </dependency> <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-batch</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.codehaus.sonar</groupId> - <artifactId>sonar-batch-maven-compat</artifactId> - <version>${project.version}</version> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.codehaus.sonar</groupId> @@ -49,6 +43,12 @@ <dependency> <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-deprecated</artifactId> + <exclusions> + <exclusion> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.codehaus.sonar</groupId> @@ -498,26 +498,12 @@ </dependency> <dependency> <groupId>org.codehaus.sonar.plugins</groupId> - <artifactId>sonar-l10n-en-plugin</artifactId> - <version>${project.version}</version> - <type>sonar-plugin</type> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.codehaus.sonar.plugins</groupId> <artifactId>sonar-email-notifications-plugin</artifactId> <version>${project.version}</version> <type>sonar-plugin</type> <scope>provided</scope> </dependency> <dependency> - <groupId>org.codehaus.sonar.plugins</groupId> - <artifactId>sonar-maven-batch-plugin</artifactId> - <version>${project.version}</version> - <type>sonar-plugin</type> - <scope>provided</scope> - </dependency> - <dependency> <groupId>org.codehaus.sonar-plugins.java</groupId> <artifactId>sonar-jacoco-plugin</artifactId> <version>${sonarJava.version}</version> @@ -636,12 +622,6 @@ </plugin> </plugins> </build> - <dependencies> - <dependency> - <groupId>com.h2database</groupId> - <artifactId>h2</artifactId> - </dependency> - </dependencies> </profile> <profile> diff --git a/sonar-server/src/main/java/org/sonar/server/db/EmbeddedDatabase.java b/sonar-server/src/main/java/org/sonar/server/db/EmbeddedDatabase.java index ced29614549..2ed48e023e9 100644 --- a/sonar-server/src/main/java/org/sonar/server/db/EmbeddedDatabase.java +++ b/sonar-server/src/main/java/org/sonar/server/db/EmbeddedDatabase.java @@ -23,6 +23,7 @@ import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang.StringUtils; import org.h2.Driver; import org.h2.tools.Server; +import org.picocontainer.Startable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; @@ -34,7 +35,7 @@ import java.io.File; import java.sql.DriverManager; import java.sql.SQLException; -public class EmbeddedDatabase { +public class EmbeddedDatabase implements Startable { private static final Logger LOG = LoggerFactory.getLogger(EmbeddedDatabase.class); private final Settings settings; private Server server; @@ -43,6 +44,7 @@ public class EmbeddedDatabase { this.settings = settings; } + @Override public void start() { File dbHome = getDataDirectory(settings); if (!dbHome.exists()) { @@ -71,6 +73,7 @@ public class EmbeddedDatabase { } } + @Override public void stop() { if (server != null) { server.stop(); diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrator.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrator.java index 833389ad924..af25da2e929 100644 --- a/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrator.java +++ b/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrator.java @@ -22,6 +22,7 @@ package org.sonar.server.db.migrations; import com.google.common.annotations.VisibleForTesting; import org.apache.commons.dbutils.DbUtils; import org.apache.ibatis.session.SqlSession; +import org.picocontainer.Startable; import org.slf4j.LoggerFactory; import org.sonar.api.ServerComponent; import org.sonar.core.persistence.Database; @@ -36,7 +37,7 @@ import java.sql.Connection; * * @since 2.12 */ -public class DatabaseMigrator implements ServerComponent { +public class DatabaseMigrator implements ServerComponent, Startable { private final MyBatis myBatis; private final Database database; @@ -48,10 +49,21 @@ public class DatabaseMigrator implements ServerComponent { this.migrations = migrations; } + @Override + public void start(){ + createDatabase(); + } + + @Override + public void stop(){ + // Nothing to do + } + /** * @return true if the database has been created, false if this database is not supported */ - public boolean createDatabase() { + @VisibleForTesting + boolean createDatabase() { if (!DdlUtils.supportsDialect(database.getDialect().getId())) { return false; } diff --git a/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java b/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java index 473fbd0e8f8..8095d1911b6 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java @@ -21,14 +21,17 @@ package org.sonar.server.platform; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.FileFilterUtils; -import org.apache.commons.lang.StringUtils; import org.picocontainer.Startable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; +import org.sonar.api.platform.Server; import org.sonar.api.platform.ServerFileSystem; import org.sonar.core.persistence.Database; +import org.sonar.core.persistence.dialect.H2; + +import javax.annotation.CheckForNull; import java.io.File; import java.io.FileFilter; @@ -47,26 +50,22 @@ public class DefaultServerFileSystem implements ServerFileSystem, Startable { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultServerFileSystem.class); private Database database; - private File deployDir; + private final Server server; private File homeDir; - public DefaultServerFileSystem(Database database, Settings settings) { + public DefaultServerFileSystem(Database database, Settings settings, Server server) { this.database = database; + this.server = server; this.homeDir = new File(settings.getString(CoreProperties.SONAR_HOME)); - - String deployPath = settings.getString(ServerSettings.DEPLOY_DIR); - if (StringUtils.isNotBlank(deployPath)) { - this.deployDir = new File(deployPath); - } } /** * for unit tests */ - public DefaultServerFileSystem(Database database, File homeDir, File deployDir) { + public DefaultServerFileSystem(Database database, File homeDir, Server server) { this.database = database; - this.deployDir = deployDir; this.homeDir = homeDir; + this.server = server; } @Override @@ -76,19 +75,19 @@ public class DefaultServerFileSystem implements ServerFileSystem, Startable { throw new IllegalStateException("SonarQube home directory does not exist"); } - if (deployDir == null) { - throw new IllegalStateException("The target directory to deploy libraries is not set"); - } - try { - LOGGER.info("Deploy dir: " + deployDir.getAbsolutePath()); - FileUtils.forceMkdir(deployDir); - for (File subDirectory : deployDir.listFiles((FileFilter) FileFilterUtils.directoryFileFilter())) { + if (getDeployDir() == null) { + throw new IllegalArgumentException("Web app directory does not exist: " + getDeployDir()); + } + + LOGGER.info("Deploy dir: " + getDeployDir().getAbsolutePath()); + FileUtils.forceMkdir(getDeployDir()); + for (File subDirectory : getDeployDir().listFiles((FileFilter) FileFilterUtils.directoryFileFilter())) { FileUtils.cleanDirectory(subDirectory); } } catch (IOException e) { - throw new IllegalStateException("The following directory can not be created: " + deployDir.getAbsolutePath(), e); + throw new IllegalStateException("The following directory can not be created: " + getDeployDir().getAbsolutePath(), e); } File deprecated = getDeprecatedPluginsDir(); @@ -117,15 +116,15 @@ public class DefaultServerFileSystem implements ServerFileSystem, Startable { } public File getDeployDir() { - return deployDir; + return server.getDeployDir(); } public File getDeployedJdbcDriverIndex() { - return new File(deployDir, "jdbc-driver.txt"); + return new File(getDeployDir(), "jdbc-driver.txt"); } public File getDeployedPluginsDir() { - return new File(deployDir, "plugins"); + return new File(getDeployDir(), "plugins"); } public File getDownloadedPluginsDir() { @@ -136,8 +135,15 @@ public class DefaultServerFileSystem implements ServerFileSystem, Startable { return new File(getHomeDir(), "extensions/trash"); } + /** + * Return null when database is H2, as batch is already containing H2 jar + */ + @CheckForNull public File getJdbcDriver() { String dialect = database.getDialect().getId(); + if (H2.ID.equals(dialect)) { + return null; + } File dir = new File(getHomeDir(), "/extensions/jdbc-driver/" + dialect + "/"); List<File> jars = getFiles(dir, "jar"); if (jars.isEmpty()) { @@ -176,10 +182,6 @@ public class DefaultServerFileSystem implements ServerFileSystem, Startable { return new File(getDeployDir(), "plugins/index.txt"); } - public File getBootstrapIndex() { - return new File(getDeployDir(), "bootstrap/index.txt"); - } - /** * @deprecated since 4.1 */ diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index 353893e7d0b..510b3f6f620 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -25,7 +25,8 @@ import org.sonar.api.platform.Server; import org.sonar.core.persistence.DatabaseVersion; import javax.annotation.CheckForNull; -import javax.servlet.ServletContext; + +import java.util.Properties; /** * @since 2.2 @@ -40,7 +41,7 @@ public class Platform { private boolean dbConnected = false; private boolean started = false; - private Platform() { + public Platform() { } public static Platform getInstance() { @@ -65,8 +66,8 @@ public class Platform { return null; } - public void init(ServletContext servletContext) { - serverComponents = new ServerComponents(this, servletContext); + public void init(Properties properties) { + serverComponents = new ServerComponents(this, properties); if (!dbConnected) { startLevel1Container(); startLevel2Container(); diff --git a/sonar-server/src/main/java/org/sonar/server/platform/PlatformServletContextListener.java b/sonar-server/src/main/java/org/sonar/server/platform/PlatformServletContextListener.java index 6257c03551d..82e2e659596 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/PlatformServletContextListener.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/PlatformServletContextListener.java @@ -50,7 +50,7 @@ public final class PlatformServletContextListener implements ServletContextListe public void contextInitialized(ServletContextEvent event) { try { configureLogback(event); - Platform.getInstance().init(event.getServletContext()); + Platform.getInstance().init(System.getProperties()); Platform.getInstance().doStart(); } catch (Throwable t) { // Tomcat 7 "limitations": diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 73e14c71530..e7f9d4d9385 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -39,6 +39,7 @@ import org.sonar.api.utils.UriReader; import org.sonar.api.utils.internal.TempFolderCleaner; import org.sonar.core.component.SnapshotPerspectives; import org.sonar.core.component.db.ComponentDao; +import org.sonar.core.config.CorePropertyDefinitions; import org.sonar.core.config.Logback; import org.sonar.core.i18n.DefaultI18n; import org.sonar.core.i18n.GwtI18n; @@ -162,6 +163,7 @@ class ServerComponents { new TempFolderProvider(), System2.INSTANCE )); + components.addAll(CorePropertyDefinitions.all()); components.addAll(DatabaseMigrations.CLASSES); components.addAll(DaoUtils.getDaoClasses()); return components; @@ -191,7 +193,8 @@ class ServerComponents { // ws RestartHandler.class, - SystemWs.class + SystemWs.class, + BatchWs.class ); } @@ -405,7 +408,6 @@ class ServerComponents { startupContainer.addSingleton(JdbcDriverDeployer.class); startupContainer.addSingleton(RegisterDebtModel.class); startupContainer.addSingleton(GeneratePluginIndex.class); - startupContainer.addSingleton(GenerateBootstrapIndex.class); startupContainer.addSingleton(RegisterNewMeasureFilters.class); startupContainer.addSingleton(RegisterDashboards.class); startupContainer.addSingleton(RegisterPermissionTemplates.class); diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerImpl.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerImpl.java index 79d4e11ac18..8ceb686e0a0 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/ServerImpl.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerImpl.java @@ -20,7 +20,9 @@ package org.sonar.server.platform; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Charsets; import com.google.common.base.Joiner; +import com.google.common.io.Resources; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.picocontainer.Startable; @@ -30,8 +32,10 @@ import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; @@ -42,21 +46,24 @@ public final class ServerImpl extends Server implements Startable { private final Settings settings; private final Date startedAt; private final String buildProperties; - private final String pomProperties; + private final String versionPath; private String id; private String version; private String implementationBuild; + private String contextPath; + private File sonarHome; + private File deployDir; public ServerImpl(Settings settings) { - this(settings, "/build.properties", "/META-INF/maven/org.codehaus.sonar/sonar-plugin-api/pom.properties"); + this(settings, "/build.properties", "/sq-version.txt"); } @VisibleForTesting - ServerImpl(Settings settings, String buildProperties, String pomProperties) { + ServerImpl(Settings settings, String buildProperties, String versionPath) { this.settings = settings; this.startedAt = new Date(); this.buildProperties = buildProperties; - this.pomProperties = pomProperties; + this.versionPath = versionPath; } @Override @@ -64,13 +71,17 @@ public final class ServerImpl extends Server implements Startable { try { id = new SimpleDateFormat("yyyyMMddHHmmss").format(startedAt); - version = read(pomProperties).getProperty("version", ""); + version = readVersion(versionPath); implementationBuild = read(buildProperties).getProperty("Implementation-Build"); + contextPath = StringUtils.defaultIfBlank(settings.getString("sonar.web.context"), "/"); - if (StringUtils.isBlank(version)) { - throw new IllegalStateException("Unknown SonarQube version"); + sonarHome = new File(settings.getString(CoreProperties.SONAR_HOME)); + if (!sonarHome.isDirectory()) { + throw new IllegalStateException("SonarQube home directory is not valid"); } + deployDir = new File(sonarHome, "/web/deploy/"); + LOG.info("SonarQube {}", Joiner.on(" / ").skipNulls().join("Server", version, implementationBuild)); } catch (IOException e) { @@ -107,6 +118,32 @@ public final class ServerImpl extends Server implements Startable { return startedAt; } + @Override + public File getRootDir() { + return sonarHome; + } + + @Override + public File getDeployDir() { + return deployDir; + } + + @Override + public String getContextPath() { + return contextPath; + } + + private static String readVersion(String filename) throws IOException { + URL url = ServerImpl.class.getResource(filename); + if (url != null) { + String version = Resources.toString(url, Charsets.UTF_8); + if (!StringUtils.isBlank(version)) { + return StringUtils.deleteWhitespace(version); + } + } + throw new IllegalStateException("Unknown SonarQube version"); + } + private static Properties read(String filename) throws IOException { Properties properties = new Properties(); @@ -122,6 +159,7 @@ public final class ServerImpl extends Server implements Startable { return properties; } + @Override public String getURL() { return null; diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java index 81d5116b6dc..21c301b3cfe 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java @@ -19,17 +19,13 @@ */ package org.sonar.server.platform; -import com.google.common.annotations.VisibleForTesting; import org.apache.commons.configuration.Configuration; import org.sonar.api.CoreProperties; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; -import org.sonar.core.config.ConfigurationUtils; import javax.annotation.Nullable; -import javax.servlet.ServletContext; -import java.io.File; import java.util.Collections; import java.util.Map; import java.util.Properties; @@ -47,23 +43,14 @@ import java.util.Properties; */ public class ServerSettings extends Settings { - public static final String DEPLOY_DIR = "sonar.web.deployDir"; - + private final Properties properties; private Configuration deprecatedConfiguration; - private File deployDir; - private File sonarHome; - - public ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, ServletContext servletContext) { - this(definitions, deprecatedConfiguration, getDeployDir(servletContext), SonarHome.getHome()); - } - @VisibleForTesting - ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, File deployDir, File sonarHome) { + public ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, Properties properties) { super(definitions); this.deprecatedConfiguration = deprecatedConfiguration; - this.deployDir = deployDir; - this.sonarHome = sonarHome; - load(Collections.<String, String> emptyMap()); + this.properties = properties; + load(Collections.<String, String>emptyMap()); // Secret key is loaded from conf/sonar.properties getEncryption().setPathToSecretKey(getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); } @@ -74,43 +61,14 @@ public class ServerSettings extends Settings { private ServerSettings load(Map<String, String> databaseSettings) { clear(); - setProperty(CoreProperties.SONAR_HOME, sonarHome.getAbsolutePath()); - setProperty(DEPLOY_DIR, deployDir.getAbsolutePath()); // order is important : the last override the first addProperties(databaseSettings); - loadPropertiesFile(sonarHome); - addEnvironmentVariables(); - addSystemProperties(); + addProperties(properties); return this; } - private void loadPropertiesFile(File sonarHome) { - File propertiesFile = new File(sonarHome, "conf/sonar.properties"); - if (!propertiesFile.isFile() || !propertiesFile.exists()) { - throw new IllegalStateException("Properties file does not exist: " + propertiesFile); - } - try { - Properties p = ConfigurationUtils.openProperties(propertiesFile); - addProperties(ConfigurationUtils.interpolateEnvVariables(p)); - } catch (Exception e) { - throw new IllegalStateException("Fail to load configuration file: " + propertiesFile, e); - } - } - - static File getDeployDir(ServletContext servletContext) { - String dirname = servletContext.getRealPath("/deploy/"); - if (dirname == null) { - throw new IllegalArgumentException("Web app directory not found : /deploy/"); - } - File dir = new File(dirname); - if (!dir.exists()) { - throw new IllegalArgumentException("Web app directory does not exist: " + dir); - } - return dir; - } - @Override protected void doOnSetProperty(String key, @Nullable String value) { deprecatedConfiguration.setProperty(key, value); diff --git a/sonar-server/src/main/java/org/sonar/server/platform/SonarHome.java b/sonar-server/src/main/java/org/sonar/server/platform/SonarHome.java index 26cf45ed572..2f1b7bcfafd 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/SonarHome.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/SonarHome.java @@ -22,6 +22,7 @@ package org.sonar.server.platform; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import org.apache.commons.lang.StringUtils; +import org.sonar.api.CoreProperties; import java.io.File; @@ -33,6 +34,8 @@ import java.io.File; * </ol> * * @since 2.12 + * + * TODO Delete it as it's now useless (SONAR_HOME is set by Tomcat) */ final class SonarHome { @@ -40,12 +43,10 @@ final class SonarHome { // only static methods } - static final String SONAR_HOME = "SONAR_HOME"; - static Supplier<File> homeSupplier = Suppliers.memoize(new Supplier<File>() { public File get() { File home = locate(); - System.setProperty(SONAR_HOME, home.getAbsolutePath()); + System.setProperty(CoreProperties.SONAR_HOME, home.getAbsolutePath()); return home; } }); @@ -55,19 +56,19 @@ final class SonarHome { } static File locate() { - String value = System.getProperty(SONAR_HOME); + String value = System.getProperty(CoreProperties.SONAR_HOME); if (StringUtils.isBlank(value)) { - value = System.getenv(SONAR_HOME); + value = System.getenv(CoreProperties.SONAR_HOME); } if (StringUtils.isBlank(value)) { - throw new IllegalStateException("The system property or env variable " + SONAR_HOME + " is not set"); + throw new IllegalStateException("The system property or env variable " + CoreProperties.SONAR_HOME + " is not set"); } File dir = new File(value); if (!dir.isDirectory() || !dir.exists()) { - throw new IllegalStateException(SONAR_HOME + " is not valid: " + value + ". Please fix the env variable/system " + - "property " + SONAR_HOME); + throw new IllegalStateException(CoreProperties.SONAR_HOME + " is not valid: " + value + ". Please fix the env variable/system " + + "property " + CoreProperties.SONAR_HOME); } return dir; } diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/BatchResourcesServlet.java b/sonar-server/src/main/java/org/sonar/server/plugins/BatchResourcesServlet.java deleted file mode 100644 index bcb7546ed08..00000000000 --- a/sonar-server/src/main/java/org/sonar/server/plugins/BatchResourcesServlet.java +++ /dev/null @@ -1,95 +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.server.plugins; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.server.startup.GenerateBootstrapIndex; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; - -/** - * This servlet allows to load libraries from directory "WEB-INF/lib" in order to provide them for batch-bootstrapper. - * Most probably this is not a best solution. - */ -public class BatchResourcesServlet extends HttpServlet { - - private static final Logger LOG = LoggerFactory.getLogger(BatchResourcesServlet.class); - private static final long serialVersionUID = -2100128371794649028L; - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - String filename = filename(request); - if (StringUtils.isBlank(filename)) { - PrintWriter writer = null; - try { - response.setContentType("text/plain"); - writer = response.getWriter(); - writer.print(StringUtils.join(GenerateBootstrapIndex.getLibs(getServletContext()), ',')); - } catch (IOException e) { - LOG.error("Unable to provide list of batch resources", e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } finally { - IOUtils.closeQuietly(writer); - } - } else { - InputStream in = null; - OutputStream out = null; - try { - in = getServletContext().getResourceAsStream("/WEB-INF/lib/" + filename); - if (in == null) { - // TODO - } else { - response.setContentType("application/java-archive"); - out = response.getOutputStream(); - IOUtils.copy(in, out); - } - } catch (Exception e) { - LOG.error("Unable to load batch resource '" + filename + "'", e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } finally { - IOUtils.closeQuietly(in); - IOUtils.closeQuietly(out); - } - } - } - - /** - * @return part of request URL after servlet path - */ - String filename(HttpServletRequest request) { - String filename = null; - if (StringUtils.endsWithIgnoreCase(request.getRequestURI(), "jar")) { - filename = StringUtils.substringAfterLast(request.getRequestURI(), "/"); - } - return filename; - } - -} diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/BatchWs.java b/sonar-server/src/main/java/org/sonar/server/plugins/BatchWs.java new file mode 100644 index 00000000000..25c4cc91746 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/plugins/BatchWs.java @@ -0,0 +1,122 @@ +/* + * 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.server.plugins; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.filefilter.FileFilterUtils; +import org.apache.commons.io.filefilter.HiddenFileFilter; +import org.apache.commons.lang.CharUtils; +import org.apache.commons.lang.StringUtils; +import org.picocontainer.Startable; +import org.sonar.api.platform.Server; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.RequestHandler; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.home.cache.FileHashes; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; + +/** + * JAR files to be downloaded by sonar-runner. + */ +public class BatchWs implements WebService, Startable { + + private final Server server; + private String index; + private File batchDir; + + public BatchWs(Server server) { + this.server = server; + } + + @Override + public void start() { + StringBuilder sb = new StringBuilder(); + batchDir = new File(server.getRootDir(), "lib/batch"); + if (batchDir.exists()) { + Collection<File> files = FileUtils.listFiles(batchDir, HiddenFileFilter.VISIBLE, FileFilterUtils.directoryFileFilter()); + for (File file : files) { + String filename = file.getName(); + if (StringUtils.endsWith(filename, ".jar")) { + sb.append(filename).append('|').append(new FileHashes().of(file)).append(CharUtils.LF); + } + } + } + this.index = sb.toString(); + } + + @Override + public void stop() { + // nothing to do + } + + @Override + public void define(Context context) { + NewController controller = context.createController("batch"); + controller.createAction("index") + .setInternal(true) + .setDescription("List the JAR files to be downloaded by source analyzer") + .setHandler(new RequestHandler() { + @Override + public void handle(Request request, Response response) { + index(response); + } + }); + controller.createAction("file") + .setInternal(true) + .setDescription("Download a JAR file required by source analyzer") + .setHandler(new RequestHandler() { + @Override + public void handle(Request request, Response response) { + file(request, response); + } + }).createParam("name", "Filename"); + + controller.done(); + } + + private void index(Response response) { + try { + response.stream().setMediaType("text/plain"); + IOUtils.write(index, response.stream().output()); + } catch (IOException e) { + throw new IllegalStateException("Fail to send batch index", e); + } + } + + private void file(Request request, Response response) { + String filename = request.mandatoryParam("name"); + try { + File input = new File(batchDir, filename); + if (!input.exists() || !FileUtils.directoryContains(batchDir, input)) { + throw new IllegalArgumentException("Bad filename: " + filename); + } + response.stream().setMediaType("application/java-archive"); + FileUtils.copyFile(input, response.stream().output()); + + } catch (IOException e) { + throw new IllegalStateException("Fail to send batch file " + filename, e); + } + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWs.java b/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWs.java index 33187d35072..18af6b9758c 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWs.java +++ b/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWs.java @@ -43,6 +43,7 @@ public class RulesWs implements WebService { controller.createAction("list") .setDescription("List rules that match the given criteria") .setSince("4.3") + .setInternal(true) .setHandler(searchHandler) .createParam("s", "An optional query that will be matched against rule titles.") .createParam("k", "An optional query that will be matched exactly agains rule keys.") diff --git a/sonar-server/src/main/java/org/sonar/server/source/CodeColorizers.java b/sonar-server/src/main/java/org/sonar/server/source/CodeColorizers.java index 16509e8b9da..67803e8a6e5 100644 --- a/sonar-server/src/main/java/org/sonar/server/source/CodeColorizers.java +++ b/sonar-server/src/main/java/org/sonar/server/source/CodeColorizers.java @@ -19,6 +19,7 @@ */ package org.sonar.server.source; +import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import org.sonar.api.ServerExtension; import org.sonar.api.utils.Logs; @@ -49,6 +50,13 @@ public class CodeColorizers implements ServerExtension { Logs.INFO.info("Code colorizer, supported languages: " + StringUtils.join(byLang.keySet(), ",")); } + /** + * Used when no plugin is defining some CodeColorizerFormat + */ + public CodeColorizers() { + this(Lists.<CodeColorizerFormat>newArrayList()); + } + public String toHtml(String code, String language) { CodeColorizerFormat format = byLang.get(language); List<Tokenizer> tokenizers; diff --git a/sonar-server/src/main/java/org/sonar/server/startup/GenerateBootstrapIndex.java b/sonar-server/src/main/java/org/sonar/server/startup/GenerateBootstrapIndex.java deleted file mode 100644 index 70def7e35b0..00000000000 --- a/sonar-server/src/main/java/org/sonar/server/startup/GenerateBootstrapIndex.java +++ /dev/null @@ -1,102 +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.server.startup; - -import com.google.common.collect.Lists; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.CharUtils; -import org.apache.commons.lang.StringUtils; -import org.sonar.home.cache.FileHashes; -import org.sonar.server.platform.DefaultServerFileSystem; - -import javax.servlet.ServletContext; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Set; - -/** - * @since 3.5 - */ -public final class GenerateBootstrapIndex { - - // JARs starting with one of these prefixes are excluded from batch - private static final String[] IGNORE = {"jtds", "mysql", "postgresql", "jruby", "jfreechart", "eastwood", - "elasticsearch", "lucene"}; - - private final ServletContext servletContext; - private final DefaultServerFileSystem fileSystem; - - public GenerateBootstrapIndex(DefaultServerFileSystem fileSystem, ServletContext servletContext) { - this.servletContext = servletContext; - this.fileSystem = fileSystem; - } - - public void start() throws IOException { - writeIndex(fileSystem.getBootstrapIndex()); - } - - void writeIndex(File indexFile) throws IOException { - FileUtils.forceMkdir(indexFile.getParentFile()); - FileWriter writer = new FileWriter(indexFile, false); - try { - for (String path : getLibs(servletContext)) { - writer.append(path); - InputStream is = servletContext.getResourceAsStream("/WEB-INF/lib/" + path); - writer.append("|").append(new FileHashes().of(is)); - writer.append(CharUtils.LF); - } - writer.flush(); - - } finally { - IOUtils.closeQuietly(writer); - } - } - - public static List<String> getLibs(ServletContext servletContext) { - List<String> libs = Lists.newArrayList(); - Set<String> paths = servletContext.getResourcePaths("/WEB-INF/lib/"); - for (String path : paths) { - if (StringUtils.endsWith(path, ".jar")) { - String filename = StringUtils.removeStart(path, "/WEB-INF/lib/"); - if (!isIgnored(filename)) { - libs.add(filename); - } - } - } - return libs; - } - - /** - * Dirty hack to disable downloading for certain files. - */ - static boolean isIgnored(String filename) { - for (String prefix : IGNORE) { - if (StringUtils.startsWith(filename, prefix)) { - return true; - } - } - return false; - } -} diff --git a/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java b/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java index 8980988255b..a69b50a758c 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java @@ -19,17 +19,18 @@ */ package org.sonar.server.startup; +import com.google.common.annotations.VisibleForTesting; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.config.Settings; +import org.sonar.api.platform.Server; import org.sonar.api.utils.Logs; import org.sonar.api.utils.SonarException; import org.sonar.api.utils.TimeProfiler; import org.sonar.api.utils.ZipUtils; import org.sonar.api.web.GwtExtension; -import org.sonar.server.platform.ServerSettings; import java.io.File; import java.io.IOException; @@ -41,15 +42,23 @@ import java.util.zip.ZipEntry; public class GwtPublisher { private static final Logger LOG = LoggerFactory.getLogger(GwtPublisher.class); - private Settings settings; + private Server server; private GwtExtension[] extensions = null; private File outputDir = null; - public GwtPublisher(GwtExtension[] extensions, Settings settings) { + public GwtPublisher(GwtExtension[] extensions, Settings settings, Server server) { this.extensions = extensions; - this.settings = settings; + this.server = server; } + /** + * Used when no plugin is defining some GwtExtension + */ + public GwtPublisher(Settings settings, Server server) { + this(new GwtExtension[]{}, settings, server); + } + + @VisibleForTesting GwtPublisher(GwtExtension[] extensions, File outputDir) { this.extensions = extensions; this.outputDir = outputDir; @@ -62,7 +71,7 @@ public class GwtPublisher { TimeProfiler profiler = new TimeProfiler().start("Deploy GWT plugins"); try { cleanDirectory(); - this.outputDir = new File(settings.getString(ServerSettings.DEPLOY_DIR), "gwt"); + this.outputDir = new File(server.getDeployDir(), "gwt"); LoggerFactory.getLogger(GwtPublisher.class).debug("Deploy {} GWT extensions to {}", extensions.length, outputDir); publish(); diff --git a/sonar-server/src/main/java/org/sonar/server/startup/JdbcDriverDeployer.java b/sonar-server/src/main/java/org/sonar/server/startup/JdbcDriverDeployer.java index 141cc2e1261..bb8ee65f373 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/JdbcDriverDeployer.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/JdbcDriverDeployer.java @@ -23,6 +23,8 @@ import org.apache.commons.io.FileUtils; import org.sonar.home.cache.FileHashes; import org.sonar.server.platform.DefaultServerFileSystem; +import javax.annotation.Nullable; + import java.io.File; import java.io.IOException; @@ -35,22 +37,35 @@ public class JdbcDriverDeployer { } public void start() { + File deployedDriver = null; File driver = fileSystem.getJdbcDriver(); - File deployedDriver = new File(fileSystem.getDeployDir(), driver.getName()); - if (!deployedDriver.exists() || deployedDriver.length() != driver.length()) { - try { - FileUtils.copyFile(driver, deployedDriver); + // Driver can be null for H2, in that case we write an empty jdbc-driver.txt file + if (driver != null) { + deployedDriver = new File(fileSystem.getDeployDir(), driver.getName()); + if (!deployedDriver.exists() || deployedDriver.length() != driver.length()) { + try { + FileUtils.copyFile(driver, deployedDriver); - } catch (IOException e) { - throw new IllegalStateException("Can not copy the JDBC driver from " + driver + " to " + deployedDriver, e); + } catch (IOException e) { + throw new IllegalStateException("Can not copy the JDBC driver from " + driver + " to " + deployedDriver, e); + } } } + File deployedDriverIndex = fileSystem.getDeployedJdbcDriverIndex(); try { - String hash = new FileHashes().of(deployedDriver); - FileUtils.writeStringToFile(deployedDriverIndex, deployedDriver.getName() + "|" + hash); + FileUtils.writeStringToFile(deployedDriverIndex, driverIndexContent(deployedDriver)); } catch (IOException e) { throw new IllegalStateException("Can not generate index of JDBC driver", e); } } + + private String driverIndexContent(@Nullable File deployedDriver){ + if (deployedDriver != null) { + String hash = new FileHashes().of(deployedDriver); + return deployedDriver.getName() + "|" + hash; + } + return ""; + } + } diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterDashboards.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterDashboards.java index 11f85d0e53d..317e08d9a47 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/RegisterDashboards.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterDashboards.java @@ -57,6 +57,13 @@ public class RegisterDashboards implements Startable { this.loadedTemplateDao = loadedTemplateDao; } + /** + * Used when no plugin is defining some DashboardTemplate + */ + public RegisterDashboards(DashboardDao dashboardDao, ActiveDashboardDao activeDashboardDao, LoadedTemplateDao loadedTemplateDao) { + this(new DashboardTemplate[]{}, dashboardDao, activeDashboardDao, loadedTemplateDao); + } + @Override public void start() { TimeProfiler profiler = new TimeProfiler(LOG).start("Register dashboards"); diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java index 689348d9ca0..5e5b6cfc582 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterMetrics.java @@ -51,6 +51,13 @@ public class RegisterMetrics { this.conditionDao = conditionDao; } + /** + * Used when no plugin is defining Metrics + */ + public RegisterMetrics(MeasuresDao measuresDao, QualityGateConditionDao conditionDao) { + this(measuresDao, conditionDao, new Metrics[]{}); + } + public void start() { TimeProfiler profiler = new TimeProfiler().start("Load metrics"); measuresDao.disableAutomaticMetrics(); diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewMeasureFilters.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewMeasureFilters.java index e2c8574b838..755a1eed6a6 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewMeasureFilters.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterNewMeasureFilters.java @@ -54,6 +54,13 @@ public final class RegisterNewMeasureFilters { this.loadedTemplateDao = loadedTemplateDao; } + /** + * Used when no plugin is defining some FilterTemplate + */ + public RegisterNewMeasureFilters(MeasureFilterDao filterDao, LoadedTemplateDao loadedTemplateDao) { + this(new FilterTemplate[]{}, filterDao, loadedTemplateDao); + } + public void start() { TimeProfiler profiler = new TimeProfiler(LOG).start("Register measure filters"); diff --git a/sonar-server/src/main/java/org/sonar/server/text/MacroInterpreter.java b/sonar-server/src/main/java/org/sonar/server/text/MacroInterpreter.java index 0f8c60ac335..0971feae8a0 100644 --- a/sonar-server/src/main/java/org/sonar/server/text/MacroInterpreter.java +++ b/sonar-server/src/main/java/org/sonar/server/text/MacroInterpreter.java @@ -22,17 +22,17 @@ package org.sonar.server.text; import com.google.common.collect.ImmutableList; import org.sonar.api.ServerComponent; +import org.sonar.api.platform.Server; -import javax.servlet.ServletContext; import java.util.List; public class MacroInterpreter implements ServerComponent { private final List<Macro> macros; - public MacroInterpreter(ServletContext servletContext) { + public MacroInterpreter(Server server) { this.macros = ImmutableList.<Macro>of( - new RuleMacro(servletContext.getContextPath()) + new RuleMacro(server.getContextPath()) ); } diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index f480f7447ca..b3f764ebc58 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -46,7 +46,10 @@ import org.sonar.core.resource.ResourceIndexerDao; import org.sonar.core.resource.ResourceKeyUpdaterDao; import org.sonar.core.timemachine.Periods; import org.sonar.server.db.migrations.DatabaseMigrator; -import org.sonar.server.platform.*; +import org.sonar.server.platform.Platform; +import org.sonar.server.platform.ServerIdGenerator; +import org.sonar.server.platform.ServerSettings; +import org.sonar.server.platform.SettingsChangeNotifier; import org.sonar.server.plugins.*; import org.sonar.server.rule.RuleRepositories; import org.sonar.server.source.CodeColorizers; @@ -57,7 +60,7 @@ import org.sonar.updatecenter.common.Version; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.io.IOException; + import java.net.InetAddress; import java.sql.Connection; import java.util.Collection; @@ -233,6 +236,7 @@ public final class JRubyFacade { return get(Database.class); } + // Only used by Java migration public DatabaseMigrator databaseMigrator() { return get(DatabaseMigrator.class); } @@ -369,10 +373,6 @@ public final class JRubyFacade { return Platform.getInstance().getContainer(); } - public String boostrapIndexPath() throws IOException { - return getContainer().getComponentByType(DefaultServerFileSystem.class).getBootstrapIndex().getCanonicalPath(); - } - // UPDATE PROJECT KEY ------------------------------------------------------------------ public void updateResourceKey(long projectId, String newKey) { get(ResourceKeyUpdaterDao.class).updateKey(projectId, newKey); diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb index e8e7f802538..a12fb2fbc52 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb @@ -90,11 +90,6 @@ class BatchBootstrapController < Api::ApiController render :json => JSON(json_properties) end - # GET /batch_bootstrap/index - def index - render :file => java_facade.boostrapIndexPath(), :layout => false - end - private def render_unauthorized(message, status=403) diff --git a/sonar-server/src/main/webapp/WEB-INF/config/routes.rb b/sonar-server/src/main/webapp/WEB-INF/config/routes.rb index 2a04f24fd55..72dbd1eb08b 100644 --- a/sonar-server/src/main/webapp/WEB-INF/config/routes.rb +++ b/sonar-server/src/main/webapp/WEB-INF/config/routes.rb @@ -14,6 +14,11 @@ ActionController::Routing::Routes.draw do |map| end map.connect 'api', :controller => 'api/java_ws', :action => 'redirect_to_ws_listing' + + # deprecated, sonar-runner should use batch/index and batch/file?name=xxx + map.connect 'batch_bootstrap/index', :controller => 'api/java_ws', :action => 'index', :wspath => 'batch', :wsaction => 'index' + map.connect 'batch/:name', :controller => 'api/java_ws', :action => 'index', :wspath => 'batch', :wsaction => 'file', :requirements => { :name => /.*/ } + map.connect 'api/metrics', :controller => 'api/metrics', :action => 'index', :conditions => { :method => :get } map.connect 'api/metrics/:id', :controller => 'api/metrics', :action => 'show', :conditions => { :method => :get } map.connect 'api/metrics/:id', :controller => 'api/metrics', :action => 'create', :conditions => { :method => :post } diff --git a/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb b/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb index eec43b43741..24415ce1c0e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb +++ b/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb @@ -70,7 +70,6 @@ class DatabaseVersion def self.automatic_setup if current_version<=0 - try_restore_structure_dump() upgrade_and_start() elsif uptodate? load_java_web_services @@ -84,20 +83,6 @@ class DatabaseVersion ActiveRecord::Base.connected? end - def self.try_restore_structure_dump() - ::Java::OrgSonarServerUi::JRubyFacade.getInstance().databaseMigrator().createDatabase() - end - - def self.execute_sql_requests(requests) - requests.each do |request| - unless request.blank? || request.start_with?('--') - request.chomp! - request.chop! if request.end_with?(';') - ActiveRecord::Base.connection.execute(request) - end - end - end - def self.dialect ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getDialect().getActiveRecordDialectCode() end diff --git a/sonar-server/src/main/webapp/WEB-INF/web.xml b/sonar-server/src/main/webapp/WEB-INF/web.xml index 1dff5cbff4c..b4896f15c56 100644 --- a/sonar-server/src/main/webapp/WEB-INF/web.xml +++ b/sonar-server/src/main/webapp/WEB-INF/web.xml @@ -90,10 +90,6 @@ <servlet-name>static</servlet-name> <servlet-class>org.sonar.server.plugins.StaticResourcesServlet</servlet-class> </servlet> - <servlet> - <servlet-name>batch</servlet-name> - <servlet-class>org.sonar.server.plugins.BatchResourcesServlet</servlet-class> - </servlet> <servlet-mapping> <servlet-name>chart</servlet-name> @@ -107,10 +103,6 @@ <servlet-name>static</servlet-name> <url-pattern>/static/*</url-pattern> </servlet-mapping> - <servlet-mapping> - <servlet-name>batch</servlet-name> - <url-pattern>/batch/*</url-pattern> - </servlet-mapping> <session-config> <!-- in minutes --> diff --git a/sonar-server/src/test/java/org/sonar/server/platform/DefaultServerFileSystemTest.java b/sonar-server/src/test/java/org/sonar/server/platform/DefaultServerFileSystemTest.java index dd97bd9b638..8f22e23a815 100644 --- a/sonar-server/src/test/java/org/sonar/server/platform/DefaultServerFileSystemTest.java +++ b/sonar-server/src/test/java/org/sonar/server/platform/DefaultServerFileSystemTest.java @@ -23,14 +23,14 @@ import org.junit.Test; import org.sonar.api.platform.ServerFileSystem; import org.sonar.core.persistence.Database; import org.sonar.core.persistence.dialect.Dialect; +import org.sonar.core.persistence.dialect.H2; import org.sonar.core.persistence.dialect.MySql; import org.sonar.test.TestUtils; import java.io.File; import java.util.List; -import static junit.framework.Assert.assertNotNull; -import static org.junit.Assert.assertEquals; +import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -39,15 +39,22 @@ public class DefaultServerFileSystemTest { private static final String PATH = "/org/sonar/server/platform/DefaultServerFileSystemTest/"; @Test - public void testGetJdbcDriver() { + public void get_jdbc_driver() { Database database = mock(Database.class); when(database.getDialect()).thenReturn(new MySql()); File driver = new DefaultServerFileSystem(database, TestUtils.getResource(PATH + "testGetJdbcDriver"), null).getJdbcDriver(); - assertNotNull(driver); + assertThat(driver).isNotNull(); + } + + @Test + public void get_jdbc_driver_return_null_when_h2() { + Database database = mock(Database.class); + when(database.getDialect()).thenReturn(new H2()); + assertThat(new DefaultServerFileSystem(database, (File) null, null).getJdbcDriver()).isNull(); } @Test(expected = IllegalStateException.class) - public void failIfJdbcDriverNotFound() { + public void fail_if_jdbc_driver_not_found() { Database database = mock(Database.class); Dialect fakeDialect = mock(Dialect.class); @@ -58,40 +65,40 @@ public class DefaultServerFileSystemTest { } @Test - public void shouldFindPlugins() { + public void find_plugins() { List<File> plugins = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldFindPlugins"), null).getUserPlugins(); - assertEquals(2, plugins.size()); + assertThat(plugins).hasSize(2); } @Test - public void shouldNotFailIfNoPlugins() { + public void not_fail_if_no_plugins() { List<File> plugins = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldNotFailIfNoPlugins"), null).getUserPlugins(); - assertEquals(0, plugins.size()); + assertThat(plugins).isEmpty(); } @Test - public void shouldFindCheckstyleExtensions() { + public void find_checkstyle_extensions() { ServerFileSystem fs = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldFindCheckstyleExtensions"), null); List<File> xmls = fs.getExtensions("checkstyle", "xml"); - assertEquals(1, xmls.size()); + assertThat(xmls).hasSize(1); List<File> all = fs.getExtensions("checkstyle"); - assertEquals(3, all.size()); + assertThat(all).hasSize(3); } @Test - public void shouldNotFailIfNoCheckstyleExtensions() { + public void not_fail_if_no_checkstyle_extensions() { ServerFileSystem fs = new DefaultServerFileSystem(null, TestUtils.getResource(PATH + "shouldNotFailIfNoCheckstyleExtensions"), null); List<File> xmls = fs.getExtensions("checkstyle", "xml"); - assertEquals(0, xmls.size()); + assertThat(xmls).isEmpty(); List<File> jars = fs.getExtensions("checkstyle"); - assertEquals(0, jars.size()); + assertThat(jars).isEmpty(); } @Test(expected = IllegalStateException.class) - public void shouldFailIfHomeDirectoryNotExists() { + public void fail_if_home_directory_not_exists() { DefaultServerFileSystem fs = new DefaultServerFileSystem(null, new File("/notexists"), null); fs.start(); } diff --git a/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java b/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java index cc6f008d474..3612c104526 100644 --- a/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java @@ -28,9 +28,9 @@ import org.sonar.api.config.PropertyDefinitions; import org.sonar.core.properties.PropertiesDao; import org.sonar.core.properties.PropertyDto; -import java.io.File; import java.net.URISyntaxException; import java.util.Arrays; +import java.util.Properties; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Matchers.argThat; @@ -44,11 +44,11 @@ public class PersistentSettingsTest { @Before public void init() throws URISyntaxException { dao = mock(PropertiesDao.class); + settings = new ServerSettings( new PropertyDefinitions(), new PropertiesConfiguration(), - new File("."), - new File(PersistentSettingsTest.class.getResource("/org/sonar/server/platform/PersistentSettingsTest/").toURI())); + new Properties()); } @Test diff --git a/sonar-server/src/test/java/org/sonar/server/platform/ServerImplTest.java b/sonar-server/src/test/java/org/sonar/server/platform/ServerImplTest.java index 2101db16a78..44954c85fb6 100644 --- a/sonar-server/src/test/java/org/sonar/server/platform/ServerImplTest.java +++ b/sonar-server/src/test/java/org/sonar/server/platform/ServerImplTest.java @@ -20,22 +20,41 @@ package org.sonar.server.platform; import org.hamcrest.core.Is; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; +import java.io.File; + import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertThat; public class ServerImplTest { + @Rule public ExpectedException exception = ExpectedException.none(); + @Rule + public TemporaryFolder sonarHome = new TemporaryFolder(); + + Settings settings; + + ServerImpl server; + + @Before + public void setUp() throws Exception { + settings = new Settings().setProperty(CoreProperties.SONAR_HOME, sonarHome.getRoot().getAbsolutePath()); + new File(sonarHome.getRoot(), "web/deploy").mkdirs(); + + server = new ServerImpl(settings, "/org/sonar/server/platform/ServerImplTest/build.properties", "/org/sonar/server/platform/ServerImplTest/version.txt"); + } + @Test - public void alwaysReturnTheSameValues() { - ServerImpl server = new ServerImpl(new Settings(), "", "/org/sonar/server/platform/ServerImplTest/pom-with-version.properties"); + public void always_return_the_same_values() { server.start(); assertThat(server.getId()).isNotNull(); @@ -49,52 +68,48 @@ public class ServerImplTest { } @Test - public void getVersionFromFile() { - ServerImpl server = new ServerImpl(new Settings(), "", "/org/sonar/server/platform/ServerImplTest/pom-with-version.properties"); + public void read_version_from_file() { server.start(); assertThat(server.getVersion()).isEqualTo("1.0"); } @Test - public void getImplementationBuildFromManifest() { - ServerImpl server = new ServerImpl(new Settings(), - "/org/sonar/server/platform/ServerImplTest/build.properties", - "/org/sonar/server/platform/ServerImplTest/pom-with-version.properties"); + public void read_implementation_build_from_manifest() { server.start(); assertThat(server.getImplementationBuild()).isEqualTo("0b9545a8b74aca473cb776275be4dc93a327c363"); } @Test - public void testFileWithNoVersion() { + public void read_file_with_no_version() { exception.expect(IllegalStateException.class); exception.expectMessage("Unknown SonarQube version"); - ServerImpl server = new ServerImpl(new Settings(), "", "/org/sonar/server/platform/ServerImplTest/pom-without-version.properties"); + ServerImpl server = new ServerImpl(settings, "", "/org/sonar/server/platform/ServerImplTest/empty-version.txt"); server.start(); } @Test - public void testFileWithEmptyVersionParameter() { + public void read_file_with_empty_version() { exception.expect(IllegalStateException.class); exception.expectMessage("Unknown SonarQube version"); - ServerImpl server = new ServerImpl(new Settings(), "", "/org/sonar/server/platform/ServerImplTest/pom-with-empty-version.properties"); + ServerImpl server = new ServerImpl(settings, "", "/org/sonar/server/platform/ServerImplTest/empty-version.txt"); server.start(); } @Test - public void shouldFailIfFileNotFound() { + public void fail_if_version_file_not_found() { exception.expect(IllegalStateException.class); exception.expectMessage("Unknown SonarQube version"); - ServerImpl server = new ServerImpl(new Settings(), "", "/org/sonar/server/platform/ServerImplTest/unknown-file.properties"); + ServerImpl server = new ServerImpl(settings, "", "/org/sonar/server/platform/ServerImplTest/unknown-file.properties"); server.start(); } @Test - public void shouldLoadServerIdFromDatabase() { + public void load_server_id_from_database() { Settings settings = new Settings(); settings.setProperty(CoreProperties.PERMANENT_SERVER_ID, "abcde"); @@ -102,4 +117,18 @@ public class ServerImplTest { assertThat(server.getPermanentServerId(), Is.is("abcde")); } + + @Test + public void use_default_context_path() { + server.start(); + assertThat(server.getContextPath()).isEqualTo("/"); + } + + @Test + public void get_context_path_from_settings() { + settings.setProperty("sonar.web.context", "/my_path"); + server.start(); + assertThat(server.getContextPath()).isEqualTo("/my_path"); + } + } diff --git a/sonar-server/src/test/java/org/sonar/server/platform/ServerLifecycleNotifierTest.java b/sonar-server/src/test/java/org/sonar/server/platform/ServerLifecycleNotifierTest.java index 4acb5baf2ce..8907b3e6d5d 100644 --- a/sonar-server/src/test/java/org/sonar/server/platform/ServerLifecycleNotifierTest.java +++ b/sonar-server/src/test/java/org/sonar/server/platform/ServerLifecycleNotifierTest.java @@ -21,10 +21,11 @@ package org.sonar.server.platform; import org.junit.Before; import org.junit.Test; +import org.sonar.api.platform.Server; import org.sonar.api.platform.ServerStartHandler; import org.sonar.api.platform.ServerStopHandler; -import org.sonar.api.platform.Server; +import java.io.File; import java.util.Date; import static org.mockito.Mockito.*; @@ -100,6 +101,21 @@ class FakeServer extends Server { } @Override + public File getRootDir() { + return null; + } + + @Override + public File getDeployDir() { + return null; + } + + @Override + public String getContextPath() { + return null; + } + + @Override public String getURL() { return null; } diff --git a/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java b/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java index 4b7ef9b0edf..af0cc558e8f 100644 --- a/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java @@ -21,44 +21,37 @@ package org.sonar.server.platform; import com.google.common.collect.ImmutableMap; import org.apache.commons.configuration.BaseConfiguration; +import org.junit.Before; import org.junit.Test; import org.sonar.api.config.PropertyDefinitions; -import java.io.File; -import java.net.URISyntaxException; import java.util.Map; +import java.util.Properties; import static org.fest.assertions.Assertions.assertThat; public class ServerSettingsTest { - private static File home = getHome(); + Properties properties; - @Test - public void load_properties_file() { - ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home); + ServerSettings settings; - assertThat(settings.getString("hello")).isEqualTo("world"); + @Before + public void before() throws Exception { + properties = new Properties(); + properties.put("hello", "world"); + properties.put("in_file", "true"); + properties.put("ServerSettingsTestEnv", "in_file"); + settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), properties); } @Test - public void systemPropertiesShouldOverridePropertiesFile() { - System.setProperty("ServerSettingsTestEnv", "in_env"); - ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home); - - assertThat(settings.getString("ServerSettingsTestEnv")).isEqualTo("in_env"); - } - - @Test(expected = IllegalStateException.class) - public void fail_if_properties_file_is_not_found() { - File sonarHome = new File("unknown/path"); - new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), sonarHome); + public void load_properties_file() { + assertThat(settings.getString("hello")).isEqualTo("world"); } @Test - public void activateDatabaseSettings() { - ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home); - + public void activate_database_settings() { Map<String, String> databaseProperties = ImmutableMap.of("in_db", "true"); settings.activateDatabaseSettings(databaseProperties); @@ -67,7 +60,6 @@ public class ServerSettingsTest { @Test public void file_settings_override_db_settings() { - ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home); assertThat(settings.getString("in_file")).isEqualTo("true"); Map<String, String> databaseProperties = ImmutableMap.of("in_file", "false"); @@ -79,7 +71,7 @@ public class ServerSettingsTest { @Test public void synchronize_deprecated_commons_configuration() { BaseConfiguration deprecated = new BaseConfiguration(); - ServerSettings settings = new ServerSettings(new PropertyDefinitions(), deprecated, new File("."), home); + ServerSettings settings = new ServerSettings(new PropertyDefinitions(), deprecated, properties); assertThat(settings.getString("in_file")).isEqualTo("true"); assertThat(deprecated.getString("in_file")).isEqualTo("true"); @@ -90,12 +82,4 @@ public class ServerSettingsTest { settings.removeProperty("foo"); assertThat(deprecated.getString("foo")).isNull(); } - - private static File getHome() { - try { - return new File(ServerSettingsTest.class.getResource("/org/sonar/server/platform/ServerSettingsTest/").toURI()); - } catch (URISyntaxException e) { - throw new IllegalStateException(e); - } - } } diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/BatchResourcesServletTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/BatchResourcesServletTest.java deleted file mode 100644 index 0ad48616e6b..00000000000 --- a/sonar-server/src/test/java/org/sonar/server/plugins/BatchResourcesServletTest.java +++ /dev/null @@ -1,62 +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.server.plugins; - -import org.junit.Before; -import org.junit.Test; - -import javax.servlet.http.HttpServletRequest; - -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class BatchResourcesServletTest { - private BatchResourcesServlet servlet; - private HttpServletRequest request; - - @Before - public void setUp() throws Exception { - servlet = new BatchResourcesServlet(); - request = mock(HttpServletRequest.class); - } - - @Test - public void test_filename() { - when(request.getContextPath()).thenReturn("sonar"); - when(request.getServletPath()).thenReturn("/batch"); - - when(request.getRequestURI()).thenReturn("/sonar/batch/sonar-core-2.6.jar"); - assertThat(servlet.filename(request)).isEqualTo("sonar-core-2.6.jar"); - - when(request.getRequestURI()).thenReturn("/sonar/batch/"); - assertThat(servlet.filename(request)).isNull(); - - when(request.getRequestURI()).thenReturn("/sonar/batch"); - assertThat(servlet.filename(request)).isNull(); - - when(request.getRequestURI()).thenReturn("/sonar/batch.html"); - assertThat(servlet.filename(request)).isNull(); - - when(request.getRequestURI()).thenReturn("/sonar/batch/index.html"); - assertThat(servlet.filename(request)).isNull(); - } - -} diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/BatchWsTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/BatchWsTest.java new file mode 100644 index 00000000000..d20d346180d --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/plugins/BatchWsTest.java @@ -0,0 +1,108 @@ +/* + * 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.server.plugins; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.CharUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.platform.Server; +import org.sonar.api.server.ws.WsTester; + +import java.io.File; +import java.io.IOException; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class BatchWsTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + Server server = mock(Server.class); + + @Before + public void prepare_fs() throws IOException { + File rootDir = temp.newFolder(); + when(server.getRootDir()).thenReturn(rootDir); + + File batchDir = new File(rootDir, "lib/batch"); + FileUtils.forceMkdir(batchDir); + FileUtils.writeStringToFile(new File(batchDir, "sonar-batch.jar"), "foo"); + } + + @Test + public void download_index() throws Exception { + BatchWs ws = new BatchWs(server); + ws.start(); + WsTester tester = new WsTester(ws); + + String index = tester.newRequest("index").execute().outputAsString(); + assertThat(index).isEqualTo("sonar-batch.jar|acbd18db4cc2f85cedef654fccc4a4d8" + CharUtils.LF); + + ws.stop(); + } + + @Test + public void download_file() throws Exception { + BatchWs ws = new BatchWs(server); + ws.start(); + WsTester tester = new WsTester(ws); + + String jar = tester.newRequest("file").setParam("name", "sonar-batch.jar").execute().outputAsString(); + assertThat(jar).isEqualTo("foo"); + } + + /** + * Do not allow to download files located outside the directory lib/batch, for example + * /etc/passwd + */ + @Test + public void check_location_of_file() throws Exception { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Bad filename: ../sonar-batch.jar"); + + BatchWs ws = new BatchWs(server); + ws.start(); + WsTester tester = new WsTester(ws); + + tester.newRequest("file").setParam("name", "../sonar-batch.jar").execute(); + } + + @Test + public void file_does_not_exist() throws Exception { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Bad filename: other.jar"); + + BatchWs ws = new BatchWs(server); + ws.start(); + WsTester tester = new WsTester(ws); + + tester.newRequest("file").setParam("name", "other.jar").execute(); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarsInstallerTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarsInstallerTest.java index caf2b8f7acc..c5404935d8d 100644 --- a/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarsInstallerTest.java +++ b/sonar-server/src/test/java/org/sonar/server/plugins/ServerPluginJarsInstallerTest.java @@ -50,7 +50,7 @@ public class ServerPluginJarsInstallerTest { public TemporaryFolder temp = new TemporaryFolder(); DefaultServerFileSystem fileSystem; - File homeDir, deployDir, pluginsDir, downloadsDir, bundledDir, trashDir, coreDir; + File homeDir, pluginsDir, downloadsDir, bundledDir, trashDir, coreDir; ServerPluginJarInstaller jarInstaller; ServerPluginJarsInstaller jarsInstaller; Server server = mock(Server.class); @@ -59,6 +59,8 @@ public class ServerPluginJarsInstallerTest { @Before public void before() throws IOException { when(server.getVersion()).thenReturn("3.1"); + when(server.getDeployDir()).thenReturn(temp.newFolder("deploy")); + homeDir = temp.newFolder("home"); pluginsDir = new File(homeDir, "extensions/plugins"); FileUtils.forceMkdir(pluginsDir); @@ -67,8 +69,8 @@ public class ServerPluginJarsInstallerTest { bundledDir = new File(homeDir, "lib/bundled-plugins"); coreDir = new File(homeDir, "lib/core-plugins"); FileUtils.forceMkdir(bundledDir); - deployDir = temp.newFolder("deploy"); - fileSystem = new DefaultServerFileSystem(mock(Database.class), homeDir, deployDir); + + fileSystem = new DefaultServerFileSystem(mock(Database.class), homeDir, server); jarInstaller = new ServerPluginJarInstaller(); jarsInstaller = new ServerPluginJarsInstaller(server, upgradeStatus, fileSystem, jarInstaller); } diff --git a/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsTest.java b/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsTest.java index 3c71fd573dc..a8e0e867578 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsTest.java @@ -64,7 +64,7 @@ public class RulesWsTest { assertThat(list.handler()).isNotNull(); assertThat(list.since()).isEqualTo("4.3"); assertThat(list.isPost()).isFalse(); - assertThat(list.isInternal()).isFalse(); + assertThat(list.isInternal()).isTrue(); assertThat(list.params()).hasSize(11); WebService.Action show = controller.action("show"); diff --git a/sonar-server/src/test/java/org/sonar/server/startup/GenerateBootstrapIndexTest.java b/sonar-server/src/test/java/org/sonar/server/startup/GenerateBootstrapIndexTest.java deleted file mode 100644 index 3b4686a461c..00000000000 --- a/sonar-server/src/test/java/org/sonar/server/startup/GenerateBootstrapIndexTest.java +++ /dev/null @@ -1,68 +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.server.startup; - -import com.google.common.collect.Sets; -import org.junit.Before; -import org.junit.Test; - -import javax.servlet.ServletContext; - -import java.util.Set; - -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class GenerateBootstrapIndexTest { - - @Before - public void setUp() throws Exception { - } - - @Test - public void shouldDetermineListOfResources() { - ServletContext servletContext = mock(ServletContext.class); - Set<String> libs = Sets.newHashSet(); - libs.add("/WEB-INF/lib/sonar-core-2.6.jar"); - libs.add("/WEB-INF/lib/treemap.rb"); - libs.add("/WEB-INF/lib/directory/"); - when(servletContext.getResourcePaths(anyString())).thenReturn(libs); - - assertThat(GenerateBootstrapIndex.getLibs(servletContext)).hasSize(1); - assertThat(GenerateBootstrapIndex.getLibs(servletContext).get(0)).isEqualTo("sonar-core-2.6.jar"); - } - - @Test - public void shouldIgnore() { - assertThat(GenerateBootstrapIndex.isIgnored("sonar-batch-2.6-SNAPSHOT.jar")).isFalse(); - assertThat(GenerateBootstrapIndex.isIgnored("mysql-connector-java-5.1.13.jar")).isTrue(); - assertThat(GenerateBootstrapIndex.isIgnored("postgresql-9.0-801.jdbc3.jar")).isTrue(); - assertThat(GenerateBootstrapIndex.isIgnored("jtds-1.2.4.jar")).isTrue(); - assertThat(GenerateBootstrapIndex.isIgnored("jfreechart-1.0.9.jar")).isTrue(); - assertThat(GenerateBootstrapIndex.isIgnored("eastwood-1.1.0.jar")).isTrue(); - assertThat(GenerateBootstrapIndex.isIgnored("jruby-complete-1.5.6.jar")).isTrue(); - assertThat(GenerateBootstrapIndex.isIgnored("jruby-rack-1.0.5.jar")).isTrue(); - assertThat(GenerateBootstrapIndex.isIgnored("elasticsearch-0.90.6.jar")).isTrue(); - assertThat(GenerateBootstrapIndex.isIgnored("lucene-core-4.5.1.jar")).isTrue(); - } - -} diff --git a/sonar-server/src/test/java/org/sonar/server/startup/GwtPublisherTest.java b/sonar-server/src/test/java/org/sonar/server/startup/GwtPublisherTest.java index fc6ffdc3945..8e900809fc4 100644 --- a/sonar-server/src/test/java/org/sonar/server/startup/GwtPublisherTest.java +++ b/sonar-server/src/test/java/org/sonar/server/startup/GwtPublisherTest.java @@ -45,7 +45,6 @@ public class GwtPublisherTest { outputDir = new File("./target/test-tmp/org/sonar/server/startup/GwtPublisherTest/output"); if (outputDir.exists()) { FileUtils.forceDelete(outputDir); - } } diff --git a/sonar-server/src/test/java/org/sonar/server/startup/JdbcDriverDeployerTest.java b/sonar-server/src/test/java/org/sonar/server/startup/JdbcDriverDeployerTest.java index 3f85cf0c1a4..f03d4f86f77 100644 --- a/sonar-server/src/test/java/org/sonar/server/startup/JdbcDriverDeployerTest.java +++ b/sonar-server/src/test/java/org/sonar/server/startup/JdbcDriverDeployerTest.java @@ -19,8 +19,11 @@ */ package org.sonar.server.startup; -import org.apache.commons.io.FileUtils; +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.sonar.server.platform.DefaultServerFileSystem; import org.sonar.test.TestUtils; @@ -32,13 +35,16 @@ import static org.mockito.Mockito.when; public class JdbcDriverDeployerTest { + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + @Test public void test_deploy() throws Exception { DefaultServerFileSystem fs = mock(DefaultServerFileSystem.class); File initialDriver = TestUtils.getResource(getClass(), "deploy/my-driver.jar"); when(fs.getJdbcDriver()).thenReturn(initialDriver); - File deployDir = TestUtils.getTestTempDir(getClass(), "deploy", true); + File deployDir = temp.newFolder("deploy"); when(fs.getDeployDir()).thenReturn(deployDir); File deployedIndex = new File(deployDir, "jdbc-driver.txt"); File deployedFile = new File(deployDir, "my-driver.jar"); @@ -46,12 +52,29 @@ public class JdbcDriverDeployerTest { assertThat(deployedFile).doesNotExist(); when(fs.getDeployedJdbcDriverIndex()).thenReturn(deployedIndex); - JdbcDriverDeployer deployer = new JdbcDriverDeployer(fs); - deployer.start(); + new JdbcDriverDeployer(fs).start(); assertThat(deployedIndex).exists(); assertThat(deployedFile).exists(); assertThat(deployedFile).hasSize(initialDriver.length()); - assertThat(FileUtils.readFileToString(deployedIndex)).isEqualTo("my-driver.jar|02b97f7bc37b2b68fc847fcc3fc1c156"); + + assertThat(Files.toString(deployedIndex, Charsets.UTF_8)).isEqualTo("my-driver.jar|02b97f7bc37b2b68fc847fcc3fc1c156"); + } + + @Test + public void create_empty_file_when_no_jdbc_driver() throws Exception { + DefaultServerFileSystem fs = mock(DefaultServerFileSystem.class); + when(fs.getJdbcDriver()).thenReturn(null); + + File deployDir = temp.newFolder("deploy"); + when(fs.getDeployDir()).thenReturn(deployDir); + File deployedIndex = new File(deployDir, "jdbc-driver.txt"); + assertThat(deployedIndex).doesNotExist(); + when(fs.getDeployedJdbcDriverIndex()).thenReturn(deployedIndex); + + new JdbcDriverDeployer(fs).start(); + + assertThat(deployedIndex).exists(); + assertThat(Files.toString(deployedIndex, Charsets.UTF_8)).isEqualTo(""); } } diff --git a/sonar-server/src/test/java/org/sonar/server/tester/MediumTest.java b/sonar-server/src/test/java/org/sonar/server/tester/MediumTest.java new file mode 100644 index 00000000000..9f5a9b50386 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/tester/MediumTest.java @@ -0,0 +1,114 @@ +/* + * 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.server.tester; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.i18n.I18n; +import org.sonar.core.i18n.GwtI18n; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.rule.RuleDao; +import org.sonar.core.rule.RuleDto; +import org.sonar.server.debt.DebtModelService; +import org.sonar.server.rule.RuleQuery; +import org.sonar.server.rule.RuleRegistry; +import org.sonar.server.rule.Rules; +import org.sonar.server.user.MockUserSession; + +import java.util.Locale; + +import static org.fest.assertions.Assertions.assertThat; + +public class MediumTest { + + ServerTester serverTester = new ServerTester(); + + @Before + public void before() throws Exception { + serverTester.start(); + } + + @After + public void after() throws Exception { + serverTester.stop(); + } + + @Test + public void find_characteristics() throws Exception { + DebtModelService debtModelService = serverTester.get(DebtModelService.class); + + assertThat(debtModelService.allCharacteristics()).hasSize(39); + } + + @Test + public void create_characteristic() throws Exception { + MockUserSession.set().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + DebtModelService debtModelService = serverTester.get(DebtModelService.class); + debtModelService.create("NEW ONE", null); + + assertThat(debtModelService.allCharacteristics()).hasSize(40); + } + + @Test + public void create_another_characteristic() throws Exception { + MockUserSession.set().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + DebtModelService debtModelService = serverTester.get(DebtModelService.class); + debtModelService.create("NEW TWO", null); + + assertThat(debtModelService.allCharacteristics()).hasSize(40); + } + + @Test + public void create_rule() throws Exception { + Rules rules = serverTester.get(Rules.class); + assertThat(rules.find(RuleQuery.builder().build()).results()).isEmpty(); + + RuleDto ruleDto = new RuleDto().setRepositoryKey("repo").setRuleKey("key").setSeverity("MAJOR"); + serverTester.get(RuleDao.class).insert(ruleDto); + serverTester.get(RuleRegistry.class).reindex(ruleDto); + + assertThat(rules.find(RuleQuery.builder().build()).results()).hasSize(1); + } + + @Test + public void create_another_rule() throws Exception { + Rules rules = serverTester.get(Rules.class); + assertThat(rules.find(RuleQuery.builder().build()).results()).isEmpty(); + + RuleDto ruleDto = new RuleDto().setRepositoryKey("repo2").setRuleKey("key2").setSeverity("MAJOR"); + serverTester.get(RuleDao.class).insert(ruleDto); + serverTester.get(RuleRegistry.class).reindex(ruleDto); + + assertThat(rules.find(RuleQuery.builder().build()).results()).hasSize(1); + } + + @Test + public void i18n_message() throws Exception { + I18n i18n = serverTester.get(I18n.class); + assertThat(i18n.message(Locale.ENGLISH, "any", null)).isEqualTo("Any"); + + GwtI18n gwtI18n= serverTester.get(GwtI18n.class); + assertThat(gwtI18n.getJsDictionnary(Locale.ENGLISH)).contains("\"design.help\": \"Help\""); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java b/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java new file mode 100644 index 00000000000..4a92e0a79b3 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java @@ -0,0 +1,62 @@ +/* + * 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.server.tester; + +import org.apache.commons.io.FileUtils; +import org.sonar.api.CoreProperties; +import org.sonar.server.platform.Platform; + +import java.io.File; +import java.util.Properties; +import java.util.UUID; + +public class ServerTester { + + private File temp; + + private Platform platform; + + public ServerTester() { + platform = new Platform(); + } + + public void start() { + temp = new File("target/" + UUID.randomUUID().toString()); + temp.mkdirs(); + + Properties properties = new Properties(); + properties.setProperty(CoreProperties.SONAR_HOME, temp.getAbsolutePath()); + properties.setProperty("sonar.jdbc.dialect", "h2"); + properties.setProperty("sonar.jdbc.url", "jdbc:h2:" + temp.getAbsolutePath() + "/h2"); + + platform.init(properties); + platform.doStart(); + } + + public void stop() { + platform.doStop(); + FileUtils.deleteQuietly(temp); + } + + public <E> E get(Class<E> component) { + return platform.getContainer().getComponentByType(component); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/text/MacroInterpreterTest.java b/sonar-server/src/test/java/org/sonar/server/text/MacroInterpreterTest.java index ef9ad6775ae..b993dbfd058 100644 --- a/sonar-server/src/test/java/org/sonar/server/text/MacroInterpreterTest.java +++ b/sonar-server/src/test/java/org/sonar/server/text/MacroInterpreterTest.java @@ -22,8 +22,7 @@ package org.sonar.server.text; import org.junit.Before; import org.junit.Test; - -import javax.servlet.ServletContext; +import org.sonar.api.platform.Server; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -36,9 +35,9 @@ public class MacroInterpreterTest { @Before public void setUp() { - ServletContext servletContext = mock(ServletContext.class); - when(servletContext.getContextPath()).thenReturn(path); - interpreter = new MacroInterpreter(servletContext); + Server server = mock(Server.class); + when(server.getContextPath()).thenReturn(path); + interpreter = new MacroInterpreter(server); } @Test diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/PersistentSettingsTest/conf/sonar.properties b/sonar-server/src/test/resources/org/sonar/server/platform/PersistentSettingsTest/conf/sonar.properties deleted file mode 100644 index b4a8077471c..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/platform/PersistentSettingsTest/conf/sonar.properties +++ /dev/null @@ -1 +0,0 @@ -in_file: true
\ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/empty-version.txt b/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/empty-version.txt new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/empty-version.txt diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/pom-with-empty-version.properties b/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/pom-with-empty-version.properties deleted file mode 100644 index 287ce487033..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/pom-with-empty-version.properties +++ /dev/null @@ -1,5 +0,0 @@ -#Generated by Maven -#Fri Nov 23 14:23:53 CET 2007 -groupId=org.codehaus.sonar -artifactId=sonar-core -version=
\ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/pom-with-version.properties b/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/pom-with-version.properties deleted file mode 100644 index 6fff0c5f4d1..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/pom-with-version.properties +++ /dev/null @@ -1,5 +0,0 @@ -#Generated by Maven -#Fri Nov 23 14:23:53 CET 2007 -version=1.0 -groupId=org.codehaus.sonar -artifactId=sonar-core diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/pom-without-version.properties b/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/pom-without-version.properties deleted file mode 100644 index 8d70c2289f8..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/pom-without-version.properties +++ /dev/null @@ -1,4 +0,0 @@ -#Generated by Maven -#Fri Nov 23 14:23:53 CET 2007 -groupId=org.codehaus.sonar -artifactId=sonar-core diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/version.txt b/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/version.txt new file mode 100644 index 00000000000..d3827e75a5c --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/platform/ServerImplTest/version.txt @@ -0,0 +1 @@ +1.0 diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/conf/sonar.properties b/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/conf/sonar.properties deleted file mode 100644 index 020777dad4f..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/conf/sonar.properties +++ /dev/null @@ -1,3 +0,0 @@ -hello: world -in_file: true -ServerSettingsTestEnv: in_file
\ No newline at end of file |