diff options
17 files changed, 118 insertions, 50 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java index 63d6e09cccf..8184d2cae0c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java @@ -25,6 +25,7 @@ import org.sonar.api.component.RubyComponentService; import org.sonar.api.i18n.I18n; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.internal.Uuids; import org.sonar.core.component.ComponentDto; import org.sonar.core.component.ComponentKeys; import org.sonar.core.resource.ResourceDao; @@ -75,7 +76,7 @@ public class DefaultRubyComponentService implements RubyComponentService { } checkKeyFormat(qualifier, kee); - String uuid = UUID.randomUUID().toString(); + String uuid = Uuids.create(); resourceDao.insertOrUpdate( new ResourceDto() .setUuid(uuid) diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v36/ViolationConverter.java b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v36/ViolationConverter.java index 1c9de9f6d12..4403fe294c7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v36/ViolationConverter.java +++ b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v36/ViolationConverter.java @@ -27,6 +27,7 @@ import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.AbstractListHandler; import org.sonar.api.rule.Severity; +import org.sonar.api.utils.internal.Uuids; import org.sonar.core.persistence.Database; import org.sonar.server.db.migrations.SqlUtil; @@ -177,7 +178,7 @@ class ViolationConverter implements Callable<Object> { if (componentId == null) { continue; } - String issueKey = UUID.randomUUID().toString(); + String issueKey = Uuids.create(); String status, severity, reporter = null; boolean manualSeverity; Object createdAt = Objects.firstNonNull(row.get(CREATED_AT), ONE_YEAR_AGO); @@ -248,7 +249,7 @@ class ViolationConverter implements Callable<Object> { String login = referentials.userLogin((Long) comment.get(USER_ID)); if (login != null) { Object[] params = new Object[6]; - params[0] = UUID.randomUUID().toString(); + params[0] = Uuids.create(); params[1] = comment.get(ISSUE_KEY); params[2] = login; params[3] = comment.get(REVIEW_TEXT); diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigration.java b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigration.java index 6bb0228c2c5..1e6cab9ba16 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigration.java +++ b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigration.java @@ -25,6 +25,7 @@ import com.google.common.base.Strings; import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler; import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.internal.Uuids; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.migration.v50.Component; import org.sonar.core.persistence.migration.v50.Migration50Mapper; @@ -35,7 +36,6 @@ import org.sonar.server.db.migrations.MassUpdate; import java.util.List; import java.util.Map; import java.util.Timer; -import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; import static com.google.common.collect.Lists.newArrayList; @@ -159,7 +159,7 @@ public class PopulateProjectsUuidColumnsMigration implements DatabaseMigration { private void migrateComponentsWithoutUuid(DbSession readSession, DbSession writeSession) { for (Component component : readSession.getMapper(Migration50Mapper.class).selectComponentsWithoutUuid()) { - String uuid = UUID.randomUUID().toString(); + String uuid = Uuids.create(); component.setUuid(uuid); component.setProjectUuid(uuid); @@ -172,7 +172,7 @@ public class PopulateProjectsUuidColumnsMigration implements DatabaseMigration { String existingUuid = component.getUuid(); String uuid = existingUuid == null ? uuidByComponentId.get(component.getId()) : existingUuid; if (uuid == null) { - String newUuid = UUID.randomUUID().toString(); + String newUuid = Uuids.create(); uuidByComponentId.put(component.getId(), newUuid); return newUuid; } diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/394_add_key_to_action_plan.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/394_add_key_to_action_plan.rb index 4143743906d..1da713a5c12 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/394_add_key_to_action_plan.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/394_add_key_to_action_plan.rb @@ -30,7 +30,7 @@ class AddKeyToActionPlan < ActiveRecord::Migration add_column 'action_plans', 'kee', :string, :null => true, :limit => 100 ActionPlan.reset_column_information ActionPlan.all.each do |a| - a.update_attributes!(:kee => Java::JavaUtil::UUID.randomUUID().toString()) + a.update_attributes!(:kee => Java::OrgSonarApiUtilsInternal::Uuids.create()) end end diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java index ea6a2d640d7..0f7faddb25f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java @@ -36,6 +36,7 @@ import org.sonar.api.resources.ResourceUtils; import org.sonar.api.resources.Scopes; import org.sonar.api.security.ResourcePermissions; import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.internal.Uuids; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -46,7 +47,6 @@ import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.UUID; public final class DefaultResourcePersister implements ResourcePersister { @@ -306,7 +306,7 @@ public final class DefaultResourcePersister implements ResourcePersister { model.setEnabled(Boolean.TRUE); model.setDescription(resource.getDescription()); model.setKey(resource.getEffectiveKey()); - model.setUuid(UUID.randomUUID().toString()); + model.setUuid(Uuids.create()); model.setPath(resource.getPath()); Language language = resource.getLanguage(); if (language != null) { diff --git a/sonar-core/pom.xml b/sonar-core/pom.xml index 0f16861286f..956440c1268 100644 --- a/sonar-core/pom.xml +++ b/sonar-core/pom.xml @@ -140,18 +140,8 @@ <!-- tests --> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-core</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest-all</artifactId> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-testing-harness</artifactId> <scope>test</scope> </dependency> <dependency> @@ -160,11 +150,6 @@ <scope>test</scope> </dependency> <dependency> - <groupId>org.easytesting</groupId> - <artifactId>fest-assert</artifactId> - <scope>test</scope> - </dependency> - <dependency> <groupId>com.google.code.bean-matchers</groupId> <artifactId>bean-matchers</artifactId> <scope>test</scope> diff --git a/sonar-core/src/main/java/org/sonar/core/activity/db/ActivityDto.java b/sonar-core/src/main/java/org/sonar/core/activity/db/ActivityDto.java index 2e4ae57f118..517f0e998a7 100644 --- a/sonar-core/src/main/java/org/sonar/core/activity/db/ActivityDto.java +++ b/sonar-core/src/main/java/org/sonar/core/activity/db/ActivityDto.java @@ -22,12 +22,11 @@ package org.sonar.core.activity.db; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.sonar.api.utils.KeyValueFormat; +import org.sonar.api.utils.internal.Uuids; import org.sonar.core.activity.Activity; import org.sonar.core.activity.ActivityLog; import org.sonar.core.persistence.Dto; -import java.util.UUID; - /** * @since 4.4 */ @@ -42,7 +41,7 @@ public final class ActivityDto extends Dto<String> { private String data; protected ActivityDto() { - this.key = UUID.randomUUID().toString(); + this.key = Uuids.create(); } @Override diff --git a/sonar-core/src/main/java/org/sonar/core/issue/ActionPlanStats.java b/sonar-core/src/main/java/org/sonar/core/issue/ActionPlanStats.java index bafd57fbf6d..cc4eba49a18 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/ActionPlanStats.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/ActionPlanStats.java @@ -21,9 +21,9 @@ package org.sonar.core.issue; import org.sonar.api.issue.ActionPlan; +import org.sonar.api.utils.internal.Uuids; import java.util.Date; -import java.util.UUID; public class ActionPlanStats extends DefaultActionPlan { @@ -36,7 +36,7 @@ public class ActionPlanStats extends DefaultActionPlan { public static ActionPlanStats create(String name) { ActionPlanStats actionPlan = new ActionPlanStats(); - actionPlan.setKey(UUID.randomUUID().toString()); + actionPlan.setKey(Uuids.create()); Date now = new Date(); actionPlan.setName(name); actionPlan.setStatus(ActionPlan.STATUS_OPEN); diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultActionPlan.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultActionPlan.java index 6106fd7a9ff..0fe3fd96aeb 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultActionPlan.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultActionPlan.java @@ -21,12 +21,11 @@ package org.sonar.core.issue; import org.sonar.api.issue.ActionPlan; +import org.sonar.api.utils.internal.Uuids; import javax.annotation.CheckForNull; import javax.annotation.Nullable; - import java.util.Date; -import java.util.UUID; public class DefaultActionPlan implements ActionPlan { @@ -46,7 +45,7 @@ public class DefaultActionPlan implements ActionPlan { public static DefaultActionPlan create(String name) { DefaultActionPlan actionPlan = new DefaultActionPlan(); - actionPlan.setKey(UUID.randomUUID().toString()); + actionPlan.setKey(Uuids.create()); Date now = new Date(); actionPlan.setName(name); actionPlan.setStatus(ActionPlan.STATUS_OPEN); diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueBuilder.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueBuilder.java index 3d1eaea3383..e81ae5448b6 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueBuilder.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueBuilder.java @@ -20,17 +20,15 @@ package org.sonar.core.issue; import com.google.common.base.Preconditions; -import com.google.common.base.Strings; import com.google.common.collect.Maps; import org.sonar.api.issue.Issuable; import org.sonar.api.issue.Issue; import org.sonar.api.issue.internal.DefaultIssue; import org.sonar.api.rule.RuleKey; +import org.sonar.api.utils.internal.Uuids; import javax.annotation.Nullable; - import java.util.Map; -import java.util.UUID; public class DefaultIssueBuilder implements Issuable.IssueBuilder { @@ -110,8 +108,7 @@ public class DefaultIssueBuilder implements Issuable.IssueBuilder { Preconditions.checkNotNull(ruleKey, "Rule key must be set"); DefaultIssue issue = new DefaultIssue(); - String key = UUID.randomUUID().toString(); - Preconditions.checkState(!Strings.isNullOrEmpty(key), "Fail to generate issue key"); + String key = Uuids.create(); issue.setKey(key); issue.setComponentKey(componentKey); issue.setProjectKey(projectKey); diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java index 378c2fca6b2..387d36efa6f 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java @@ -28,6 +28,7 @@ import org.sonar.api.resources.Project; import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.Duration; import org.sonar.api.utils.KeyValueFormat; +import org.sonar.api.utils.internal.Uuids; import org.sonar.core.component.ComponentDto; import org.sonar.core.persistence.Dto; import org.sonar.core.rule.RuleDto; @@ -633,6 +634,6 @@ public final class IssueDto extends Dto<String> implements Serializable { return new IssueDto() .setProjectId(Long.valueOf(project.getId())) .setRuleId(rule.getId()) - .setKee(UUID.randomUUID().toString()); + .setKee(Uuids.create()); } } diff --git a/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java index aa2a82606a5..538ff9cbb7f 100644 --- a/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java +++ b/sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java @@ -25,6 +25,7 @@ import org.apache.ibatis.session.SqlSession; import org.sonar.api.component.Component; import org.sonar.api.resources.Scopes; import org.sonar.api.utils.System2; +import org.sonar.api.utils.internal.Uuids; import org.sonar.core.component.ComponentDto; import org.sonar.core.component.SnapshotDto; import org.sonar.core.persistence.DaoComponent; @@ -151,7 +152,7 @@ public class ResourceDao implements DaoComponent { if (resource.getId() == null) { // Fix for Views if (resource.getUuid() == null && Scopes.PROJECT.equals(resource.getScope())) { - String uuid = UUID.randomUUID().toString(); + String uuid = Uuids.create(); resource.setUuid(uuid); resource.setProjectUuid(uuid); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java index ab7912cc8a8..df4779a4894 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java @@ -28,12 +28,11 @@ import org.sonar.api.batch.sensor.SensorStorage; import org.sonar.api.batch.sensor.internal.DefaultStorable; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.rule.RuleKey; +import org.sonar.api.utils.internal.Uuids; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.UUID; - public class DefaultIssue extends DefaultStorable implements Issue { private static final String INPUT_DIR_SHOULD_BE_NON_NULL = "InputDir should be non null"; @@ -51,12 +50,12 @@ public class DefaultIssue extends DefaultStorable implements Issue { public DefaultIssue() { super(null); - this.key = UUID.randomUUID().toString(); + this.key = Uuids.create(); } public DefaultIssue(SensorStorage storage) { super(storage); - this.key = UUID.randomUUID().toString(); + this.key = Uuids.create(); } @Override diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssueComment.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssueComment.java index dbff36ff056..ad77a21f1c1 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssueComment.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssueComment.java @@ -20,13 +20,12 @@ package org.sonar.api.issue.internal; import org.sonar.api.issue.IssueComment; +import org.sonar.api.utils.internal.Uuids; import javax.annotation.CheckForNull; import javax.annotation.Nullable; - import java.io.Serializable; import java.util.Date; -import java.util.UUID; /** * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING. @@ -118,7 +117,7 @@ public class DefaultIssueComment implements Serializable, IssueComment { public static DefaultIssueComment create(String issueKey, @Nullable String login, String markdownText) { DefaultIssueComment comment = new DefaultIssueComment(); comment.setIssueKey(issueKey); - comment.setKey(UUID.randomUUID().toString()); + comment.setKey(Uuids.create()); Date now = new Date(); comment.setUserLogin(login); comment.setMarkdownText(markdownText); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentKeys.java b/sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentKeys.java index 13da7d21776..3a603649e3b 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentKeys.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/platform/ComponentKeys.java @@ -22,10 +22,10 @@ package org.sonar.api.platform; import com.google.common.annotations.VisibleForTesting; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.utils.internal.Uuids; import java.util.HashSet; import java.util.Set; -import java.util.UUID; import java.util.regex.Pattern; /** @@ -50,7 +50,7 @@ class ComponentKeys { if (!objectsWithoutToString.add(component.getClass())) { log.warn(String.format("Bad component key: %s. Please implement toString() method on class %s", key, component.getClass().getName())); } - key += UUID.randomUUID().toString(); + key += Uuids.create(); } return new StringBuilder().append(component.getClass().getCanonicalName()).append("-").append(key).toString(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/Uuids.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/Uuids.java new file mode 100644 index 00000000000..e72c123e42e --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/Uuids.java @@ -0,0 +1,39 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.utils.internal; + +import java.util.UUID; + +/** + * @since 5.0 + */ +public class Uuids { + + private Uuids() { + // only static fields + } + + /** + * Create a universally unique identifier. Underlying algorithm can change over SQ versions. + */ + public static String create() { + return UUID.randomUUID().toString(); + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/internal/UuidsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/internal/UuidsTest.java new file mode 100644 index 00000000000..70f11710d19 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/internal/UuidsTest.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.api.utils.internal; + +import com.google.common.collect.Sets; +import org.junit.Test; +import org.sonar.test.TestUtils; + +import java.util.Set; + +import static org.fest.assertions.Assertions.assertThat; + +public class UuidsTest { + + @Test + public void create_unique() throws Exception { + Set<String> all = Sets.newHashSet(); + for (int i = 0; i < 50; i++) { + String uuid = Uuids.create(); + assertThat(uuid).isNotEmpty(); + all.add(uuid); + } + assertThat(all).hasSize(50); + } + + @Test + public void constructor_is_private() throws Exception { + TestUtils.hasOnlyPrivateConstructors(Uuids.class); + } +} |