HydraReader.js (5886B)
1 /** 2 * JSON-LD / Hydra Reader. 3 * 4 * Supports in-line references. 5 */ 6 Ext.define("PartKeepr.data.HydraReader", { 7 extend: 'Ext.data.reader.Json', 8 alias: 'reader.hydra', 9 10 totalProperty: 'hydra:totalItems', 11 12 replacements: [], 13 loadedRecords: {}, 14 15 getResponseData: function (response) { 16 var data = this.callParent([response]); 17 18 if (data["@type"] == "hydra:PagedCollection" || data["@type"] == "hydra:Collection") { 19 this.setRootProperty("hydra:member"); 20 } else { 21 this.setRootProperty(""); 22 } 23 return data; 24 }, 25 26 read: function(response, readOptions) { 27 var data, result, responseText; 28 29 if (response) { 30 responseText = response.responseText; 31 if (responseText) { 32 result = this.getResponseData(response); 33 if (result && result.__$isError) { 34 return new Ext.data.ResultSet({ 35 total : 0, 36 count : 0, 37 records: [], 38 success: false, 39 message: result.msg 40 }); 41 } else { 42 data = this.readRecords(result, readOptions); 43 } 44 } else if (responseText !== '') { 45 data = this.readRecords(response, readOptions); 46 } 47 } 48 49 var replacement; 50 51 for (var i=0;i<this.replacements.length;i++) { 52 replacement = this.replacements[i]; 53 54 if (typeof this.loadedRecords[replacement.id] === "object") 55 { 56 replacement.record[replacement.setterName](this.loadedRecords[replacement.id]); 57 } 58 } 59 60 return data || this.nullResultSet; 61 }, 62 /** 63 * Loads the record associations from the data object. Supports late-tree replacements. 64 * 65 * @param {Ext.data.Model} record The record to load associations for. 66 * @param {Object} data The raw data object. 67 * @param {Object} readOptions See {@link #read}. 68 * 69 * @private 70 */ 71 readAssociated: function(record, data, readOptions) { 72 var roles = record.associations, 73 key, role; 74 75 for (key in roles) { 76 if (roles.hasOwnProperty(key)) { 77 role = roles[key]; 78 // The class for the other role may not have loaded yet 79 if (role.cls) { 80 if (typeof data[role.role] === "string") { 81 // Association is a string, save for later 82 this.replacements.push({ 83 record: record, 84 associationKey: role.role, 85 id: data[role.role], 86 setterName: role.setterName 87 }); 88 } else { 89 role.read(record, data, this, readOptions); 90 } 91 92 } 93 } 94 } 95 }, 96 97 /** 98 * Overrides the changes of the JsonReader to support referenced associations. 99 * @param root 100 * @param readOptions 101 * @returns {Array} 102 */ 103 extractData: function(root, readOptions) { 104 105 var me = this, 106 entityType = readOptions && readOptions.model ? Ext.data.schema.Schema.lookupEntity(readOptions.model) : me.getModel(), 107 schema = entityType.schema, 108 includes = schema.hasAssociations(entityType) && me.getImplicitIncludes(), 109 fieldExtractorInfo = me.getFieldExtractorInfo(entityType.fieldExtractors), 110 length = root.length, 111 records = new Array(length), 112 typeProperty = me.getTypeProperty(), 113 reader, node, nodeType, record, i; 114 115 if (!length && Ext.isObject(root)) { 116 root = [root]; 117 length = 1; 118 } 119 120 for (i = 0; i < length; i++) { 121 record = root[i]; 122 if (!record.isModel) { 123 // If we're given a model instance in the data, just push it on 124 // without doing any conversion. Otherwise, create a record. 125 node = record; 126 127 // This Reader may be configured to produce different model types based on 128 // a differentiator field in the incoming data: 129 // typeProperty name be a string, a function which yields the child type, or an object: { 130 // name: 'mtype', 131 // namespace: 'MyApp' 132 // } 133 if (typeProperty && (nodeType = me.getChildType(schema, node, typeProperty))) { 134 135 reader = nodeType.getProxy().getReader(); 136 137 record = reader.extractRecord(node, readOptions, nodeType, 138 schema.hasAssociations(nodeType) && reader.getImplicitIncludes(), 139 reader.getFieldExtractorInfo(nodeType.fieldExtractors)); 140 141 } else { 142 record = me.extractRecord(node, readOptions, entityType, includes, 143 fieldExtractorInfo); 144 } 145 146 var kk = {}; 147 148 this.loadedRecords[record.getId()] = record; 149 150 // Generally we don't want to have references to XML documents 151 // or XML nodes to hang around in memory but Trees need to be able 152 // to access the raw XML node data in order to process its children. 153 // See https://sencha.jira.com/browse/EXTJS-15785 and 154 // https://sencha.jira.com/browse/EXTJS-14286 155 if (record.isModel && record.isNode) { 156 record.raw = node; 157 } 158 } 159 if (record.onLoad) { 160 record.onLoad(); 161 } 162 records[i] = record; 163 } 164 165 return records; 166 } 167 });