diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2013-11-27 09:23:55 +0100 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2013-11-27 09:24:42 +0100 |
commit | 56b6fa8c650d96a05734983e874f48c1aff40dae (patch) | |
tree | 114c68e9f12664219ff6d04ffdf28223316f8fb5 /sonar-plugin-api | |
parent | ac5db8387bfabeb9a78ce172fedc6fa86eb9b1e2 (diff) | |
download | sonarqube-56b6fa8c650d96a05734983e874f48c1aff40dae.tar.gz sonarqube-56b6fa8c650d96a05734983e874f48c1aff40dae.zip |
SONAR-4892 SONAR-4917 Update technical debt merge model and technical debt decorator to use mybatis classes
Diffstat (limited to 'sonar-plugin-api')
7 files changed, 506 insertions, 16 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java index f6d95c232b2..3f4e9a06693 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java @@ -23,7 +23,6 @@ import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.sonar.api.database.DatabaseSession; import org.sonar.api.measures.Metric; -import org.sonar.api.qualitymodel.Characteristic; import org.sonar.api.rules.RulePriority; import javax.persistence.*; @@ -112,9 +111,8 @@ public class MeasureModel implements Cloneable { @OneToMany(mappedBy = "measure", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}) private List<MeasureData> measureData = new ArrayList<MeasureData>(); - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "characteristic_id") - private Characteristic characteristic; + @Column(name = "characteristic_id", nullable = true) + private Integer characteristicId; @Column(name = "person_id", updatable = true, nullable = true) private Integer personId; @@ -497,12 +495,12 @@ public class MeasureModel implements Cloneable { return this; } - public Characteristic getCharacteristic() { - return characteristic; + public Integer getCharacteristicId() { + return characteristicId; } - public MeasureModel setCharacteristic(Characteristic c) { - this.characteristic = c; + public MeasureModel setCharacteristicId(Integer characteristicId) { + this.characteristicId = characteristicId; return this; } @@ -535,7 +533,7 @@ public class MeasureModel implements Cloneable { clone.setSnapshotId(getSnapshotId()); clone.setMeasureDate(getMeasureDate()); clone.setUrl(getUrl()); - clone.setCharacteristic(getCharacteristic()); + clone.setCharacteristicId(getCharacteristicId()); clone.setPersonId(getPersonId()); return clone; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java index f286c28790f..b6a78b582ba 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java @@ -22,8 +22,10 @@ package org.sonar.api.measures; import com.google.common.annotations.Beta; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.math.NumberUtils; -import org.sonar.api.qualitymodel.Characteristic; +import org.sonar.api.technicaldebt.Characteristic; +import org.sonar.api.technicaldebt.Requirement; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import java.math.BigDecimal; @@ -59,6 +61,7 @@ public class Measure { protected Double variation1, variation2, variation3, variation4, variation5; protected String url; protected Characteristic characteristic; + protected Requirement requirement; protected Integer personId; protected PersistenceMode persistenceMode = PersistenceMode.FULL; @@ -584,21 +587,38 @@ public class Measure { } /** - * @since 2.3 + * @since 4.1 */ + @CheckForNull public final Characteristic getCharacteristic() { return characteristic; } /** - * @since 2.3 + * @since 4.1 */ - public final Measure setCharacteristic(Characteristic characteristic) { + public final Measure setCharacteristic(@Nullable Characteristic characteristic) { this.characteristic = characteristic; return this; } /** + * @since 4.1 + */ + @CheckForNull + public final Requirement getRequirement() { + return requirement; + } + + /** + * @since 4.1 + */ + public final Measure setRequirement(@Nullable Requirement requirement) { + this.requirement = requirement; + return this; + } + + /** * @since 2.14 */ @Beta @@ -660,6 +680,9 @@ public class Measure { if (characteristic != null ? !characteristic.equals(measure.characteristic) : measure.characteristic != null) { return false; } + if (requirement != null ? !requirement.equals(measure.requirement) : measure.requirement != null) { + return false; + } if (personId != null ? !personId.equals(measure.personId) : measure.personId != null) { return false; } @@ -670,6 +693,7 @@ public class Measure { public int hashCode() { int result = metricKey != null ? metricKey.hashCode() : 0; result = 31 * result + (characteristic != null ? characteristic.hashCode() : 0); + result = 31 * result + (requirement != null ? requirement.hashCode() : 0); result = 31 * result + (personId != null ? personId.hashCode() : 0); return result; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java index 2806ef43f23..83e88e15a94 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java @@ -19,8 +19,9 @@ */ package org.sonar.api.measures; -import org.sonar.api.qualitymodel.Characteristic; import org.sonar.api.rules.Rule; +import org.sonar.api.technicaldebt.Characteristic; +import org.sonar.api.technicaldebt.Requirement; import java.util.ArrayList; import java.util.Collection; @@ -88,6 +89,27 @@ public final class MeasuresFilters { }; } + public static MeasuresFilter<Measure> requirement(final Metric metric, final Requirement requirement) { + return new MetricFilter<Measure>(metric) { + + public Measure filter(Collection<Measure> measures) { + if (measures == null) { + return null; + } + for (Measure measure : measures) { + if (measure.getClass().equals(Measure.class) && + measure.getMetric().equals(metric) && + measure.getPersonId() == null && + measure.getRequirement() != null && + measure.getRequirement().equals(requirement)) { + return measure; + } + } + return null; + } + }; + } + /** * @since 2.0 */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/technicaldebt/Characteristic.java b/sonar-plugin-api/src/main/java/org/sonar/api/technicaldebt/Characteristic.java new file mode 100644 index 00000000000..cbb45451c9f --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/technicaldebt/Characteristic.java @@ -0,0 +1,176 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 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.technicaldebt; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import java.util.Date; +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; + +public class Characteristic { + + private Integer id; + private String key; + private String name; + private Integer order; + private Characteristic parent; + private List<Characteristic> children; + private List<Requirement> requirements; + + private Date createdAt; + private Date updatedAt; + + public Characteristic() { + this.children = newArrayList(); + this.requirements = newArrayList(); + } + + public Integer id() { + return id; + } + + public Characteristic setId(Integer id) { + this.id = id; + return this; + } + + public String key() { + return key; + } + + public Characteristic setKey(String key) { + this.key = StringUtils.trimToNull(key); + return this; + } + + public String name() { + return name; + } + + public Characteristic setName(String name) { + return setName(name, false); + } + + public Characteristic setName(String s, boolean asKey) { + this.name = StringUtils.trimToNull(s); + if (asKey) { + this.key = StringUtils.upperCase(this.name); + this.key = StringUtils.replaceChars(this.key, ' ', '_'); + } + return this; + } + + public Integer order() { + return order; + } + + public Characteristic setOrder(Integer order) { + this.order = order; + return this; + } + + @CheckForNull + public Characteristic parent() { + return parent; + } + + public Characteristic setParent(@Nullable Characteristic parent) { + if (parent != null) { + this.parent = parent; + parent.addChild(this); + } + return this; + } + + public List<Characteristic> children() { + return children; + } + + private Characteristic addChild(Characteristic child){ + this.children.add(child); + return this; + } + + public List<Requirement> requirements() { + return requirements; + } + + protected Characteristic addRequirement(Requirement requirement){ + this.requirements.add(requirement); + return this; + } + + public Characteristic removeRequirement(Requirement requirement){ + this.requirements.remove(requirement); + return this; + } + + public boolean isRoot(){ + return parent == null; + } + + public Date createdAt() { + return createdAt; + } + + public Characteristic setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + return this; + } + + public Date updatedAt() { + return updatedAt; + } + + public Characteristic setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Characteristic that = (Characteristic) o; + return key.equals(that.key); + } + + @Override + public int hashCode() { + return key.hashCode(); + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/technicaldebt/Requirement.java b/sonar-plugin-api/src/main/java/org/sonar/api/technicaldebt/Requirement.java new file mode 100644 index 00000000000..66f7949aaeb --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/technicaldebt/Requirement.java @@ -0,0 +1,164 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 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.technicaldebt; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.sonar.api.rule.RuleKey; + +import java.util.Date; +import java.util.List; + +public class Requirement { + + public static final String FUNCTION_LINEAR = "linear"; + public static final String FUNCTION_LINEAR_WITH_OFFSET = "linear_offset"; + public static final String CONSTANT_ISSUE = "constant_issue"; + + public static final List<String> FUNCTIONS = ImmutableList.of(FUNCTION_LINEAR, FUNCTION_LINEAR_WITH_OFFSET, CONSTANT_ISSUE); + + private Integer id; + private RuleKey ruleKey; + private Characteristic characteristic; + + private String function; + private WorkUnit factor; + private WorkUnit offset; + + private Date createdAt; + private Date updatedAt; + + public Requirement() { + this.factor = WorkUnit.create(0d, WorkUnit.DEFAULT_UNIT); + this.offset = WorkUnit.create(0d, WorkUnit.DEFAULT_UNIT); + } + + public Integer id() { + return id; + } + + public Requirement setId(Integer id) { + this.id = id; + return this; + } + + public RuleKey ruleKey() { + return ruleKey; + } + + public Requirement setRuleKey(RuleKey ruleKey) { + this.ruleKey = ruleKey; + return this; + } + + public Characteristic characteristic() { + return characteristic; + } + + public Requirement setCharacteristic(Characteristic characteristic) { + this.characteristic = characteristic; + this.characteristic.addRequirement(this); + return this; + } + + public String function() { + return function; + } + + public Requirement setFunction(String function) { + if (!FUNCTIONS.contains(function)) { + throw new IllegalArgumentException("Function '"+ function +"' is unknown."); + } + this.function = function; + return this; + } + + public WorkUnit factor() { + return factor; + } + + public Requirement setFactor(WorkUnit factor) { + this.factor = factor; + return this; + } + + public WorkUnit offset() { + return offset; + } + + public Requirement setOffset(WorkUnit offset) { + this.offset = offset; + return this; + } + + public Date createdAt() { + return createdAt; + } + + public Requirement setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + return this; + } + + public Date updatedAt() { + return updatedAt; + } + + public Requirement setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + return this; + } + + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Requirement that = (Requirement) o; + + if (!characteristic.equals(that.characteristic)) { + return false; + } + if (!ruleKey.equals(that.ruleKey)) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = ruleKey.hashCode(); + result = 31 * result + characteristic.hashCode(); + return result; + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/technicaldebt/WorkUnit.java b/sonar-plugin-api/src/main/java/org/sonar/api/technicaldebt/WorkUnit.java new file mode 100644 index 00000000000..febef93870c --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/technicaldebt/WorkUnit.java @@ -0,0 +1,106 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 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.technicaldebt; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +import javax.annotation.Nullable; + +public final class WorkUnit { + + public static final String DAYS = "d"; + public static final String MINUTES = "mn"; + public static final String HOURS = "h"; + public static final String DEFAULT_UNIT = DAYS; + private static final String[] UNITS = {DAYS, MINUTES, HOURS}; + + public static final double DEFAULT_VALUE = 0.0; + + private double value = 0d; + private String unit = DEFAULT_UNIT; + + WorkUnit(double value, String unit) { + this.value = value; + this.unit = unit; + } + + public double getValue() { + return value; + } + + public String getUnit() { + return unit; + } + + public static WorkUnit create(@Nullable Double value, @Nullable String unit) { + unit = StringUtils.defaultIfEmpty(unit, DEFAULT_UNIT); + if (!ArrayUtils.contains(UNITS, unit)) { + throw new IllegalArgumentException("Unit can not be: " + unit + ". Possible values are " + ArrayUtils.toString(UNITS)); + } + double d = value != null ? value : DEFAULT_VALUE; + if (d < 0.0) { + throw new IllegalArgumentException("Value can not be negative: " + d); + } + return new WorkUnit(d, unit); + } + + public static WorkUnit create() { + return create(0d, DEFAULT_UNIT); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + WorkUnit workUnit = (WorkUnit) o; + + if (Double.compare(workUnit.value, value) != 0) { + return false; + } + if (!unit.equals(workUnit.unit)) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result; + long temp; + temp = Double.doubleToLongBits(value); + result = (int) (temp ^ (temp >>> 32)); + result = 31 * result + unit.hashCode(); + return result; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } +} diff --git a/sonar-plugin-api/src/main/resources/org/sonar/api/database/model/MeasureMapper.xml b/sonar-plugin-api/src/main/resources/org/sonar/api/database/model/MeasureMapper.xml index 1ae3c8f845d..a3f83181d75 100644 --- a/sonar-plugin-api/src/main/resources/org/sonar/api/database/model/MeasureMapper.xml +++ b/sonar-plugin-api/src/main/resources/org/sonar/api/database/model/MeasureMapper.xml @@ -11,7 +11,7 @@ VALUES ( #{value}, #{metricId}, #{snapshotId}, #{ruleId}, #{textValue}, #{tendency}, #{measureDate}, #{projectId}, #{alertStatus}, #{alertText}, - #{url}, #{description}, #{rulePriority.ordinal}, #{characteristic.id}, #{variationValue1}, + #{url}, #{description}, #{rulePriority.ordinal}, #{characteristicId}, #{variationValue1}, #{variationValue2}, #{variationValue3}, #{variationValue4}, #{variationValue5}, #{personId} ) </insert> @@ -38,7 +38,7 @@ url = #{url}, description = #{description}, rule_priority = #{rulePriority.ordinal}, - characteristic_id = #{characteristic.id}, + characteristic_id = #{characteristicId}, variation_value_1 = #{variationValue1}, variation_value_2 = #{variationValue2}, variation_value_3 = #{variationValue3}, |