UNPKG

jaydata-reso

Version:

Jaydata fork for RESO Web API

457 lines (388 loc) 19.5 kB
$data.Class.define('$data.oDataServer.EntityXmlTransform', $data.oDataServer.EntityTransform, null, { constructor: function (context, requesUrl, config) { /// <signature> /// <summary>Transform class for Atom format</summary> /// <description>Transform class for Atom format</description> /// <param name="context" type="$data.EntityContext">Context instance</param> /// <param name="requesUrl" type="String">Service Url</param> /// <param name="config" type="Object">Config for customize xml</param> /// </signature> this.cfg = $data.typeSystem.extend({ m: 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata', d: 'http://schemas.microsoft.com/ado/2007/08/dataservices', xmlns: 'http://www.w3.org/2005/Atom', scheme: 'http://schemas.microsoft.com/ado/2007/08/dataservices/scheme', related: 'http://schemas.microsoft.com/ado/2007/08/dataservices/related', xmlHead: '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>', headers: [], excelUserAgent: 'PowerPivot', gml: 'http://www.opengis.net/gml', georss: 'http://www.georss.org/georss' }, config); }, convertToResponse: function (results, collectionNameOrElementType, selectedFields, includes) { /// <signature> /// <summary>Transform entities for JSON verbose format</summary> /// <description>Transform entities for JSON verbose format</description> /// <param name="results" type="Array">Array of Entities from any EntitySet of context</param> /// <param name="collectionNameOrElementType" type="function">elementType of input items</param> /// <param name="selectedFields" type="Array">Fields for result</param> /// <param name="includes" type="Array">navigation property includes</param> /// <return type="String" /> /// </signature> /// <signature> /// <summary>Transform entities for JSON verbose format</summary> /// <description>Transform entities for JSON verbose format</description> /// <param name="results" type="Array">Array of Entities from any EntitySet of context</param> /// <param name="collectionNameOrElementType" type="string">EntitySet name</param> /// <param name="selectedFields" type="Array">Fields for result</param> /// <param name="includes" type="Array">navigation property includes</param> /// <return type="String" /> /// </signature> if (!collectionNameOrElementType) return '<error />'; if (!selectedFields) selectedFields = []; if (!includes) includes = []; var entitySetDef; var defaultType = collectionNameOrElementType; if (typeof collectionNameOrElementType === 'string') { entitySetDef = this.context.memberDefinitions.getMember(collectionNameOrElementType); defaultType = entitySetDef.elementType; } else { entitySetDef = this._getEntitySetDefByType(defaultType); } var memDefs = defaultType.memberDefinitions.getPublicMappedProperties(); if (selectedFields && selectedFields.length > 0) { memDefs = memDefs.filter(function (memDef) { return selectedFields.indexOf(memDef.name) >= 0 || selectedFields.filter(function(it){ return it.split('.')[0] === memDef.name }).length; }); } var xmlResult = this.cfg.xmlHead; this.xml = new $data.Xml.XmlCreator(); this.xml.startDocument(); if ($data.Array.isArray(results)) { this._buildFeed(results, entitySetDef, defaultType, memDefs, selectedFields, includes, ''); } else { this._buildEntry(results, entitySetDef, defaultType, memDefs, selectedFields, includes, true, ''); } this.xml.endDocument(); xmlResult += this.xml.getXmlString(); return xmlResult; }, _buildFeed: function (data, esDef, elementType, memDefs, selectedFields, includes, path, rootHref) { var feed = this.xml.declareElement('feed'); this.xml.startElement(feed); if (!path){ this._addMainNamespaces(esDef); } //id var id = this.xml.declareElement('id'); this.xml.startElement(id) .addText(this.generateUri(null, esDef)).endElement(); //title var type = this.xml.declareAttribute('type'); var title = this.xml.declareElement('title'); this.xml.startElement(title) .addAttribute(type, 'text') .addText(esDef.name).endElement(); //updated var updated = this.xml.declareElement('updated'); this.xml.startElement(updated) .addText(new Date().toISOString()).endElement(); //link var rel = this.xml.declareAttribute('rel'); var title = this.xml.declareAttribute('title'); var href = this.xml.declareAttribute('href'); var link = this.xml.declareElement('link'); this.xml.startElement(link) .addAttribute(rel, 'self') .addAttribute(title, esDef.name) .addAttribute(href, rootHref || esDef.name) .endElement(); for (var i = 0; i < data.length; i++) { this._buildEntry(data[i], esDef, elementType, memDefs, selectedFields, includes, false, path); } if (data.length === 0) { var author = this.xml.declareElement('author'); var name = this.xml.declareElement('name'); this.xml.startElement(author) .startElement(name).endElement() .endElement(); } this.xml.endElement(); }, _buildEntry: function (data, esDef, elementType, memDefs, selectedFields, includes, isRoot, path) { var entry = this.xml.declareElement('entry'); this.xml.startElement(entry); if (isRoot) this._addMainNamespaces(esDef); var itemUrl = this.generateUri(data, esDef); //id var id = this.xml.declareElement('id'); this.xml.startElement(id) .addText(itemUrl).endElement(); //category var term = this.xml.declareAttribute('term'); var scheme = this.xml.declareAttribute('scheme'); var category = this.xml.declareElement('category'); this.xml.startElement(category) .addAttribute(term, Container.resolveName(esDef.elementType)) .addAttribute(scheme, this.cfg.scheme).endElement(); //link var rel = this.xml.declareAttribute('rel'); var title = this.xml.declareAttribute('title'); var href = this.xml.declareAttribute('href'); var link = this.xml.declareElement('link'); var typeName = elementType.name; this.xml.startElement(link) .addAttribute(rel, 'edit') .addAttribute(title, typeName) .addAttribute(href, itemUrl.slice(this.requesUrl.length + 1)) .endElement(); //navProperties this._buildNavProperties(data, esDef, elementType, itemUrl, memDefs, selectedFields, includes, path); //title var title = this.xml.declareElement('title'); this.xml.startElement(title).endElement(); //updated var updated = this.xml.declareElement('updated'); this.xml.startElement(updated) .addText(new Date().toISOString()).endElement(); //author var author = this.xml.declareElement('author'); var name = this.xml.declareElement('name'); this.xml.startElement(author) .startElement(name).endElement() .endElement(); //content var content = this.xml.declareElement('content'); var contentType = this.xml.declareAttribute('type'); var m = this.xml.declareNamespace(this.cfg.m, 'm'); var properties = this.xml.declareElement(m, 'properties'); this.xml.startElement(content) .addAttribute(contentType, 'application/xml') .startElement(properties); this._buildProperties(data, esDef, elementType, memDefs, selectedFields, includes, path); this.xml.endElement() .endElement() .endElement(); }, _addMainNamespaces: function (esDef) { var xmlns = this.xml.declareAttribute('xmlns'); this.xml.addAttribute(xmlns, this.cfg.xmlns); var d = this.xml.declareNamespace(this.cfg.d, 'd'); this.xml.addNamespace(d); var m = this.xml.declareNamespace(this.cfg.m, 'm'); this.xml.addNamespace(m); var base = this.xml.declareAttribute('xml:base'); this.xml.addAttribute(base, this.requesUrl + '/' + esDef.name); }, _buildNavProperties: function (data, esDef, elementType, itemUrl, memDefs, selectedFields, includes, path) { var memDefs = elementType.memberDefinitions.getPublicMappedProperties(); if (path && selectedFields && selectedFields.length > 0) memDefs = memDefs.filter(function(it){ return selectedFields.indexOf(path + '.' + it.name) >= 0; }); for (var i = 0; i < memDefs.length; i++) { var memDef = memDefs[i]; if (memDef.inverseProperty !== undefined) { var linkType = 'entry'; var type = Container.resolveType(memDef.type); var linkEsDef; if (type === $data.Array) { linkType = 'feed'; var type = Container.resolveType(memDef.elementType); linkEsDef = this._getEntitySetDefByType(type); } else { linkEsDef = this._getEntitySetDefByType(type); } var rel = this.xml.declareAttribute('rel'); var atype = this.xml.declareAttribute('type'); var href = this.xml.declareAttribute('href'); var link = this.xml.declareElement('link'); var typeName = elementType.name; this.xml.startElement(link) .addAttribute(rel, this.cfg.related + '/' + (type === $data.Array ? linkEsDef.name : memDef.name)) .addAttribute(atype, 'application/atom+xml;type=' + linkType) .addAttribute(href, itemUrl.slice(this.requesUrl.length + 1) + '/' + memDef.name); //includes if (data[memDef.name] !== undefined){ var m = this.xml.declareNamespace(this.cfg.m, 'm'); var inline = this.xml.declareElement(m, 'inline'); this.xml.startElement(inline); var defaultType = Container.resolveType(memDef.elementType || memDef.type); var esType = this._getEntitySetDefByType(defaultType); var path = path ? path + '.' + memDef.name : memDef.name; if (memDef.elementType){ this._buildFeed(data[memDef.name], esType, defaultType, defaultType.memberDefinitions.getPublicMappedProperties(), selectedFields, includes, path, itemUrl.slice(this.requesUrl.length + 1) + '/' + memDef.name); }else{ this._buildEntry(data[memDef.name], esType, defaultType, memDefs, selectedFields, includes, false, path); } this.xml.endElement(); } this.xml.endElement(); } } }, _buildProperties: function (data, esDef, elementType, memDefs, selectedFields, includes, path) { var m = this.xml.declareNamespace(this.cfg.m, 'm'); var d = this.xml.declareNamespace(this.cfg.d, 'd'); var memDefs = elementType.memberDefinitions.getPublicMappedProperties(); if (path){ if (selectedFields && selectedFields.length > 0) memDefs = memDefs.filter(function(it){ return (selectedFields.indexOf(path) >= 0 && selectedFields.indexOf(path + '.' + it.name) < 0) || selectedFields.indexOf(path + '.' + it.name) >= 0; }); }else{ if (selectedFields && selectedFields.length > 0) memDefs = memDefs.filter(function(it){ return selectedFields.indexOf(it.name) >= 0; }); } for (var i = 0; i < memDefs.length; i++) { var memDef = memDefs[i]; if (memDef.inverseProperty === undefined && (memDef.lazyLoad !== true || (Array.isArray(selectedFields) && selectedFields.indexOf(memDef.name) >= 0))) { this._buildProperty(data, memDef, m, d); } } }, _buildProperty: function (data, memDef, m, d) { var resolvedUserAgent = this.supports[this._getUserAgent()]; var typeName = this._resolveEdmType(memDef); var type = Container.resolveType(memDef.type); if (!resolvedUserAgent || (resolvedUserAgent && resolvedUserAgent.indexOf(typeName) >= 0) || (type.isAssignableTo && type.isAssignableTo($data.Entity))) { var memberType = this.xml.declareAttribute(m, 'type'); var prop = this.xml.declareElement(d, memDef.name); this.xml.startElement(prop); if (typeName !== 'Edm.String') this.xml.addAttribute(memberType, typeName); var value = data[memDef.name]; if (value !== null && value !== undefined) { if (type === $data.Array) { type = Container.resolveType(memDef.elementType); if (type.isAssignableTo && type.isAssignableTo($data.Entity)) { var subEntitySet = this._getEntitySetDefByType(type); if (subEntitySet) { //array of ComplexEntitys var inline = this.xml.declareElement(m, 'inline'); this.xml.startElement(inline); this._buildComplexArray(data[memDef.name], type, m, d); this.xml.endElement(); } else { this._buildComplexArray(data[memDef.name], type, m, d); } } else { //array of Primitive types if (this._getUserAgent() !== this.cfg.excelUserAgent) { this._buildComplexArray(data[memDef.name], type, m, d); } } } else if (type.isAssignableTo && type.isAssignableTo($data.Entity)) { //complexType this._buildProperties(data[memDef.name], undefined, type); } else { //primitive types var typeName = Container.resolveName(type); var converter = this._valueConverters.xmlEscape[typeName]; this.xml.addText(converter ? converter.call(this, value) : value.toString()); } } else { var nullValue = this.xml.declareAttribute(m, 'null'); this.xml.addAttribute(nullValue, 'true'); } this.xml.endElement(); } }, _buildComplexArray: function (data, type, m, d) { var item = this.xml.declareElement(m, 'item'); var itemType = this.xml.declareAttribute('type'); if (type.isAssignableTo && type.isAssignableTo($data.Entity)) { for (var i = 0; i < data.length; i++) { this.xml.startElement(item) .addAttribute(itemType, Container.resolveName(type)); this._buildProperties(data[i], undefined, type); this.xml.endElement(); } } else { for (var i = 0; i < data.length; i++) { var typeName = Container.resolveName(type); var edmTypeName = this._edmTypeMapping[typeName] ? this._edmTypeMapping[typeName] : typeName; this.xml.startElement(item); if (edmTypeName !== 'Edm.String') this.xml.addAttribute(itemType, edmTypeName); var converter = this._valueConverters.xmlEscape[typeName]; this.xml.addText(converter ? converter.call(this, data[i]) : data[i].toString()); this.xml.endElement(); } } }, _resolveEdmType: function (memDef) { var type = Container.resolveType(memDef.type); var typeName = Container.resolveName(type); if (type === $data.Array) { type = Container.resolveType(memDef.elementType); typeName = Container.resolveName(type); return 'Collection(' + (this._edmTypeMapping[typeName] ? this._edmTypeMapping[typeName] : typeName) + ')'; } return this._edmTypeMapping[typeName] ? this._edmTypeMapping[typeName] : typeName; }, _buildSpatialPoint: function (value, srsName) { var gml = this.xml.declareNamespace(this.cfg.gml, 'gml'); var point = this.xml.declareElement(gml, value.type); var srsNameAttr = this.xml.declareAttribute(gml, 'srsName'); this.xml.startElement(point) .addAttribute(srsNameAttr, srsName); var pos = this.xml.declareElement(gml, 'pos'); this.xml.startElement(pos); this.xml.addText(value.coordinates.join(' ')); this.xml.endElement(); this.xml.endElement(); }, _buildSpatialLineString: function (value, srsName) { var gml = this.xml.declareNamespace(this.cfg.gml, 'gml'); var point = this.xml.declareElement(gml, value.type); var srsNameAttr = this.xml.declareAttribute(gml, 'srsName'); this.xml.startElement(point) .addAttribute(srsNameAttr, srsName); var pos = this.xml.declareElement(gml, 'posList'); this.xml.startElement(pos); var valueText = ''; if (value.coordinates) { for (var i = 0; i < value.coordinates.length; i++) { if (Array.isArray(value.coordinates[i])) { if (i !== 0) valueText += ' '; valueText += value.coordinates[i].join(' '); } } } this.xml.addText(valueText); this.xml.endElement(); this.xml.endElement(); }, _edmTypeMapping:{ value: $data.oDataEdmMapping }, _valueConverters: { value: $data.oDataConverter }, supports: { value: { 'PowerPivot': [ 'Edm.Byte', 'Edm.SByte', 'Edm.Decimal', 'Edm.Float', 'Edm.Int16', 'Edm.Int64', 'Edm.DateTimeOffset', 'Edm.Time', 'Edm.Boolean', 'Edm.Binary', 'Edm.DateTime', 'Edm.Double', 'Edm.Int32', 'Edm.String', 'Edm.Guid' ] } }, _getUserAgent: function () { return this.cfg.headers['user-agent'] || this.cfg.headers['User-Agent'] || ''; } });