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 }