package org.infernus.idea.checkstyle.exception;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
import org.infernus.idea.checkstyle.csapi.CheckstyleInternalObject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* The service layer did not understand a {@link CheckstyleInternalObject} passed to it. This exception always
* indicates a bug! The root cause can be a simple oversight (CheckstyleInternalObject is just a tagging interface,
* so it may just be the wrong object), or the CheckstyleInternalObject was cached for too long, and the classloader
* of the service layer has changed.
* <p><b>Important:</b> Be sure to throw it <em>only</em> from the 'csaccess' sourceset!</p>
*/
public class CheckstyleVersionMixException extends CheckstyleServiceException {
public CheckstyleVersionMixException(@NotNull final Class<? extends CheckstyleInternalObject> expectedClass,
@Nullable final CheckstyleInternalObject actualObject) {
super(buildMessage(expectedClass, actualObject));
}
@NotNull
private static String buildMessage(@NotNull final Class<? extends CheckstyleInternalObject> expectedClass,
@Nullable final CheckstyleInternalObject actualObject) {
StringBuilder sb = new StringBuilder("internal error - A ");
sb.append(CheckstyleInternalObject.class.getSimpleName());
sb.append(" passed to the service layer could not be processed. Expected: ");
sb.append(expectedClass.getName());
sb.append(", actual: ");
if (actualObject != null) {
sb.append(actualObject.getClass().getName());
sb.append(" [interfaces: ");
for (Iterator<String> iter = getAllInterfaces(actualObject.getClass()).iterator(); iter.hasNext(); ) {
sb.append(iter.next());
if (iter.hasNext()) {
sb.append(", ");
}
}
sb.append("]");
} else {
sb.append("null");
}
sb.append(". ");
sb.append("This is a bug. Either the wrong object (or null) was passed to the service layer, or a ");
sb.append(CheckstyleInternalObject.class.getSimpleName());
sb.append(" was cached for too long and the service layer's classloader has changed.");
return sb.toString();
}
@NotNull
private static SortedSet<String> getAllInterfaces(@Nullable final Class<?> theClass) {
SortedSet<String> result = new TreeSet<>();
for (Class<?> c = theClass; c != null; c = c.getSuperclass()) {
for (Class<?> intf : c.getInterfaces()) {
result.add(intf.getName());
result.addAll(getAllInterfaces(intf)); // get super interfaces
}
}
return result;
}
}