partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

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 });