use of org.neo4j.kernel.api.procedure.FailedLoadAggregatedFunction in project neo4j by neo4j.
the class ProcedureCompiler method compileAggregationFunction.
private CallableUserAggregationFunction compileAggregationFunction(Class<?> definition, Method create, QualifiedName funcName) throws ProcedureException {
restrictions.verify(funcName);
// find update and result method
Method update = null;
Method result = null;
Class<?> aggregator = create.getReturnType();
for (Method m : aggregator.getDeclaredMethods()) {
if (m.isAnnotationPresent(UserAggregationUpdate.class)) {
if (update != null) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Class '%s' contains multiple methods annotated with '@%s'.", aggregator.getSimpleName(), UserAggregationUpdate.class.getSimpleName());
}
update = m;
}
if (m.isAnnotationPresent(UserAggregationResult.class)) {
if (result != null) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Class '%s' contains multiple methods annotated with '@%s'.", aggregator.getSimpleName(), UserAggregationResult.class.getSimpleName());
}
result = m;
}
}
if (result == null || update == null) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Class '%s' must contain methods annotated with both '@%s' as well as '@%s'.", aggregator.getSimpleName(), UserAggregationResult.class.getSimpleName(), UserAggregationUpdate.class.getSimpleName());
}
if (update.getReturnType() != void.class) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Update method '%s' in %s has type '%s' but must have return type 'void'.", update.getName(), aggregator.getSimpleName(), update.getReturnType().getSimpleName());
}
if (!isPublic(create.getModifiers())) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Aggregation method '%s' in %s must be public.", create.getName(), definition.getSimpleName());
}
if (!isPublic(aggregator.getModifiers())) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Aggregation class '%s' must be public.", aggregator.getSimpleName());
}
if (!isPublic(update.getModifiers())) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Aggregation update method '%s' in %s must be public.", update.getName(), aggregator.getSimpleName());
}
if (!isPublic(result.getModifiers())) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Aggregation result method '%s' in %s must be public.", result.getName(), aggregator.getSimpleName());
}
List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor(update);
Class<?> returnType = result.getReturnType();
TypeCheckers.TypeChecker valueConverter = typeCheckers.checkerFor(returnType);
String description = description(create);
UserAggregationFunction function = create.getAnnotation(UserAggregationFunction.class);
String deprecated = deprecated(create, function::deprecatedBy, "Use of @UserAggregationFunction(deprecatedBy) without @Deprecated in " + funcName);
List<FieldSetter> setters = allFieldInjections.setters(definition);
if (!config.fullAccessFor(funcName.toString())) {
try {
setters = safeFieldInjections.setters(definition);
} catch (ComponentInjectionException e) {
description = describeAndLogLoadFailure(funcName);
UserFunctionSignature signature = new UserFunctionSignature(funcName, inputSignature, valueConverter.type(), deprecated, config.rolesFor(funcName.toString()), description, null, false);
return new FailedLoadAggregatedFunction(signature);
}
}
UserFunctionSignature signature = new UserFunctionSignature(funcName, inputSignature, valueConverter.type(), deprecated, config.rolesFor(funcName.toString()), description, null, false);
return ProcedureCompilation.compileAggregation(signature, setters, create, update, result);
}
Aggregations