Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | 1x 41x 41x 41x 20x 41x 4x 41x 16x 41x 8x 8x 1x 7x 41x 5x 5x 1x 4x 41x 1x 41x 2x 4x 4x 4x 1x 6x 3x 1x 2x 3x 1x 1x | "use strict";
const AnnotationTarget = require("../../oasis/annotations/AnnotationTarget");
/**
* Envelops a navigation property.
*
* There are big differences OASIS-CSDL and MC-CSDL navigation properties. SAP follows MC-CSDL in this.
*
* https://docs.microsoft.com/en-us/openspecs/windows_protocols/mc-csdl/e83d21c4-7f0a-4cc7-ac38-f2fbe15d3398
* (http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/cs01/odata-csdl-xml-v4.01-cs01.html#sec_NavigationProperty)
*
* @class NavigationProperty
* @extends {AnnotationTarget}
*/
class NavigationProperty extends AnnotationTarget {
/**
* Creates an instance of NavigationProperty.
* @param {Object} rawMetadata raw metadata object for navigation property
* @memberof NavigationProperty
*/
constructor(...args) {
const rawMetadata = args[0];
super(...args);
Object.defineProperty(this, "relationship", {
get: () => rawMetadata.$.Relationship,
});
Object.defineProperty(this, "fromRole", {
get: () => rawMetadata.$.FromRole,
});
Object.defineProperty(this, "toRole", {
get: () => rawMetadata.$.ToRole,
});
Object.defineProperty(this, "association", {
get: () => {
const association = this.model.resolveModelPath(this.relationship);
if (!association) {
throw new Error(
`Association for navigation property ${this.name} does not exists.`
);
}
return association;
},
});
Object.defineProperty(this, "associationEnd", {
get: () => {
const associationEnd = this.association.findEnd(this.toRole);
if (!associationEnd) {
throw new Error(
`Association endpoint for navigation property ${this.name} does not exists.`
);
}
return associationEnd;
},
});
Object.defineProperty(this, "type", {
get: () => {
return {
elementType: this.associationEnd.type,
};
},
});
Object.defineProperty(this, "isCollection", {
get: () => {
return this.associationEnd.multiplicity === "*";
},
});
}
/**
* Gets navigation property target information.
*
* @param {CsdlSchema} schema to resolve model paths
* @returns {Object} navigation property target
* @memberof NavigationProperty
*/
getTarget(schema) {
let associationSet = schema
.getEntityContainer()
.associationSets.find(
(a) => `${schema.namespace}.${a.association.name}` === this.relationship
);
if (!associationSet) {
throw new Error(
`AssociationSet for association '${this.relationship}' not found.`
);
}
let end = associationSet.ends.find((e) => e.role === this.toRole);
if (!end) {
throw new Error(
`AssociationSet End with ${this.toRole} role not present in '${this.relationship}' association set.`
);
}
return {
associationSetEnd: end,
entitySet: end.entitySet,
entityType: end.entitySet.entityType,
isMultiple: end.associationEnd.multiplicity === "*",
};
}
/**
* Gets legacy api object. (XML casing, maybe some other changes.)
*
* @returns {Object} legacy api object
* @memberof NavigationProperty
*/
getLegacyApiObject() {
return Object.assign(super.getLegacyApiObject(), {
getTarget: (schema) => this.getTarget(schema),
Relationship: this.relationship,
FromRole: this.fromRole,
ToRole: this.toRole,
});
}
}
module.exports = NavigationProperty;
|