cdc.issues.checks.AbstractChecker Maven / Gradle / Ivy
package cdc.issues.checks;
import cdc.issues.locations.LocatedObject;
import cdc.issues.locations.Location;
import cdc.util.debug.Printable;
import cdc.util.lang.Checks;
/**
* Base abstract class of checkers.
*
* @author Damien Carbonne
*
* @param The checked object type.
*/
public abstract class AbstractChecker implements Printable {
/** The associated manager. */
private final SnapshotManager manager;
/** The class of checked objects. */
private final Class objectClass;
private static CheckResult invoke(AbstractChecker super O> checker,
CheckContext context,
O object,
Location location) {
try {
if (checker.isEnabled()) { // Will probably not throw any exception
if (checker.accepts(object)) { // Might throw an exception
if (checker.isCorrectlyConfigured()) {
return checker.check(context, object, location); // Might throw an exception
} else {
return CheckResult.MISCONFIGURED;
}
} else {
return CheckResult.SKIPPED;
}
} else {
return CheckResult.DISABLED;
}
} catch (final RuntimeException e) {
return CheckResult.EXCEPTION;
}
}
/**
* Invokes a checker and stores the returned result.
*
* @param The checked object type.
* @param checker The checker.
* @param context The context.
* @param object The object to check.
* @param location The object location.
*/
protected static void checkAndStat(AbstractChecker super O> checker,
CheckContext context,
O object,
Location location) {
final CheckResult result = invoke(checker, context, object, location);
checker.addStat(location, result);
}
/**
* Create a checker.
*
* @param manager The manager.
* @param objectClass The object class.
*/
protected AbstractChecker(SnapshotManager manager,
Class objectClass) {
this.manager = Checks.isNotNull(manager, "manager");
this.objectClass = Checks.isNotNull(objectClass, "objectClass");
}
/**
* @return The {@link SnapshotManager}.
*/
public final SnapshotManager getManager() {
return manager;
}
/**
* @param The snapshot manager type.
* @param snapshotManagerClass The snapshot manager class.
* @return The {@link SnapshotManager} as an instance of {@code snapshotManagerClass}.
*/
public final M getManager(Class snapshotManagerClass) {
return snapshotManagerClass.cast(manager);
}
/**
* @return The class of checked objects.
*/
public final Class getObjectClass() {
return objectClass;
}
/**
* @return {@code true} if this checker is enabled.
*/
public abstract boolean isEnabled();
/**
* Returns {@code true} if this checker is correctly configured.
*
* This can be overridden by checkers that depend on a correct configuration.
*
* @return {@code true} if this checker is correctly configured.
*/
public abstract boolean isCorrectlyConfigured();
/**
* Add statistics entry.
*
* Note: Statistics of {@link AbstractRuleChecker} are saved, others are ignored.
*
* @param location The checked object.
* @param result The check result.
*/
private void addStat(Location location,
CheckResult result) {
if (manager.hasStats() && this instanceof AbstractRuleChecker) {
manager.getStats().add(location, ((AbstractRuleChecker>) this).getRule().getId(), result);
}
}
/**
* Returns {@code true} if the passed object must be checked.
*
* A check may be applied to an object only if some conditions are met.
* This may be overridden to define such conditions.
* The default implementation always returns {@code true}.
*
* Note: configuration of checker shall NOT be taken into account.
*
* @param object The object to test.
* @return {@code true} if this checker accepts {@code object}.
*/
public boolean accepts(O object) {
return true;
}
/**
* Method that must be specialized to check an object.
*
* It is this method responsibility to store detected issues into the associated manager.
*
* Note: specializations of {@link AbstractRuleChecker} should return
* {@link CheckResult#SUCCESS SUCCESS} or {@link CheckResult#FAILURE FAILURE}.
* Other results ({@link CheckResult#DISABLED DISABLED}, {@link CheckResult#SKIPPED SKIPPED},
* {@link CheckResult#EXCEPTION EXCEPTION} and {@link CheckResult#MISCONFIGURED MISCONFIGURED})
* are handled by the framework.
*
* @param context The context.
* @param object The object to check.
* @param location The object location.
*
* @return The check result.
*/
public abstract CheckResult check(CheckContext context,
O object,
Location location);
/**
* Check a located object.
*
* @param context The context.
* @param data The located object.
* @return The check result.
*/
public final CheckResult check(CheckContext context,
LocatedObject extends O> data) {
return check(context,
data.getObject(),
data.getLocation());
}
}