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  * @class
 19  * @name _Transports
 20  * @memberOf myfaces._impl.xhrCore
 21  * @description
 22  *
 23  * The xhr core adapter
 24  * which provides the transport mechanisms to the calling
 25  * objects, and controls the queue behavior, the error handling
 26  * and partial page submit functionality among other things
 27  * <p />
 28  * The idea behind this is to make the ajax request object as barebones
 29  * as possible and shift the extra functionality like queuing
 30  * parameter handling etc... to this class so that our transports become more easily
 31  * pluggable. This should keep the path open to iframe submits and other transport layers
 32  * <p />
 33  * the call to the corresponding transport just should be a
 34  * transport.xhrQueuedPost <br />
 35  * or transport.xhrPost,transport.xhrGet  etc... in the future
 36  * <p />
 37  * Note we have taken a pattern lesson or two from the dojo toolkit and its excellent handling
 38  * of transports by our patterns here (which is mainly a centralized transport singleton which routes
 39  * to different transport implementations and the auto passing of parameters into their
 40  * corresponding protected attributes on class level in the transports themselves)
 41  */
 42 _MF_SINGLTN(_PFX_XHR + "_Transports", _MF_OBJECT,
 43         /** @lends myfaces._impl.xhrCore._Transports.prototype */ {
 44 
 45     _PAR_ERRORLEVEL:"errorlevel",
 46     _PAR_QUEUESIZE:"queuesize",
 47     _PAR_PPS:"pps",
 48     _PAR_TIMEOUT:"timeout",
 49     _PAR_DELAY:"delay",
 50 
 51 
 52     /**
 53      * a singleton queue
 54      * note the structure of our inheritance
 55      * is that that _queue is attached to prototype
 56      * and hence the pointer to the request qeue
 57      * is shared over all instances
 58      *
 59      * if you need to have it per instance for complex objects
 60      * you have to initialize in the constructor
 61      *
 62      * (This is the same limitation dojo class inheritance
 63      * where our inheritance pattern is derived from has)
 64      */
 65     _q: new myfaces._impl.xhrCore._AjaxRequestQueue(),
 66 
 67     /**
 68      * xhr post with enqueuing as defined by the jsf 2.0 specification
 69      *
 70      * mapped options already have the exec and view properly in place
 71      * myfaces specifics can be found under mappedOptions.myFaces
 72      * @param {Node} source the source of this call
 73      * @param {Node} sourceForm the html form which is the source of this call
 74      * @param {Object} context (Map) the internal pass through context
 75      * @param {Object} passThrgh (Map) values to be passed through
 76      **/
 77     xhrQueuedPost : function(source, sourceForm, context, passThrgh) {
 78         context._mfInternal.xhrOp = "xhrQueuedPost";
 79         this._q.enqueue(
 80                 new (this._getAjaxReqClass(context))(this._getArguments(source, sourceForm, context, passThrgh)));
 81     },
 82 
 83     /**
 84       * iframe queued post
 85       *
 86       * mapped options already have the exec and view properly in place
 87       * myfaces specifics can be found under mappedOptions.myFaces
 88       * @param {Node} source the source of this call
 89       * @param {Node} sourceForm the html form which is the source of this call
 90       * @param {Object} context (Map) the internal pass through context
 91       * @param {Object} passThrgh (Map) values to be passed through
 92       **/
 93      multipartQueuedPost : function(source, sourceForm, context, passThrgh) {
 94          context._mfInternal.xhrOp = "multipartQueuedPost";
 95          var args = this._getArguments(source, sourceForm, context, passThrgh);
 96          // note in get the timeout is not working delay however is and queue size as well
 97          // since there are no cross browser ways to resolve a timeout on xhr level
 98          this._q.enqueue(
 99                  new (this._getMultipartReqClass(context))(args));
100      },
101 
102 
103     /**
104      * creates the arguments map and
105      * fetches the config params in a proper way in to
106      * deal with them in a flat way (from the nested context way)
107      *
108      * @param source the source of the request
109      * @param sourceForm the sourceform
110      * @param context   the context holding all values
111      * @param passThrgh the passThrough values to be blended into the response
112      */
113     _getArguments: function(source, sourceForm, context, passThrgh) {
114         var _RT = myfaces._impl.core._Runtime,
115         /** @ignore */
116              _Lang = myfaces._impl._util._Lang,
117              applyCfg = _Lang.hitch(this, this._applyConfig),
118             //RT does not have this references, hence no hitch needed
119              getCfg = _RT.getLocalOrGlobalConfig,
120 
121 
122             ret = {
123                 "source": source,
124                 "sourceForm": sourceForm,
125                 "context": context,
126                 "passThrough": passThrgh,
127                 "xhrQueue": this._q
128             };
129 
130         //we now mix in the config settings which might either be set globally
131         //or pushed in under the context myfaces.<contextValue> into the current request
132         applyCfg(ret, context, "alarmThreshold", this._PAR_ERRORLEVEL);
133         applyCfg(ret, context, "queueSize", this._PAR_QUEUESIZE);
134         //TODO timeout probably not needed anymore
135         applyCfg(ret, context, "timeout", this._PAR_TIMEOUT);
136         //applyCfg(ret, context, "delay", this._PAR_DELAY);
137 
138         //now partial page submit needs a different treatment
139         //since pps == execute strings
140         if (getCfg(context, this._PAR_PPS, false)
141                 && _Lang.exists(passThrgh, myfaces._impl.core.Impl.P_EXECUTE)
142                 && passThrgh[myfaces._impl.core.Impl.P_EXECUTE].length > 0) {
143             ret['partialIdsArray'] = passThrgh[myfaces._impl.core.Impl.P_EXECUTE].split(" ");
144         }
145         return ret;
146     },
147 
148     /**
149      * helper method to apply a config setting to our varargs param list
150      *
151      * @param destination the destination map to receive the setting
152      * @param context the current context
153      * @param destParm the destination param of the destination map
154      * @param srcParm the source param which is the key to our config setting
155      */
156     _applyConfig: function(destination, context, destParm, srcParm) {
157         var _RT = myfaces._impl.core._Runtime;
158         /** @ignore */
159         var _getConfig = _RT.getLocalOrGlobalConfig;
160         if (_getConfig(context, srcParm, null) != null) {
161             destination[destParm] = _getConfig(context, srcParm, null);
162         }
163     },
164 
165     /**
166      * centralized transport switching helper
167      * for the multipart submit case
168      *
169      * @param context the context which is passed down
170      */
171     _getMultipartReqClass: function(context) {
172        if (this._RT.getXHRLvl() >= 2) {
173             return myfaces._impl.xhrCore._MultipartAjaxRequestLevel2;
174        } else {
175             return myfaces._impl.xhrCore._IFrameRequest;
176        }
177     },
178 
179 
180     _getAjaxReqClass: function(context) {
181         // var _RT = myfaces._impl.core._Runtime;
182         if(this._RT.getXHRLvl() < 2) {
183            return myfaces._impl.xhrCore._AjaxRequest;
184         } else {
185            return myfaces._impl.xhrCore._AjaxRequestLevel2;
186         }
187     }
188 
189 });
190