/*
* SonarLint for Eclipse
* Copyright (C) 2015-2017 SonarSource SA
* sonarlint@sonarsource.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonarlint.eclipse.core.internal.tracking;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import org.sonarlint.eclipse.core.internal.proto.Sonarlint;
import org.sonarlint.eclipse.core.resource.ISonarLintProject;
import org.sonarsource.sonarlint.core.client.api.connected.objectstore.HashingPathMapper;
import org.sonarsource.sonarlint.core.client.api.connected.objectstore.PathMapper;
import org.sonarsource.sonarlint.core.client.api.connected.objectstore.Reader;
import org.sonarsource.sonarlint.core.client.api.connected.objectstore.Writer;
import org.sonarsource.sonarlint.core.client.api.util.FileUtils;
public class IssueStore {
private Path basePath;
private IndexedObjectStore<String, Sonarlint.Issues> store;
public IssueStore(Path storeBasePath, ISonarLintProject project) {
this.basePath = storeBasePath;
FileUtils.mkdirs(storeBasePath);
StoreIndex<String> index = new StringStoreIndex(storeBasePath);
PathMapper<String> mapper = new HashingPathMapper(storeBasePath, 2);
StoreKeyValidator<String> validator = new PathStoreKeyValidator(project);
Reader<Sonarlint.Issues> reader = is -> {
try {
return Sonarlint.Issues.parseFrom(is);
} catch (IOException e) {
throw new IllegalStateException("Failed to read issues", e);
}
};
Writer<Sonarlint.Issues> writer = (os, issues) -> {
try {
issues.writeTo(os);
} catch (IOException e) {
throw new IllegalStateException("Failed to save issues", e);
}
};
store = new IndexedObjectStore<>(index, mapper, reader, writer, validator);
store.deleteInvalid();
}
public boolean contains(String key) {
return store.contains(key);
}
public void save(String key, Collection<Trackable> issues) throws IOException {
store.write(key, transform(issues));
}
@CheckForNull
public Collection<Trackable> read(String key) throws IOException {
Optional<Sonarlint.Issues> issues = store.read(key);
if (issues.isPresent()) {
return transform(issues.get());
}
return null;
}
public void clean() {
store.deleteInvalid();
}
public void clear() {
FileUtils.deleteRecursively(basePath);
FileUtils.mkdirs(basePath);
}
private static Collection<Trackable> transform(Sonarlint.Issues protoIssues) {
return protoIssues.getIssueList().stream()
.map(IssueStore::transform)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
private static Sonarlint.Issues transform(Collection<Trackable> localIssues) {
Sonarlint.Issues.Builder builder = Sonarlint.Issues.newBuilder();
localIssues.stream()
.map(IssueStore::transform)
.filter(Objects::nonNull)
.forEach(builder::addIssue);
return builder.build();
}
private static Trackable transform(Sonarlint.Issues.Issue issue) {
return new ProtobufIssueTrackable(issue);
}
@CheckForNull
private static Sonarlint.Issues.Issue transform(Trackable localIssue) {
Sonarlint.Issues.Issue.Builder builder = Sonarlint.Issues.Issue.newBuilder()
.setRuleKey(localIssue.getRuleKey())
.setMessage(localIssue.getMessage())
.setResolved(localIssue.isResolved())
.setSeverity(localIssue.getSeverity())
.setType(localIssue.getType());
if (localIssue.getAssignee() != null) {
builder.setAssignee(localIssue.getAssignee());
}
if (localIssue.getCreationDate() != null) {
builder.setCreationDate(localIssue.getCreationDate());
}
if (localIssue.getLineHash() != null) {
builder.setChecksum(localIssue.getLineHash());
}
if (localIssue.getServerIssueKey() != null) {
builder.setServerIssueKey(localIssue.getServerIssueKey());
}
if (localIssue.getLine() != null) {
builder.setLine(localIssue.getLine());
}
if (localIssue.getMarkerId() != null) {
builder.setMarkerId(localIssue.getMarkerId());
}
return builder.build();
}
}