001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2011 SonarSource 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 }