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.ToStringBuilder;
023 import org.sonar.api.BatchExtension;
024 import org.sonar.api.ServerExtension;
025 import org.sonar.api.database.BaseIdentifiable;
026
027 import javax.persistence.*;
028
029 /**
030 * @since 1.10
031 */
032 @Table(name = "metrics")
033 @Entity(name = "Metric")
034 public class Metric extends BaseIdentifiable implements ServerExtension, BatchExtension {
035
036 /**
037 * A metric bigger value means a degradation
038 */
039 public final static int DIRECTION_WORST = -1;
040 /**
041 * A metric bigger value means an improvement
042 */
043 public final static int DIRECTION_BETTER = 1;
044 /**
045 * The metric direction has no meaning
046 */
047 public final static int DIRECTION_NONE = 0;
048
049 public enum ValueType {
050 INT, FLOAT, PERCENT, BOOL, STRING, MILLISEC, DATA, LEVEL, DISTRIB
051 }
052
053 public enum Level {
054 OK("Green"), WARN("Orange"), ERROR("Red");
055
056 private String colorName;
057
058 Level(String colorName) {
059 this.colorName = colorName;
060 }
061
062 public String getColorName() {
063 return colorName;
064 }
065 }
066
067 public enum Origin {
068 JAV, GUI, WS
069 }
070
071 @Transient
072 private Formula formula;
073
074 @Column(name = "name", updatable = false, nullable = false, length = 64)
075 private String key;
076
077 @Column(name = "description", updatable = true, nullable = true, length = 255)
078 private String description;
079
080 @Column(name = "val_type", updatable = true, nullable = true)
081 @Enumerated(EnumType.STRING)
082 private ValueType type;
083
084 @Column(name = "direction", updatable = true, nullable = true)
085 private Integer direction;
086
087 @Column(name = "domain", updatable = true, nullable = true, length = 60)
088 private String domain;
089
090 @Column(name = "short_name", updatable = true, nullable = true, length = 64)
091 private String name;
092
093 @Column(name = "qualitative", updatable = true, nullable = true)
094 private Boolean qualitative = Boolean.FALSE;
095
096 @Column(name = "user_managed", updatable = true, nullable = true)
097 private Boolean userManaged = Boolean.FALSE;
098
099 @Column(name = "enabled", updatable = true, nullable = true)
100 private Boolean enabled = Boolean.TRUE;
101
102 @Column(name = "origin", updatable = true, nullable = true, length = 3)
103 @Enumerated(EnumType.STRING)
104 private Origin origin;
105
106 @Column(name = "worst_value", updatable = true, nullable = true, precision = 30, scale = 20)
107 private Double worstValue;
108
109 @Column(name = "best_value", updatable = true, nullable = true, precision = 30, scale = 20)
110 private Double bestValue;
111
112 @Column(name = "optimized_best_value", updatable = true, nullable = true)
113 private Boolean optimizedBestValue;
114
115 @Column(name = "hidden", updatable = true, nullable = true)
116 private Boolean hidden = Boolean.FALSE;
117
118
119 /**
120 * Creates an empty metric
121 */
122 @Deprecated public Metric() {
123 }
124
125 /**
126 * Creates a metric based on its key. Shortcut to Metric(key, ValueType.INT)
127 *
128 * @param key the metric key
129 */
130 public Metric(String key) {
131 this(key, ValueType.INT);
132 }
133
134 /**
135 * Creates a metric based on a key and a type. Shortcut to
136 * Metric(key, key, key, type, -1, Boolean.FALSE, null, false)
137 *
138 * @param key the key
139 * @param type the type
140 */
141 public Metric(String key, ValueType type) {
142 this(key, key, key, type, -1, Boolean.FALSE, null, false);
143 }
144
145 public Metric(String key, String name, String description, ValueType type, Integer direction, Boolean qualitative, String domain) {
146 this(key, name, description, type, direction, qualitative, domain, false);
147 }
148
149 /**
150 * Creates a fully qualified metric. This defaults some values:
151 * <ul>
152 * <li>origin : Origin.JAV</li>
153 * </ul>
154 *
155 * @param key the metric key
156 * @param name the metric name
157 * @param description the metric description
158 * @param type the metric type
159 * @param direction the metric direction
160 * @param qualitative whether the metric is qualitative
161 * @param domain the metric domain
162 * @param userManaged whether the metric is user managed
163 */
164 @Deprecated
165 public Metric(String key, String name, String description, ValueType type, Integer direction, Boolean qualitative, String domain, boolean userManaged) {
166 this.key = key;
167 this.description = description;
168 this.type = type;
169 this.direction = direction;
170 this.domain = domain;
171 this.name = name;
172 this.qualitative = qualitative;
173 this.userManaged = userManaged;
174 this.origin = Origin.JAV;
175 if (ValueType.PERCENT.equals(this.type)) {
176 this.bestValue = (direction==DIRECTION_BETTER ? 100.0 : 0.0);
177 this.worstValue = (direction==DIRECTION_BETTER ? 0.0 : 100.0);
178 }
179 }
180
181 /**
182 * Creates a fully qualified metric. This defaults some values:
183 * <ul>
184 * <li>origin : Origin.JAV</li>
185 * <li>enabled : true</li>
186 * <li>userManaged : true</li>
187 * </ul>
188 *
189 * @param key the metric key
190 * @param name the metric name
191 * @param type the metric type
192 * @param direction the metric direction
193 * @param qualitative whether the metric is qualitative
194 * @param domain the metric domain
195 * @param formula the metric formula
196 */
197 public Metric(String key, String name, ValueType type, Integer direction, Boolean qualitative, String domain, Formula formula) {
198 this.key = key;
199 this.name = name;
200 this.type = type;
201 this.direction = direction;
202 this.domain = domain;
203 this.qualitative = qualitative;
204 this.origin = Origin.JAV;
205 this.enabled = true;
206 this.userManaged = false;
207 this.formula = formula;
208 if (ValueType.PERCENT.equals(this.type)) {
209 this.bestValue = (direction==DIRECTION_BETTER ? 100.0 : 0.0);
210 this.worstValue = (direction==DIRECTION_BETTER ? 0.0 : 100.0);
211 }
212 }
213
214 /**
215 * @return the metric formula
216 */
217 public Formula getFormula() {
218 return formula;
219 }
220
221 /**
222 * Sets the metric formula
223 *
224 * @param formula the formula
225 * @return this
226 */
227 public Metric setFormula(Formula formula) {
228 this.formula = formula;
229 return this;
230 }
231
232 /**
233 * @return wether the metric is qualitative
234 */
235 public Boolean getQualitative() {
236 return qualitative;
237 }
238
239 /**
240 * Sets whether the metric is qualitative
241 *
242 * @param qualitative whether the metric is qualitative
243 * @return this
244 */
245 public Metric setQualitative(Boolean qualitative) {
246 this.qualitative = qualitative;
247 return this;
248 }
249
250 /**
251 * @return the metric key
252 */
253 public String getKey() {
254 return key;
255 }
256
257 /**
258 * Sets the metric key
259 *
260 * @param key the key
261 * @return this
262 */
263 public Metric setKey(String key) {
264 this.key = key;
265 return this;
266 }
267
268 /**
269 * @return the metric type
270 */
271 public ValueType getType() {
272 return type;
273 }
274
275 /**
276 * Sets the metric type
277 *
278 * @param type the type
279 * @return this
280 */
281 public Metric setType(ValueType type) {
282 this.type = type;
283 return this;
284 }
285
286 /**
287 * @return the metric description
288 */
289 public String getDescription() {
290 return description;
291 }
292
293 /**
294 * Sets the metric description
295 *
296 * @param description the description
297 * @return this
298 */
299 public Metric setDescription(String description) {
300 this.description = description;
301 return this;
302 }
303
304 /**
305 * @return whether the metric is a managed by the users (manual metric)
306 */
307 public Boolean getUserManaged() {
308 return userManaged;
309 }
310
311 /**
312 * Sets whether the metric is user managed
313 *
314 * @param userManaged whether the metric is user managed
315 * @return this
316 */
317 public Metric setUserManaged(Boolean userManaged) {
318 this.userManaged = userManaged;
319 return this;
320 }
321
322 /**
323 * @return whether the metric is enabled
324 */
325 public Boolean getEnabled() {
326 return enabled;
327 }
328
329 /**
330 * Sets whether the metric is enabled
331 *
332 * @param enabled whether the metric is enabled
333 * @return this
334 */
335 public Metric setEnabled(Boolean enabled) {
336 this.enabled = enabled;
337 return this;
338 }
339
340 /**
341 * @return the metric direction
342 */
343 public Integer getDirection() {
344 return direction;
345 }
346
347 /**
348 * Sets the metric direction.
349 *
350 * @param direction the direction
351 */
352 public Metric setDirection(Integer direction) {
353 this.direction = direction;
354 return this;
355 }
356
357 /**
358 * @return the domain of the metric
359 */
360 public String getDomain() {
361 return domain;
362 }
363
364 /**
365 * Sets the domain for the metric (General, Complexity...)
366 *
367 * @param domain the domain
368 * @return this
369 */
370 public Metric setDomain(String domain) {
371 this.domain = domain;
372 return this;
373 }
374
375 /**
376 * @return the metric name
377 */
378 public String getName() {
379 return name;
380 }
381
382 /**
383 * Sets the metric name
384 *
385 * @param name the name
386 * @return this
387 */
388 public Metric setName(String name) {
389 this.name = name;
390 return this;
391 }
392
393 /**
394 * @return the origin of the metric - Internal use only
395 */
396 public Origin getOrigin() {
397 return origin;
398 }
399
400 /**
401 * Set the origin of the metric - Internal use only
402 *
403 * @param origin the origin
404 * @return this
405 */
406 public Metric setOrigin(Origin origin) {
407 this.origin = origin;
408 return this;
409 }
410
411 public Double getWorstValue() {
412 return worstValue;
413 }
414
415 public Double getBestValue() {
416 return bestValue;
417 }
418
419 /**
420 * @return this
421 */
422 public Metric setWorstValue(Double d) {
423 this.worstValue = d;
424 return this;
425 }
426
427 /**
428 * @param bestValue the best value. It can be null.
429 * @return this
430 */
431 public Metric setBestValue(Double bestValue) {
432 this.bestValue = bestValue;
433 return this;
434 }
435
436 /**
437 * @return whether the metric is of a numeric type (int, percentage...)
438 */
439 public boolean isNumericType() {
440 return ValueType.INT.equals(type)
441 || ValueType.FLOAT.equals(type)
442 || ValueType.PERCENT.equals(type)
443 || ValueType.BOOL.equals(type)
444 || ValueType.MILLISEC.equals(type);
445 }
446
447 /**
448 * @return whether the metric is of type data
449 */
450 public boolean isDataType() {
451 return ValueType.DATA.equals(type) || ValueType.DISTRIB.equals(type);
452 }
453
454 /**
455 * @return whether the metric is of type percentage
456 */
457 public boolean isPercentageType() {
458 return ValueType.PERCENT.equals(type);
459 }
460
461 public Metric setOptimizedBestValue(Boolean b) {
462 this.optimizedBestValue = b;
463 return this;
464 }
465
466 public Boolean isOptimizedBestValue() {
467 return optimizedBestValue;
468 }
469
470 public Boolean isHidden() {
471 return hidden;
472 }
473
474 public Metric setHidden(Boolean hidden) {
475 this.hidden = hidden;
476 return this;
477 }
478
479 @Override
480 public int hashCode() {
481 return key.hashCode();
482 }
483
484 @Override
485 public boolean equals(Object obj) {
486 if (!(obj instanceof Metric)) {
487 return false;
488 }
489 if (this == obj) {
490 return true;
491 }
492 Metric other = (Metric) obj;
493 return key.equals(other.getKey());
494 }
495
496 @Override
497 public String toString() {
498 return new ToStringBuilder(this)
499 .append("key", key)
500 .append("name", name)
501 .append("type", type)
502 .append("enabled", enabled)
503 .append("qualitative", qualitative)
504 .append("direction", direction)
505 .append("domain", domain)
506 .append("worstValue", worstValue)
507 .append("bestValue", bestValue)
508 .append("optimizedBestValue", optimizedBestValue)
509 .append("hidden", hidden)
510 .toString();
511 }
512
513 /**
514 * Merge with fields from other metric. All fields are copied, except the id.
515 * @return this
516 */
517 public Metric merge(final Metric with) {
518 this.description = with.description;
519 this.domain = with.domain;
520 this.enabled = with.enabled;
521 this.qualitative = with.qualitative;
522 this.worstValue = with.worstValue;
523 this.bestValue = with.bestValue;
524 this.optimizedBestValue = with.optimizedBestValue;
525 this.direction = with.direction;
526 this.key = with.key;
527 this.type = with.type;
528 this.name = with.name;
529 this.userManaged = with.userManaged;
530 this.origin = with.origin;
531 this.hidden = with.hidden;
532 return this;
533 }
534 }