Search in sources :

Example 1 with Cardinality

use of io.requery.meta.Cardinality in project requery by requery.

the class AttributeMember method processAssociativeAnnotations.

private void processAssociativeAnnotations(ProcessingEnvironment processingEnvironment, ElementValidator validator) {
    Optional<Annotation> oneToOne = annotationOf(OneToOne.class);
    Optional<Annotation> oneToMany = annotationOf(OneToMany.class);
    Optional<Annotation> manyToOne = annotationOf(ManyToOne.class);
    Optional<Annotation> manyToMany = annotationOf(ManyToMany.class);
    oneToOne = oneToOne.isPresent() ? oneToOne : annotationOf(javax.persistence.OneToOne.class);
    oneToMany = oneToMany.isPresent() ? oneToMany : annotationOf(javax.persistence.OneToMany.class);
    manyToOne = manyToOne.isPresent() ? manyToOne : annotationOf(javax.persistence.ManyToOne.class);
    manyToMany = manyToMany.isPresent() ? manyToMany : annotationOf(javax.persistence.ManyToMany.class);
    if (Stream.of(oneToOne, oneToMany, manyToOne, manyToMany).filter(Optional::isPresent).count() > 1) {
        validator.error("Cannot have more than one associative annotation per field");
    }
    if (oneToOne.isPresent()) {
        cardinality = Cardinality.ONE_TO_ONE;
        ReflectiveAssociation reflect = new ReflectiveAssociation(oneToOne.get());
        mappedBy = reflect.mappedBy();
        cascadeActions = reflect.cascade();
        if (!isForeignKey()) {
            isReadOnly = true;
            if (!isKey()) {
                isUnique = true;
            }
        }
    }
    if (oneToMany.isPresent()) {
        isIterable = true;
        cardinality = Cardinality.ONE_TO_MANY;
        isReadOnly = true;
        ReflectiveAssociation reflect = new ReflectiveAssociation(oneToMany.get());
        mappedBy = reflect.mappedBy();
        cascadeActions = reflect.cascade();
        checkIterable(validator);
        processOrderBy();
    }
    if (manyToOne.isPresent()) {
        cardinality = Cardinality.MANY_TO_ONE;
        isForeignKey = true;
        ReflectiveAssociation reflect = new ReflectiveAssociation(manyToOne.get());
        cascadeActions = reflect.cascade();
        if (deleteAction == null) {
            deleteAction = ReferentialAction.CASCADE;
        }
        if (updateAction == null) {
            updateAction = ReferentialAction.CASCADE;
        }
    }
    if (manyToMany.isPresent()) {
        isIterable = true;
        cardinality = Cardinality.MANY_TO_MANY;
        ReflectiveAssociation reflect = new ReflectiveAssociation(manyToMany.get());
        mappedBy = reflect.mappedBy();
        cascadeActions = reflect.cascade();
        Optional<JunctionTable> junctionTable = annotationOf(JunctionTable.class);
        Optional<javax.persistence.JoinTable> joinTable = annotationOf(javax.persistence.JoinTable.class);
        if (junctionTable.isPresent()) {
            Elements elements = processingEnvironment.getElementUtils();
            associativeDescriptor = new JunctionTableAssociation(elements, this, junctionTable.get());
        } else if (joinTable.isPresent()) {
            associativeDescriptor = new JoinTableAssociation(joinTable.get());
        }
        isReadOnly = true;
        checkIterable(validator);
        processOrderBy();
    }
    if (isForeignKey()) {
        if (deleteAction == ReferentialAction.SET_NULL && !isNullable()) {
            validator.error("Cannot SET_NULL on optional attribute", ForeignKey.class);
        }
        // user mirror so generated type can be referenced
        Optional<? extends AnnotationMirror> mirror = Mirrors.findAnnotationMirror(element(), ForeignKey.class);
        if (mirror.isPresent()) {
            referencedType = mirror.flatMap(m -> Mirrors.findAnnotationValue(m, "references")).map(value -> value.getValue().toString()).orElse(null);
        } else if (!typeMirror().getKind().isPrimitive()) {
            referencedType = typeMirror().toString();
        }
    }
}
Also used : Arrays(java.util.Arrays) Nullable(io.requery.Nullable) Modifier(javax.lang.model.element.Modifier) Lazy(io.requery.Lazy) TypeElement(javax.lang.model.element.TypeElement) Elements(javax.lang.model.util.Elements) ForeignKey(io.requery.ForeignKey) EnumType(javax.persistence.EnumType) ConstraintMode(javax.persistence.ConstraintMode) OrderBy(io.requery.OrderBy) Locale(java.util.Locale) Map(java.util.Map) OneToOne(io.requery.OneToOne) PropertyNameStyle(io.requery.PropertyNameStyle) Enumerated(javax.persistence.Enumerated) OneToMany(io.requery.OneToMany) EnumSet(java.util.EnumSet) Index(io.requery.Index) CascadeType(javax.persistence.CascadeType) Naming(io.requery.Naming) Set(java.util.Set) ReadOnly(io.requery.ReadOnly) Element(javax.lang.model.element.Element) Types(javax.lang.model.util.Types) Version(io.requery.Version) TypeKind(javax.lang.model.type.TypeKind) ManyToOne(io.requery.ManyToOne) Basic(javax.persistence.Basic) SourceVersion(javax.lang.model.SourceVersion) GenerationType(javax.persistence.GenerationType) List(java.util.List) Cardinality(io.requery.meta.Cardinality) Stream(java.util.stream.Stream) GeneratedValue(javax.persistence.GeneratedValue) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) MapAttributeBuilder(io.requery.meta.MapAttributeBuilder) ListAttributeBuilder(io.requery.meta.ListAttributeBuilder) Key(io.requery.Key) Transient(io.requery.Transient) JunctionTable(io.requery.JunctionTable) VariableElement(javax.lang.model.element.VariableElement) SetAttributeBuilder(io.requery.meta.SetAttributeBuilder) Convert(io.requery.Convert) ReferentialAction(io.requery.ReferentialAction) Embedded(io.requery.Embedded) ElementFilter(javax.lang.model.util.ElementFilter) LinkedHashSet(java.util.LinkedHashSet) ElementKind(javax.lang.model.element.ElementKind) ExecutableElement(javax.lang.model.element.ExecutableElement) JoinColumn(javax.persistence.JoinColumn) EnumOrdinalConverter(io.requery.converter.EnumOrdinalConverter) ResultAttributeBuilder(io.requery.meta.ResultAttributeBuilder) Generated(io.requery.Generated) Order(io.requery.query.Order) AnnotationMirror(javax.lang.model.element.AnnotationMirror) CascadeAction(io.requery.CascadeAction) TypeMirror(javax.lang.model.type.TypeMirror) Column(io.requery.Column) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) FetchType(javax.persistence.FetchType) Collections(java.util.Collections) ManyToMany(io.requery.ManyToMany) AttributeBuilder(io.requery.meta.AttributeBuilder) Optional(java.util.Optional) Elements(javax.lang.model.util.Elements) Annotation(java.lang.annotation.Annotation) JunctionTable(io.requery.JunctionTable)

Example 2 with Cardinality

use of io.requery.meta.Cardinality in project requery by requery.

the class EntityGraphValidator method validateRelationship.

private void validateRelationship(ElementValidator validator, AttributeDescriptor source, AttributeDescriptor mapped) {
    Cardinality sourceCardinality = source.cardinality();
    Cardinality mappedCardinality = mapped.cardinality();
    Cardinality expectedCardinality;
    switch(sourceCardinality) {
        case ONE_TO_ONE:
            expectedCardinality = Cardinality.ONE_TO_ONE;
            break;
        case ONE_TO_MANY:
            expectedCardinality = Cardinality.MANY_TO_ONE;
            break;
        case MANY_TO_ONE:
            expectedCardinality = Cardinality.ONE_TO_MANY;
            break;
        case MANY_TO_MANY:
            expectedCardinality = Cardinality.MANY_TO_MANY;
            break;
        default:
            throw new IllegalStateException();
    }
    if (mappedCardinality != expectedCardinality && mapped.cardinality() != null) {
        String message = mappingErrorMessage(source, mapped, expectedCardinality);
        validator.error(message);
    } else if (sourceCardinality == Cardinality.MANY_TO_MANY) {
        Optional<AssociativeEntityDescriptor> sourceAssociation = source.associativeEntity();
        Optional<AssociativeEntityDescriptor> mappedAssociation = mapped.associativeEntity();
        if (!sourceAssociation.isPresent() && !mappedAssociation.isPresent()) {
            validator.error("One side of the ManyToMany relationship must specify the " + "@JunctionTable/@JoinTable annotation");
        }
        if (sourceAssociation.isPresent() && mappedAssociation.isPresent()) {
            validator.error("@JunctionTable should be specified on only one side of a " + "ManyToMany relationship");
        }
    } else if (sourceCardinality == Cardinality.ONE_TO_ONE) {
        if (!source.isForeignKey() && !mapped.isForeignKey()) {
            validator.error("One side of the OneToOne relationship must specify the " + "@ForeignKey/@JoinColumn annotation");
        }
        if (source.isForeignKey() && mapped.isForeignKey() && source != mapped) {
            validator.error("Only one side of the OneToOne relationship can specify the " + "@ForeignKey/@JoinColumn annotation");
        }
    }
}
Also used : Cardinality(io.requery.meta.Cardinality) Optional(java.util.Optional)

Aggregations

Cardinality (io.requery.meta.Cardinality)2 Optional (java.util.Optional)2 CascadeAction (io.requery.CascadeAction)1 Column (io.requery.Column)1 Convert (io.requery.Convert)1 Embedded (io.requery.Embedded)1 ForeignKey (io.requery.ForeignKey)1 Generated (io.requery.Generated)1 Index (io.requery.Index)1 JunctionTable (io.requery.JunctionTable)1 Key (io.requery.Key)1 Lazy (io.requery.Lazy)1 ManyToMany (io.requery.ManyToMany)1 ManyToOne (io.requery.ManyToOne)1 Naming (io.requery.Naming)1 Nullable (io.requery.Nullable)1 OneToMany (io.requery.OneToMany)1 OneToOne (io.requery.OneToOne)1 OrderBy (io.requery.OrderBy)1 PropertyNameStyle (io.requery.PropertyNameStyle)1