/hippo/src/main/webapp/ext/src/data/DataReader.js

http://hdbc.googlecode.com/ · JavaScript · 160 lines · 76 code · 8 blank · 76 comment · 20 complexity · 865c37e9cc88a999d65a299cfd4c33d1 MD5 · raw file

  1. /*!
  2. * Ext JS Library 3.0.0
  3. * Copyright(c) 2006-2009 Ext JS, LLC
  4. * licensing@extjs.com
  5. * http://www.extjs.com/license
  6. */
  7. /**
  8. * @class Ext.data.DataReader
  9. * Abstract base class for reading structured data from a data source and converting
  10. * it into an object containing {@link Ext.data.Record} objects and metadata for use
  11. * by an {@link Ext.data.Store}. This class is intended to be extended and should not
  12. * be created directly. For existing implementations, see {@link Ext.data.ArrayReader},
  13. * {@link Ext.data.JsonReader} and {@link Ext.data.XmlReader}.
  14. * @constructor Create a new DataReader
  15. * @param {Object} meta Metadata configuration options (implementation-specific).
  16. * @param {Array/Object} recordType
  17. * <p>Either an Array of {@link Ext.data.Field Field} definition objects (which
  18. * will be passed to {@link Ext.data.Record#create}, or a {@link Ext.data.Record Record}
  19. * constructor created using {@link Ext.data.Record#create}.</p>
  20. */
  21. Ext.data.DataReader = function(meta, recordType){
  22. /**
  23. * This DataReader's configured metadata as passed to the constructor.
  24. * @type Mixed
  25. * @property meta
  26. */
  27. this.meta = meta;
  28. /**
  29. * @cfg {Array/Object} fields
  30. * <p>Either an Array of {@link Ext.data.Field Field} definition objects (which
  31. * will be passed to {@link Ext.data.Record#create}, or a {@link Ext.data.Record Record}
  32. * constructor created from {@link Ext.data.Record#create}.</p>
  33. */
  34. this.recordType = Ext.isArray(recordType) ?
  35. Ext.data.Record.create(recordType) : recordType;
  36. };
  37. Ext.data.DataReader.prototype = {
  38. /**
  39. * Abstract method, overridden in {@link Ext.data.JsonReader}
  40. */
  41. buildExtractors : Ext.emptyFn,
  42. /**
  43. * Used for un-phantoming a record after a successful database insert. Sets the records pk along with new data from server.
  44. * You <b>must</b> return at least the database pk using the idProperty defined in your DataReader configuration. The incoming
  45. * data from server will be merged with the data in the local record.
  46. * In addition, you <b>must</b> return record-data from the server in the same order received.
  47. * Will perform a commit as well, un-marking dirty-fields. Store's "update" event will be suppressed.
  48. * @param {Record/Record[]} record The phantom record to be realized.
  49. * @param {Object/Object[]} data The new record data to apply. Must include the primary-key from database defined in idProperty field.
  50. */
  51. realize: function(rs, data){
  52. if (Ext.isArray(rs)) {
  53. for (var i = rs.length - 1; i >= 0; i--) {
  54. // recurse
  55. if (Ext.isArray(data)) {
  56. this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
  57. }
  58. else {
  59. // weird...rs is an array but data isn't?? recurse but just send in the whole invalid data object.
  60. // the else clause below will detect !this.isData and throw exception.
  61. this.realize(rs.splice(i,1).shift(), data);
  62. }
  63. }
  64. }
  65. else {
  66. // If rs is NOT an array but data IS, see if data contains just 1 record. If so extract it and carry on.
  67. if (Ext.isArray(data) && data.length == 1) {
  68. data = data.shift();
  69. }
  70. if (!this.isData(data)) {
  71. // TODO: Let exception-handler choose to commit or not rather than blindly rs.commit() here.
  72. //rs.commit();
  73. throw new Ext.data.DataReader.Error('realize', rs);
  74. }
  75. this.buildExtractors();
  76. var values = this.extractValues(data, rs.fields.items, rs.fields.items.length);
  77. rs.phantom = false; // <-- That's what it's all about
  78. rs._phid = rs.id; // <-- copy phantom-id -> _phid, so we can remap in Store#onCreateRecords
  79. rs.id = data[this.meta.idProperty];
  80. rs.data = values;
  81. rs.commit();
  82. }
  83. },
  84. /**
  85. * Used for updating a non-phantom or "real" record's data with fresh data from server after remote-save.
  86. * You <b>must</b> return a complete new record from the server. If you don't, your local record's missing fields
  87. * will be populated with the default values specified in your Ext.data.Record.create specification. Without a defaultValue,
  88. * local fields will be populated with empty string "". So return your entire record's data after both remote create and update.
  89. * In addition, you <b>must</b> return record-data from the server in the same order received.
  90. * Will perform a commit as well, un-marking dirty-fields. Store's "update" event will be suppressed as the record receives
  91. * a fresh new data-hash.
  92. * @param {Record/Record[]} rs
  93. * @param {Object/Object[]} data
  94. */
  95. update : function(rs, data) {
  96. if (Ext.isArray(rs)) {
  97. for (var i=rs.length-1; i >= 0; i--) {
  98. if (Ext.isArray(data)) {
  99. this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
  100. }
  101. else {
  102. // weird...rs is an array but data isn't?? recurse but just send in the whole data object.
  103. // the else clause below will detect !this.isData and throw exception.
  104. this.update(rs.splice(i,1).shift(), data);
  105. }
  106. }
  107. }
  108. else {
  109. // If rs is NOT an array but data IS, see if data contains just 1 record. If so extract it and carry on.
  110. if (Ext.isArray(data) && data.length == 1) {
  111. data = data.shift();
  112. }
  113. if (!this.isData(data)) {
  114. // TODO: create custom Exception class to return record in thrown exception. Allow exception-handler the choice
  115. // to commit or not rather than blindly rs.commit() here.
  116. rs.commit();
  117. throw new Ext.data.DataReader.Error('update', rs);
  118. }
  119. this.buildExtractors();
  120. rs.data = this.extractValues(Ext.apply(rs.data, data), rs.fields.items, rs.fields.items.length);
  121. rs.commit();
  122. }
  123. },
  124. /**
  125. * Returns true if the supplied data-hash <b>looks</b> and quacks like data. Checks to see if it has a key
  126. * corresponding to idProperty defined in your DataReader config containing non-empty pk.
  127. * @param {Object} data
  128. * @return {Boolean}
  129. */
  130. isData : function(data) {
  131. return (data && Ext.isObject(data) && !Ext.isEmpty(data[this.meta.idProperty])) ? true : false;
  132. }
  133. };
  134. /**
  135. * @class Ext.data.DataReader.Error
  136. * @extends Ext.Error
  137. * General error class for Ext.data.DataReader
  138. */
  139. Ext.data.DataReader.Error = Ext.extend(Ext.Error, {
  140. constructor : function(message, arg) {
  141. this.arg = arg;
  142. Ext.Error.call(this, message);
  143. },
  144. name: 'Ext.data.DataReader'
  145. });
  146. Ext.apply(Ext.data.DataReader.Error.prototype, {
  147. lang : {
  148. 'update': "#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.",
  149. 'realize': "#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.",
  150. 'invalid-response': "#readResponse received an invalid response from the server."
  151. }
  152. });