1 /**
  2  * @fileOverview JavaScript representation of the Finesse MediaPropertiesLayout object
  3  *
  4  * @name finesse.restservices.MediaPropertiesLayout
  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.MediaPropertiesLayout = finesse.restservices.RestBase.extend(/** @lends finesse.restservices.MediaPropertiesLayout.prototype */{
 16 
 17     /**
 18      * @class
 19      * JavaScript representation of a MediaPropertiesLayout object. Also exposes
 20      * methods to operate on the object against the server.
 21      *
 22 	 * @param {Object} options
 23 	 *     An object with the following properties:<ul>
 24      *         <li><b>id:</b> The id of the object being constructed</li>
 25      *         <li><b>onLoad(this): (optional)</b> when the object is successfully loaded from the server</li>
 26      *         <li><b>onChange(this): (optional)</b> when an update notification of the object is received</li>
 27      *         <li><b>onAdd(this): (optional)</b> when a notification that the object is created is received</li>
 28      *         <li><b>onDelete(this): (optional)</b> when a notification that the object is deleted is received</li>
 29      *         <li><b>onError(rsp): (optional)</b> if loading of the object fails, invoked with the error response object:<ul>
 30      *             <li><b>status:</b> {Number} The HTTP status code returned</li>
 31      *             <li><b>content:</b> {String} Raw string of response</li>
 32      *             <li><b>object:</b> {Object} Parsed object of response</li>
 33      *             <li><b>error:</b> {Object} Wrapped exception that was caught:<ul>
 34      *                 <li><b>errorType:</b> {String} Type of error that was caught</li>
 35      *                 <li><b>errorMessage:</b> {String} Message associated with error</li>
 36      *             </ul></li>
 37      *         </ul></li>
 38      *         <li><b>parentObj: (optional)</b> The parent object</li></ul>
 39      * @constructs finesse.restservices.MediaPropertiesLayout
 40      **/
 41     init: function (options) {
 42         this._super(options);
 43     },
 44 
 45     /**
 46      * @private
 47      * Gets the REST class for the current object - this is the MediaPropertiesLayout object.
 48      */
 49     getRestClass: function () {
 50         return finesse.restservices.MediaPropertiesLayout;
 51     },
 52 
 53     /**
 54      * @private
 55      * Gets the REST type for the current object - this is a "MediaPropertiesLayout".
 56      */
 57     getRestType: function () {
 58         return "MediaPropertiesLayout";
 59     },
 60 
 61     /**
 62      * @private
 63      * Overrides the parent class.  Returns the url for the MediaPropertiesLayout resource
 64      */
 65     getRestUrl: function () {
 66         return ("/finesse/api/User/" + this.getId() + "/" + this.getRestType());
 67     },
 68 
 69     /**
 70      * @private
 71      * Returns whether this object supports subscriptions
 72      */
 73     supportsSubscriptions: false,
 74 
 75     /**
 76      * Retrieve the media properties layout
 77      * @returns {finesse.restservices.MediaPropertiesLayout}
 78      *     This MediaPropertiesLayout object to allow cascading
 79      */
 80     get: function () {
 81         this._synchronize();
 82 
 83         return this; //Allow cascading
 84     },
 85 
 86     /**
 87      * Gets the data for this object.
 88      * 
 89      * Performs safe conversion from raw API data to ensure that the returned layout object
 90      * always has a header with correct entry fields, and exactly two columns with lists of entries.
 91      *
 92      * @returns Object which are contained in data
 93      */
 94     getData: function () {
 95 
 96         var layout = this._data, result, _addColumnData;
 97 
 98         result = this.getEmptyData();
 99 
100 	    /**
101 	     * @private
102 	     */
103         _addColumnData = function (entryData, colIndex) {
104 
105             if (!entryData) {
106                 //If there's no entry data at all, rewrite entryData to be an empty collection of entries
107                 entryData = {};
108             } else if (entryData.mediaProperty) {
109                 //If entryData contains the keys for a single entry rather than being a collection of entries,
110                 //rewrite it to be a collection containing a single entry
111                 entryData = { "": entryData };
112             }
113 
114             //Add each of the entries in the list to the column
115             jQuery.each(entryData, function (i, entryData) {
116 
117                 //If the entry has no displayName specified, explicitly set it to the empty string
118                 if (!entryData.displayName) {
119                     entryData.displayName = "";
120                 }
121 
122                 result.columns[colIndex].push(entryData);
123 
124             });
125 
126         };
127 
128         //The header should only contain a single entry
129         if (layout.header && layout.header.entry) {
130 
131             //If the entry has no displayName specified, explicitly set it to the empty string
132             if (!layout.header.entry.displayName) {
133                 layout.header.entry.displayName = "";
134             }
135 
136             result.header = layout.header.entry;
137 
138         } else {
139 
140             throw "MediaPropertiesLayout.getData() - Header does not contain an entry";
141 
142         }
143 
144         //If the column object contains an entry object that wasn't part of a list of entries,
145         //it must be a single right-hand entry object (left-hand entry object would be part of a list.)
146         //Force the entry object to be the 2nd element in an otherwise-empty list.
147         if (layout.column && layout.column.entry) {
148             layout.column = [
149                 null,
150                 { "entry": layout.column.entry }
151             ];
152         }
153 
154         if (layout.column && layout.column.length > 0 && layout.column.length <= 2) {
155 
156             //Render left column entries
157             if (layout.column[0] && layout.column[0].entry) {
158                 _addColumnData(layout.column[0].entry, 0);
159             }
160 
161             //Render right column entries
162             if (layout.column[1] && layout.column[1].entry) {
163                 _addColumnData(layout.column[1].entry, 1);
164             }
165 
166         }
167 
168         return result;
169 
170     },
171 
172     /**
173      * Empty/template version of getData().
174      *
175      * Used by getData(), and by callers of getData() in error cases.
176      */
177     getEmptyData: function () {
178 
179         return {
180             header : {
181                 displayName: null,
182                 mediaProperty: null
183             },
184             columns : [[], []]
185         };
186 
187     },
188 
189     /**
190      * Set the layout of this MediaPropertiesLayout.
191      * @param {String} layout
192      *     The layout you are setting
193      * @param {Object} handlers
194      *     An object containing the following (optional) handlers for the request:<ul>
195      *         <li><b>success(rsp):</b> A callback function for a successful request to be invoked with the following
196      *         response object as its only parameter:<ul>
197      *             <li><b>status:</b> {Number} The HTTP status code returned</li>
198      *             <li><b>content:</b> {String} Raw string of response</li>
199      *             <li><b>object:</b> {Object} Parsed object of response</li></ul>
200      *         <li>A error callback function for an unsuccessful request to be invoked with the
201      *         error response object as its only parameter:<ul>
202      *             <li><b>status:</b> {Number} The HTTP status code returned</li>
203      *             <li><b>content:</b> {String} Raw string of response</li>
204      *             <li><b>object:</b> {Object} Parsed object of response (HTTP errors)</li>
205      *             <li><b>error:</b> {Object} Wrapped exception that was caught:<ul>
206      *                 <li><b>errorType:</b> {String} Type of error that was caught</li>
207      *                 <li><b>errorMessage:</b> {String} Message associated with error</li>
208      *             </ul></li>
209      *         </ul>
210      * @returns {finesse.restservices.MediaPropertiesLayout}
211      *     This MediaPropertiesLayout object to allow cascading
212      */
213     setLayout: function (layout, handlers) {
214 
215         var contentBody = {};
216 
217         contentBody[this.getRestType()] = layout;
218 
219         //Protect against null dereferencing of options allowing its (nonexistant) keys to be read as undefined
220         handlers = handlers || {};
221 
222         this.restRequest(this.getRestUrl(), {
223             method: 'PUT',
224             success: handlers.success,
225             error: handlers.error,
226             content: contentBody
227         });
228 
229         return this; // Allow cascading
230     }
231 
232 });
233