001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2009 SonarSource SA
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.api.measures;
021    
022    import org.apache.commons.lang.builder.EqualsBuilder;
023    import org.apache.commons.lang.builder.ToStringBuilder;
024    
025    import java.math.BigDecimal;
026    import java.math.RoundingMode;
027    import java.util.Date;
028    
029    /**
030     * @since 1.10
031     */
032    public class Measure {
033      protected static final int MAX_TEXT_SIZE = 96;
034    
035      /**
036       * Default precision when saving a float type metric
037       */
038      public final static int DEFAULT_PRECISION = 1;
039    
040      private Integer id; // for internal use
041      protected Metric metric;
042      protected Double value;
043      protected String data;
044      protected String description;
045      protected Metric.Level alertStatus;
046      protected String alertText;
047      protected Integer tendency;
048      protected Date date;
049      protected Double diff1, diff2, diff3;
050      protected String url;
051      protected PersistenceMode persistenceMode = PersistenceMode.FULL;
052    
053      public Measure(Metric metric) {
054        this.metric = metric;
055      }
056    
057      public Measure(Metric metric, Double value) {
058        this.metric = metric;
059        setValue(value);
060      }
061    
062      public Measure(Metric metric, Double value, int precision) {
063        this.metric = metric;
064        setValue(value, precision);
065      }
066    
067      public Measure(Metric metric, Double value, String data) {
068        this.metric = metric;
069        setValue(value);
070        setData(data);
071      }
072    
073      /**
074       * Measure with text data.
075       */
076      public Measure(Metric metric, String data) {
077        this.metric = metric;
078        setData(data);
079      }
080    
081      public Measure(Metric metric, Metric.Level level) {
082        this.metric = metric;
083        if (level != null) {
084          this.data = level.toString();
085        }
086      }
087    
088      public Measure() {
089      }
090    
091      /**
092       * Default persistence mode is FULL, except when instantiating the measure with a String parameter.
093       */
094      public PersistenceMode getPersistenceMode() {
095        return persistenceMode;
096      }
097    
098      public Measure setPersistenceMode(PersistenceMode mode) {
099        this.persistenceMode = mode;
100        return this;
101      }
102    
103      public Metric getMetric() {
104        return metric;
105      }
106    
107      public Measure setMetric(Metric metric) {
108        this.metric = metric;
109        return this;
110      }
111    
112      public Metric.Level getDataAsLevel() {
113        if (data != null) {
114          return Metric.Level.valueOf(data);
115        }
116        return null;
117      }
118    
119      /**
120       * Used only in TimeMachine queries
121       */
122      public Date getDate() {
123        return date;
124      }
125    
126      /**
127       * Used only in TimeMachine queries
128       */
129      public Measure setDate(Date date) {
130        this.date = date;
131        return this;
132      }
133    
134      public Double getValue() {
135        return value;
136      }
137    
138      public Integer getIntValue() {
139        if (value == null) {
140          return null;
141        }
142        return value.intValue();
143      }
144    
145      /**
146       * Setting the measure value with the default precision of 1
147       *
148       * @param v the measure value
149       * @return the measure object instance
150       */
151      public Measure setValue(Double v) {
152        return setValue(v, DEFAULT_PRECISION);
153      }
154    
155      public Measure setIntValue(Integer i) {
156        if (i == null) {
157          this.value = null;
158        } else {
159          this.value = Double.valueOf(i);
160        }
161        return this;
162      }
163    
164      /**
165       * Setting the measure value with a given precision
166       *
167       * @param v         the measure value
168       * @param precision the measure value precision
169       * @return the measure object instance
170       */
171      public Measure setValue(Double v, int precision) {
172        if (v != null) {
173          if (Double.isNaN(v)) {
174            throw new IllegalArgumentException("Measure value can not be NaN");
175          }
176          this.value = scaleValue(v, precision);
177        } else {
178          this.value = null;
179        }
180        return this;
181      }
182    
183      private double scaleValue(double value, int scale) {
184        BigDecimal bd = BigDecimal.valueOf(value);
185        return bd.setScale(scale, RoundingMode.HALF_UP).doubleValue();
186      }
187    
188      public String getData() {
189        return data;
190      }
191    
192      public Measure setData(String s) {
193        if (s != null && s.length() >= MAX_TEXT_SIZE && !metric.isDataType()) {
194          throw new IllegalArgumentException("Data is too long for non-data metric : size=" + s.length() + ", max=" + MAX_TEXT_SIZE);
195        }
196        this.data = s;
197        return this;
198      }
199    
200      public Measure setData(Metric.Level level) {
201        if (level == null) {
202          this.data = null;
203        } else {
204          this.data = level.toString();
205        }
206        return this;
207      }
208    
209      public String getDescription() {
210        return description;
211      }
212    
213      public Measure setDescription(String description) {
214        this.description = description;
215        return this;
216      }
217    
218      public Metric.Level getAlertStatus() {
219        return alertStatus;
220      }
221    
222      public Measure setAlertStatus(Metric.Level status) {
223        this.alertStatus = status;
224        return this;
225      }
226    
227      public String getAlertText() {
228        return alertText;
229      }
230    
231      public Measure setAlertText(String alertText) {
232        this.alertText = alertText;
233        return this;
234      }
235    
236      public Integer getTendency() {
237        return tendency;
238      }
239    
240      public Measure setTendency(Integer tendency) {
241        this.tendency = tendency;
242        return this;
243      }
244    
245      public Integer getId() {
246        return id;
247      }
248    
249      public Measure setId(Integer id) {
250        this.id = id;
251        return this;
252      }
253    
254      public Double getDiffValue1() {
255        return diff1;
256      }
257    
258      public Measure setDiffValue1(Double diff1) {
259        this.diff1 = diff1;
260        return this;
261      }
262    
263      public Double getDiffValue2() {
264        return diff2;
265      }
266    
267      public Measure setDiffValue2(Double diff2) {
268        this.diff2 = diff2;
269        return this;
270      }
271    
272      public Double getDiffValue3() {
273        return diff3;
274      }
275    
276      public Measure setDiffValue3(Double diff3) {
277        this.diff3 = diff3;
278        return this;
279      }
280    
281      public String getUrl() {
282        return url;
283      }
284    
285      public Measure setUrl(String url) {
286        this.url = url;
287        return this;
288      }
289    
290      @Override
291      public boolean equals(Object obj) {
292        if (!(obj instanceof Measure)) {
293          return false;
294        }
295        if (this == obj) {
296          return true;
297        }
298        Measure rhs = (Measure) obj;
299        return new EqualsBuilder()
300            .append(metric, rhs.getMetric())
301            .isEquals();
302      }
303    
304      @Override
305      public int hashCode() {
306        return (metric != null ? metric.hashCode() : 0);
307      }
308    
309      @Override
310      public String toString() {
311        return new ToStringBuilder(this).
312            append("id", id).
313            append("metric", metric).
314            append("value", value).
315            append("data", data).
316            append("description", description).
317            append("alertStatus", alertStatus).
318            append("alertText", alertText).
319            append("tendency", tendency).
320            append("diff1", diff1).
321            append("diff2", diff2).
322            append("diff3", diff3).
323            toString();
324      }
325    
326    }