package org.infernus.idea.checkstyle.service;
import java.util.HashSet;
import java.util.Set;
import antlr.RecognitionException;
import antlr.TokenStreamException;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import org.infernus.idea.checkstyle.exception.CheckStylePluginException;
import org.infernus.idea.checkstyle.exception.CheckStylePluginParseException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static java.util.Arrays.asList;
import static java.util.Optional.ofNullable;
public class ExceptionWrapper {
private static final Set<Class<? extends Throwable>> PARSE_EXCEPTIONS = new HashSet<>(asList(
RecognitionException.class,
TokenStreamException.class,
NullPointerException.class,
ArrayIndexOutOfBoundsException.class,
StringIndexOutOfBoundsException.class,
IllegalStateException.class));
public CheckStylePluginException wrap(@Nullable final String message, @NotNull final Throwable error) {
final Throwable root = rootOrCheckStyleException(error);
final String exMessage = ofNullable(message).orElseGet(root::getMessage);
if (isParseException(root)) {
return new CheckStylePluginParseException(exMessage, root);
}
return new CheckStylePluginException(exMessage, root);
}
private Throwable rootOrCheckStyleException(final Throwable error) {
Throwable root = error;
while (root.getCause() != null && notBaseCheckstyleException(root)) {
root = root.getCause();
}
return root;
}
private boolean notBaseCheckstyleException(final Throwable root) {
return !(root instanceof CheckstyleException && !(root.getCause() instanceof CheckstyleException));
}
private boolean isParseException(final Throwable throwable) {
if (throwable instanceof CheckstyleException && throwable.getCause() != null) {
for (Class<? extends Throwable> parseExceptionType : PARSE_EXCEPTIONS) {
if (parseExceptionType.isAssignableFrom(throwable.getCause().getClass())) {
return true;
}
}
}
return false;
}
}