Search in sources :

Example 1 with ComponentInjectionException

use of org.neo4j.kernel.api.exceptions.ComponentInjectionException in project neo4j by neo4j.

the class FieldInjections method createInjector.

private FieldSetter createInjector(Class<?> cls, Field field) throws ProcedureException {
    try {
        ComponentRegistry.Provider<?> provider = components.providerFor(field.getType());
        if (provider == null) {
            throw new ComponentInjectionException(Status.Procedure.ProcedureRegistrationFailed, "Unable to set up injection for procedure `%s`, the field `%s` " + "has type `%s` which is not a known injectable component.", cls.getSimpleName(), field.getName(), field.getType());
        }
        MethodHandle setter = MethodHandles.lookup().unreflectSetter(field);
        return new FieldSetter(field, setter, provider);
    } catch (IllegalAccessException e) {
        throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Unable to set up injection for `%s`, failed to access field `%s`: %s", e, cls.getSimpleName(), field.getName(), e.getMessage());
    }
}
Also used : ProcedureException(org.neo4j.kernel.api.exceptions.ProcedureException) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException) MethodHandle(java.lang.invoke.MethodHandle)

Example 2 with ComponentInjectionException

use of org.neo4j.kernel.api.exceptions.ComponentInjectionException in project neo4j by neo4j.

the class ReflectiveProcedureCompiler method compileProcedure.

private CallableProcedure compileProcedure(Class<?> procDefinition, MethodHandle constructor, Method method, Optional<String> warning, boolean fullAccess, QualifiedName procName) throws ProcedureException, IllegalAccessException {
    MethodHandle procedureMethod = lookup.unreflect(method);
    List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor(method);
    OutputMapper outputMapper = outputMappers.mapper(method);
    Optional<String> description = description(method);
    Procedure procedure = method.getAnnotation(Procedure.class);
    Mode mode = procedure.mode();
    if (method.isAnnotationPresent(PerformsWrites.class)) {
        if (!procedure.mode().equals(org.neo4j.procedure.Mode.DEFAULT)) {
            throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Conflicting procedure annotation, cannot use PerformsWrites and mode");
        } else {
            mode = Mode.WRITE;
        }
    }
    Optional<String> deprecated = deprecated(method, procedure::deprecatedBy, "Use of @Procedure(deprecatedBy) without @Deprecated in " + procName);
    List<FieldInjections.FieldSetter> setters = allFieldInjections.setters(procDefinition);
    if (!fullAccess && !config.fullAccessFor(procName.toString())) {
        try {
            setters = safeFieldInjections.setters(procDefinition);
        } catch (ComponentInjectionException e) {
            description = Optional.of(procName.toString() + " is not available due to having restricted access rights, check configuration.");
            log.warn(description.get());
            ProcedureSignature signature = new ProcedureSignature(procName, inputSignature, outputMapper.signature(), Mode.DEFAULT, Optional.empty(), new String[0], description, warning);
            return new FailedLoadProcedure(signature);
        }
    }
    ProcedureSignature signature = new ProcedureSignature(procName, inputSignature, outputMapper.signature(), mode, deprecated, config.rolesFor(procName.toString()), description, warning);
    return new ReflectiveProcedure(signature, constructor, procedureMethod, outputMapper, setters);
}
Also used : FailedLoadProcedure(org.neo4j.kernel.api.proc.FailedLoadProcedure) Mode(org.neo4j.procedure.Mode) FieldSignature(org.neo4j.kernel.api.proc.FieldSignature) ProcedureSignature(org.neo4j.kernel.api.proc.ProcedureSignature) FailedLoadProcedure(org.neo4j.kernel.api.proc.FailedLoadProcedure) CallableProcedure(org.neo4j.kernel.api.proc.CallableProcedure) Procedure(org.neo4j.procedure.Procedure) ProcedureException(org.neo4j.kernel.api.exceptions.ProcedureException) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException) OutputMapper(org.neo4j.kernel.impl.proc.OutputMappers.OutputMapper) MethodHandle(java.lang.invoke.MethodHandle)

Example 3 with ComponentInjectionException

use of org.neo4j.kernel.api.exceptions.ComponentInjectionException in project neo4j by neo4j.

the class ReflectiveProcedureCompiler method compileAggregationFunction.

private CallableUserAggregationFunction compileAggregationFunction(Class<?> definition, MethodHandle constructor, Method method, QualifiedName funcName) throws ProcedureException, IllegalAccessException {
    if (funcName.namespace() == null || funcName.namespace().length == 0) {
        throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "It is not allowed to define functions in the root namespace please use a namespace, e.g. `@UserFunction(\"org.example.com.%s\")", funcName.name());
    }
    //find update and result method
    Method update = null;
    Method result = null;
    Class<?> aggregator = method.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 (!Modifier.isPublic(method.getModifiers())) {
        throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Aggregation method '%s' in %s must be public.", method.getName(), definition.getSimpleName());
    }
    if (!Modifier.isPublic(aggregator.getModifiers())) {
        throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Aggregation class '%s' must be public.", aggregator.getSimpleName());
    }
    if (!Modifier.isPublic(update.getModifiers())) {
        throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Aggregation update method '%s' in %s must be public.", method.getName(), aggregator.getSimpleName());
    }
    if (!Modifier.isPublic(result.getModifiers())) {
        throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Aggregation result method '%s' in %s must be public.", method.getName(), aggregator.getSimpleName());
    }
    List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor(update);
    Class<?> returnType = result.getReturnType();
    TypeMappers.NeoValueConverter valueConverter = typeMappers.converterFor(returnType);
    MethodHandle creator = lookup.unreflect(method);
    MethodHandle updateMethod = lookup.unreflect(update);
    MethodHandle resultMethod = lookup.unreflect(result);
    Optional<String> description = description(method);
    UserAggregationFunction function = method.getAnnotation(UserAggregationFunction.class);
    Optional<String> deprecated = deprecated(method, function::deprecatedBy, "Use of @UserAggregationFunction(deprecatedBy) without @Deprecated in " + funcName);
    List<FieldInjections.FieldSetter> setters = allFieldInjections.setters(definition);
    if (!config.fullAccessFor(funcName.toString())) {
        try {
            setters = safeFieldInjections.setters(definition);
        } catch (ComponentInjectionException e) {
            description = Optional.of(funcName.toString() + " is not available due to having restricted access rights, check configuration.");
            log.warn(description.get());
            UserFunctionSignature signature = new UserFunctionSignature(funcName, inputSignature, valueConverter.type(), deprecated, config.rolesFor(funcName.toString()), description);
            return new FailedLoadAggregatedFunction(signature);
        }
    }
    UserFunctionSignature signature = new UserFunctionSignature(funcName, inputSignature, valueConverter.type(), deprecated, config.rolesFor(funcName.toString()), description);
    return new ReflectiveUserAggregationFunction(signature, constructor, creator, updateMethod, resultMethod, valueConverter, setters);
}
Also used : UserAggregationResult(org.neo4j.procedure.UserAggregationResult) UserAggregationUpdate(org.neo4j.procedure.UserAggregationUpdate) FieldSignature(org.neo4j.kernel.api.proc.FieldSignature) Method(java.lang.reflect.Method) UserFunctionSignature(org.neo4j.kernel.api.proc.UserFunctionSignature) CallableUserAggregationFunction(org.neo4j.kernel.api.proc.CallableUserAggregationFunction) UserAggregationFunction(org.neo4j.procedure.UserAggregationFunction) FailedLoadAggregatedFunction(org.neo4j.kernel.api.proc.FailedLoadAggregatedFunction) ProcedureException(org.neo4j.kernel.api.exceptions.ProcedureException) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException) MethodHandle(java.lang.invoke.MethodHandle)

Example 4 with ComponentInjectionException

use of org.neo4j.kernel.api.exceptions.ComponentInjectionException in project neo4j by neo4j.

the class ReflectiveProcedureCompiler method compileFunction.

private CallableUserFunction compileFunction(Class<?> procDefinition, MethodHandle constructor, Method method, QualifiedName procName) throws ProcedureException, IllegalAccessException {
    if (procName.namespace() == null || procName.namespace().length == 0) {
        throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "It is not allowed to define functions in the root namespace please use a namespace, e.g. `@UserFunction(\"org.example.com.%s\")", procName.name());
    }
    List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor(method);
    Class<?> returnType = method.getReturnType();
    TypeMappers.NeoValueConverter valueConverter = typeMappers.converterFor(returnType);
    MethodHandle procedureMethod = lookup.unreflect(method);
    Optional<String> description = description(method);
    UserFunction function = method.getAnnotation(UserFunction.class);
    Optional<String> deprecated = deprecated(method, function::deprecatedBy, "Use of @UserFunction(deprecatedBy) without @Deprecated in " + procName);
    List<FieldInjections.FieldSetter> setters = allFieldInjections.setters(procDefinition);
    if (!config.fullAccessFor(procName.toString())) {
        try {
            setters = safeFieldInjections.setters(procDefinition);
        } catch (ComponentInjectionException e) {
            description = Optional.of(procName.toString() + " is not available due to having restricted access rights, check configuration.");
            log.warn(description.get());
            UserFunctionSignature signature = new UserFunctionSignature(procName, inputSignature, valueConverter.type(), deprecated, config.rolesFor(procName.toString()), description);
            return new FailedLoadFunction(signature);
        }
    }
    UserFunctionSignature signature = new UserFunctionSignature(procName, inputSignature, valueConverter.type(), deprecated, config.rolesFor(procName.toString()), description);
    return new ReflectiveUserFunction(signature, constructor, procedureMethod, valueConverter, setters);
}
Also used : FieldSignature(org.neo4j.kernel.api.proc.FieldSignature) UserFunctionSignature(org.neo4j.kernel.api.proc.UserFunctionSignature) FailedLoadFunction(org.neo4j.kernel.api.proc.FailedLoadFunction) CallableUserFunction(org.neo4j.kernel.api.proc.CallableUserFunction) UserFunction(org.neo4j.procedure.UserFunction) ProcedureException(org.neo4j.kernel.api.exceptions.ProcedureException) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

MethodHandle (java.lang.invoke.MethodHandle)4 ComponentInjectionException (org.neo4j.kernel.api.exceptions.ComponentInjectionException)4 ProcedureException (org.neo4j.kernel.api.exceptions.ProcedureException)4 FieldSignature (org.neo4j.kernel.api.proc.FieldSignature)3 UserFunctionSignature (org.neo4j.kernel.api.proc.UserFunctionSignature)2 Method (java.lang.reflect.Method)1 CallableProcedure (org.neo4j.kernel.api.proc.CallableProcedure)1 CallableUserAggregationFunction (org.neo4j.kernel.api.proc.CallableUserAggregationFunction)1 CallableUserFunction (org.neo4j.kernel.api.proc.CallableUserFunction)1 FailedLoadAggregatedFunction (org.neo4j.kernel.api.proc.FailedLoadAggregatedFunction)1 FailedLoadFunction (org.neo4j.kernel.api.proc.FailedLoadFunction)1 FailedLoadProcedure (org.neo4j.kernel.api.proc.FailedLoadProcedure)1 ProcedureSignature (org.neo4j.kernel.api.proc.ProcedureSignature)1 OutputMapper (org.neo4j.kernel.impl.proc.OutputMappers.OutputMapper)1 Mode (org.neo4j.procedure.Mode)1 Procedure (org.neo4j.procedure.Procedure)1 UserAggregationFunction (org.neo4j.procedure.UserAggregationFunction)1 UserAggregationResult (org.neo4j.procedure.UserAggregationResult)1 UserAggregationUpdate (org.neo4j.procedure.UserAggregationUpdate)1 UserFunction (org.neo4j.procedure.UserFunction)1