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 }