Search in sources :

Example 1 with MappedEntity

use of io.micronaut.data.annotation.MappedEntity in project micronaut-data by micronaut-projects.

the class MappedEntityVisitor method computeMappingDefaults.

private void computeMappingDefaults(NamingStrategy namingStrategy, PersistentProperty property, Map<String, DataType> dataTypes, Map<String, String> dataConverters, VisitorContext context) {
    AnnotationMetadata annotationMetadata = property.getAnnotationMetadata();
    SourcePersistentProperty spp = (SourcePersistentProperty) property;
    PropertyElement propertyElement = spp.getPropertyElement();
    boolean isRelation = propertyElement.hasStereotype(Relation.class);
    DataType dataType = annotationMetadata.getValue(TypeDef.class, "type", DataType.class).orElse(null);
    String converter = annotationMetadata.stringValue(MappedProperty.class, "converter").orElseGet(() -> annotationMetadata.stringValue(TypeDef.class, "converter").orElse(null));
    if (Objects.equals(converter, Object.class.getName())) {
        converter = null;
    }
    if (converter == null) {
        ClassElement type = propertyElement.getGenericType();
        converter = TypeUtils.resolveDataConverter(type, dataConverters);
    }
    if (converter != null) {
        if (isRelation) {
            context.fail("Relation cannot have converter specified", propertyElement);
            return;
        }
        ClassElement persistedClassFromConverter = getPersistedClassFromConverter(converter, context);
        if (persistedClassFromConverter != null) {
            propertyElement.annotate(MappedProperty.class, builder -> {
                builder.member("converterPersistedType", new AnnotationClassValue<>(persistedClassFromConverter.getCanonicalName()));
            });
        }
        if (dataType == null) {
            dataType = getDataTypeFromConverter(propertyElement.getGenericType(), converter, dataTypes, context);
            if (dataType == null) {
                context.fail("Cannot recognize proper data type. Please use @TypeDef to specify one", propertyElement);
                return;
            }
        }
    } else {
        if (dataType == null && spp.getType().isEnum()) {
            if (spp.getOwner().getAnnotationMetadata().hasAnnotation("javax.persistence.Entity") || spp.getOwner().getAnnotationMetadata().hasAnnotation("jakarta.persistence.Entity")) {
                // JPA enums have default ORDINAL mapping for enums
                dataType = DataType.INTEGER;
            }
        }
        if (dataType == null) {
            ClassElement type = propertyElement.getGenericType();
            dataType = TypeUtils.resolveDataType(type, dataTypes);
        }
    }
    if (dataType == DataType.ENTITY && !isRelation) {
        propertyElement = (PropertyElement) propertyElement.annotate(Relation.class, builder -> builder.value(Relation.Kind.MANY_TO_ONE));
    } else if (isRelation) {
        Relation.Kind kind = propertyElement.enumValue(Relation.class, Relation.Kind.class).orElse(Relation.Kind.MANY_TO_ONE);
        if (kind == Relation.Kind.EMBEDDED || kind == Relation.Kind.MANY_TO_ONE) {
            if (propertyElement.stringValue(Relation.class, "mappedBy").isPresent()) {
                context.fail("Relation " + kind + " doesn't support 'mappedBy'.", propertyElement);
            }
        }
        if (kind == Relation.Kind.EMBEDDED) {
            // handled embedded
            SourcePersistentEntity embeddedEntity = entityResolver.apply(propertyElement.getType());
            List<SourcePersistentProperty> persistentProperties = embeddedEntity.getPersistentProperties();
            List<AnnotationValue<Property>> embeddedProperties = new ArrayList<>(persistentProperties.size());
            for (SourcePersistentProperty embeddedProperty : persistentProperties) {
                if (!(embeddedProperty instanceof Association)) {
                    String mappedName = embeddedProperty.stringValue(MappedProperty.class).orElseGet(() -> namingStrategy.mappedName(property.getName() + embeddedProperty.getCapitilizedName()));
                    AnnotationValue<Property> av = AnnotationValue.builder(Property.class).value(mappedName).member("name", embeddedProperty.getName()).build();
                    embeddedProperties.add(av);
                }
            // else {
            // // TODO: handle nested embedded
            // }
            }
            propertyElement.annotate(MappedProperty.class, builder -> builder.member(MappedProperty.EMBEDDED_PROPERTIES, embeddedProperties.toArray(new AnnotationValue[0])));
        }
    }
    Optional<String> mapping = annotationMetadata.stringValue(MappedProperty.class);
    if (mappedEntity && !mapping.isPresent()) {
        propertyElement.annotate(MappedProperty.class, builder -> builder.value(namingStrategy.mappedName(spp)));
    }
    if (dataType != DataType.OBJECT) {
        DataType finalDataType = dataType;
        propertyElement.annotate(MappedProperty.class, builder -> builder.member("type", finalDataType));
    }
    if (converter != null) {
        String finalConverter = converter;
        propertyElement.annotate(MappedProperty.class, builder -> builder.member("converter", new AnnotationClassValue<>(finalConverter)));
    }
}
Also used : DataType(io.micronaut.data.model.DataType) MappedEntity(io.micronaut.data.annotation.MappedEntity) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ClassElement(io.micronaut.inject.ast.ClassElement) HashMap(java.util.HashMap) TypeDef(io.micronaut.data.annotation.TypeDef) Function(java.util.function.Function) ArrayList(java.util.ArrayList) Utils.getConfiguredDataTypes(io.micronaut.data.processor.visitors.Utils.getConfiguredDataTypes) Utils.getConfiguredDataConverters(io.micronaut.data.processor.visitors.Utils.getConfiguredDataConverters) TypeElementVisitor(io.micronaut.inject.visitor.TypeElementVisitor) MappedProperty(io.micronaut.data.annotation.MappedProperty) PropertyElement(io.micronaut.inject.ast.PropertyElement) InstantiationUtils(io.micronaut.core.reflect.InstantiationUtils) Map(java.util.Map) TypeUtils(io.micronaut.data.processor.visitors.finders.TypeUtils) AnnotationClassValue(io.micronaut.core.annotation.AnnotationClassValue) NamingStrategies(io.micronaut.data.model.naming.NamingStrategies) PersistentProperty(io.micronaut.data.model.PersistentProperty) Property(io.micronaut.context.annotation.Property) Index(io.micronaut.data.annotation.Index) NamingStrategy(io.micronaut.data.model.naming.NamingStrategy) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Collectors(java.util.stream.Collectors) Indexes(io.micronaut.data.annotation.Indexes) Objects(java.util.Objects) NonNull(io.micronaut.core.annotation.NonNull) VisitorContext(io.micronaut.inject.visitor.VisitorContext) List(java.util.List) Association(io.micronaut.data.model.Association) Stream(java.util.stream.Stream) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) Optional(java.util.Optional) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) AttributeConverter(io.micronaut.data.model.runtime.convert.AttributeConverter) Relation(io.micronaut.data.annotation.Relation) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) ClassElement(io.micronaut.inject.ast.ClassElement) AnnotationClassValue(io.micronaut.core.annotation.AnnotationClassValue) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Relation(io.micronaut.data.annotation.Relation) Association(io.micronaut.data.model.Association) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) TypeDef(io.micronaut.data.annotation.TypeDef) MappedProperty(io.micronaut.data.annotation.MappedProperty) DataType(io.micronaut.data.model.DataType) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) ArrayList(java.util.ArrayList) List(java.util.List) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) MappedProperty(io.micronaut.data.annotation.MappedProperty) PersistentProperty(io.micronaut.data.model.PersistentProperty) Property(io.micronaut.context.annotation.Property) PropertyElement(io.micronaut.inject.ast.PropertyElement)

Aggregations

Property (io.micronaut.context.annotation.Property)1 AnnotationClassValue (io.micronaut.core.annotation.AnnotationClassValue)1 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)1 AnnotationValue (io.micronaut.core.annotation.AnnotationValue)1 NonNull (io.micronaut.core.annotation.NonNull)1 InstantiationUtils (io.micronaut.core.reflect.InstantiationUtils)1 Index (io.micronaut.data.annotation.Index)1 Indexes (io.micronaut.data.annotation.Indexes)1 MappedEntity (io.micronaut.data.annotation.MappedEntity)1 MappedProperty (io.micronaut.data.annotation.MappedProperty)1 Relation (io.micronaut.data.annotation.Relation)1 TypeDef (io.micronaut.data.annotation.TypeDef)1 Association (io.micronaut.data.model.Association)1 DataType (io.micronaut.data.model.DataType)1 PersistentProperty (io.micronaut.data.model.PersistentProperty)1 NamingStrategies (io.micronaut.data.model.naming.NamingStrategies)1 NamingStrategy (io.micronaut.data.model.naming.NamingStrategy)1 AttributeConverter (io.micronaut.data.model.runtime.convert.AttributeConverter)1 SourcePersistentEntity (io.micronaut.data.processor.model.SourcePersistentEntity)1 SourcePersistentProperty (io.micronaut.data.processor.model.SourcePersistentProperty)1