1 /* Licensed to the Apache Software Foundation (ASF) under one or more
  2  * contributor license agreements.  See the NOTICE file distributed with
  3  * this work for additional information regarding copyright ownership.
  4  * The ASF licenses this file to you under the Apache License, Version 2.0
  5  * (the "License"); you may not use this file except in compliance with
  6  * the License.  You may obtain a copy of the License at
  7  *
  8  *      http://www.apache.org/licenses/LICENSE-2.0
  9  *
 10  * Unless required by applicable law or agreed to in writing, software
 11  * distributed under the License is distributed on an "AS IS" BASIS,
 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  * See the License for the specific language governing permissions and
 14  * limitations under the License.
 15  */
 16 
 17 /**
 18  *
 19  * Author: Werner Punz (latest modification by $Author: ganeshpuri $)
 20  * Version: $Revision: 1.4 $ $Date: 2009/05/31 09:16:44 $
 21  */
 22 
 23 /**
 24  * @memberOf myfaces._impl
 25  * @namespace
 26  * @name xhrCore
 27  */
 28 
 29 /**
 30  * @class
 31  * @name _BaseRequest
 32  * @memberOf myfaces._impl.xhrCore
 33  * @extends myfaces._impl.xhrCore._FinalizeableObj
 34  *
 35  * @description
 36  * Abstract base request encapuslating all methods and variables
 37  * shared over all different request objects
 38  * <p />
 39  * Abstract methods which have to be implemented:<br />
 40  * Since we do not have abstract methods we simulate them
 41  * by using empty ones
 42  */
 43 myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._BaseRequest", myfaces._impl.xhrCore._FinalizeableObj,
 44 /** @lends myfaces._impl.xhrCore._BaseRequest.prototype */
 45 {
 46 
 47     _Dom: null,
 48     _Lang: null,
 49     _RT: myfaces._impl.core._Runtime,
 50 
 51     _contentType: "application/x-www-form-urlencoded",
 52     _source: null,
 53     _xhr: null,
 54     _encoding:null ,
 55 
 56     _context:null,
 57     _ajaxUtil: null,
 58     _sourceForm: null,
 59     _passThrough: null,
 60     _requestParameters: null,
 61     _exception: null,
 62     _timeout: null,
 63     _delay:null,
 64     _queueSize:-1,
 65     _xhrQueue: null,
 66 
 67     _partialIdsArray : null,
 68     //callbacks for onDone... done issues
 69     //onSuccess everything has passed through
 70     //onError server side error
 71 
 72     //onException exception thrown by the client
 73     //onWarning warning issued by the client
 74     //onException exception thrown by the client
 75     //onWarning warning issued by the client
 76     _onDone : null,
 77     _onSuccess: null,
 78     _onError: null,
 79     _onException: null,
 80     _onWarning: null,
 81     _onTimeout:null,
 82 
 83     /*response object which is exposed to the queue*/
 84     _response: null,
 85 
 86     _timeoutId: null,
 87 
 88     /*all instance vars can be set from the outside
 89      * via a parameter map*/
 90     _ajaxType: "POST",
 91 
 92     /*
 93      * constants used internally
 94      */
 95     _CONTENT_TYPE:"Content-Type",
 96     _HEAD_FACES_REQ:"Faces-Request",
 97 
 98     _READY_STATE_DONE: 4,
 99     _STATUS_OK_MINOR: 200,
100     _STATUS_OK_MAJOR: 300,
101 
102     _VAL_AJAX: "partial/ajax",
103 
104 
105 
106 
107     //abstract methods which have to be implemented
108     //since we do not have abstract methods we simulate them
109     //by using empty ones
110     constructor_: function() {
111         this._callSuper("constructor");
112         this._initDefaultFinalizableFields();
113 
114         this._Lang = myfaces._impl._util._Lang;
115         this._Dom = myfaces._impl._util._Dom;
116 
117         //we fixate the scopes just in case
118         this._onException = this._Lang.hitch(this, this._stdErrorHandler);
119         this._onWarn = this._Lang.hitch(this, this._stdErrorHandler);
120         this._onError = this._Lang.hitch(this, this._stdXhrServerError);
121         this._onSuccess = this._Lang.hitch(this, this._stdOnSuccess);
122         this._onDone = this._Lang.hitch(this, this._stdOnDone);
123         this._onTimeout = this._Lang.hitch(this, this._stdOnTimeout);
124 
125         //we clear any exceptions being thrown
126         //if(this._xhrQueue) {
127         //    if(this._xhrQueue.isEmpty()) {
128         this._Lang.clearExceptionProcessed();
129         //    }
130         //}
131 
132     },
133 
134     /**
135      * send the request
136      */
137     send: function() {
138     },
139 
140     /**
141      * the callback function after the request is done
142      */
143     callback: function() {
144 
145     },
146 
147     //non abstract ones
148     /**
149      * Spec. 13.3.1
150      * Collect and encode input elements.
151      * Additionally the hidden element javax.faces.ViewState
152      *
153      *
154      * @return  an element of formDataWrapper
155      * which keeps the final Send Representation of the
156      */
157     getViewState : function() {
158         var ret = this._Lang.createFormDataDecorator(new Array());
159 
160         this._ajaxUtil.encodeSubmittableFields(ret, this._xhr, this._context, this._source,
161                 this._sourceForm, this._partialIdsArray);
162 
163         return ret;
164     },
165 
166     _getImpl: function() {
167         this._Impl = this._Impl || myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
168         return this._Impl;
169     },
170 
171     /**
172      * standard on done handler which routes to the
173      * event sending specified by the spec
174      *
175      * @param ajaxRequest request object holding all data
176      */
177     _stdOnDone: function() {
178         this._getImpl().sendEvent(this._xhr, this._context, this._getImpl().COMPLETE);
179     },
180 
181     /**
182      * standard spec compliant success handler
183      *
184      * @param request the xhr request object
185      * @param context the context holding all values for further processing
186      */
187     _stdOnSuccess: function() {
188         //_onSuccess
189         var _Impl = this._getImpl();
190 
191         try {
192             //now we have to reroute into our official api
193             //because users might want to decorate it, we will split it apart afterwards
194             this._context._mfInternal = this._context._mfInternal || {};
195             this._context._mfInternal._mfRequest = this;
196 
197             jsf.ajax.response(this._xhr, this._context);
198 
199             _Impl.sendEvent(this._xhr, this._context, _Impl.SUCCESS);
200         } finally {
201             if (this.isQueued()) {
202                 this._xhrQueue.processQueue();
203             }
204             //ie6 helper cleanup
205             delete this._context.source;
206         }
207     },
208 
209 
210     /**
211      * now to the error case handlers which by spec should
212      * route to our standard error queue
213      *
214      * @param {BaseRequest} ajaxRequest the ajax request object
215      */
216     _stdXhrServerError: function() {
217         var _Impl = this._getImpl();
218 
219         //_onError
220         var errorText;
221         try {
222             var UNKNOWN = this._Lang.getMessage("UNKNOWN");
223             var errorText = this._Lang.getMessage("ERR_REQU_FAILED", null,
224                     (this._xhr.status || UNKNOWN),
225                     (this._xhr.statusText || UNKNOWN));
226 
227         } catch (e) {
228             errorText = this._Lang.getMessage("ERR_REQ_FAILED_UNKNOWN", null);
229         } finally {
230             try {
231                 _Impl.sendError(this._xhr, this._context, _Impl.HTTPERROR,
232                         _Impl.HTTPERROR, errorText);
233             } finally {
234                 if (this._xhrQueue) {
235                     this._xhrQueue.processQueue();
236                 }
237                 //ie6 helper cleanup
238                 delete this.getContext().source;
239 
240             }
241         }
242         //_onError
243 
244     },
245 
246     /**
247      * standard timeout handler
248      * the details on how to handle the timeout are
249      * handled by the calling request object
250      */
251     _stdOnTimeout: function(request, context) {
252         var _Impl = this._getImpl();
253         try {
254             //we issue an event not an error here before killing the xhr process
255             _Impl.sendEvent(request, context, _Impl.TIMEOUT_EVENT,
256                     _Impl.TIMEOUT_EVENT);
257             //timeout done we process the next in the queue
258         } finally {
259             //We trigger the next one in the queue
260             if (this._xhrQueue) {
261                 this._xhrQueue.processQueue();
262             }
263         }
264         //ready state done should be called automatically
265     },
266 
267     /**
268      * Client error handlers which also in the long run route into our error queue
269      * but also are able to deliver more meaningful messages
270      * note, in case of an error all subsequent xhr requests are dropped
271      * to get a clean state on things
272      *
273      * @param request the xhr request object
274      * @param context the context holding all values for further processing
275      * @param sourceClass (String) the issuing class for a more meaningful message
276      * @param func the issuing function
277      * @param exception the embedded exception
278      */
279     _stdErrorHandler: function(request, context, sourceClass, func, exception) {
280         try {
281             var _Impl = this._getImpl();
282             _Impl.stdErrorHandler(request, context, sourceClass, func, exception);
283         } finally {
284             if (this._xhrQueue) {
285                 this._xhrQueue.cleanup();
286             }
287         }
288     },
289 
290     getXhr: function() {
291         return this._xhr;
292     },
293 
294     getContext: function() {
295         return this._context;
296     },
297 
298     setQueue: function(queue) {
299         this._xhrQueue = queue;
300     },
301 
302     isQueued: function() {
303         return this._xhrQueue;
304     }
305 
306 
307 });