package pl.touk.sputnik.processor.scalastyle;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.scalastyle.EndFile;
import org.scalastyle.FileSpec;
import org.scalastyle.Level;
import org.scalastyle.Message;
import org.scalastyle.MessageHelper;
import org.scalastyle.RealFileSpec;
import org.scalastyle.ScalastyleChecker;
import org.scalastyle.ScalastyleConfiguration;
import org.scalastyle.StartFile;
import org.scalastyle.StyleError;
import pl.touk.sputnik.configuration.Configuration;
import pl.touk.sputnik.configuration.GeneralOption;
import pl.touk.sputnik.review.Review;
import pl.touk.sputnik.review.ReviewProcessor;
import pl.touk.sputnik.review.ReviewResult;
import pl.touk.sputnik.review.Severity;
import pl.touk.sputnik.review.Violation;
import pl.touk.sputnik.review.filter.ScalaFilter;
import pl.touk.sputnik.review.transformer.IOFileTransformer;
import scala.Option;
import scala.Some;
import java.io.File;
import java.util.List;
@Slf4j
@AllArgsConstructor
public class ScalastyleProcessor implements ReviewProcessor {
private static final String SOURCE_NAME = "Scalastyle";
private final MessageHelper messageHelper = new MessageHelper(ClassLoader.getSystemClassLoader());
@NotNull
private final Configuration config;
@Nullable
@Override
@SuppressWarnings("unchecked")
public ReviewResult process(@NotNull Review review) {
String scalastyleConfigFile = config.getProperty(GeneralOption.SCALASTYLE_CONFIGURATION_FILE);
ScalastyleConfiguration configuration = ScalastyleConfiguration.readFromXml(scalastyleConfigFile);
List<Message> messages = new ScalastyleChecker().checkFilesAsJava(configuration, toFileSpec(review.getFiles(new ScalaFilter(), new IOFileTransformer())));
return toReviewResult(messages);
}
private List<FileSpec> toFileSpec(List<File> ioFiles) {
List<FileSpec> fileSpecs = Lists.newArrayList();
for (File file : ioFiles) {
fileSpecs.add(new RealFileSpec(file.getAbsolutePath(), new Some<>("UTF-8")));
}
return fileSpecs;
}
@SuppressWarnings("unchecked")
private ReviewResult toReviewResult(List<Message> messages) {
ReviewResult reviewResult = new ReviewResult();
String currentFileName = null;
for (Message msg : messages) {
log.info("Got msg: {}", msg);
if (msg instanceof StartFile) {
StartFile startFile = (StartFile) msg;
currentFileName = startFile.fileSpec().name();
}
if (msg instanceof EndFile) {
currentFileName = null;
}
if (msg instanceof StyleError) {
StyleError styleError = (StyleError) msg;
reviewResult.add(new Violation(currentFileName,
option(styleError.lineNumber(), -1),
messageHelper.message(styleError.clazz().getClassLoader(), styleError.key(), styleError.args()),
errorLevel(styleError.level())));
}
}
return reviewResult;
}
@SuppressWarnings("unchecked")
private <T> T option(Option option, T elseValue) {
if (option.isDefined()) {
return (T) option.get();
} else {
return elseValue;
}
}
private Severity errorLevel(Level level) {
if (level.name().equals(Level.Error())) {
return Severity.ERROR;
}
if (level.name().equals(Level.Info())) {
return Severity.INFO;
}
if (level.name().equals(Level.Warning())) {
return Severity.WARNING;
}
log.warn("Got unrecognized severity level: {}", level);
return Severity.IGNORE;
}
@NotNull
@Override
public String getName() {
return SOURCE_NAME;
}
}