private void validateClass(Class<?> source, ValidationProblemCollector problems) { int modifiers = source.getModifiers(); if (Modifier.isInterface(modifiers)) { problems.add("Must be a class, not an interface"); } if (source.getEnclosingClass() != null) { if (Modifier.isStatic(modifiers)) { if (Modifier.isPrivate(modifiers)) { problems.add("Class cannot be private"); } } else { problems.add("Enclosed classes must be static and non private"); } } Constructor<?>[] constructors = source.getDeclaredConstructors(); for (Constructor<?> constructor : constructors) { if (constructor.getParameterTypes().length > 0) { problems.add("Cannot declare a constructor that takes arguments"); break; } } Field[] fields = source.getDeclaredFields(); for (Field field : fields) { int fieldModifiers = field.getModifiers(); if (!field.isSynthetic() && !(Modifier.isStatic(fieldModifiers) && Modifier.isFinal(fieldModifiers))) { problems.add(field, "Fields must be static final."); } } }
private void validateNonRuleMethod(Method method, ValidationProblemCollector problems) { if (!Modifier.isPrivate(method.getModifiers()) && !Modifier.isStatic(method.getModifiers()) && !method.isSynthetic() && !ModelSchemaUtils.isObjectMethod(method)) { problems.add(method, "A method that is not annotated as a rule must be private"); } }
private void validateRuleMethod( MethodRuleDefinition<?, ?> ruleDefinition, Method ruleMethod, ValidationProblemCollector problems) { if (Modifier.isPrivate(ruleMethod.getModifiers())) { problems.add(ruleMethod, "A rule method cannot be private"); } if (Modifier.isAbstract(ruleMethod.getModifiers())) { problems.add(ruleMethod, "A rule method cannot be abstract"); } if (ruleMethod.getTypeParameters().length > 0) { problems.add(ruleMethod, "Cannot have type variables (i.e. cannot be a generic method)"); } // TODO validations on method: synthetic, bridge methods, varargs, abstract, native ModelType<?> returnType = ModelType.returnType(ruleMethod); if (returnType.isRawClassOfParameterizedType()) { problems.add( ruleMethod, "Raw type " + returnType + " used for return type (all type parameters must be specified of parameterized type)"); } for (int i = 0; i < ruleDefinition.getReferences().size(); i++) { ModelReference<?> reference = ruleDefinition.getReferences().get(i); if (reference.getType().isRawClassOfParameterizedType()) { problems.add( ruleMethod, "Raw type " + reference.getType() + " used for parameter " + (i + 1) + " (all type parameters must be specified of parameterized type)"); } if (reference.getPath() != null) { try { ModelPath.validatePath(reference.getPath().toString()); } catch (Exception e) { problems.add( ruleDefinition, "The declared model element path '" + reference.getPath() + "' used for parameter " + (i + 1) + " is not a valid path", e); } } } }