001 /* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2014 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * SonarQube 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 * SonarQube 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 License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020 package org.sonar.api.batch.sensor.issue.internal; 021 022 import com.google.common.base.Preconditions; 023 import com.google.common.base.Strings; 024 import org.sonar.api.batch.fs.InputDir; 025 import org.sonar.api.batch.fs.InputFile; 026 import org.sonar.api.batch.fs.InputPath; 027 import org.sonar.api.batch.sensor.SensorStorage; 028 import org.sonar.api.batch.sensor.internal.DefaultStorable; 029 import org.sonar.api.batch.sensor.issue.Issue; 030 import org.sonar.api.rule.RuleKey; 031 import org.sonar.api.utils.internal.Uuids; 032 033 import javax.annotation.CheckForNull; 034 import javax.annotation.Nullable; 035 036 public class DefaultIssue extends DefaultStorable implements Issue { 037 038 private static final String INPUT_DIR_SHOULD_BE_NON_NULL = "InputDir should be non null"; 039 private static final String INPUT_FILE_SHOULD_BE_NON_NULL = "InputFile should be non null"; 040 private static final String ON_FILE_OR_ON_DIR_ALREADY_CALLED = "onFile or onDir already called"; 041 private static final String ON_PROJECT_ALREADY_CALLED = "onProject already called"; 042 private String key; 043 private boolean onProject = false; 044 private InputPath path; 045 private RuleKey ruleKey; 046 private String message; 047 private Integer line; 048 private Double effortToFix; 049 private Severity overridenSeverity; 050 051 public DefaultIssue() { 052 super(null); 053 this.key = Uuids.create(); 054 } 055 056 public DefaultIssue(SensorStorage storage) { 057 super(storage); 058 this.key = Uuids.create(); 059 } 060 061 @Override 062 public DefaultIssue ruleKey(RuleKey ruleKey) { 063 this.ruleKey = ruleKey; 064 return this; 065 } 066 067 @Override 068 public DefaultIssue onFile(InputFile file) { 069 Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED); 070 Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED); 071 Preconditions.checkNotNull(file, INPUT_FILE_SHOULD_BE_NON_NULL); 072 this.path = file; 073 return this; 074 } 075 076 @Override 077 public DefaultIssue onDir(InputDir dir) { 078 Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED); 079 Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED); 080 Preconditions.checkNotNull(dir, INPUT_DIR_SHOULD_BE_NON_NULL); 081 this.path = dir; 082 return this; 083 } 084 085 @Override 086 public DefaultIssue onProject() { 087 Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED); 088 Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED); 089 this.onProject = true; 090 return this; 091 } 092 093 @Override 094 public DefaultIssue atLine(int line) { 095 Preconditions.checkState(this.path != null && this.path instanceof InputFile, "atLine should be called after onFile"); 096 this.line = line; 097 return this; 098 } 099 100 @Override 101 public DefaultIssue effortToFix(@Nullable Double effortToFix) { 102 this.effortToFix = effortToFix; 103 return this; 104 } 105 106 @Override 107 public DefaultIssue message(String message) { 108 this.message = message; 109 return this; 110 } 111 112 @Override 113 public Issue overrideSeverity(@Nullable Severity severity) { 114 this.overridenSeverity = severity; 115 return this; 116 } 117 118 @Override 119 public RuleKey ruleKey() { 120 return this.ruleKey; 121 } 122 123 @CheckForNull 124 @Override 125 public InputPath inputPath() { 126 return this.path; 127 } 128 129 @Override 130 public Integer line() { 131 return this.line; 132 } 133 134 @Override 135 public String message() { 136 return this.message; 137 } 138 139 @Override 140 public Severity overridenSeverity() { 141 return this.overridenSeverity; 142 } 143 144 @Override 145 public Double effortToFix() { 146 return this.effortToFix; 147 } 148 149 public String key() { 150 return this.key; 151 } 152 153 @Override 154 public void doSave() { 155 Preconditions.checkNotNull(this.ruleKey, "ruleKey is mandatory on issue"); 156 Preconditions.checkState(!Strings.isNullOrEmpty(key), "Fail to generate issue key"); 157 storage.store(this); 158 } 159 160 /** 161 * For testing only. 162 */ 163 public DefaultIssue withKey(String key) { 164 this.key = key; 165 return this; 166 } 167 168 @Override 169 public boolean equals(Object o) { 170 if (this == o) { 171 return true; 172 } 173 if (o == null || getClass() != o.getClass()) { 174 return false; 175 } 176 DefaultIssue that = (DefaultIssue) o; 177 return !key.equals(that.key); 178 } 179 180 @Override 181 public int hashCode() { 182 return key.hashCode(); 183 } 184 185 }