All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.evrete.dsl.WrappedFieldDeclarationMethod Maven / Gradle / Ivy

The newest version!
package org.evrete.dsl;

import org.evrete.api.Type;
import org.evrete.api.TypeResolver;
import org.evrete.dsl.annotation.FieldDeclaration;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.function.Function;

class WrappedFieldDeclarationMethod extends WrappedCloneableMethod> {
    final Class factJavaType;
    private final String factLogicalName;
    final String fieldName;
    private final Class fieldType;

    @SuppressWarnings("unchecked")
    public WrappedFieldDeclarationMethod(WrappedClass declaringClass, Method delegate, FieldDeclaration ann) {
        super(declaringClass, delegate);

        // 1. Get the field's name
        String declaredName = ann.name().trim();
        if (declaredName.isEmpty()) {
            this.fieldName = delegate.getName();
        } else {
            this.fieldName = declaredName;
        }

        // 2. Get the field's type
        this.fieldType = (Class) delegate.getReturnType();
        if (fieldType.equals(void.class) || fieldType.equals(Void.class)) {
            throw new MalformedResourceException("Method " + delegate + " in the " + delegate.getDeclaringClass() + " is annotated as field declaration but is void");
        }

        // 3. Get the fact's Java type
        Parameter[] parameters = delegate.getParameters();
        if (parameters.length != 1) {
            throw new IllegalArgumentException("FieldDeclaration method must have exactly one parameter. Failed method: " + delegate);
        }
        String typeName = ann.type();
        this.factJavaType = (Class) parameters[0].getType();

        // 4. Get the fact's logical type
        this.factLogicalName = typeName == null || typeName.isEmpty() ? Type.logicalNameOf(this.factJavaType) : typeName;

        AbstractDSLProvider.LOGGER.fine(() -> "New field declaration. Subject: '" + this.factLogicalName + "' (" + this.factJavaType.getName() + "), Field: '" + this.fieldName + "' (" + this.fieldType.getName() + "), Declaring method: " + delegate);
    }

    WrappedFieldDeclarationMethod(WrappedFieldDeclarationMethod other, Object bindInstance) {
        super(other, bindInstance);
        this.factLogicalName = other.factLogicalName;
        this.factJavaType = other.factJavaType;
        this.fieldName = other.fieldName;
        this.fieldType = other.fieldType;
    }

    void selfRegister(TypeResolver resolver) {
        selfRegister(resolver, asFunction());
    }

    private void selfRegister(TypeResolver resolver, Function fieldFunction) {
        resolver.getOrDeclare(factLogicalName, factJavaType).declareField(fieldName, fieldType, fieldFunction);
    }

    void dummyRegister(TypeResolver resolver) {
        selfRegister(resolver, new FailingFunction<>());
    }

    @Override
    WrappedFieldDeclarationMethod bindTo(Object bindInstance) {
        return new WrappedFieldDeclarationMethod<>(this, bindInstance);
    }

    static class FailingFunction implements Function {
        @Override
        public V apply(T t) {
            throw new IllegalStateException("Field declaration not updated, please report the bug.");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy