package org.odata4j.edm; import org.odata4j.core.ImmutableList; /** * A CSDL NavigationProperty element. * * <p>A NavigationProperty element defines a navigation property, which provides a reference to the other end of an * association. Unlike properties defined with the Property element, navigation properties do not define the shape * and characteristics of data. They provide a way to navigate an association between two entity types. * * <p>Note that navigation properties are optional on both entity types at the ends of an association. If you define * a navigation property on one entity type at the end of an association, you do not have to define a navigation property * on the entity type at the other end of the association. * * <p>The data type returned by a navigation property is determined by the multiplicity of its remote association end. * For example, suppose a navigation property, OrdersNavProp, exists on a Customer entity type and navigates a one-to-many * association between Customer and Order. Because the remote association end for the navigation property has multiplicity * many (*), its data type is a collection (of Order). Similarly, if a navigation property, CustomerNavProp, exists on the * Order entity type, its data type would be Customer since the multiplicity of the remote end is one (1). * * @see <a href="http://msdn.microsoft.com/en-us/library/bb387104.aspx">[msdn] NavigationProperty Element (CSDL)</a> */ public class EdmNavigationProperty extends EdmPropertyBase { private final EdmAssociation relationship; private final EdmAssociationEnd fromRole; private final EdmAssociationEnd toRole; private final boolean containsTarget; private EdmNavigationProperty(EdmDocumentation documentation, ImmutableList<EdmAnnotation<?>> annotations, ImmutableList<EdmAnnotation<?>> annotElements, String name, EdmAssociation relationship, EdmAssociationEnd fromRole, EdmAssociationEnd toRole, boolean containsTarget) { super(documentation, annotations, annotElements, name); this.relationship = relationship; this.fromRole = fromRole; this.toRole = toRole; this.containsTarget = containsTarget; } public EdmAssociation getRelationship() { return relationship; } public EdmAssociationEnd getFromRole() { return fromRole; } public EdmAssociationEnd getToRole() { return toRole; } public boolean getCotainsTarget() { return containsTarget; } @Override public String toString() { return String.format("EdmNavigationProperty[%s,rel=%s,from=%s,to=%s]", getName(), relationship, fromRole, toRole); } public static Builder newBuilder(String name) { return new Builder(name); } static Builder newBuilder(EdmNavigationProperty navigationProperty, BuilderContext context) { return context.newBuilder(navigationProperty, new Builder(navigationProperty.getName())); } /** Mutable builder for {@link EdmNavigationProperty} objects. */ public static class Builder extends EdmPropertyBase.Builder<EdmNavigationProperty, Builder> { private EdmAssociation.Builder relationship; private String relationshipName; private EdmAssociationEnd.Builder fromRole; private String fromRoleName; private EdmAssociationEnd.Builder toRole; private String toRoleName; //A containment NavigationProperty is a NavigationProperty that has a ContainsTarget attribute set to "true". private boolean containsTarget = false; private Builder(String name) { super(name); } @Override Builder newBuilder(EdmNavigationProperty navigationProperty, BuilderContext context) { this.relationship = EdmAssociation.newBuilder(navigationProperty.relationship, context); this.fromRole = EdmAssociationEnd.newBuilder(navigationProperty.fromRole, context); this.toRole = EdmAssociationEnd.newBuilder(navigationProperty.toRole, context); return this; } public Builder setRelationship(EdmAssociation.Builder relationship) { this.relationship = relationship; return this; } public Builder setFromTo(EdmAssociationEnd.Builder fromRole, EdmAssociationEnd.Builder toRole) { this.fromRole = fromRole; this.toRole = toRole; return this; } public Builder setContainsTarget(boolean containsTarget) { this.containsTarget = containsTarget; return this; } public EdmNavigationProperty build() { return new EdmNavigationProperty(getDocumentation(), ImmutableList.copyOf(getAnnotations()), ImmutableList.copyOf(getAnnotationElements()), getName(), relationship.build(), fromRole.build(), toRole.build(), containsTarget); } public String getRelationshipName() { return relationshipName; } public String getFromRoleName() { return fromRoleName; } public String getToRoleName() { return toRoleName; } public Builder setRelationshipName(String relationshipName) { this.relationshipName = relationshipName; return this; } public Builder setFromToName(String fromRoleName, String toRoleName) { this.fromRoleName = fromRoleName; this.toRoleName = toRoleName; return this; } } }