[opensocial-actionscript-client] r118 committed - Implemented batch request.

1 view
Skip to first unread message

opensocial-acti...@googlecode.com

unread,
Feb 28, 2010, 11:07:57 PM2/28/10
to opensocial-acti...@googlegroups.com
Revision: 118
Author: zakiy...@gmail.com
Date: Sun Feb 28 20:07:20 2010
Log: Implemented batch request.
http://code.google.com/p/opensocial-actionscript-client/source/detail?r=118

Added:
/trunk/src/org/opensocial/client/features/BatchRequest.as
Modified:
/trunk/sample/flash/SampleApp.as
/trunk/sample/flash/SampleApp.fla
/trunk/sample/flex/SampleApp.mxml
/trunk/src/org/opensocial/client/base/ResponseItem.as
/trunk/src/org/opensocial/client/core/OpenSocialClient.as
/trunk/src/org/opensocial/client/ext/myspace/jswrapper/myspace.xml
/trunk/src/org/opensocial/client/features/AsyncRequest.as
/trunk/src/org/opensocial/client/jswrapper/JsWrapperClient.as
/trunk/src/org/opensocial/client/jswrapper/JsWrapperParsers.as
/trunk/src/org/opensocial/client/jswrapper/default.xml

=======================================
--- /dev/null
+++ /trunk/src/org/opensocial/client/features/BatchRequest.as Sun Feb 28
20:07:20 2010
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.opensocial.client.features {
+
+import flash.events.EventDispatcher;
+import flash.utils.Dictionary;
+
+import org.opensocial.client.base.OpenSocialError;
+import org.opensocial.client.base.ResponseItem;
+import org.opensocial.client.core.OpenSocialClient;
+
+
+/**
+ * Dispatched when the data request complete and with a
<code>ResponseItem</code> object returned.
+ * @eventType org.opensocial.client.features.ResponseItemEvent.COMPLETE
+ */
+[Event(name="complete",
type="org.opensocial.client.features.ResponseItemEvent.COMPLETE")]
+
+/**
+ * Dispatched when the request got error.
+ * @eventType org.opensocial.client.features.ResponseItemEvent.ERROR
+ */
+[Event(name="error",
type="org.opensocial.client.features.ResponseItemEvent.ERROR")]
+
+/**
+ * Event dispatcher for OpenSocial batch request.
+ * <p>
+ * This request covers <code><j>osapi.people</j></code>,
<code><j>osapi.actvities</j></code>,
+ * <code><j>osapi.appdata</j></code> and <code><j>osapi.ui</j></code>
services and is initialized
+ * by different <code>RequestOptions</code>. Here is the list:
+ * </p>
+ * <p>
+ * <table class=innertable>
+ * <tr><th>osapi service</th><th>RequestOptions</th></tr>
+ *
<tr><td><code><j>osapi.people</j></code></td><td><code>PeopleRequestOptions</code></td></tr>
+ *
<tr><td><code><j>osapi.actvities</j></code></td><td><code>ActivitiesRequestOptions</code></td></tr>
+ *
<tr><td><code><j>osapi.appdata</j></code></td><td><code>AppDataRequestOptions</code></td></tr>
+ *
<tr><td><code><j>osapi.ui</j></code></td><td><code>UIRequestOptions</code></td></tr>
+ * </table>
+ * </p>
+ * <p>
+ * Here lists the example codes for requesting friends of viewer and
itself's profile.
+ * (For more examples please see the <code>SampleApp</code>):
+ * </p>
+ * @example
+ * <listing version="3.0">
+ * private function batchRequest():void {
+ * var batch:BatchRequest = new BatchRequest();
+ * var req:AsyncDataRequest = new AsyncDataRequest(
+ * Feature.PEOPLE_GET,
+ * new PeopleRequestOptions()
+ * .setUserId("&#64;me")
+ * .setGroupId("&#64;self"));
+ *
+ * req.addEventListener(ResponseItemEvent.COMPLETE,
batchFetchMeEventHandler);
+ * // You may like to add event listener for each AsyncDataRequest
object.
+ * // If the event listener is added, it will be notified by the
registered event,
+ * // after the event being dispatched to the BatchRequest object first.
+ * batch.add(req, "meProfile");
+ *
+ * req = new AsyncDataRequest(
+ * Feature.PEOPLE_GET,
+ * new PeopleRequestOptions()
+ * .setUserId("&#64;me")
+ * .setGroupId("&#64;friends")
+ * .setCount(2) // Request 2 friends each time.
+ * .setStartIndex(0)); // First time starts with 0.
+ *
+ * req.addEventListener(ResponseItemEvent.COMPLETE,
batchFetchFriendsEventHandler);
+ * batch.add(req, "friendList");
+ *
+ * batch.addEventListener(ResponseItemEvent.COMPLETE,
batchDataRequestEventHandler);
+ * batch.addEventListener(ResponseItemEvent.ERROR,
batchDataRequestErrorHandler);
+ * batch.send(client); // Send the batch request and
start to listen.
+ * }
+ *
+ * private function
batchDataRequestEventHandler(event:ResponseItemEvent):void {
+ * var p:Person = event.response.getData("meProfile");
+ * //do something with person...
+ *
+ * var c:Collection = event.response.getData("friendList");
+ * var arr:Array = c.getArray();
+ * for (var i:int = 0; i &lt; arr.length; i++) {
+ * var person:Person = arr[i];
+ * //do something with person...
+ * }
+ * }
+ *
+ * private function
batchDataRequestErrorHandler(event:ResponseItemEvent):void {
+ * //do something with error...
+ * }
+ *
+ * private function batchFetchMeEventHandler(event:ResponseItemEvent):void
{
+ * var p:Person = event.response.getData();
+ * //do something with person...
+ * }
+ *
+ * private function
batchFetchFriendsEventHandler(event:ResponseItemEvent):void {
+ * var c:Collection = event.response.getData();;
+ * var arr:Array = c.getArray();
+ * for (var i:int = 0; i &lt; arr.length; i++) {
+ * var p:Person = arr[i];
+ * //do something with person...
+ * }
+ * // Continue to fetch the remaining friends
+ * if (c.getRemainingSize() &gt; 0) {
+ * var req:AsyncDataRequest = event.target as AsyncDataRequest;
+ * (req.getOptions() as
PeopleRequestOptions).setStartIndex(c.getNextOffset());
+ * req.send(client); // Send this async request and
start to listen.
+ * }
+ * }
+ * </listing>
+ *
+ * @see org.opensocial.client.base.ResponseItem
+ *
+ * @author zakiy...@gmail.com (Zhinan Yan)
+ */
+public class BatchRequest extends EventDispatcher {
+
+ /**
+ * The request collection.
+ * @private
+ */
+ private var requests:Dictionary;
+
+ /**
+ * Indicates this request instance is running or not.
+ * And you can't re-establish the running request concurrently.
+ * @private
+ */
+ protected var isRunning_:Boolean;
+
+ /**
+ * Indicates this request instance is running or not.
+ * And you can't re-establish the running request concurrently.
+ * @return True if it's running.
+ */
+ public function get isRunning():Boolean {
+ return isRunning_;
+ }
+
+ /**
+ * Constructor of this request event dispatcher.
+ */
+ public function BatchRequest() {
+ requests = new Dictionary();
+ isRunning_ = false;
+ }
+
+ /**
+ * The function for add an AsyncDataRequest object to batch request.
+ * @param asyncDataRequest The AsyncDataRequest object.
+ * @param resKey The identity of the response data of this async request.
+ */
+ public function add(asyncDataRequest:AsyncDataRequest,
resKey:String):void {
+ if (asyncDataRequest && resKey) {
+ if (asyncDataRequest.featureName.indexOf("ui.request") > 0) {
+ throw new OpenSocialError("The request can not added to batch.");
+ } else if (requests[resKey]) {
+ throw new OpenSocialError("The resKey has already been taken.");
+ } else {
+ requests[resKey] = asyncDataRequest;
+ }
+ }
+ }
+
+ /**
+ * The function for the async callback which is registered on the client
callback manager.
+ * It takes in the async response raw data to create a corresponding
event then dispatches it.
+ * This function will be override by derieved classes.
+ * @param rawData The raw response object.
+ * @private
+ */
+ protected function callback(rawData:*):void {
+ var response:ResponseItem = new ResponseItem(rawData);
+ var event:ResponseItemEvent = new ResponseItemEvent(response);
+ isRunning_ = false;
+ dispatchEvent(event);
+
+ for (var resKey:String in requests) {
+ var responseItem:ResponseItem = new ResponseItem(rawData[resKey]);
+ var responseItemEvent:ResponseItemEvent = new
ResponseItemEvent(responseItem);
+ var dataRequest:AsyncDataRequest = requests[resKey];
+ dataRequest.dispatchEvent(responseItemEvent);
+ }
+ }
+
+ /**
+ * The quick short-cut for adding a callback function when request
succeed. It wraps the async
+ * request from event-driven style to a simple callback style.
+ * @param callback The callback function
+ * @return The request instance itself.
+ */
+ public function addCompleteHandler(callback:Function):BatchRequest {
+ addEventListener(ResponseItemEvent.COMPLETE,
+ function(event:ResponseItemEvent):void {
+ callback(event.response);
+ }, false, 0, true);
+ return this;
+ }
+
+ /**
+ * The quick short-cut for adding a callback function when request
failed. It wraps the async
+ * request from event-driven style to a simple callback style.
+ * @param callback The callback function
+ * @return The request instance itself.
+ */
+ public function addErrorHandler(callback:Function):BatchRequest {
+ addEventListener(ResponseItemEvent.ERROR,
+ function(event:ResponseItemEvent):void {
+ callback(event.response);
+ }, false, 0, true);
+ return this;
+ }
+
+ /**
+ * Sends out the request using client's batch call api. If this request
instance is running, then
+ * this method will do nothing.
+ * <p>
+ * The underlying client has no knowledge on the event-driven system.
+ * </p>
+ * <p>
+ * Considering to be renamed to 'execute'.
+ * </p>
+ * @param client The client, could be JsWrapperClient or RestfulClient.
+ */
+ public function send(client:OpenSocialClient):void {
+ if (isRunning_) {
+ throw new OpenSocialError("The request instance already running.");
+ }
+ var args:Array = [requests, callback];
+ client.callBatch.apply(client, args);
+ isRunning_ = true;
+ }
+
+ /**
+ * Get an AsyncDataRequest object for this batch request.
+ * @param resKey The identity of the response data of this async request.
+ */
+ public function getAsyncDataRequest(resKey:String):AsyncDataRequest {
+ return requests[resKey] as AsyncDataRequest;
+ }
+}
+}
=======================================
--- /trunk/sample/flash/SampleApp.as Wed Sep 30 01:09:12 2009
+++ /trunk/sample/flash/SampleApp.as Sun Feb 28 20:07:20 2010
@@ -78,10 +78,10 @@
}

private function onReady(event:OpenSocialClientEvent):void {
- logger.info("Domain: " + helper.getDomain());
- logger.info("ContainerDomain: " + helper.getContainerDomain());
- logger.info("CurrentView: " + helper.getCurrentView());
- logger.info("Client Ready.");
+ logger.log("Domain: " + helper.getDomain());
+ logger.log("ContainerDomain: " + helper.getContainerDomain());
+ logger.log("CurrentView: " + helper.getCurrentView());
+ logger.log("Client Ready.");
}

// -------------------------------------------------------------
@@ -101,7 +101,7 @@

private function fetchMeEventHandler(event:ResponseItemEvent):void {
var p:Person = event.response.getData();
- logger.info(p.getDisplayName());
+ logger.log(p.getDisplayName());
drawPerson(p, 0);
}

@@ -121,11 +121,11 @@

private function fetchFriendsEventHandler(event:ResponseItemEvent):void {
var c:Collection = event.response.getData();
- logger.info(c.toDebugString());
+ logger.log(c.toDebugString());
var arr:Array = c.getArray();
for (var i:int = 0; i < arr.length; i++) {
var p:Person = arr[i];
- logger.info(p.getDisplayName());
+ logger.log(p.getDisplayName());
drawPerson(p, i + 1);
}

@@ -153,10 +153,10 @@
}

private function sendMessageEventHandler(event:ResponseItemEvent):void {
- logger.info("msg sent.");
+ logger.log("msg sent.");
}
private function
sendMessageEventErrorHandler(event:ResponseItemEvent):void {
- logger.info("msg sending failed: " + event.response.getErrorMessage());
+ logger.log("msg sending failed: " + event.response.getErrorMessage());
}


@@ -164,9 +164,6 @@
private function createActivity():void {
var activity:Activity = Activity.newInstance("My new
activity!", "Hello World...");
// the change for myspace. myspace's Activity object need
set 'TITLE_ID'.
- activity.setField(Activity.Field.TITLE_ID,"Msg");
- activity.setField(Activity.Field.TEMPLATE_PARAMS,
{"body":"lkjasldkjflksjdlkfjslkdjfdsj"});
-
logger.log(activity.toRawObject());
var req:AsyncDataRequest = new AsyncDataRequest(
Feature.REQUEST_CREATE_ACTIVITY,
@@ -178,10 +175,10 @@
}

private function
createActivityEventHandler(event:ResponseItemEvent):void {
- logger.info("activity created");
+ logger.log("activity created");
}
private function
createActivityEventErrorHandler(event:ResponseItemEvent):void {
- logger.info("activity creation failed: " +
event.response.getErrorMessage());
+ logger.log("activity creation failed: " +
event.response.getErrorMessage());
}


@@ -197,10 +194,10 @@
}

private function makeRequestEventHandler(event:ProxiedRequestEvent):void
{
- logger.info(event.response.getData());
+ logger.log(event.response.getData());
}
private function
makeRequestEventErrorHandler(event:ProxiedRequestEvent):void {
- logger.info("make request failed: " + event.response.getRC() + "|" +
+ logger.log("make request failed: " + event.response.getRC() + "|" +
event.response.getText());
}

@@ -221,7 +218,7 @@
}

private function callRpcEventHandler(event:RPCRequestEvent):void {
- logger.info("--- invoked by the returning of 'srv-parent' ---");
+ logger.log("--- invoked by the returning of 'srv-parent' ---");
logger.log(event.returnValue);
}

@@ -243,7 +240,7 @@
}

private function serviceEventHandler(event:RPCServiceEvent):void {
- logger.info("--- invoked by 'srv-app' get called ---");
+ logger.log("--- invoked by 'srv-app' get called ---");
logger.log(event.params);
event.callback("'srv-app' returned.");
}
@@ -264,14 +261,98 @@
req.addEventListener(ResponseItemEvent.ERROR,
shareAppEventErrorHandler);
req.send(client);
}
-
+
private function shareAppEventHandler(event:ResponseItemEvent):void {
- logger.info("msg sent.");
+ logger.log("msg sent.");
}
private function shareAppEventErrorHandler(event:ResponseItemEvent):void
{
- logger.info("msg sending failed: " + event.response.getErrorMessage());
+ logger.log("msg sending failed: " + event.response.getErrorMessage());
+ }
+ // ----------------- Batch Request------------------
+ private function batchRequest():void {
+ var batch:BatchRequest = new BatchRequest();
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.PEOPLE_GET,
+ new PeopleRequestOptions()
+ .setUserId("@me")
+ .setGroupId("@self"));
+
+ req.addEventListener(ResponseItemEvent.COMPLETE,
batchFetchMeEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
batchFetchMeEventErrorHandler);
+
+
+ batch.add(req, "meProfile");
+
+ req = new AsyncDataRequest(
+ Feature.PEOPLE_GET,
+ new PeopleRequestOptions()
+ .setUserId("@me")
+ .setGroupId("@friends")
+ .setCount(2)
+ .setStartIndex(0));
+
+ req.addEventListener(ResponseItemEvent.COMPLETE,
batchFetchFriendsEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
batchFetchFriendsEventErrorHandler);
+
+ batch.add(req, "friendList");
+
+ batch.addEventListener(ResponseItemEvent.COMPLETE,
batchDataRequestEventHandler);
+ batch.addEventListener(ResponseItemEvent.ERROR,
batchDataRequestErrorHandler);
+ batch.send(client);
+ }
+
+ private function
batchDataRequestEventHandler(event:ResponseItemEvent):void {
+ logger.log("=============== Batch Success ================");
+ var p:Person = event.response.getData("meProfile");
+ logger.log("meProfile =============== " + p.getDisplayName());
+
+ var c:Collection = event.response.getData("friendList");
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var person:Person = arr[i];
+ logger.log("friendList =============== " + person.getDisplayName());
+ }
+
+ logger.log("=============== Batch Success ================");
}

+ private function
batchDataRequestErrorHandler(event:ResponseItemEvent):void {
+ logger.log("=============== Batch Error ================");
+ logger.log(event.response.getErrorMessage());
+ logger.log("=============== Batch Error ================");
+ }
+
+ private function batchFetchMeEventHandler(event:ResponseItemEvent):void {
+ var p:Person = event.response.getData();
+ logger.log(p.getDisplayName());
+ drawPerson(p, 0);
+ }
+
+ private function
batchFetchMeEventErrorHandler(event:ResponseItemEvent):void {
+ logger.log("fetch me failed: " + event.response.getErrorMessage());
+ }
+
+ private function
batchFetchFriendsEventHandler(event:ResponseItemEvent):void {
+ var c:Collection = event.response.getData();
+ logger.log(c.toDebugString());
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var p:Person = arr[i];
+ logger.log(p.getDisplayName());
+ drawPerson(p, i + 1);
+ }
+
+ if (c.getRemainingSize() > 0) {
+ var req:AsyncDataRequest = event.target as AsyncDataRequest;
+ (req.getOptions() as
PeopleRequestOptions).setStartIndex(c.getNextOffset());
+ req.send(client);
+ }
+ }
+
+ private function
batchFetchFriendsEventErrorHandler(event:ResponseItemEvent):void {
+ logger.log("fetch friends failed: " +
event.response.getErrorMessage());
+ }
+
// -------------------------------------------------------------
// Helper functions for action and display
// -------------------------------------------------------------
@@ -325,6 +406,13 @@
registerService();
});
}
+
+ if (this['batchRequestBtn']) {
+ var btn8:TextField = this['batchRequestBtn'] as TextField;
+ btn8.addEventListener(MouseEvent.CLICK,
function(event:MouseEvent):void {
+ batchRequest();
+ });
+ }
}

private function drawPerson(person:Person, index:int):void {
@@ -348,7 +436,7 @@

try {
var url:String = person.getThumbnailUrl();
- //logger.info(url);
+ //logger.log(url);
if (url != null) {
var request:URLRequest = new URLRequest(url);
var thumb:Loader = new Loader();
=======================================
--- /trunk/sample/flash/SampleApp.fla Wed Sep 30 01:09:12 2009
+++ /trunk/sample/flash/SampleApp.fla Sun Feb 28 20:07:20 2010
Binary file, no diff available.
=======================================
--- /trunk/sample/flex/SampleApp.mxml Tue Oct 20 10:03:37 2009
+++ /trunk/sample/flex/SampleApp.mxml Sun Feb 28 20:07:20 2010
@@ -104,6 +104,7 @@
.setUserId("@me")
.setGroupId("@self"));
req.addEventListener(ResponseItemEvent.COMPLETE,
fetchMeEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
fetchMeEventErrorHandler);
req.send(client);
people.removeAll();
}
@@ -113,6 +114,10 @@
logger.info(p.getDisplayName());
people.addItem(p);
}
+
+ private function
fetchMeEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch me failed: " +
event.response.getErrorMessage());
+ }


// ----------------- Fetch Friends ------------------
@@ -122,9 +127,10 @@
new PeopleRequestOptions()
.setUserId("@me")
.setGroupId("@friends")
- .setCount(5)
+ .setCount(2)
.setStartIndex(0));
req.addEventListener(ResponseItemEvent.COMPLETE,
fetchFriendsEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
fetchFriendsEventErrorHandler);
req.send(client);
people.removeAll();
}
@@ -145,12 +151,15 @@
req.send(client);
}
}
-
+
+ private function
fetchFriendsEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch friends failed: " +
event.response.getErrorMessage());
+ }

// ----------------- Send Message ------------------
private function sendMessage():void {
// the change for myspace. myspace is not support Message object's
type equal to null.
- var message:Message = Message.newInstance("Hello World...", "My
new message.", Message.Type.NOTIFICATION);
+ var message:Message = Message.newInstance("Hello World...", "My
new message.", Message.Type.EMAIL);
logger.log(message.toRawObject());

var req:AsyncDataRequest = new AsyncDataRequest(
@@ -167,16 +176,15 @@
logger.info("msg sent.");
}
private function
sendMessageEventErrorHandler(event:ResponseItemEvent):void {
- logger.info("msg sending failed: " +
event.response.getErrorMessage());
+ logger.info("msg sending failed: " +
event.response.getErrorMessage()
+ + " msg error code:" + event.response.getErrorCode());
}


// ----------------- Create Activity ------------------
private function createActivity():void {
- var activity:Activity = Activity.newInstance("My new
activity!", "Hello World...", "Msg");
-
- // the change for myspace. myspace's Activity object need
set 'TITLE_ID'.
- activity.setField(Activity.Field.TEMPLATE_PARAMS, {"body":"Hello
World..."});
+ var activity:Activity = Activity.newInstance("My new
activity!", "Hello World...");
+
logger.log(activity.toRawObject());
var req:AsyncDataRequest = new AsyncDataRequest(
Feature.REQUEST_CREATE_ACTIVITY,
@@ -283,6 +291,90 @@
logger.info("msg sending failed: " +
event.response.getErrorMessage());
}

+ // ----------------- Batch Request------------------
+ private function batchRequest():void {
+ var batch:BatchRequest = new BatchRequest();
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.PEOPLE_GET,
+ new PeopleRequestOptions()
+ .setUserId("@me")
+ .setGroupId("@self"));
+
+ req.addEventListener(ResponseItemEvent.COMPLETE,
batchFetchMeEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
batchFetchMeEventErrorHandler);
+
+
+ batch.add(req, "meProfile");
+
+ req = new AsyncDataRequest(
+ Feature.PEOPLE_GET,
+ new PeopleRequestOptions()
+ .setUserId("@me")
+ .setGroupId("@friends")
+ .setCount(2)
+ .setStartIndex(0));
+
+ req.addEventListener(ResponseItemEvent.COMPLETE,
batchFetchFriendsEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
batchFetchFriendsEventErrorHandler);
+
+ batch.add(req, "friendList");
+
+ batch.addEventListener(ResponseItemEvent.COMPLETE,
batchDataRequestEventHandler);
+ batch.addEventListener(ResponseItemEvent.ERROR,
batchDataRequestErrorHandler);
+ batch.send(client);
+ }
+
+ private function
batchDataRequestEventHandler(event:ResponseItemEvent):void {
+ logger.info("=============== Batch Success ================");
+ var p:Person = event.response.getData("meProfile");
+ logger.info("meProfile =============== " + p.getDisplayName());
+
+ var c:Collection = event.response.getData("friendList");
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var person:Person = arr[i];
+ logger.info("friendList =============== " +
person.getDisplayName());
+ }
+
+ logger.info("=============== Batch Success ================");
+ }
+
+ private function
batchDataRequestErrorHandler(event:ResponseItemEvent):void {
+ logger.info("=============== Batch Error ================");
+ logger.info(event.response.getErrorMessage());
+ logger.info("=============== Batch Error ================");
+ }
+
+ private function
batchFetchMeEventHandler(event:ResponseItemEvent):void {
+ var p:Person = event.response.getData();
+ logger.info(p.getDisplayName());
+ people.addItem(p);
+ }
+
+ private function
batchFetchMeEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch me failed: " +
event.response.getErrorMessage());
+ }
+
+ private function
batchFetchFriendsEventHandler(event:ResponseItemEvent):void {
+ var c:Collection = event.response.getData();
+ logger.info(c.toDebugString());
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var p:Person = arr[i];
+ logger.info(p.getDisplayName());
+ people.addItem(p);
+ }
+
+ if (c.getRemainingSize() > 0) {
+ var req:AsyncDataRequest = event.target as AsyncDataRequest;
+ (req.getOptions() as
PeopleRequestOptions).setStartIndex(c.getNextOffset());
+ req.send(client);
+ }
+ }
+
+ private function
batchFetchFriendsEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch friends failed: " +
event.response.getErrorMessage());
+ }
]]>
</mx:Script>
<mx:Button x="468" y="47" label="Fetch Me" id="fetchMeBtn" height="22"
width="123" click="fetchMe()"/>
@@ -292,6 +384,7 @@
<mx:Button x="468" y="167" label="Make Request" height="22" width="123"
id="makeRequestBtn" click="makeRequest()"/>
<mx:Button x="468" y="197" label="Call Rpc" height="22" width="123"
id="rpcCallBtn" click="callRpc()"/>
<mx:Button x="468" y="227" label="Register Srv" height="22" width="123"
id="rpcRegisterBtn" click="registerService()"/>
+ <mx:Button x="468" y="257" label="Batch Request" height="22" width="123"
id="batchRequestBtn" click="batchRequest()"/>
<mx:TileList width="450" height="120" id="titleList"
dataProvider="{people}" itemClick="shareApp(event)" x="10" y="26"
backgroundColor="#666666">
<mx:itemRenderer>
<mx:Component>
=======================================
--- /trunk/src/org/opensocial/client/base/ResponseItem.as Wed Sep 30
01:09:12 2009
+++ /trunk/src/org/opensocial/client/base/ResponseItem.as Sun Feb 28
20:07:20 2010
@@ -120,10 +120,15 @@

/**
* Gets the data.
+ * @param resKey The response key.
* @return The data object.
*/
- public function getData():* {
- return data_;
+ public function getData(resKey:String = null):* {
+ if (resKey) {
+ return data_[resKey].getData();
+ } else {
+ return data_;
+ }
}
}
}
=======================================
--- /trunk/src/org/opensocial/client/core/OpenSocialClient.as Tue Oct 20
10:03:37 2009
+++ /trunk/src/org/opensocial/client/core/OpenSocialClient.as Sun Feb 28
20:07:20 2010
@@ -155,6 +155,17 @@
// Must be overriden
throw new OpenSocialError("This method in this abstract class must be
overriden.");
}
+
+ /**
+ * Executes batch request.
+ * @param requests request collection.
+ * @param callback The callback to handle the response.
+ *
+ */
+ public function callBatch(requests:Dictionary, handler:Function):void {
+ // Must be overriden
+ throw new OpenSocialError("This method in this abstract class must be
overriden.");
+ }

/**
* Registers a callback handler on this client.
=======================================
--- /trunk/src/org/opensocial/client/ext/myspace/jswrapper/myspace.xml Tue
Oct 20 10:03:37 2009
+++ /trunk/src/org/opensocial/client/ext/myspace/jswrapper/myspace.xml Sun
Feb 28 20:07:20 2010
@@ -44,6 +44,38 @@
<script><![CDATA[
api.photos = {};
]]></script>
+ <getRequest>
+ <script><![CDATA[
+ /**
+ * According to operation mode, get request object.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * PeopleRequestOptions.
+ * @param {string} mode The operation mode.
+ * @param {DataRequest} req An exist DataRequest.
+ * @member opensocial.flash.ext.myspace.photos
+ */
+ api.photos.getRequest = function(options, mode, req) {
+ switch (mode){
+ case 'get':
+ var photoId = options['photoId'];
+ var userId = options['userId'];
+ userId = me.translateIds(userId);
+ var params = me.translatePaginationParams(options);
+ if (photoId == null) {
+
+ if (options['albumId']) {
+
params[MyOpenSpace.DataRequest.PhotoRequestFields.ALBUM_ID] =
+ options['albumId'];
+ }
+
+ return
MyOpenSpace.DataRequest.newFetchPhotosRequest(userId, params);
+ } else {
+ return
MyOpenSpace.DataRequest.newFetchPhotoRequest(userId, photoId);
+ }
+ }
+ };
+ ]]></script>
+ </getRequest>
<get>
<script><![CDATA[
/**
@@ -54,39 +86,17 @@
* @member opensocial.flash.ext.myspace.photos
*/
api.photos.get = function(reqID, options) {
- var photoId = options['photoId'];
- var userId = options['userId'];
- userId = me.translateIds(userId);
- var params = me.translatePaginationParams(options);
-
var req = opensocial.newDataRequest();
- if (photoId == null) {
-
- if (options['albumId']) {
-
params[MyOpenSpace.DataRequest.PhotoRequestFields.ALBUM_ID] =
- options['albumId'];
- }
-
-
req.add(MyOpenSpace.DataRequest.newFetchPhotosRequest(userId, params), 'p');
- req.send(function(dataResponse) {
- try {
- var respPhotos =
me.wrapObject(me.getData(dataResponse, 'p'));
- me.handleAsync(reqID, respPhotos);
- } catch (e) {
- me.handleError(reqID, e);
- }
- });
- } else {
-
req.add(MyOpenSpace.DataRequest.newFetchPhotoRequest(userId, photoId), 'p');
- req.send(function(dataResponse) {
- try {
- var respPhoto =
me.wrapObject(me.getData(dataResponse, 'p'));
- me.handleAsync(reqID, respPhoto);
- } catch (e) {
- me.handleError(reqID, e);
- }
- });
- }
+ var request = me.api.appdata.getRequest(options, 'get',
req);
+ req.add(request, 'p');
+ req.send(function(dataResponse) {
+ try {
+ var response =
me.wrapObject(me.getData(dataResponse, 'p'));
+ me.handleAsync(reqID, response);
+ } catch (e) {
+ me.handleError(reqID, e);
+ }
+ });
};
]]></script>
</get>
=======================================
--- /trunk/src/org/opensocial/client/features/AsyncRequest.as Wed Sep 30
01:09:12 2009
+++ /trunk/src/org/opensocial/client/features/AsyncRequest.as Sun Feb 28
20:07:20 2010
@@ -40,7 +40,8 @@
protected var featureName_:String;

/**
- * Indicates this request instance is waiting for response or not.
+ * Indicates this request instance is running or not.
+ * And you can't re-establish the running request concurrently.
* @private
*/
protected var isRunning_:Boolean;
@@ -75,8 +76,9 @@
}

/**
- * Indicates this request instance is waiting for response or not.
- * @return True if it's waiting.
+ * Indicates this request instance is running or not.
+ * And you can't re-establish the running request concurrently.
+ * @return True if it's running.
*/
public function get isRunning():Boolean {
return isRunning_;
@@ -100,6 +102,14 @@
params_ = params;
return this;
}
+
+ /**
+ * Returns the request featrue name.
+ * @return The featrue name.
+ */
+ public function get featureName():String {
+ return featureName_;
+ }

/**
* The function for the async callback which is registered on the client
callback manager.
@@ -126,7 +136,7 @@
*/
public function send(client:OpenSocialClient):void {
if (isRunning_) {
- return;
+ throw new OpenSocialError("The request instance already running.");
}
var args:Array = [featureName_, callback];
if (params_ != null) {
=======================================
--- /trunk/src/org/opensocial/client/jswrapper/JsWrapperClient.as Sun Oct
25 03:47:09 2009
+++ /trunk/src/org/opensocial/client/jswrapper/JsWrapperClient.as Sun Feb
28 20:07:20 2010
@@ -22,10 +22,12 @@
import flash.events.TimerEvent;
import flash.external.ExternalInterface;
import flash.system.Security;
+import flash.utils.Dictionary;
import flash.utils.Timer;

import org.opensocial.client.base.*;
import org.opensocial.client.core.*;
+import org.opensocial.client.features.AsyncDataRequest;
import org.opensocial.client.util.*;

/**
@@ -324,6 +326,35 @@
parsedParams.unshift(jsNamespace_ + "." + featureName, reqID);
ExternalInterface.call.apply(null, parsedParams);
}
+
+ /**
+ * @inheritDoc
+ */
+ override public function callBatch(requests:Dictionary,
handler:Function):void {
+ assertReady();
+ var callback:Function = function(rawData:*):void {
+ var data:Dictionary = new Dictionary();
+ for (var resKey:String in requests) {
+ var dataRequest:AsyncDataRequest = requests[resKey];
+ var feature:Feature = checkFeature(dataRequest.featureName);
+ data[resKey] = feature.resParser(rawData[resKey]);
+ }
+ handler(data);
+ };
+
+ var jsRequests:Object = new Object();
+ var reqID:String = callbacks_.push(callback);
+ for (var resKey:String in requests) {
+ var dataRequest:AsyncDataRequest = requests[resKey];
+ var feature:Feature = checkFeature(dataRequest.featureName);
+ var params:Array = feature.reqParser(dataRequest.params);
+ params.unshift(jsNamespace_ + "." + dataRequest.featureName);
+ jsRequests[resKey] = params;
+ }
+ var parsedParams:Array = [jsNamespace_ + ".batch.send", reqID,
jsRequests];
+ ExternalInterface.call.apply(null, parsedParams);
+ }
+

/**
* @inheritDoc
=======================================
--- /trunk/src/org/opensocial/client/jswrapper/JsWrapperParsers.as Tue Oct
20 10:03:37 2009
+++ /trunk/src/org/opensocial/client/jswrapper/JsWrapperParsers.as Sun Feb
28 20:07:20 2010
@@ -19,8 +19,6 @@

package org.opensocial.client.jswrapper {

-import flash.utils.getDefinitionByName;
-
import org.opensocial.client.base.*;

/**
@@ -48,11 +46,15 @@

public static function parseWrappedData(obj:*):ResponseItem {
if (obj is OpenSocialError) return parseError(obj);
+ if (obj && obj["name"] == "OpenSocialError")
+ return new ResponseItem(null, obj["code"], obj["message"]);
return new ResponseItem(AbstractDataType.create(obj));
}

public static function parseRawData(obj:*):ResponseItem {
if (obj is OpenSocialError) return parseError(obj);
+ if (obj && obj["name"] == "OpenSocialError")
+ return new ResponseItem(null, obj["code"], obj["message"]);
return new ResponseItem(obj);
}

@@ -62,6 +64,8 @@

public static function parseEmpty(obj:*):ResponseItem {
if (obj is OpenSocialError) return parseError(obj);
+ if (obj && obj["name"] == "OpenSocialError")
+ return new ResponseItem(null, obj["code"], obj["message"]);
return ResponseItem.SIMPLE_SUCCESS;
}
}
=======================================
--- /trunk/src/org/opensocial/client/jswrapper/default.xml Tue Oct 20
10:03:37 2009
+++ /trunk/src/org/opensocial/client/jswrapper/default.xml Sun Feb 28
20:07:20 2010
@@ -329,7 +329,7 @@
EXPORT('DATA_RESPONSE', {'key': key, 'data': dataResponse});

if (!dataResponse) return null;
- if (dataResponse.hadError()) {
+ if (dataResponse.hadError() &&
dataResponse.getErrorMessage()) {
var e = new Error(dataResponse.getErrorMessage());
e['name'] = "OpensocialError";
throw e;
@@ -1120,6 +1120,60 @@
</io>


+ <!-- ========================== Batch Request
=========================== -->
+ <batch>
+ <script><![CDATA[
+ api.batch = {};
+ ]]></script>
+
+ <send>
+ <script><![CDATA[
+ /**
+ * send a batch request.
+ * @param {string} reqID The request id.
+ * @param {Object.<string, Object>?} The request collection.
+ * @member opensocial.flash.batch
+ */
+ api.batch.send = function(reqID, requests) {
+ var req = opensocial.newDataRequest();
+ for (resKey in requests) {
+ var featureName = requests[resKey][0];
+ var splitIndex = featureName.lastIndexOf('.');
+ var operationMode = featureName.slice(splitIndex + 1);
+ var getRequestFuncitonName = featureName.slice(0,
splitIndex) + ".getRequest";
+ var options = requests[resKey][1];
+ var getRequestFunciton = new Function('return ' +
getRequestFuncitonName);
+ var getRequest = getRequestFunciton();
+ var request = getRequest(options, operationMode, req);
+ req.add(request, resKey);
+ }
+
+ req.send(function(dataResponse) {
+ var response = {};
+ for (resKey in requests) {
+ var featureName = requests[resKey][0];
+ if (featureName.indexOf('.appdata.') > -1) {
+ try {
+ response[resKey] = me.getData(dataResponse,
resKey);
+ } catch (e) {
+ response[resKey] = e;
+ }
+ } else {
+ try {
+ response[resKey] =
me.wrapObject(me.getData(dataResponse, resKey));
+ } catch (e) {
+ response[resKey] = e;
+ }
+ }
+ }
+ me.handleAsync(reqID, response);
+ });
+ };
+ ]]></script>
+ </send>
+ </batch>
+
+
<!-- ========================== OSAPI Services
=========================== -->
<!--
NOTE: Currently not all container support osapi.
@@ -1133,6 +1187,34 @@
api.people = {};
]]></script>

+ <getRequest>
+ <script><![CDATA[
+ /**
+ * According to operation mode, get request object.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * PeopleRequestOptions.
+ * @param {string} mode The operation mode.
+ * @param {DataRequest} req An exist DataRequest.
+ * @member opensocial.flash.people
+ */
+ api.people.getRequest = function(options, mode, req) {
+ switch (mode){
+ case 'get':
+ var params = me.translatePeopleRequestParams(options);
+ params = me.translatePaginationParams(options, params);
+ var idSpec = me.translateIdSpec(options);
+ var userId =
idSpec.getField(opensocial.IdSpec.Field.USER_ID);
+ var groupId =
idSpec.getField(opensocial.IdSpec.Field.GROUP_ID);
+
+ if (groupId == opensocial.IdSpec.GroupId.SELF) {
+ return req.newFetchPersonRequest(userId, params);
+ } else {
+ return req.newFetchPeopleRequest(idSpec, params);
+ }
+ }
+ };
+ ]]></script>
+ </getRequest>
<get>
<script><![CDATA[
/**
@@ -1143,35 +1225,17 @@
* @member opensocial.flash.people
*/
api.people.get = function(reqID, options) {
- var params = me.translatePeopleRequestParams(options);
- params = me.translatePaginationParams(options, params);
- var idSpec = me.translateIdSpec(options);
- var userId =
idSpec.getField(opensocial.IdSpec.Field.USER_ID);
- var groupId =
idSpec.getField(opensocial.IdSpec.Field.GROUP_ID);
var req = opensocial.newDataRequest();
-
- if (groupId == opensocial.IdSpec.GroupId.SELF) {
- req.add(req.newFetchPersonRequest(userId, params), 'p');
- req.send(function(dataResponse) {
- try {
- var respPerson =
me.wrapObject(me.getData(dataResponse, 'p'));
- me.handleAsync(reqID, respPerson);
- } catch (e) {
- me.handleError(reqID, e);
- }
- });
-
- } else {
- req.add(req.newFetchPeopleRequest(idSpec, params), 'f');
- req.send(function(dataResponse) {
- try {
- var respPeople =
me.wrapObject(me.getData(dataResponse, 'f'));
- me.handleAsync(reqID, respPeople);
- } catch (e) {
- me.handleError(reqID, e);
- }
- });
- }
+ var request = me.api.people.getRequest(options, 'get',
req);
+ req.add(request, 'p');
+ req.send(function(dataResponse) {
+ try {
+ var response =
me.wrapObject(me.getData(dataResponse, 'p'));
+ me.handleAsync(reqID, response);
+ } catch (e) {
+ me.handleError(reqID, e);
+ }
+ });
};
]]></script>
</get>
@@ -1184,6 +1248,27 @@
api.activities = {};
]]></script>

+ <getRequest>
+ <script><![CDATA[
+ /**
+ * According to operation mode, get request object.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * PeopleRequestOptions.
+ * @param {string} mode The operation mode.
+ * @param {DataRequest} req An exist DataRequest.
+ * @member opensocial.flash.people
+ */
+ api.activities.getRequest = function(options, mode, req) {
+ switch (mode){
+ case 'get':
+ var params =
me.translateActivityRequestParams(options);
+ params = me.translatePaginationParams(options, params);
+ var idSpec = me.translateIdSpec(options);
+ return req.newFetchActivitiesRequest(idSpec, params);
+ }
+ };
+ ]]></script>
+ </getRequest>
<get>
<script><![CDATA[
/**
@@ -1194,11 +1279,9 @@
* @member opensocial.flash.activities
*/
api.activities.get = function(reqID, options) {
- var params = me.translateActivityRequestParams(options);
- params = me.translatePaginationParams(options, params);
- var idSpec = me.translateIdSpec(options);
var req = opensocial.newDataRequest();
- req.add(req.newFetchActivitiesRequest(idSpec,
params), 'a');
+ var request = me.api.activities.getRequest(options, 'get',
req);
+ req.add(request, 'a');
req.send(function(dataResponse) {
try {
var respActivities =
me.wrapObject(me.getData(dataResponse, 'a'));
@@ -1219,6 +1302,41 @@
api.appdata = {};
]]></script>

+ <getRequest>
+ <script><![CDATA[
+ /**
+ * According to operation mode, get request object.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * PeopleRequestOptions.
+ * @param {string} mode The operation mode.
+ * @param {DataRequest} req An exist DataRequest.
+ * @member opensocial.flash.people
+ */
+ api.appdata.getRequest = function(options, mode, req) {
+ switch (mode){
+ case 'get':
+ var idSpec = me.translateIdSpec(options);
+ var keys = options['keys'];
+ return req.newFetchPersonAppDataRequest(idSpec, keys);
+ case 'update':
+ var idSpec = me.translateIdSpec(options);
+ var userId =
idSpec.getField(opensocial.IdSpec.Field.USER_ID);
+ var key;
+ var value;
+ for (key in options['data']) {
+ value = options['data'][key];
+ break;
+ }
+ return req.newUpdatePersonAppDataRequest(userId, key,
value);
+ case 'deleteData':
+ var idSpec = me.translateIdSpec(options);
+ var userId =
idSpec.getField(opensocial.IdSpec.Field.USER_ID);
+ var keys = options['keys'];
+ return req.newRemovePersonAppDataRequest(userId, keys);
+ }
+ };
+ ]]></script>
+ </getRequest>
<get>
<script><![CDATA[
/**
@@ -1228,15 +1346,15 @@
* AppDataRequestOptions.
* @member opensocial.flash.appdata
*/
- api.appdata.get = function(reqID, options) {
- var idSpec = me.translateIdSpec(options);
- var keys = options['keys'];
+ api.appdata.get = function(reqID, options, req, resKey) {
var req = opensocial.newDataRequest();
- req.add(req.newFetchPersonAppDataRequest(idSpec,
keys), 'd');
+ var request = me.api.appdata.getRequest(options, 'get',
req);
+ req.add(request, 'd');
req.send(function(dataResponse) {
try {
var dataSet = me.getData(dataResponse, 'd');
- /* dataSet�s type: Object.<opensocial.IdSpec.PersonId,
Object.<string, Object>>
+ /* dataSet's type:
+ * Object.<opensocial.IdSpec.PersonId,
Object.<string, Object>>
*/
me.handleAsync(reqID, dataSet);
} catch (e) {
@@ -1256,17 +1374,9 @@
* @member opensocial.flash.appdata
*/
api.appdata.update = function(reqID, options) {
- var idSpec = me.translateIdSpec(options);
- var userId =
idSpec.getField(opensocial.IdSpec.Field.USER_ID);
- var key;
- var value;
- for (key in options['data']) {
- value = options['data'][key];
- break;
- }
-
var req = opensocial.newDataRequest();
- req.add(req.newUpdatePersonAppDataRequest(userId, key,
value), 'u');
+ var request = me.api.appdata.getRequest(options, 'update',
req);
+ req.add(request, 'u');
req.send(function(dataResponse) {
try {
me.getData(dataResponse, 'u');
@@ -1288,12 +1398,9 @@
* @member opensocial.flash.appdata
*/
api.appdata.deleteData = function(reqID, options) {
- var idSpec = me.translateIdSpec(options);
- var userId =
idSpec.getField(opensocial.IdSpec.Field.USER_ID);
- var keys = options['keys'];
-
var req = opensocial.newDataRequest();
- req.add(req.newRemovePersonAppDataRequest(userId,
keys), 'r');
+ var request =
me.api.appdata.getRequest(options, 'deleteData', req);
+ req.add(request, 'r');
req.send(function(dataResponse) {
try {
me.getData(dataResponse, 'r');
Reply all
Reply to author
Forward
0 new messages