use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.
the class ExhaustiveVisitor method verify.
public static void verify(ClassMirror<? extends ExhaustiveVisitor> classMirror) throws ClassNotFoundException {
Class<? extends ExhaustiveVisitor> clazz = classMirror.loadClass();
System.out.println("Verifying " + clazz);
VisitorInfo info = clazz.getAnnotation(VisitorInfo.class);
Class<?> baseClass = classMirror.getGenerics().get(new ClassMirror<>(ExhaustiveVisitor.class).getClassReference()).get(0).loadClass();
List<String> uhohs = new ArrayList<>();
// Make sure all public visit methods have only one parameter (which extends T) and return void
Set<Class<?>> handledClasses = new HashSet<>();
for (Method m : clazz.getMethods()) {
if (m.getDeclaringClass() == ExhaustiveVisitor.class) {
// This is the method defined in this class, which doesn't need to be checked. Skip it.
continue;
}
if (VISIT.equals(m.getName()) && (m.getModifiers() & Modifier.PUBLIC) != 0) {
if (m.getReturnType() != void.class) {
uhohs.add("Return type of public visit() methods must be void, but " + clazz.getName() + " " + m + " does not conform");
}
if (m.getParameterTypes().length != 1) {
uhohs.add("Public visit() methods must accept exactly one parameter, but" + clazz.getName() + " " + m + " does not conform");
} else {
Class<?> param = m.getParameterTypes()[0];
if (baseClass.isAssignableFrom(param)) {
handledClasses.add(param);
} else {
uhohs.add("Public visit() methods parameters must extend the given base class's type, but the" + " parameter of method " + m + " in " + clazz.getName() + " has a disjoint type than " + baseClass.getName() + ". Make the method non-public, or rename it, if you would" + " like to keep the method.");
}
}
}
}
// Make sure that all subclasses are accounted for, taking into
// account the value of directSubclassOnly
Set<Class<?>> needsToHandle = new HashSet<>();
for (Class<?> c : ClassDiscovery.getDefaultInstance().loadClassesThatExtend(baseClass)) {
if ((c.getModifiers() & Modifier.ABSTRACT) != 0) {
// thus is not required to be implemented
continue;
}
if (info != null && info.directSubclassOnly()) {
if (c.getSuperclass() == baseClass || Arrays.asList(c.getInterfaces()).contains(c)) {
needsToHandle.add(c);
}
} else {
needsToHandle.add(c);
}
}
if (!needsToHandle.equals(handledClasses)) {
String s = clazz.getName() + " is missing needed implementations of the visit method. It is required" + " that it handle the following: " + needsToHandle + ", however, it only handles the following:" + " " + handledClasses + ". Please add the following implementations:\n";
needsToHandle.removeAll(handledClasses);
for (Class<?> n : needsToHandle) {
s += "public void visit(" + n.getName().replace("$", ".") + " obj) { /* Implement me */ }\n";
}
uhohs.add(s);
}
if (!uhohs.isEmpty()) {
throw new RuntimeException(StringUtils.Join(uhohs, "\n"));
}
}
use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.
the class ClassDiscovery method getKnownClasses.
/**
* Returns a list of all known classes. The ClassMirror for each class is returned, and further examination can be
* done on each class, or loadClass can be called on the ClassMirror to get the actual Class object. No ClassLoaders
* are involved directly in this operation.
*
* @return A list of ClassMirror objects for all known classes
*/
public Set<ClassMirror<?>> getKnownClasses() {
doDiscovery();
Set<ClassMirror<?>> ret = new HashSet<>();
for (URL url : urlCache) {
ret.addAll(getKnownClasses(url));
}
return ret;
}
use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.
the class AnnotationChecks method verifyNonInheritImplements.
public static void verifyNonInheritImplements() throws ClassNotFoundException {
Set<ClassMirror<?>> toVerify;
toVerify = ClassDiscovery.getDefaultInstance().getClassesWithAnnotation(NonInheritImplements.class);
Set<String> uhohs = new HashSet<>();
for (ClassMirror<?> c : toVerify) {
Class<?> iface = Class.forName(c.getAnnotation(NonInheritImplements.class).getValue("value").toString());
if (!iface.isInterface()) {
uhohs.add("The class given to @NonInheritImplements, tagged on " + c.getClassName() + " is not an interface, and must be.");
continue;
}
// methods.
for (Method im : iface.getDeclaredMethods()) {
try {
c.getMethod(im.getName(), im.getParameterTypes());
} catch (NoSuchMethodException ex) {
String msg = "The class " + c.getClassName() + " implements " + iface.getSimpleName() + " but does not" + " implement the method public " + im.getReturnType().getSimpleName() + " " + im.getName() + "(";
List<String> params = new ArrayList<>();
msg += StringUtils.Join(im.getParameters(), ", ", ", ", ", ", "", (Object item) -> {
Parameter ci = (Parameter) item;
return ci.getType().getSimpleName() + " " + ci.getName();
});
msg += ") {}";
uhohs.add(msg);
}
}
}
if (!uhohs.isEmpty()) {
String error = StringUtils.Join(uhohs, "\n");
throw new Error(error);
}
}
use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.
the class GeneralTest method testAnnotationValue.
@Test
public void testAnnotationValue() throws Exception {
ClassMirror<?> c1 = ClassDiscovery.getDefaultInstance().forName(GeneralTest.class.getName());
ClassMirror<GeneralTest> c2 = new ClassMirror<>(GeneralTest.class);
FieldMirror f1 = c1.getField("field");
FieldMirror f2 = c1.getField("field");
MethodMirror m1 = c1.getMethod("method", new Class[] {});
MethodMirror m2 = c2.getMethod("method", new Class[] {});
assertEquals(c1.loadAnnotation(TestAnnotation.class).value(), "value");
assertEquals(c2.loadAnnotation(TestAnnotation.class).value(), "value");
assertEquals(f1.loadAnnotation(TestAnnotation.class).value(), "field");
assertEquals(f2.loadAnnotation(TestAnnotation.class).value(), "field");
assertEquals(m1.loadAnnotation(TestAnnotation.class).value(), "method");
assertEquals(m2.loadAnnotation(TestAnnotation.class).value(), "method");
}
Aggregations