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