<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>JSDoc: Source: odata/metadata.js</title> | |
<script src="scripts/prettify/prettify.js"> </script> | |
<script src="scripts/prettify/lang-css.js"> </script> | |
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | |
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | |
</head> | |
<body> | |
<div id="main"> | |
<h1 class="page-title">Source: odata/metadata.js</h1> | |
<section> | |
<article> | |
<pre class="prettyprint source"><code>/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
'use strict'; | |
/** @module odata/metadata */ | |
var utils = require('./../utils.js'); | |
var oDSxml = require('./../xml.js'); | |
var odataHandler = require('./handler.js'); | |
// imports | |
var contains = utils.contains; | |
var normalizeURI = utils.normalizeURI; | |
var xmlAttributes = oDSxml.xmlAttributes; | |
var xmlChildElements = oDSxml.xmlChildElements; | |
var xmlFirstChildElement = oDSxml.xmlFirstChildElement; | |
var xmlInnerText = oDSxml.xmlInnerText; | |
var xmlLocalName = oDSxml.xmlLocalName; | |
var xmlNamespaceURI = oDSxml.xmlNamespaceURI; | |
var xmlNS = oDSxml.xmlNS; | |
var xmlnsNS = oDSxml.xmlnsNS; | |
var xmlParse = oDSxml.xmlParse; | |
var ado = oDSxml.http + "docs.oasis-open.org/odata/"; // http://docs.oasis-open.org/odata/ | |
var adoDs = ado + "ns"; // http://docs.oasis-open.org/odata/ns | |
var edmxNs = adoDs + "/edmx"; // http://docs.oasis-open.org/odata/ns/edmx | |
var edmNs1 = adoDs + "/edm"; // http://docs.oasis-open.org/odata/ns/edm | |
var odataMetaXmlNs = adoDs + "/metadata"; // http://docs.oasis-open.org/odata/ns/metadata | |
var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION; | |
var xmlMediaType = "application/xml"; | |
/** Creates an object that describes an element in an schema. | |
* @param {Array} attributes - List containing the names of the attributes allowed for this element. | |
* @param {Array} elements - List containing the names of the child elements allowed for this element. | |
* @param {Boolean} text - Flag indicating if the element's text value is of interest or not. | |
* @param {String} ns - Namespace to which the element belongs to. | |
* If a child element name ends with * then it is understood by the schema that that child element can appear 0 or more times. | |
* @returns {Object} Object with attributes, elements, text, and ns fields. | |
*/ | |
function schemaElement(attributes, elements, text, ns) { | |
return { | |
attributes: attributes, | |
elements: elements, | |
text: text || false, | |
ns: ns | |
}; | |
} | |
// It's assumed that all elements may have Documentation children and Annotation elements. | |
// See http://docs.oasis-open.org/odata/odata/v4.0/cs01/part3-csdl/odata-v4.0-cs01-part3-csdl.html for a CSDL reference. | |
var schema = { | |
elements: { | |
Action: schemaElement( | |
/*attributes*/["Name", "IsBound", "EntitySetPath"], | |
/*elements*/["ReturnType", "Parameter*", "Annotation*"] | |
), | |
ActionImport: schemaElement( | |
/*attributes*/["Name", "Action", "EntitySet", "Annotation*"] | |
), | |
Annotation: schemaElement( | |
/*attributes*/["Term", "Qualifier", "Binary", "Bool", "Date", "DateTimeOffset", "Decimal", "Duration", "EnumMember", "Float", "Guid", "Int", "String", "TimeOfDay", "AnnotationPath", "NavigationPropertyPath", "Path", "PropertyPath", "UrlRef"], | |
/*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*", "Annotation*"] | |
), | |
AnnotationPath: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Annotations: schemaElement( | |
/*attributes*/["Target", "Qualifier"], | |
/*elements*/["Annotation*"] | |
), | |
Apply: schemaElement( | |
/*attributes*/["Function"], | |
/*elements*/["String*", "Path*", "LabeledElement*", "Annotation*"] | |
), | |
And: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Or: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Not: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Eq: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Ne: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Gt: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Ge: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Lt: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Le: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Binary: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Bool: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Cast: schemaElement( | |
/*attributes*/["Type"], | |
/*elements*/["Path*", "Annotation*"] | |
), | |
Collection: schemaElement( | |
/*attributes*/null, | |
/*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*"] | |
), | |
ComplexType: schemaElement( | |
/*attributes*/["Name", "BaseType", "Abstract", "OpenType"], | |
/*elements*/["Property*", "NavigationProperty*", "Annotation*"] | |
), | |
Date: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
DateTimeOffset: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Decimal: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Duration: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
EntityContainer: schemaElement( | |
/*attributes*/["Name", "Extends"], | |
/*elements*/["EntitySet*", "Singleton*", "ActionImport*", "FunctionImport*", "Annotation*"] | |
), | |
EntitySet: schemaElement( | |
/*attributes*/["Name", "EntityType", "IncludeInServiceDocument"], | |
/*elements*/["NavigationPropertyBinding*", "Annotation*"] | |
), | |
EntityType: schemaElement( | |
/*attributes*/["Name", "BaseType", "Abstract", "OpenType", "HasStream"], | |
/*elements*/["Key*", "Property*", "NavigationProperty*", "Annotation*"] | |
), | |
EnumMember: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
EnumType: schemaElement( | |
/*attributes*/["Name", "UnderlyingType", "IsFlags"], | |
/*elements*/["Member*"] | |
), | |
Float: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Function: schemaElement( | |
/*attributes*/["Name", "IsBound", "IsComposable", "EntitySetPath"], | |
/*elements*/["ReturnType", "Parameter*", "Annotation*"] | |
), | |
FunctionImport: schemaElement( | |
/*attributes*/["Name", "Function", "EntitySet", "IncludeInServiceDocument", "Annotation*"] | |
), | |
Guid: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
If: schemaElement( | |
/*attributes*/null, | |
/*elements*/["Path*", "String*", "Annotation*"] | |
), | |
Int: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
IsOf: schemaElement( | |
/*attributes*/["Type", "MaxLength", "Precision", "Scale", "Unicode", "SRID", "DefaultValue", "Annotation*"], | |
/*elements*/["Path*"] | |
), | |
Key: schemaElement( | |
/*attributes*/null, | |
/*elements*/["PropertyRef*"] | |
), | |
LabeledElement: schemaElement( | |
/*attributes*/["Name"], | |
/*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*", "Annotation*"] | |
), | |
LabeledElementReference: schemaElement( | |
/*attributes*/["Term"], | |
/*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*"] | |
), | |
Member: schemaElement( | |
/*attributes*/["Name", "Value"], | |
/*element*/["Annotation*"] | |
), | |
NavigationProperty: schemaElement( | |
/*attributes*/["Name", "Type", "Nullable", "Partner", "ContainsTarget"], | |
/*elements*/["ReferentialConstraint*", "OnDelete*", "Annotation*"] | |
), | |
NavigationPropertyBinding: schemaElement( | |
/*attributes*/["Path", "Target"] | |
), | |
NavigationPropertyPath: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Null: schemaElement( | |
/*attributes*/null, | |
/*elements*/["Annotation*"] | |
), | |
OnDelete: schemaElement( | |
/*attributes*/["Action"], | |
/*elements*/["Annotation*"] | |
), | |
Path: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Parameter: schemaElement( | |
/*attributes*/["Name", "Type", "Nullable", "MaxLength", "Precision", "Scale", "SRID"], | |
/*elements*/["Annotation*"] | |
), | |
Property: schemaElement( | |
/*attributes*/["Name", "Type", "Nullable", "MaxLength", "Precision", "Scale", "Unicode", "SRID", "DefaultValue"], | |
/*elements*/["Annotation*"] | |
), | |
PropertyPath: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
PropertyRef: schemaElement( | |
/*attributes*/["Name", "Alias"] | |
), | |
PropertyValue: schemaElement( | |
/*attributes*/["Property", "Path"], | |
/*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*", "Annotation*"] | |
), | |
Record: schemaElement( | |
/*attributes*/null, | |
/*Elements*/["PropertyValue*", "Property*", "Annotation*"] | |
), | |
ReferentialConstraint: schemaElement( | |
/*attributes*/["Property", "ReferencedProperty", "Annotation*"] | |
), | |
ReturnType: schemaElement( | |
/*attributes*/["Type", "Nullable", "MaxLength", "Precision", "Scale", "SRID"] | |
), | |
String: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
Schema: schemaElement( | |
/*attributes*/["Namespace", "Alias"], | |
/*elements*/["Action*", "Annotations*", "Annotation*", "ComplexType*", "EntityContainer", "EntityType*", "EnumType*", "Function*", "Term*", "TypeDefinition*", "Annotation*"] | |
), | |
Singleton: schemaElement( | |
/*attributes*/["Name", "Type"], | |
/*elements*/["NavigationPropertyBinding*", "Annotation*"] | |
), | |
Term: schemaElement( | |
/*attributes*/["Name", "Type", "BaseTerm", "DefaultValue ", "AppliesTo", "Nullable", "MaxLength", "Precision", "Scale", "SRID"], | |
/*elements*/["Annotation*"] | |
), | |
TimeOfDay: schemaElement( | |
/*attributes*/null, | |
/*elements*/null, | |
/*text*/true | |
), | |
TypeDefinition: schemaElement( | |
/*attributes*/["Name", "UnderlyingType", "MaxLength", "Unicode", "Precision", "Scale", "SRID"], | |
/*elements*/["Annotation*"] | |
), | |
UrlRef: schemaElement( | |
/*attributes*/null, | |
/*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*", "Annotation*"] | |
), | |
// See http://msdn.microsoft.com/en-us/library/dd541238(v=prot.10) for an EDMX reference. | |
Edmx: schemaElement( | |
/*attributes*/["Version"], | |
/*elements*/["DataServices", "Reference*"], | |
/*text*/false, | |
/*ns*/edmxNs | |
), | |
DataServices: schemaElement( | |
/*attributes*/["m:MaxDataServiceVersion", "m:DataServiceVersion"], | |
/*elements*/["Schema*"], | |
/*text*/false, | |
/*ns*/edmxNs | |
), | |
Reference: schemaElement( | |
/*attributes*/["Uri"], | |
/*elements*/["Include*", "IncludeAnnotations*", "Annotation*"] | |
), | |
Include: schemaElement( | |
/*attributes*/["Namespace", "Alias"] | |
), | |
IncludeAnnotations: schemaElement( | |
/*attributes*/["TermNamespace", "Qualifier", "TargetNamespace"] | |
) | |
} | |
}; | |
/** Converts a Pascal-case identifier into a camel-case identifier. | |
* @param {String} text - Text to convert. | |
* @returns {String} Converted text. | |
* If the text starts with multiple uppercase characters, it is left as-is. | |
*/ | |
function scriptCase(text) { | |
if (!text) { | |
return text; | |
} | |
if (text.length > 1) { | |
var firstTwo = text.substr(0, 2); | |
if (firstTwo === firstTwo.toUpperCase()) { | |
return text; | |
} | |
return text.charAt(0).toLowerCase() + text.substr(1); | |
} | |
return text.charAt(0).toLowerCase(); | |
} | |
/** Gets the schema node for the specified element. | |
* @param {Object} parentSchema - Schema of the parent XML node of 'element'. | |
* @param candidateName - XML element name to consider. | |
* @returns {Object} The schema that describes the specified element; null if not found. | |
*/ | |
function getChildSchema(parentSchema, candidateName) { | |
var elements = parentSchema.elements; | |
if (!elements) { | |
return null; | |
} | |
var i, len; | |
for (i = 0, len = elements.length; i < len; i++) { | |
var elementName = elements[i]; | |
var multipleElements = false; | |
if (elementName.charAt(elementName.length - 1) === "*") { | |
multipleElements = true; | |
elementName = elementName.substr(0, elementName.length - 1); | |
} | |
if (candidateName === elementName) { | |
var propertyName = scriptCase(elementName); | |
return { isArray: multipleElements, propertyName: propertyName }; | |
} | |
} | |
return null; | |
} | |
/** Checks whether the specifies namespace URI is one of the known CSDL namespace URIs. | |
* @param {String} nsURI - Namespace URI to check. | |
* @returns {Boolean} true if nsURI is a known CSDL namespace; false otherwise. | |
*/ | |
function isEdmNamespace(nsURI) { | |
return nsURI === edmNs1; | |
} | |
/** Parses a CSDL document. | |
* @param element - DOM element to parse. | |
* @returns {Object} An object describing the parsed element. | |
*/ | |
function parseConceptualModelElement(element) { | |
var localName = xmlLocalName(element); | |
var nsURI = xmlNamespaceURI(element); | |
var elementSchema = schema.elements[localName]; | |
if (!elementSchema) { | |
return null; | |
} | |
if (elementSchema.ns) { | |
if (nsURI !== elementSchema.ns) { | |
return null; | |
} | |
} else if (!isEdmNamespace(nsURI)) { | |
return null; | |
} | |
var item = {}; | |
var attributes = elementSchema.attributes || []; | |
xmlAttributes(element, function (attribute) { | |
var localName = xmlLocalName(attribute); | |
var nsURI = xmlNamespaceURI(attribute); | |
var value = attribute.value; | |
// Don't do anything with xmlns attributes. | |
if (nsURI === xmlnsNS) { | |
return; | |
} | |
// Currently, only m: for metadata is supported as a prefix in the internal schema table, | |
// un-prefixed element names imply one a CSDL element. | |
var schemaName = null; | |
if (isEdmNamespace(nsURI) || nsURI === null) { | |
schemaName = ""; | |
} else if (nsURI === odataMetaXmlNs) { | |
schemaName = "m:"; | |
} | |
if (schemaName !== null) { | |
schemaName += localName; | |
if (contains(attributes, schemaName)) { | |
item[scriptCase(localName)] = value; | |
} | |
} | |
}); | |
xmlChildElements(element, function (child) { | |
var localName = xmlLocalName(child); | |
var childSchema = getChildSchema(elementSchema, localName); | |
if (childSchema) { | |
if (childSchema.isArray) { | |
var arr = item[childSchema.propertyName]; | |
if (!arr) { | |
arr = []; | |
item[childSchema.propertyName] = arr; | |
} | |
arr.push(parseConceptualModelElement(child)); | |
} else { | |
item[childSchema.propertyName] = parseConceptualModelElement(child); | |
} | |
} | |
}); | |
if (elementSchema.text) { | |
item.text = xmlInnerText(element); | |
} | |
return item; | |
} | |
/** Parses a metadata document. | |
* @param handler - This handler. | |
* @param {String} text - Metadata text. | |
* @returns An object representation of the conceptual model. | |
*/ | |
function metadataParser(handler, text) { | |
var doc = xmlParse(text); | |
var root = xmlFirstChildElement(doc); | |
return parseConceptualModelElement(root) || undefined; | |
} | |
exports.metadataHandler = odataHandler.handler(metadataParser, null, xmlMediaType, MAX_DATA_SERVICE_VERSION); | |
exports.schema = schema; | |
exports.scriptCase = scriptCase; | |
exports.getChildSchema = getChildSchema; | |
exports.parseConceptualModelElement = parseConceptualModelElement; | |
exports.metadataParser = metadataParser;</code></pre> | |
</article> | |
</section> | |
</div> | |
<nav> | |
<h2><a href="index.html">Index</a></h2><h3>Modules</h3><ul><li><a href="module-cache.html">cache</a></li><li><a href="source.html">cache/source</a></li><li><a href="module-odata.html">odata</a></li><li><a href="batch.html">odata/batch</a></li><li><a href="handler.html">odata/handler</a></li><li><a href="json.html">odata/json</a></li><li><a href="metadata.html">odata/metadata</a></li><li><a href="net.html">odata/net</a></li><li><a href="utils.html">odata/utils</a></li><li><a href="deferred.html">odatajs/deferred</a></li><li><a href="utils_.html">odatajs/utils</a></li><li><a href="xml.html">odatajs/xml</a></li><li><a href="module-store.html">store</a></li><li><a href="dom.html">store/dom</a></li><li><a href="indexeddb.html">store/indexeddb</a></li><li><a href="memory.html">store/memory</a></li></ul><h3>Classes</h3><ul><li><a href="DataCache.html">DataCache</a></li><li><a href="DataCacheOperation.html">DataCacheOperation</a></li><li><a href="DjsDeferred.html">DjsDeferred</a></li><li><a href="dom-DomStore.html">DomStore</a></li><li><a href="indexeddb-IndexedDBStore.html">IndexedDBStore</a></li><li><a href="memory-MemoryStore.html">MemoryStore</a></li><li><a href="ODataCacheSource.html">ODataCacheSource</a></li></ul><h3><a href="global.html">Global</a></h3> | |
</nav> | |
<br clear="both"> | |
<footer> | |
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Apr 09 2015 08:31:26 GMT+0200 (MESZ) | |
</footer> | |
<script> prettyPrint(); </script> | |
<script src="scripts/linenumber.js"> </script> | |
</body> | |
</html> |