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