1 /** 2 * @fileOverview JavaScript representation of the Finesse PhoneBook object. 3 * 4 * @name finesse.restservices.PhoneBook 5 * @requires finesse.clientservices.ClientServices 6 * @requires Class 7 * @requires finesse.FinesseBase 8 * @requires finesse.restservices.RestBase 9 */ 10 11 var finesse = finesse || {}; 12 finesse.restservices = finesse.restservices || {}; 13 14 /** @private */ 15 finesse.restservices.PhoneBook = finesse.restservices.RestBase.extend(/** @lends finesse.restservices.PhoneBook.prototype */{ 16 17 _contacts: null, 18 19 /** 20 * @class 21 * JavaScript representation of a PhoneBook object. Also exposes 22 * methods to operate on the object against the server. 23 * 24 * @param {Object} options 25 * An object with the following properties:<ul> 26 * <li><b>id:</b> The id of the object being constructed</li> 27 * <li><b>onLoad(this): (optional)</b> when the object is successfully loaded from the server</li> 28 * <li><b>onChange(this): (optional)</b> when an update notification of the object is received</li> 29 * <li><b>onAdd(this): (optional)</b> when a notification that the object is created is received</li> 30 * <li><b>onDelete(this): (optional)</b> when a notification that the object is deleted is received</li> 31 * <li><b>onError(rsp): (optional)</b> if loading of the object fails, invoked with the error response object:<ul> 32 * <li><b>status:</b> {Number} The HTTP status code returned</li> 33 * <li><b>content:</b> {String} Raw string of response</li> 34 * <li><b>object:</b> {Object} Parsed object of response</li> 35 * <li><b>error:</b> {Object} Wrapped exception that was caught:<ul> 36 * <li><b>errorType:</b> {String} Type of error that was caught</li> 37 * <li><b>errorMessage:</b> {String} Message associated with error</li> 38 * </ul></li> 39 * </ul></li> 40 * <li><b>parentObj: (optional)</b> The parent object</li></ul> 41 * @constructs finesse.restservices.PhoneBook 42 **/ 43 init: function (options) { 44 this._super(options); 45 }, 46 47 /** 48 * @private 49 * Gets the REST class for the current object - this is the PhoneBook class. 50 * @returns {Object} The PhoneBook class. 51 */ 52 getRestClass: function () { 53 return finesse.restservices.PhoneBook; 54 }, 55 56 /** 57 * @private 58 * Gets the REST type for the current object - this is a "PhoneBook". 59 * @returns {String} The PhoneBook string. 60 */ 61 getRestType: function () { 62 return "PhoneBook"; 63 }, 64 65 /** 66 * @private 67 * Override default to indicate that this object doesn't support making 68 * requests. 69 */ 70 supportsRequests: false, 71 72 /** 73 * @private 74 * Override default to indicate that this object doesn't support subscriptions. 75 */ 76 supportsSubscriptions: false, 77 78 /** 79 * Getter for the name. 80 * @returns {String} The name. 81 */ 82 getName: function () { 83 this.isLoaded(); 84 return this.getData().name; 85 }, 86 87 /** 88 * Getter for the type flag. 89 * @returns {String} The type. 90 */ 91 getType: function () { 92 this.isLoaded(); 93 return this.getData().type; 94 }, 95 96 /** 97 * Getter for the Uri value. 98 * @returns {String} The Uri. 99 */ 100 getUri: function () { 101 this.isLoaded(); 102 return this.getData().uri; 103 }, 104 105 /** 106 * Getter for a Contacts collection object that is associated with PhoneBook. 107 * @param handlers 108 * @returns {Contacts} 109 * A Contacts collection object. 110 */ 111 getContacts: function (callbacks) { 112 var options = callbacks || {}; 113 options.parentObj = this; 114 this.isLoaded(); 115 116 if (this._contacts === null) { 117 this._contacts = new finesse.restservices.Contacts(options); 118 } 119 120 return this._contacts; 121 }, 122 123 /** 124 * Getter for <contacts> node within PhoneBook - sometimes it's just a URI, sometimes it is a Contacts collection 125 * @returns {String} uri to contacts 126 * or {Contacts} collection 127 */ 128 getEmbeddedContacts: function(){ 129 this.isLoaded(); 130 return this.getData().contacts; 131 }, 132 133 createPutSuccessHandler: function(phonebook, contentBody, successHandler){ 134 return function (rsp) { 135 // Update internal structure based on response. Here we 136 // inject the contentBody from the PUT request into the 137 // rsp.object element to mimic a GET as a way to take 138 // advantage of the existing _processResponse method. 139 rsp.object = contentBody; 140 phonebook._processResponse(rsp); 141 142 //Remove the injected PhoneBook object before cascading response 143 rsp.object = {}; 144 145 //cascade response back to consumer's response handler 146 successHandler(rsp); 147 }; 148 }, 149 150 createPostSuccessHandler: function (phonebook, contentBody, successHandler) { 151 return function (rsp) { 152 rsp.object = contentBody; 153 phonebook._processResponse(rsp); 154 155 //Remove the injected PhoneBook object before cascading response 156 rsp.object = {}; 157 158 //cascade response back to consumer's response handler 159 successHandler(rsp); 160 }; 161 }, 162 163 /** 164 * Add 165 */ 166 add: function (newValues, handlers) { 167 // this.isLoaded(); 168 var contentBody = {}; 169 170 contentBody[this.getRestType()] = { 171 "name": newValues.name, 172 "type": newValues.type 173 }; 174 175 // Protect against null dereferencing of options allowing its (nonexistant) keys to be read as undefined 176 handlers = handlers || {}; 177 178 this.restRequest(this.getRestUrl(), { 179 method: 'POST', 180 success: this.createPostSuccessHandler(this, contentBody, handlers.success), 181 error: handlers.error, 182 content: contentBody 183 }); 184 185 return this; // Allow cascading 186 }, 187 188 /** 189 * Update 190 */ 191 update: function (newValues, handlers) { 192 this.isLoaded(); 193 var contentBody = {}; 194 195 contentBody[this.getRestType()] = { 196 "uri": this.getId(), 197 "name": newValues.name, 198 "type": newValues.type 199 }; 200 201 // Protect against null dereferencing of options allowing its (nonexistant) keys to be read as undefined 202 handlers = handlers || {}; 203 204 this.restRequest(this.getRestUrl(), { 205 method: 'PUT', 206 success: this.createPutSuccessHandler(this, contentBody, handlers.success), 207 error: handlers.error, 208 content: contentBody 209 }); 210 211 return this; // Allow cascading 212 }, 213 214 215 /** 216 * Delete 217 */ 218 "delete": function ( handlers) { 219 this.isLoaded(); 220 221 // Protect against null dereferencing of options allowing its (nonexistent) keys to be read as undefined 222 handlers = handlers || {}; 223 224 this.restRequest(this.getRestUrl(), { 225 method: 'DELETE', 226 success: this.createPutSuccessHandler(this, {}, handlers.success), 227 error: handlers.error, 228 content: undefined 229 }); 230 231 return this; // Allow cascading 232 } 233 234 235 236 }); 237 238