Search in sources :

Example 1 with PolymorphicConfigInstance

use of org.apache.ignite.configuration.annotation.PolymorphicConfigInstance in project ignite-3 by apache.

the class ConfigurationAsmGenerator method compileRootSchema.

/**
 * Generates, defines, loads and initializes all dynamic classes required for the given configuration schema.
 *
 * @param rootSchemaClass             Class of the root configuration schema.
 * @param internalSchemaExtensions    Internal extensions ({@link InternalConfiguration}) of configuration schemas ({@link
 *                                    ConfigurationRoot} and {@link Config}). Mapping: original schema -> extensions.
 * @param polymorphicSchemaExtensions Polymorphic extensions ({@link PolymorphicConfigInstance}) of configuration schemas ({@link
 *                                    PolymorphicConfig}). Mapping: original schema -> extensions.
 */
public synchronized void compileRootSchema(Class<?> rootSchemaClass, Map<Class<?>, Set<Class<?>>> internalSchemaExtensions, Map<Class<?>, Set<Class<?>>> polymorphicSchemaExtensions) {
    if (schemasInfo.containsKey(rootSchemaClass)) {
        // Already compiled.
        return;
    }
    Queue<Class<?>> compileQueue = new ArrayDeque<>();
    compileQueue.add(rootSchemaClass);
    schemasInfo.put(rootSchemaClass, new SchemaClassesInfo(rootSchemaClass));
    Set<Class<?>> schemas = new HashSet<>();
    List<ClassDefinition> classDefs = new ArrayList<>();
    while (!compileQueue.isEmpty()) {
        Class<?> schemaClass = compileQueue.poll();
        assert schemaClass.isAnnotationPresent(ConfigurationRoot.class) || schemaClass.isAnnotationPresent(Config.class) || isPolymorphicConfig(schemaClass) : schemaClass + " is not properly annotated";
        assert schemasInfo.containsKey(schemaClass) : schemaClass;
        Set<Class<?>> internalExtensions = internalSchemaExtensions.getOrDefault(schemaClass, Set.of());
        Set<Class<?>> polymorphicExtensions = polymorphicSchemaExtensions.getOrDefault(schemaClass, Set.of());
        assert internalExtensions.isEmpty() || polymorphicExtensions.isEmpty() : "Internal and polymorphic extensions are not allowed at the same time: " + schemaClass;
        if (isPolymorphicConfig(schemaClass) && polymorphicExtensions.isEmpty()) {
            throw new IllegalArgumentException(schemaClass + " is polymorphic but polymorphic extensions are absent");
        }
        List<Field> schemaFields = schemaFields(schemaClass);
        Collection<Field> internalExtensionsFields = extensionsFields(internalExtensions, true);
        Collection<Field> polymorphicExtensionsFields = extensionsFields(polymorphicExtensions, false);
        Field internalIdField = internalIdField(schemaClass, internalExtensions);
        for (Field schemaField : concat(schemaFields, internalExtensionsFields, polymorphicExtensionsFields)) {
            if (isConfigValue(schemaField) || isNamedConfigValue(schemaField)) {
                Class<?> subSchemaClass = schemaField.getType();
                if (!schemasInfo.containsKey(subSchemaClass)) {
                    compileQueue.offer(subSchemaClass);
                    schemasInfo.put(subSchemaClass, new SchemaClassesInfo(subSchemaClass));
                }
            }
        }
        for (Class<?> polymorphicExtension : polymorphicExtensions) {
            schemasInfo.put(polymorphicExtension, new SchemaClassesInfo(polymorphicExtension));
        }
        schemas.add(schemaClass);
        ClassDefinition innerNodeClassDef = createNodeClass(schemaClass, internalExtensions, polymorphicExtensions, schemaFields, internalExtensionsFields, polymorphicExtensionsFields, internalIdField);
        classDefs.add(innerNodeClassDef);
        ClassDefinition cfgImplClassDef = createCfgImplClass(schemaClass, internalExtensions, polymorphicExtensions, schemaFields, internalExtensionsFields, polymorphicExtensionsFields, internalIdField);
        classDefs.add(cfgImplClassDef);
        for (Class<?> polymorphicExtension : polymorphicExtensions) {
            // Only the fields of a specific instance of a polymorphic configuration.
            Collection<Field> polymorphicFields = polymorphicExtensionsFields.stream().filter(f -> f.getDeclaringClass() == polymorphicExtension).collect(toList());
            classDefs.add(createPolymorphicExtensionNodeClass(schemaClass, polymorphicExtension, innerNodeClassDef, schemaFields, polymorphicFields, internalIdField));
            classDefs.add(createPolymorphicExtensionCfgImplClass(schemaClass, polymorphicExtension, cfgImplClassDef, schemaFields, polymorphicFields, internalIdField));
        }
        ClassDefinition directProxyClassDef = new DirectProxyAsmGenerator(this, schemaClass, internalExtensions, schemaFields, internalExtensionsFields, internalIdField).generate();
        classDefs.add(directProxyClassDef);
    }
    Map<String, Class<?>> definedClasses = generator.defineClasses(classDefs);
    for (Class<?> schemaClass : schemas) {
        SchemaClassesInfo info = schemasInfo.get(schemaClass);
        info.nodeClass = (Class<? extends InnerNode>) definedClasses.get(info.nodeClassName);
        info.cfgImplClass = (Class<? extends DynamicConfiguration<?, ?>>) definedClasses.get(info.cfgImplClassName);
    }
}
Also used : PolymorphicId(org.apache.ignite.configuration.annotation.PolymorphicId) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression) Arrays(java.util.Arrays) DirectPropertyProxy(org.apache.ignite.internal.configuration.direct.DirectPropertyProxy) BytecodeExpressions.isNotNull(com.facebook.presto.bytecode.expression.BytecodeExpressions.isNotNull) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) ConfigurationUtil.isPolymorphicConfigInstance(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isPolymorphicConfigInstance) NamedConfigValue(org.apache.ignite.configuration.annotation.NamedConfigValue) Arrays.asList(java.util.Arrays.asList) Map(java.util.Map) DirectProxyAsmGenerator.newDirectProxyLambda(org.apache.ignite.internal.configuration.asm.DirectProxyAsmGenerator.newDirectProxyLambda) NamedConfigurationTree(org.apache.ignite.configuration.NamedConfigurationTree) IfStatement(com.facebook.presto.bytecode.control.IfStatement) DynamicConfigurationChanger(org.apache.ignite.internal.configuration.DynamicConfigurationChanger) Variable(com.facebook.presto.bytecode.Variable) DynamicConfiguration(org.apache.ignite.internal.configuration.DynamicConfiguration) Type.getType(org.objectweb.asm.Type.getType) Set(java.util.Set) BytecodeExpressions.constantBoolean(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantBoolean) ConfigurationUtil.isConfigValue(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isConfigValue) Serializable(java.io.Serializable) ConfigurationUtil.isPolymorphicId(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isPolymorphicId) FINAL(com.facebook.presto.bytecode.Access.FINAL) Stream(java.util.stream.Stream) Config(org.apache.ignite.configuration.annotation.Config) ConfigurationSource(org.apache.ignite.internal.configuration.tree.ConfigurationSource) ConfigurationUtil(org.apache.ignite.internal.configuration.util.ConfigurationUtil) BytecodeExpressions.invokeStatic(com.facebook.presto.bytecode.expression.BytecodeExpressions.invokeStatic) MethodHandle(java.lang.invoke.MethodHandle) CollectionUtils.concat(org.apache.ignite.internal.util.CollectionUtils.concat) SYNTHETIC(com.facebook.presto.bytecode.Access.SYNTHETIC) NamedListNode(org.apache.ignite.internal.configuration.tree.NamedListNode) Constructor(java.lang.reflect.Constructor) Supplier(java.util.function.Supplier) ConfigurationTree(org.apache.ignite.configuration.ConfigurationTree) InnerNode(org.apache.ignite.internal.configuration.tree.InnerNode) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Lookup(java.lang.invoke.MethodHandles.Lookup) PolymorphicConfig(org.apache.ignite.configuration.annotation.PolymorphicConfig) H_NEWINVOKESPECIAL(org.objectweb.asm.Opcodes.H_NEWINVOKESPECIAL) BytecodeExpressions.constantNull(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantNull) BytecodeExpressions.set(com.facebook.presto.bytecode.expression.BytecodeExpressions.set) Opcodes(org.objectweb.asm.Opcodes) SchemaClassesInfo.viewClassName(org.apache.ignite.internal.configuration.asm.SchemaClassesInfo.viewClassName) ConfigurationUtil.polymorphicInstanceId(org.apache.ignite.internal.configuration.util.ConfigurationUtil.polymorphicInstanceId) NamedListView(org.apache.ignite.configuration.NamedListView) Field(java.lang.reflect.Field) BytecodeExpressions.constantString(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantString) Handle(org.objectweb.asm.Handle) Type.getMethodDescriptor(org.objectweb.asm.Type.getMethodDescriptor) BytecodeExpressions.isNull(com.facebook.presto.bytecode.expression.BytecodeExpressions.isNull) EnumSet.of(java.util.EnumSet.of) ArrayDeque(java.util.ArrayDeque) ConfigurationUtil.isInternalId(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isInternalId) ParameterizedType(com.facebook.presto.bytecode.ParameterizedType) ArrayUtils.nullOrEmpty(org.apache.ignite.internal.util.ArrayUtils.nullOrEmpty) BytecodeExpressions.newArray(com.facebook.presto.bytecode.expression.BytecodeExpressions.newArray) LambdaMetafactory(java.lang.invoke.LambdaMetafactory) BiFunction(java.util.function.BiFunction) ConstructableTreeNode(org.apache.ignite.internal.configuration.tree.ConstructableTreeNode) BytecodeExpressions.invokeDynamic(com.facebook.presto.bytecode.expression.BytecodeExpressions.invokeDynamic) Type(org.objectweb.asm.Type) Collections.singleton(java.util.Collections.singleton) Collectors.toMap(java.util.stream.Collectors.toMap) ParameterizedType.type(com.facebook.presto.bytecode.ParameterizedType.type) ParameterizedType.typeFromJavaClassName(com.facebook.presto.bytecode.ParameterizedType.typeFromJavaClassName) ConfigurationUtil.isInjectedName(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isInjectedName) ConfigurationNode(org.apache.ignite.internal.configuration.ConfigurationNode) Method(java.lang.reflect.Method) ConfigurationProperty(org.apache.ignite.configuration.ConfigurationProperty) Name(org.apache.ignite.configuration.annotation.Name) Collections.emptyList(java.util.Collections.emptyList) Collection(java.util.Collection) NamedListConfiguration(org.apache.ignite.internal.configuration.NamedListConfiguration) TypeUtils(org.apache.ignite.internal.configuration.TypeUtils) UUID(java.util.UUID) RootKey(org.apache.ignite.configuration.RootKey) SchemaClassesInfo.nodeClassName(org.apache.ignite.internal.configuration.asm.SchemaClassesInfo.nodeClassName) SchemaClassesInfo.configurationClassName(org.apache.ignite.internal.configuration.asm.SchemaClassesInfo.configurationClassName) Objects(java.util.Objects) Nullable(org.jetbrains.annotations.Nullable) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) List(java.util.List) Type.getMethodType(org.objectweb.asm.Type.getMethodType) Function.identity(java.util.function.Function.identity) Queue(java.util.Queue) NotNull(org.jetbrains.annotations.NotNull) Parameter.arg(com.facebook.presto.bytecode.Parameter.arg) ConfigurationUtil.schemaFields(org.apache.ignite.internal.configuration.util.ConfigurationUtil.schemaFields) DynamicProperty(org.apache.ignite.internal.configuration.DynamicProperty) BytecodeExpressions.constantInt(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantInt) ConfigurationVisitor(org.apache.ignite.internal.configuration.tree.ConfigurationVisitor) PRIVATE(com.facebook.presto.bytecode.Access.PRIVATE) ConfigurationUtil.containsNameAnnotation(org.apache.ignite.internal.configuration.util.ConfigurationUtil.containsNameAnnotation) HashMap(java.util.HashMap) ConfigurationUtil.isNamedConfigValue(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isNamedConfigValue) BytecodeExpressions.not(com.facebook.presto.bytecode.expression.BytecodeExpressions.not) Function(java.util.function.Function) HashSet(java.util.HashSet) Collectors.toCollection(java.util.stream.Collectors.toCollection) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) NoSuchElementException(java.util.NoSuchElementException) BytecodeExpressions.constantClass(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantClass) ConfigurationUtil.extensionsFields(org.apache.ignite.internal.configuration.util.ConfigurationUtil.extensionsFields) MethodType.methodType(java.lang.invoke.MethodType.methodType) PUBLIC(com.facebook.presto.bytecode.Access.PUBLIC) BytecodeExpressions.inlineIf(com.facebook.presto.bytecode.expression.BytecodeExpressions.inlineIf) ConfigurationRoot(org.apache.ignite.configuration.annotation.ConfigurationRoot) CollectionUtils.union(org.apache.ignite.internal.util.CollectionUtils.union) SchemaClassesInfo.changeClassName(org.apache.ignite.internal.configuration.asm.SchemaClassesInfo.changeClassName) ClassGenerator(com.facebook.presto.bytecode.ClassGenerator) BytecodeExpressions.newInstance(com.facebook.presto.bytecode.expression.BytecodeExpressions.newInstance) ConfigurationUtil.isPolymorphicConfig(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isPolymorphicConfig) ConfigurationValue(org.apache.ignite.configuration.ConfigurationValue) Consumer(java.util.function.Consumer) Collectors.toList(java.util.stream.Collectors.toList) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) STATIC(com.facebook.presto.bytecode.Access.STATIC) MethodType(java.lang.invoke.MethodType) InjectedName(org.apache.ignite.configuration.annotation.InjectedName) ConfigurationUtil.isValue(org.apache.ignite.internal.configuration.util.ConfigurationUtil.isValue) PolymorphicConfigInstance(org.apache.ignite.configuration.annotation.PolymorphicConfigInstance) FieldDefinition(com.facebook.presto.bytecode.FieldDefinition) BRIDGE(com.facebook.presto.bytecode.Access.BRIDGE) ConfigurationUtil.hasDefault(org.apache.ignite.internal.configuration.util.ConfigurationUtil.hasDefault) Collections(java.util.Collections) ConfigurationTreeWrapper(org.apache.ignite.internal.configuration.ConfigurationTreeWrapper) ConfigurationWrongPolymorphicTypeIdException(org.apache.ignite.configuration.ConfigurationWrongPolymorphicTypeIdException) InternalConfiguration(org.apache.ignite.configuration.annotation.InternalConfiguration) ArrayList(java.util.ArrayList) BytecodeExpressions.constantString(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantString) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) ArrayDeque(java.util.ArrayDeque) Field(java.lang.reflect.Field) BytecodeExpressions.constantClass(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantClass) HashSet(java.util.HashSet)

Example 2 with PolymorphicConfigInstance

use of org.apache.ignite.configuration.annotation.PolymorphicConfigInstance in project ignite-3 by apache.

the class Processor method validatePolymorphicConfigInstance.

/**
 * Checks configuration schema with {@link PolymorphicConfigInstance}.
 *
 * @param clazz  type element under validation
 * @param fields non-static fields of the class under validation
 */
private void validatePolymorphicConfigInstance(TypeElement clazz, List<VariableElement> fields) {
    checkIncompatibleClassAnnotations(clazz, PolymorphicConfigInstance.class, ConfigurationRoot.class, Config.class);
    checkNotContainsPolymorphicIdField(clazz, PolymorphicConfigInstance.class, fields);
    String id = clazz.getAnnotation(PolymorphicConfigInstance.class).value();
    if (id == null || id.isBlank()) {
        throw new ProcessorException(String.format(EMPTY_FIELD_ERROR_FORMAT, simpleName(PolymorphicConfigInstance.class) + ".id()", clazz.getQualifiedName()));
    }
    checkExistSuperClass(clazz, PolymorphicConfigInstance.class);
    TypeElement superClazz = superClass(clazz);
    checkSuperclassContainAnyAnnotation(clazz, superClazz, PolymorphicConfig.class);
    checkNoConflictFieldNames(clazz, superClazz, fields, fields(superClazz));
}
Also used : PolymorphicConfigInstance(org.apache.ignite.configuration.annotation.PolymorphicConfigInstance) TypeElement(javax.lang.model.element.TypeElement)

Aggregations

BRIDGE (com.facebook.presto.bytecode.Access.BRIDGE)1 FINAL (com.facebook.presto.bytecode.Access.FINAL)1 PRIVATE (com.facebook.presto.bytecode.Access.PRIVATE)1 PUBLIC (com.facebook.presto.bytecode.Access.PUBLIC)1 STATIC (com.facebook.presto.bytecode.Access.STATIC)1 SYNTHETIC (com.facebook.presto.bytecode.Access.SYNTHETIC)1 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)1 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)1 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)1 ClassGenerator (com.facebook.presto.bytecode.ClassGenerator)1 FieldDefinition (com.facebook.presto.bytecode.FieldDefinition)1 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)1 Parameter.arg (com.facebook.presto.bytecode.Parameter.arg)1 ParameterizedType (com.facebook.presto.bytecode.ParameterizedType)1 ParameterizedType.type (com.facebook.presto.bytecode.ParameterizedType.type)1 ParameterizedType.typeFromJavaClassName (com.facebook.presto.bytecode.ParameterizedType.typeFromJavaClassName)1 Variable (com.facebook.presto.bytecode.Variable)1 IfStatement (com.facebook.presto.bytecode.control.IfStatement)1 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)1 BytecodeExpressions.constantBoolean (com.facebook.presto.bytecode.expression.BytecodeExpressions.constantBoolean)1