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);
}
}
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));
}
Aggregations