You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MeasureModel.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /*
  2. * SonarQube, open source software quality management tool.
  3. * Copyright (C) 2008-2014 SonarSource
  4. * mailto:contact AT sonarsource DOT com
  5. *
  6. * SonarQube is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * SonarQube is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.api.database.model;
  21. import com.google.common.base.Throwables;
  22. import org.apache.commons.lang.builder.ReflectionToStringBuilder;
  23. import org.apache.commons.lang.builder.ToStringStyle;
  24. import org.sonar.api.database.DatabaseSession;
  25. import org.sonar.api.measures.Metric;
  26. import org.sonar.api.rules.RulePriority;
  27. import javax.annotation.CheckForNull;
  28. import javax.persistence.Column;
  29. import javax.persistence.Entity;
  30. import javax.persistence.EnumType;
  31. import javax.persistence.Enumerated;
  32. import javax.persistence.GeneratedValue;
  33. import javax.persistence.Id;
  34. import javax.persistence.Table;
  35. import java.io.UnsupportedEncodingException;
  36. import java.nio.charset.StandardCharsets;
  37. /**
  38. * This class is the Hibernate model to store a measure in the DB
  39. */
  40. @Entity
  41. @Table(name = "project_measures")
  42. public class MeasureModel implements Cloneable {
  43. public static final int TEXT_VALUE_LENGTH = 4000;
  44. @Id
  45. @Column(name = "id")
  46. @GeneratedValue
  47. private Long id;
  48. @Column(name = "value", updatable = true, nullable = true, precision = 30, scale = 20)
  49. private Double value = 0.0;
  50. @Column(name = "text_value", updatable = true, nullable = true, length = TEXT_VALUE_LENGTH)
  51. private String textValue;
  52. @Column(name = "metric_id", updatable = false, nullable = false)
  53. private Integer metricId;
  54. @Column(name = "snapshot_id", updatable = true, nullable = true)
  55. private Integer snapshotId;
  56. @Column(name = "project_id", updatable = true, nullable = true)
  57. private Integer projectId;
  58. @Column(name = "description", updatable = true, nullable = true, length = 4000)
  59. private String description;
  60. @Column(name = "rule_id", updatable = true, nullable = true)
  61. private Integer ruleId;
  62. @Column(name = "rule_priority", updatable = false, nullable = true)
  63. @Enumerated(EnumType.ORDINAL)
  64. private RulePriority rulePriority;
  65. @Column(name = "alert_status", updatable = true, nullable = true, length = 5)
  66. private String alertStatus;
  67. @Column(name = "alert_text", updatable = true, nullable = true, length = 4000)
  68. private String alertText;
  69. @Column(name = "variation_value_1", updatable = true, nullable = true)
  70. private Double variationValue1;
  71. @Column(name = "variation_value_2", updatable = true, nullable = true)
  72. private Double variationValue2;
  73. @Column(name = "variation_value_3", updatable = true, nullable = true)
  74. private Double variationValue3;
  75. @Column(name = "variation_value_4", updatable = true, nullable = true)
  76. private Double variationValue4;
  77. @Column(name = "variation_value_5", updatable = true, nullable = true)
  78. private Double variationValue5;
  79. @Column(name = "url", updatable = true, nullable = true, length = 2000)
  80. private String url;
  81. @Column(name = "characteristic_id", nullable = true)
  82. private Integer characteristicId;
  83. @Column(name = "person_id", updatable = true, nullable = true)
  84. private Integer personId;
  85. @Column(name = "measure_data", updatable = true, nullable = true, length = 167772150)
  86. private byte[] data;
  87. /**
  88. * Creates a measure based on a metric and a double value
  89. */
  90. public MeasureModel(int metricId, Double val) {
  91. if (val.isNaN() || val.isInfinite()) {
  92. throw new IllegalArgumentException("Measure value is NaN. Metric=" + metricId);
  93. }
  94. this.metricId = metricId;
  95. this.value = val;
  96. }
  97. /**
  98. * Creates a measure based on a metric and an alert level
  99. */
  100. public MeasureModel(int metricId, Metric.Level level) {
  101. this.metricId = metricId;
  102. if (level != null) {
  103. this.textValue = level.toString();
  104. }
  105. }
  106. /**
  107. * Creates a measure based on a metric and a string value
  108. */
  109. public MeasureModel(int metricId, String val) {
  110. this.metricId = metricId;
  111. setData(val);
  112. }
  113. /**
  114. * Creates an empty measure
  115. */
  116. public MeasureModel() {
  117. }
  118. public Long getId() {
  119. return id;
  120. }
  121. public void setId(Long id) {
  122. this.id = id;
  123. }
  124. /**
  125. * @return the measure double value
  126. */
  127. public Double getValue() {
  128. return value;
  129. }
  130. /**
  131. * Sets the measure value
  132. *
  133. * @throws IllegalArgumentException in case value is not a valid double
  134. */
  135. public MeasureModel setValue(Double value) {
  136. if (value != null && (value.isNaN() || value.isInfinite())) {
  137. throw new IllegalArgumentException();
  138. }
  139. this.value = value;
  140. return this;
  141. }
  142. /**
  143. * @return the measure description
  144. */
  145. public String getDescription() {
  146. return description;
  147. }
  148. /**
  149. * Sets the measure description
  150. */
  151. public void setDescription(String description) {
  152. this.description = description;
  153. }
  154. /**
  155. * @return the measure alert level
  156. */
  157. public Metric.Level getLevelValue() {
  158. if (textValue != null) {
  159. return Metric.Level.valueOf(textValue);
  160. }
  161. return null;
  162. }
  163. /**
  164. * Use getData() instead
  165. */
  166. public String getTextValue() {
  167. return textValue;
  168. }
  169. /**
  170. * Use setData() instead
  171. */
  172. public void setTextValue(String textValue) {
  173. this.textValue = textValue;
  174. }
  175. /**
  176. * Concept of measure trend is dropped. This method always returns {@code null} since version 5.2.
  177. * @deprecated since 5.2. See https://jira.sonarsource.com/browse/SONAR-6392
  178. * @return null
  179. */
  180. @CheckForNull
  181. @Deprecated
  182. public Integer getTendency() {
  183. return null;
  184. }
  185. /**
  186. * Concept of measure trend is dropped. This method does nothing.
  187. * @deprecated since 5.2. See https://jira.sonarsource.com/browse/SONAR-6392
  188. */
  189. @Deprecated
  190. public MeasureModel setTendency(Integer tendency) {
  191. return this;
  192. }
  193. /**
  194. * @return whether the measure is about rule
  195. */
  196. public boolean isRuleMeasure() {
  197. return ruleId != null || rulePriority != null;
  198. }
  199. public Integer getMetricId() {
  200. return metricId;
  201. }
  202. public void setMetricId(Integer metricId) {
  203. this.metricId = metricId;
  204. }
  205. /**
  206. * @return the snapshot id the measure is attached to
  207. */
  208. public Integer getSnapshotId() {
  209. return snapshotId;
  210. }
  211. /**
  212. * Sets the snapshot id
  213. *
  214. * @return the current object
  215. */
  216. public MeasureModel setSnapshotId(Integer snapshotId) {
  217. this.snapshotId = snapshotId;
  218. return this;
  219. }
  220. public Integer getRuleId() {
  221. return ruleId;
  222. }
  223. /**
  224. * Sets the rule for the measure
  225. *
  226. * @return the current object
  227. */
  228. public MeasureModel setRuleId(Integer ruleId) {
  229. this.ruleId = ruleId;
  230. return this;
  231. }
  232. /**
  233. * @return the rule priority
  234. */
  235. public RulePriority getRulePriority() {
  236. return rulePriority;
  237. }
  238. /**
  239. * Sets the rule priority
  240. */
  241. public void setRulePriority(RulePriority rulePriority) {
  242. this.rulePriority = rulePriority;
  243. }
  244. /**
  245. * @return the project id
  246. */
  247. public Integer getProjectId() {
  248. return projectId;
  249. }
  250. /**
  251. * Sets the project id
  252. */
  253. public void setProjectId(Integer projectId) {
  254. this.projectId = projectId;
  255. }
  256. /**
  257. * @return the alert status if there is one, null otherwise
  258. */
  259. public Metric.Level getAlertStatus() {
  260. if (alertStatus == null) {
  261. return null;
  262. }
  263. return Metric.Level.valueOf(alertStatus);
  264. }
  265. /**
  266. * Sets the measure alert status
  267. *
  268. * @return the current object
  269. */
  270. public MeasureModel setAlertStatus(Metric.Level level) {
  271. if (level != null) {
  272. this.alertStatus = level.toString();
  273. } else {
  274. this.alertStatus = null;
  275. }
  276. return this;
  277. }
  278. /**
  279. * @return the measure data
  280. */
  281. public String getData(Metric metric) {
  282. if (this.textValue != null) {
  283. return this.textValue;
  284. }
  285. if (metric.isDataType() && data != null) {
  286. try {
  287. return new String(data, StandardCharsets.UTF_8.name());
  288. } catch (UnsupportedEncodingException e) {
  289. // how is it possible to not support UTF-8 ?
  290. Throwables.propagate(e);
  291. }
  292. }
  293. return null;
  294. }
  295. /**
  296. * Sets the measure data
  297. */
  298. public final void setData(String data) {
  299. if (data == null) {
  300. this.textValue = null;
  301. this.data = null;
  302. } else {
  303. if (data.length() > TEXT_VALUE_LENGTH) {
  304. this.textValue = null;
  305. this.data = data.getBytes(StandardCharsets.UTF_8);
  306. } else {
  307. this.textValue = data;
  308. this.data = null;
  309. }
  310. }
  311. }
  312. /**
  313. * @return the text of the alert
  314. */
  315. public String getAlertText() {
  316. return alertText;
  317. }
  318. /**
  319. * Sets the text for the alert
  320. */
  321. public void setAlertText(String alertText) {
  322. this.alertText = alertText;
  323. }
  324. /**
  325. * @return the measure URL
  326. */
  327. public String getUrl() {
  328. return url;
  329. }
  330. /**
  331. * Sets the measure URL
  332. */
  333. public void setUrl(String url) {
  334. this.url = url;
  335. }
  336. @Override
  337. public String toString() {
  338. return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString();
  339. }
  340. public Double getVariationValue1() {
  341. return variationValue1;
  342. }
  343. public void setVariationValue1(Double d) {
  344. this.variationValue1 = d;
  345. }
  346. public Double getVariationValue2() {
  347. return variationValue2;
  348. }
  349. public void setVariationValue2(Double d) {
  350. this.variationValue2 = d;
  351. }
  352. public Double getVariationValue3() {
  353. return variationValue3;
  354. }
  355. public void setVariationValue3(Double d) {
  356. this.variationValue3 = d;
  357. }
  358. public Double getVariationValue4() {
  359. return variationValue4;
  360. }
  361. public void setVariationValue4(Double d) {
  362. this.variationValue4 = d;
  363. }
  364. public Double getVariationValue5() {
  365. return variationValue5;
  366. }
  367. public void setVariationValue5(Double d) {
  368. this.variationValue5 = d;
  369. }
  370. /**
  371. * Saves the current object to database
  372. *
  373. * @return the current object
  374. */
  375. public MeasureModel save(DatabaseSession session) {
  376. session.save(this);
  377. return this;
  378. }
  379. public Integer getCharacteristicId() {
  380. return characteristicId;
  381. }
  382. public MeasureModel setCharacteristicId(Integer characteristicId) {
  383. this.characteristicId = characteristicId;
  384. return this;
  385. }
  386. public Integer getPersonId() {
  387. return personId;
  388. }
  389. public MeasureModel setPersonId(Integer i) {
  390. this.personId = i;
  391. return this;
  392. }
  393. @Override
  394. public Object clone() {
  395. MeasureModel clone = new MeasureModel();
  396. clone.setMetricId(getMetricId());
  397. clone.setDescription(getDescription());
  398. clone.setTextValue(getTextValue());
  399. clone.setAlertStatus(getAlertStatus());
  400. clone.setAlertText(getAlertText());
  401. clone.setVariationValue1(getVariationValue1());
  402. clone.setVariationValue2(getVariationValue2());
  403. clone.setVariationValue3(getVariationValue3());
  404. clone.setVariationValue4(getVariationValue4());
  405. clone.setVariationValue5(getVariationValue5());
  406. clone.setValue(getValue());
  407. clone.setRulePriority(getRulePriority());
  408. clone.setRuleId(getRuleId());
  409. clone.setSnapshotId(getSnapshotId());
  410. clone.setUrl(getUrl());
  411. clone.setCharacteristicId(getCharacteristicId());
  412. clone.setPersonId(getPersonId());
  413. return clone;
  414. }
  415. }