Added:
/branches/2009q4rewrite
/branches/2009q4rewrite/java
/branches/2009q4rewrite/java/demos
/branches/2009q4rewrite/java/demos/KitchenSink.java
/branches/2009q4rewrite/java/lib
/branches/2009q4rewrite/java/lib/commons-codec-1.3.jar
/branches/2009q4rewrite/java/lib/json_simple-1.1.jar
/branches/2009q4rewrite/java/lib/log4j-1.2.15.jar
/branches/2009q4rewrite/java/lib/oauth-20090825.jar
/branches/2009q4rewrite/java/src
/branches/2009q4rewrite/java/src/org
/branches/2009q4rewrite/java/src/org/opensocial
/branches/2009q4rewrite/java/src/org/opensocial/Client.java
/branches/2009q4rewrite/java/src/org/opensocial/Request.java
/branches/2009q4rewrite/java/src/org/opensocial/RequestException.java
/branches/2009q4rewrite/java/src/org/opensocial/Response.java
/branches/2009q4rewrite/java/src/org/opensocial/auth
/branches/2009q4rewrite/java/src/org/opensocial/auth/AuthScheme.java
/branches/2009q4rewrite/java/src/org/opensocial/auth/OAuth2LeggedScheme.java
/branches/2009q4rewrite/java/src/org/opensocial/data
/branches/2009q4rewrite/java/src/org/opensocial/data/Model.java
/branches/2009q4rewrite/java/src/org/opensocial/data/Person.java
/branches/2009q4rewrite/java/src/org/opensocial/http
/branches/2009q4rewrite/java/src/org/opensocial/http/HttpClient.java
/branches/2009q4rewrite/java/src/org/opensocial/http/HttpResponseMessage.java
/branches/2009q4rewrite/java/src/org/opensocial/parsers
/branches/2009q4rewrite/java/src/org/opensocial/parsers/JsonParser.java
/branches/2009q4rewrite/java/src/org/opensocial/parsers/Parser.java
/branches/2009q4rewrite/java/src/org/opensocial/providers
/branches/2009q4rewrite/java/src/org/opensocial/providers/MySpaceProvider.java
/branches/2009q4rewrite/java/src/org/opensocial/providers/OrkutProvider.java
/branches/2009q4rewrite/java/src/org/opensocial/providers/Provider.java
/branches/2009q4rewrite/java/src/org/opensocial/services
/branches/2009q4rewrite/java/src/org/opensocial/services/PeopleService.java
/branches/2009q4rewrite/java/src/org/opensocial/services/Service.java
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/demos/KitchenSink.java Wed Oct 14 18:05:00
2009
@@ -0,0 +1,129 @@
+
+import org.opensocial.Client;
+import org.opensocial.Request;
+import org.opensocial.RequestException;
+import org.opensocial.Response;
+import org.opensocial.auth.AuthScheme;
+import org.opensocial.auth.OAuth2LeggedScheme;
+import org.opensocial.data.Model;
+import org.opensocial.data.Person;
+import org.opensocial.providers.MySpaceProvider;
+import org.opensocial.providers.OrkutProvider;
+import org.opensocial.services.PeopleService;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class KitchenSink {
+
+ public static void main(String[] args) {
+ AuthScheme orkutAuth = new OAuth2LeggedScheme("orkut.com:623061448914",
+ "uynAeXiWTisflWX99KU1D2q5", "03067092798963641994");
+ Client orkutClient = new Client(new OrkutProvider(), orkutAuth);
+
+ AuthScheme myspaceAuth = new OAuth2LeggedScheme(
+ "http://www.myspace.com/495182150",
+ "20ab52223e684594a8050a8bfd4b06693ba9c9183ee24e1987be87746b1b03f8",
+ "495184236");
+ Client myspaceClient = new Client(new MySpaceProvider(), myspaceAuth);
+
+
+ /** orkut single request
*************************************************/
+
+ try {
+ Request request = PeopleService.get();
+ Response response = orkutClient.send(request);
+ Person user = (Person) response.getEntry();
+
+ System.out.println("\norkut profile data:");
+ System.out.println(user.getId() + " | " + user.getDisplayName());
+ } catch (RequestException e) {
+ System.out.println("RequestException thrown: " + e.getMessage());
+ e.printStackTrace();
+ } catch (IOException e) {
+ System.out.println("IOException thrown: " + e.getMessage());
+ e.printStackTrace();
+ }
+
+ /** MySpace single request
***********************************************/
+
+ try {
+ Request request = PeopleService.get();
+ Response response = myspaceClient.send(request);
+ Person user = (Person) response.getEntry();
+
+ System.out.println("\nMySpace profile data:");
+ System.out.println(user.getId() + " | " + user.getDisplayName());
+ } catch (RequestException e) {
+ System.out.println("RequestException thrown: " + e.getMessage());
+ e.printStackTrace();
+ } catch (IOException e) {
+ System.out.println("IOException thrown: " + e.getMessage());
+ e.printStackTrace();
+ }
+
+ /** orkut batch request
**************************************************/
+
+ try {
+ Request profileDataRequest =
PeopleService.get("03067092798963641994");
+ Request friendDataRequest = PeopleService.get("03067092798963641994",
+ PeopleService.FRIENDS);
+
+ Map<String, Request> requests = new HashMap<String, Request>();
+ requests.put("viewer", profileDataRequest);
+ requests.put("friends", friendDataRequest);
+
+ Map<String, Response> responses = orkutClient.send(requests);
+ Person user = (Person) responses.get("viewer").getEntry();
+ List<Model> friends = responses.get("friends").getEntries();
+
+ System.out.println("\norkut profile data:");
+ System.out.println(user.getId() + " | " + user.getDisplayName());
+
+ System.out.println("\norkut friends:");
+ for (Model friendEntry : friends) {
+ Person friend = (Person) friendEntry;
+ System.out.println(friend.getId() + " | " +
friend.getDisplayName());
+ }
+ } catch (RequestException e) {
+ System.out.println("RequestException thrown: " + e.getMessage());
+ e.printStackTrace();
+ } catch (IOException e) {
+ System.out.println("IOException thrown: " + e.getMessage());
+ e.printStackTrace();
+ }
+
+ /** MySpace batch request
************************************************/
+
+ try {
+ Request profileDataRequest = PeopleService.get();
+ Request friendDataRequest = PeopleService.get(PeopleService.VIEWER,
+ PeopleService.FRIENDS);
+
+ Map<String, Request> requests = new HashMap<String, Request>();
+ requests.put("viewer", profileDataRequest);
+ requests.put("friends", friendDataRequest);
+
+ Map<String, Response> responses = myspaceClient.send(requests);
+ Person user = (Person) responses.get("viewer").getEntry();
+ List<Model> friends = responses.get("friends").getEntries();
+
+ System.out.println("\nMySpace profile data:");
+ System.out.println(user.getId() + " | " + user.getDisplayName());
+
+ System.out.println("\nMySpace friends:");
+ for (Model friendEntry : friends) {
+ Person friend = (Person) friendEntry;
+ System.out.println(friend.getId() + " | " +
friend.getDisplayName());
+ }
+ } catch (RequestException e) {
+ System.out.println("RequestException thrown: " + e.getMessage());
+ e.printStackTrace();
+ } catch (IOException e) {
+ System.out.println("IOException thrown: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/lib/commons-codec-1.3.jar Wed Oct 14
18:05:00 2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/lib/json_simple-1.1.jar Wed Oct 14
18:05:00 2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/lib/log4j-1.2.15.jar Wed Oct 14 18:05:00
2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/lib/oauth-20090825.jar Wed Oct 14 18:05:00
2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/Client.java Wed Oct 14
18:05:00 2009
@@ -0,0 +1,174 @@
+package org.opensocial;
+
+import net.oauth.http.HttpMessage;
+
+import org.apache.log4j.Logger;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.opensocial.auth.AuthScheme;
+import org.opensocial.http.HttpClient;
+import org.opensocial.http.HttpResponseMessage;
+import org.opensocial.providers.Provider;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Client {
+
+ private Provider provider;
+ private AuthScheme authScheme;
+ private HttpClient httpClient;
+
+ private static final Logger logger = Logger.getLogger("org.opensocial");
+
+ public Client(Provider provider, AuthScheme authScheme) {
+ this.provider = provider;
+ this.authScheme = authScheme;
+ this.httpClient = new HttpClient();
+ }
+
+ public Provider getProvider() {
+ return provider;
+ }
+
+ public AuthScheme getAuthScheme() {
+ return authScheme;
+ }
+
+ public Response send(Request request) throws RequestException,
IOException {
+ final String KEY = "key";
+
+ Map<String, Request> requests = new HashMap<String, Request>();
+ requests.put(KEY, request);
+
+ Map<String, Response> responses = send(requests);
+
+ return responses.get(KEY);
+ }
+
+ public Map<String, Response> send(Map<String, Request> requests) throws
+ RequestException, IOException {
+ if (requests.size() == 0) {
+ throw new RequestException("Request queue is empty");
+ }
+
+ Map<String, Response> responses = new HashMap<String, Response>();
+
+ if (provider.getRpcEndpoint() != null) {
+ responses = submitRpc(requests);
+ } else if (provider.getRestEndpoint() != null) {
+ for (Map.Entry<String, Request> entry : requests.entrySet()) {
+ Request request = entry.getValue();
+
+ provider.preRequest(request);
+
+ Response response = submitRestRequest(request);
+ responses.put(entry.getKey(), response);
+
+ provider.postRequest(request, response);
+ }
+ } else {
+ throw new RequestException("Provider has no REST or RPC endpoint
set");
+ }
+
+ return responses;
+ }
+
+ private Map<String, Response> submitRpc(Map<String, Request> requests)
throws
+ RequestException, IOException {
+ Map<String, String> requestHeaders = new HashMap<String, String>();
+ requestHeaders.put(HttpMessage.CONTENT_TYPE,
provider.getContentType());
+
+ JSONArray requestArray = new JSONArray();
+ for (Map.Entry<String, Request> requestEntry : requests.entrySet()) {
+ JSONObject request = new JSONObject();
+ request.put("id", requestEntry.getKey());
+ request.put("method", requestEntry.getValue().getRpcMethod());
+
+ JSONObject requestParams = new JSONObject();
+ if (requestEntry.getValue().getGuid() != null) {
+ requestParams.put("userId", requestEntry.getValue().getGuid());
+ }
+ if (requestEntry.getValue().getSelector() != null) {
+ requestParams.put("groupId",
requestEntry.getValue().getSelector());
+ }
+
+ request.put("params", requestParams);
+ requestArray.add(request);
+ }
+
+ HttpMessage message = authScheme.getHttpMessage(provider, "POST",
+ buildRpcUrl(), requestHeaders, requestArray.toJSONString());
+
+ HttpResponseMessage responseMessage = httpClient.execute(message);
+
+ logger.debug("Request URL: " +
responseMessage.getUrl().toExternalForm());
+ logger.debug("Request body: " + requestArray.toJSONString());
+ logger.debug("Status code: " + responseMessage.getStatusCode());
+ logger.debug("Response: " + responseMessage.getResponse());
+
+ Map<String, Response> responses = Response.parseRpcResponse(requests,
+ responseMessage, provider.getVersion());
+
+ return responses;
+ }
+
+ private Response submitRestRequest(Request request) throws
RequestException,
+ IOException{
+ Map<String, String> requestHeaders = new HashMap<String, String>();
+ requestHeaders.put(HttpMessage.CONTENT_TYPE,
provider.getContentType());
+
+ HttpMessage message = authScheme.getHttpMessage(provider,
+ request.getRestMethod(), buildRestUrl(request), requestHeaders,
null);
+
+ HttpResponseMessage responseMessage = httpClient.execute(message);
+
+ logger.debug("Request URL: " + responseMessage.getUrl().toString());
+ logger.debug("Status code: " + responseMessage.getStatusCode());
+ logger.debug("Response: " + responseMessage.getResponse());
+
+ Response response = Response.parseRestResponse(request,
responseMessage,
+ provider.getVersion());
+
+ return response;
+ }
+
+ private String buildRestUrl(Request request) {
+ StringBuilder builder = new StringBuilder(provider.getRestEndpoint());
+ String[] components = request.getTemplate().split("/");
+
+ for (String component : components) {
+ if (component.startsWith("{") && component.endsWith("}")) {
+ String tag = component.substring(1, component.length()-1);
+
+ if (tag.equals("guid") && request.getGuid() != null) {
+ builder.append(request.getGuid());
+ builder.append("/");
+ } else if (tag.equals("selector") && request.getSelector() !=
null) {
+ builder.append(request.getSelector());
+ builder.append("/");
+ }
+ } else {
+ builder.append(component);
+ builder.append("/");
+ }
+ }
+
+ // Remove trailing forward slash
+ builder.deleteCharAt(builder.length() - 1);
+
+ return builder.toString();
+ }
+
+ private String buildRpcUrl() {
+ StringBuilder builder = new StringBuilder(provider.getRpcEndpoint());
+
+ // Remove trailing forward slash
+ if (builder.charAt(builder.length() - 1) == '/') {
+ builder.deleteCharAt(builder.length() - 1);
+ }
+
+ return builder.toString();
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/Request.java Wed Oct 14
18:05:00 2009
@@ -0,0 +1,68 @@
+package org.opensocial;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.opensocial.data.Model;
+
+public class Request {
+
+ private String guid;
+ private String selector;
+ private String template;
+ private String rpcMethod;
+ private String restMethod;
+ private Map<String, String> parameters;
+ private Class<? extends Model> modelClass;
+
+ public Request(String template, String rpcMethod, String restMethod) {
+ this.template = template;
+ this.rpcMethod = rpcMethod;
+ this.restMethod = restMethod;
+ this.parameters = new HashMap<String, String>();
+ }
+
+ public String getGuid() {
+ return guid;
+ }
+
+ public String getSelector() {
+ return selector;
+ }
+
+ public String getTemplate() {
+ return template;
+ }
+
+ public String getRpcMethod() {
+ return rpcMethod;
+ }
+
+ public String getRestMethod() {
+ return restMethod;
+ }
+
+ public Map<String, String> getParameters() {
+ return parameters;
+ }
+
+ public Class<? extends Model> getModelClass() {
+ if (modelClass == null) {
+ return Model.class;
+ }
+
+ return modelClass;
+ }
+
+ public void setGuid(String guid) {
+ this.guid = guid;
+ }
+
+ public void setSelector(String selector) {
+ this.selector = selector;
+ }
+
+ public void setModelClass(Class<? extends Model> modelClass) {
+ this.modelClass = modelClass;
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/RequestException.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,10 @@
+package org.opensocial;
+
+public class RequestException extends Exception {
+
+ private static final long serialVersionUID = 7310870933354125869L;
+
+ public RequestException(String message) {
+ super(message);
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/Response.java Wed Oct
14 18:05:00 2009
@@ -0,0 +1,120 @@
+package org.opensocial;
+
+import org.opensocial.data.Model;
+import org.opensocial.http.HttpResponseMessage;
+import org.opensocial.parsers.JsonParser;
+import org.opensocial.parsers.Parser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Response {
+
+ private Long startIndex;
+ private Long totalResults;
+ private Long itemsPerPage;
+ private Boolean isFiltered;
+ private List<Model> entries;
+
+ public Response() {
+ entries = new ArrayList<Model>();
+ }
+
+ public static Map<String, Response> parseRpcResponse(
+ Map<String, Request> requests, HttpResponseMessage responseMessage,
+ String version) {
+ Parser parser = getParser(responseMessage.getResponse());
+
+ Map<String, Class<? extends Model>> modelClasses =
+ new HashMap<String, Class<? extends Model>>();
+ for (Map.Entry<String, Request> requestEntry : requests.entrySet()) {
+ Request request = requestEntry.getValue();
+ modelClasses.put(requestEntry.getKey(), request.getModelClass());
+ }
+
+ return parser.getResponseMap(responseMessage.getResponse(),
modelClasses,
+ version);
+ }
+
+ public static Response parseRestResponse(Request request,
+ HttpResponseMessage responseMessage, String version) {
+ Parser parser = getParser(responseMessage.getResponse());
+
+ return parser.getResponseObject(responseMessage.getResponse(),
+ request.getModelClass(), version);
+ }
+
+ private static Parser getParser(String responseBody) {
+ if (responseBody.startsWith("{") || responseBody.startsWith("[")) {
+ return new JsonParser();
+ }
+
+ return null;
+ }
+
+ public long getStartIndex() {
+ return startIndex;
+ }
+
+ public long getTotalResults() {
+ return totalResults;
+ }
+
+ public long getItemsPerPage() {
+ return itemsPerPage;
+ }
+
+ public boolean isFiltered() {
+ return isFiltered;
+ }
+
+ public List<Model> getEntries() {
+ return entries;
+ }
+
+ public Model getEntry() {
+ if (entries == null || entries.size() == 0) {
+ return null;
+ }
+
+ return entries.get(0);
+ }
+
+ public void setStartIndex(Object startIndex) {
+ this.startIndex = getLongValue(startIndex);
+ }
+
+ public void setTotalResults(Object totalResults) {
+ this.totalResults = getLongValue(totalResults);
+ }
+
+ public void setItemsPerPage(Object itemsPerPage) {
+ this.itemsPerPage = getLongValue(itemsPerPage);
+ }
+
+ public void setIsFiltered(Object isFiltered) {
+ this.isFiltered = getBooleanValue(isFiltered);
+ }
+
+ private Long getLongValue(Object field) {
+ if (field.getClass().equals(String.class)) {
+ return Long.parseLong((String) field);
+ } else if (field.getClass().equals(Number.class)) {
+ return (Long) field;
+ }
+
+ return null;
+ }
+
+ private Boolean getBooleanValue(Object field) {
+ if (field.getClass().equals(String.class)) {
+ return Boolean.parseBoolean((String) field);
+ } else if (field.getClass().equals(Boolean.class)) {
+ return (Boolean) field;
+ }
+
+ return null;
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/auth/AuthScheme.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,16 @@
+package org.opensocial.auth;
+
+import java.io.IOException;
+import java.util.Map;
+
+import net.oauth.http.HttpMessage;
+
+import org.opensocial.RequestException;
+import org.opensocial.providers.Provider;
+
+public interface AuthScheme {
+
+ public HttpMessage getHttpMessage(Provider provider, String method,
+ String url, Map<String, String> headers, String body) throws
+ RequestException, IOException;
+}
=======================================
--- /dev/null
+++
/branches/2009q4rewrite/java/src/org/opensocial/auth/OAuth2LeggedScheme.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,137 @@
+package org.opensocial.auth;
+
+import net.oauth.OAuth;
+import net.oauth.OAuthAccessor;
+import net.oauth.OAuthConsumer;
+import net.oauth.OAuthException;
+import net.oauth.OAuthMessage;
+import net.oauth.ParameterStyle;
+import net.oauth.http.HttpMessage;
+
+import org.apache.commons.codec.binary.Base64;
+import org.opensocial.RequestException;
+import org.opensocial.providers.Provider;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.util.Map;
+
+public class OAuth2LeggedScheme implements AuthScheme {
+
+ private String consumerKey;
+ private String consumerSecret;
+ private String requestorId;
+
+ public OAuth2LeggedScheme(String consumerKey, String consumerSecret) {
+ this(consumerKey, consumerSecret, null);
+ }
+
+ public OAuth2LeggedScheme(String consumerKey, String consumerSecret,
+ String requestorId) {
+ this.consumerKey = consumerKey;
+ this.consumerSecret = consumerSecret;
+ this.requestorId = requestorId;
+ }
+
+ public HttpMessage getHttpMessage(Provider provider, String method,
+ String url, Map<String, String> headers, String body) throws
+ RequestException, IOException {
+ if (consumerKey == null || consumerSecret == null) {
+ return null;
+ }
+
+ url = appendRequestorIdToQueryString(url);
+ OAuthMessage message = new OAuthMessage(method, url, null,
+ StringToStream(body));
+
+ for (Map.Entry<String, String> header : headers.entrySet()) {
+ message.getHeaders().add(header);
+ }
+
+ OAuthConsumer consumer =
+ new OAuthConsumer(null, consumerKey, consumerSecret, null);
+ consumer.setProperty(OAuth.OAUTH_SIGNATURE_METHOD, OAuth.HMAC_SHA1);
+
+ OAuthAccessor accessor = new OAuthAccessor(consumer);
+
+ if (body != null) {
+ if (provider.getSignBodyHash()) {
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ byte[] hash = md.digest(body.getBytes("UTF-8"));
+ byte[] encodedHash = new Base64().encode(hash);
+
+ message.addParameter("oauth_body_hash",
+ new String(encodedHash, "UTF-8"));
+ } catch (java.security.NoSuchAlgorithmException e) {
+ // Ignore exception
+ } catch (java.io.UnsupportedEncodingException e) {
+ // Ignore exception
+ }
+ } else if (message.getHeader(HttpMessage.CONTENT_TYPE)
+ .equals("application/x-www-form-urlencoded")){
+ message.addParameter(body, "");
+ }
+ }
+
+ try {
+ message.addRequiredParameters(accessor);
+ } catch (OAuthException e) {
+ throw new RequestException(
+ "OAuth error thrown while signing request " + e.getMessage());
+ } catch (java.net.URISyntaxException e) {
+ throw new RequestException(
+ "Malformed request URL " + message.URL + " could not be signed");
+ }
+
+ return HttpMessage.newRequest(message, ParameterStyle.QUERY_STRING);
+ }
+
+ public String getConsumerKey() {
+ return consumerKey;
+ }
+
+ public String getConsumerSecret() {
+ return consumerSecret;
+ }
+
+ public String getRequestorId() {
+ return requestorId;
+ }
+
+ private InputStream StringToStream(String text) {
+ InputStream stream = null;
+
+ if (text != null) {
+ try {
+ stream = new ByteArrayInputStream(text.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ // Ignore
+ }
+ }
+
+ return stream;
+ }
+
+ private String appendRequestorIdToQueryString(String url) {
+ if (requestorId == null) {
+ return url;
+ }
+
+ StringBuilder builder = new StringBuilder(url);
+
+ if (url.indexOf('?') == -1) {
+ builder.append("?xoauth_requestor_id=");
+ } else {
+ builder.append("&xoauth_requestor_id=");
+ }
+
+ builder.append(requestorId);
+
+ return builder.toString();
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/data/Model.java Wed Oct
14 18:05:00 2009
@@ -0,0 +1,59 @@
+package org.opensocial.data;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+
+public class Model extends JSONObject {
+
+ public String[] getFieldNames() {
+ int i = 0;
+ String[] fieldNames = new String[size()];
+
+ Set<Map.Entry<String, Object>> fields = entrySet();
+ for (Map.Entry<String, Object> field : fields) {
+ fieldNames[i] = field.getKey();
+ i++;
+ }
+
+ return fieldNames;
+ }
+
+ public boolean hasField(String fieldName) {
+ return containsKey(fieldName);
+ }
+
+ public Object getField(String fieldName) {
+ return get(fieldName);
+ }
+
+ public Map getFieldAsMap(String fieldName) {
+ return (Map) get(fieldName);
+ }
+
+ public List getFieldAsList(String fieldName) {
+ return (List) get(fieldName);
+ }
+
+ public boolean isFieldComplex(String fieldName) {
+ Object field = get(fieldName);
+ if (field.getClass().equals(String.class) ||
+ field.getClass().equals(JSONArray.class)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean isFieldMultivalued(String fieldName) {
+ Object field = get(fieldName);
+ if (field.getClass().equals(JSONArray.class)) {
+ return true;
+ }
+
+ return false;
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/data/Person.java Wed
Oct 14 18:05:00 2009
@@ -0,0 +1,43 @@
+package org.opensocial.data;
+
+import java.util.Map;
+
+public class Person extends Model {
+
+ public String getId() {
+ return (String) getField("id");
+ }
+
+ public String getDisplayName() {
+ StringBuilder name = new StringBuilder();
+
+ if (getField("displayName") != null) {
+ name.append(getField("displayName"));
+ } else if (getField("nickname") != null) {
+ name.append(getField("nickname"));
+ } else if (getField("name") != null) {
+ if (isFieldComplex("name")) {
+ Map nameMap = getFieldAsMap("name");
+
+ if (nameMap.containsKey("givenName")) {
+ name.append(nameMap.get("givenName"));
+ }
+ if (nameMap.containsKey("givenName") &&
+ nameMap.containsKey("familyName")) {
+ name.append(" ");
+ }
+ if (nameMap.containsKey("familyName")) {
+ name.append(nameMap.get("familyName"));
+ }
+ } else {
+ name.append((String) getField("name"));
+ }
+ }
+
+ return name.toString();
+ }
+
+ public String getThumbnailUrl() {
+ return (String) getField("thumbnailUrl");
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/http/HttpClient.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,83 @@
+package org.opensocial.http;
+
+import net.oauth.http.HttpMessage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.util.Map;
+
+public class HttpClient implements net.oauth.http.HttpClient {
+
+ public HttpResponseMessage execute(HttpMessage message) throws
IOException {
+ return execute(message, null);
+ }
+
+ public HttpResponseMessage execute(HttpMessage message,
+ Map<String, Object> parameters) throws IOException {
+ HttpURLConnection connection = null;
+
+ try {
+ connection = getConnection(message);
+
+ if (message.getBody() != null) {
+ OutputStreamWriter out =
+ new OutputStreamWriter(connection.getOutputStream());
+ out.write(StreamToString(message.getBody()));
+ out.flush();
+ out.close();
+ }
+
+ return new HttpResponseMessage(message.method, message.url,
+ connection.getResponseCode(), connection.getInputStream());
+ } catch (IOException e) {
+ return new HttpResponseMessage(message.method, message.url,
+ connection.getResponseCode());
+ }
+ }
+
+ private HttpURLConnection getConnection(HttpMessage message) throws
+ IOException {
+ HttpURLConnection connection =
+ (HttpURLConnection) message.url.openConnection();
+
+ for (Map.Entry<String, String> header : message.headers) {
+ connection.setRequestProperty(header.getKey(), header.getValue());
+ }
+
+ connection.setRequestMethod(message.method);
+ connection.setDoOutput(true);
+ connection.connect();
+
+ return connection;
+ }
+
+ /**
+ * From http://www.kodejava.org/examples/266.html
+ *
+ * @param is
+ * @return
+ */
+ private String StreamToString(InputStream stream) {
+ BufferedReader reader = new BufferedReader(new
InputStreamReader(stream));
+ StringBuilder builder = new StringBuilder();
+
+ String line = null;
+ try {
+ while ((line = reader.readLine()) != null) {
+ builder.append(line);
+ }
+ } catch (IOException e) {
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
+ }
+
+ return builder.toString();
+ }
+}
=======================================
--- /dev/null
+++
/branches/2009q4rewrite/java/src/org/opensocial/http/HttpResponseMessage.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,61 @@
+package org.opensocial.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+public class HttpResponseMessage extends
net.oauth.http.HttpResponseMessage {
+
+ private int statusCode;
+ private String response;
+
+ public HttpResponseMessage(String method, URL url, int statusCode) throws
+ IOException {
+ this(method, url, statusCode, null);
+ }
+
+ public HttpResponseMessage(String method, URL url, int statusCode,
+ InputStream responseStream) throws IOException {
+ super(method, url);
+ this.statusCode = statusCode;
+ setResponse(responseStream);
+ }
+
+ @Override
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ public String getResponse() {
+ return response;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public URL getUrl() {
+ return url;
+ }
+
+ private void setResponse(InputStream in) {
+ if (in != null) {
+ try {
+ String line = null;
+ StringBuilder builder = new StringBuilder();
+ BufferedReader reader = new BufferedReader(new
InputStreamReader(in));
+
+ while ((line = reader.readLine()) != null) {
+ builder.append(line);
+ }
+
+ response = builder.toString();
+ in.close();
+ } catch(IOException e) {
+ response = null;
+ }
+ }
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/parsers/JsonParser.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,209 @@
+package org.opensocial.parsers;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.ContainerFactory;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.opensocial.Response;
+import org.opensocial.data.Model;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class JsonParser implements Parser {
+
+ public Response getResponseObject(String json,
+ final Class<? extends Model> modelClass, String version) {
+ if (version.equals("0.8")) {
+ return getResponseObject0p8(json, modelClass);
+ } else if (version.equals("0.9")) {
+ return getResponseObject0p9(json, modelClass);
+ }
+
+ return null;
+ }
+
+ public Map<String, Response> getResponseMap(String json,
+ Map<String, Class<? extends Model>> modelClasses, String version) {
+ if (version.equals("0.8")) {
+ return getResponseMap0p8(json, modelClasses);
+ } else if (version.equals("0.9")) {
+
+ }
+
+ return null;
+ }
+
+ private Response getResponseObject0p8(String json,
+ final Class<? extends Model> modelClass) {
+ Response response = new Response();
+
+ JSONParser parser = new JSONParser();
+ ContainerFactory containerFactory = getContainerFactory(modelClass);
+
+ try {
+ Map rootObject = (Map) parser.parse(json, containerFactory);
+
+ if (rootObject.containsKey("startIndex")) {
+ response.setTotalResults(rootObject.get("startIndex"));
+ }
+ if (rootObject.containsKey("totalResults")) {
+ response.setTotalResults(rootObject.get("totalResults"));
+ }
+ if (rootObject.containsKey("entry")) {
+ Object entry = rootObject.get("entry");
+ if (entry.getClass().equals(JSONArray.class)) {
+ for (int i = 0; i < ((List) entry).size(); i++) {
+ response.getEntries().add((Model) ((List) entry).get(i));
+ }
+ } else if (entry.getClass().equals(modelClass)) {
+ response.getEntries().add((Model) entry);
+ }
+ }
+ } catch (ParseException e) {
+ return null;
+ }
+
+ return response;
+ }
+
+ private Map<String, Response> getResponseMap0p8(String json,
+ Map<String, Class<? extends Model>> modelClasses) {
+ Map<String, Response> responses = new HashMap<String, Response>();
+
+ JSONParser parser = new JSONParser();
+ ContainerFactory containerFactory = getContainerFactory(Model.class);
+
+ try {
+ List<Map> rootArray = (List<Map>) parser.parse(json,
containerFactory);
+
+ for (Map responseObject : rootArray) {
+ String id = null;
+ Class<? extends Model> modelClass = null;
+ Response response = new Response();
+
+ if (responseObject.containsKey("id")) {
+ id = (String) responseObject.get("id");
+ modelClass = modelClasses.get(id);
+ }
+
+ if (responseObject.containsKey("data")) {
+ Map dataObject = (Map) responseObject.get("data");
+
+ if (dataObject.containsKey("startIndex")) {
+ response.setStartIndex(dataObject.get("startIndex"));
+ }
+ if (dataObject.containsKey("totalResults")) {
+ response.setStartIndex(dataObject.get("totalResults"));
+ }
+ if (dataObject.containsKey("list")) {
+ Object list = dataObject.get("list");
+ if (list.getClass().equals(JSONArray.class)) {
+ for (int i = 0; i < ((List) list).size(); i++) {
+ Model object = (Model) ((List) list).get(i);
+ response.getEntries().add(cloneModelObject(object,
+ modelClass));
+ }
+ } else if (list.getClass().equals(JSONObject.class)) {
+ response.getEntries().add(cloneModelObject((Model) list,
+ modelClass));
+ }
+ } else {
+ response.getEntries().add(cloneModelObject((Model) dataObject,
+ modelClass));
+ }
+ }
+
+ responses.put(id, response);
+ }
+ } catch (ParseException e) {
+ return null;
+ }
+
+ return responses;
+ }
+
+ private Response getResponseObject0p9(String json,
+ final Class<? extends Model> modelClass) {
+ Response response = new Response();
+
+ JSONParser parser = new JSONParser();
+ ContainerFactory containerFactory = getContainerFactory(modelClass);
+
+ try {
+ Map rootObject = (Map) parser.parse(json, containerFactory);
+
+ if (rootObject.containsKey("startIndex")) {
+ response.setTotalResults(rootObject.get("startIndex"));
+ }
+ if (rootObject.containsKey("totalResults")) {
+ response.setTotalResults(rootObject.get("totalResults"));
+ }
+ if (rootObject.containsKey("itemsPerPage")) {
+ response.setItemsPerPage(rootObject.get("itemsPerPage"));
+ }
+ if (rootObject.containsKey("isFiltered")) {
+ response.setIsFiltered(rootObject.get("isFiltered"));
+ }
+ if (rootObject.containsKey("person")) {
+ response.getEntries().add((Model) rootObject.get("person"));
+ } else if (rootObject.containsKey("entry")) {
+ Object entry = rootObject.get("entry");
+ if (entry.getClass().equals(JSONArray.class)) {
+ for (int i = 0; i < ((List) entry).size(); i++) {
+ Map currentEntry = (Map) ((List) entry).get(i);
+ if (currentEntry.containsKey("person")) {
+ response.getEntries().add((Model)
currentEntry.get("person"));
+ }
+ }
+ }
+ }
+ } catch (ParseException e) {
+ return null;
+ }
+
+ return response;
+ }
+
+ private static ContainerFactory getContainerFactory(
+ final Class<? extends Model> modelClass) {
+ ContainerFactory containerFactory = new ContainerFactory() {
+ public List creatArrayContainer() {
+ return new JSONArray();
+ }
+
+ public Map createObjectContainer() {
+ try {
+ return modelClass.newInstance();
+ } catch (InstantiationException e) {
+ return new Model();
+ } catch (IllegalAccessException e) {
+ return new Model();
+ }
+ }
+ };
+
+ return containerFactory;
+ }
+
+ private static Model cloneModelObject(Model model,
+ final Class<? extends Model> modelClass) {
+ Model clone = null;
+ try {
+ clone = modelClass.newInstance();
+ } catch (InstantiationException e) {
+ return model;
+ } catch (IllegalAccessException e) {
+ return model;
+ }
+
+ for (Map.Entry entry : (Set<Map.Entry>) model.entrySet()) {
+ clone.put(entry.getKey(), entry.getValue());
+ }
+
+ return clone;
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/parsers/Parser.java Wed
Oct 14 18:05:00 2009
@@ -0,0 +1,15 @@
+package org.opensocial.parsers;
+
+import java.util.Map;
+
+import org.opensocial.Response;
+import org.opensocial.data.Model;
+
+public interface Parser {
+
+ public Response getResponseObject(String in,
+ final Class<? extends Model> modelClass, String version);
+
+ public Map<String, Response> getResponseMap(String in,
+ Map<String, Class<? extends Model>> modelClasses, String version);
+}
=======================================
--- /dev/null
+++
/branches/2009q4rewrite/java/src/org/opensocial/providers/MySpaceProvider.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,13 @@
+package org.opensocial.providers;
+
+public class MySpaceProvider extends Provider {
+
+ public MySpaceProvider() {
+ super();
+
+ setName("MySpace");
+ setVersion("0.9");
+ setRestEndpoint("http://opensocial.myspace.com/roa/09/");
+ setSignBodyHash(false);
+ }
+}
=======================================
--- /dev/null
+++
/branches/2009q4rewrite/java/src/org/opensocial/providers/OrkutProvider.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,13 @@
+package org.opensocial.providers;
+
+public class OrkutProvider extends Provider {
+
+ public OrkutProvider() {
+ super();
+
+ setName("orkut");
+ setVersion("0.8");
+ setRpcEndpoint("http://www.orkut.com/social/rpc/");
+ setRestEndpoint("http://www.orkut.com/social/rest/");
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/providers/Provider.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,74 @@
+package org.opensocial.providers;
+
+import org.opensocial.Request;
+import org.opensocial.Response;
+
+public class Provider {
+
+ private String name;
+ private String version;
+ private String contentType;
+ private String rpcEndpoint;
+ private String restEndpoint;
+ private boolean signBodyHash = true;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getVersion() {
+ if (version == null) {
+ return "0.8";
+ }
+
+ return version;
+ }
+
+ public String getContentType() {
+ if (contentType == null) {
+ return "application/json";
+ }
+
+ return contentType;
+ }
+
+ public String getRpcEndpoint() {
+ return rpcEndpoint;
+ }
+
+ public String getRestEndpoint() {
+ return restEndpoint;
+ }
+
+ public boolean getSignBodyHash() {
+ return signBodyHash;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ public void setRpcEndpoint(String rpcEndpoint) {
+ this.rpcEndpoint = rpcEndpoint;
+ }
+
+ public void setRestEndpoint(String restEndpoint) {
+ this.restEndpoint = restEndpoint;
+ }
+
+ public void setSignBodyHash(boolean signBodyHash) {
+ this.signBodyHash = signBodyHash;
+ }
+
+ public void preRequest(Request request) {}
+
+ public void postRequest(Request request, Response response) {}
+}
=======================================
--- /dev/null
+++
/branches/2009q4rewrite/java/src/org/opensocial/services/PeopleService.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,26 @@
+package org.opensocial.services;
+
+import org.opensocial.Request;
+import org.opensocial.data.Person;
+
+public class PeopleService extends Service {
+
+ private static final String restTemplate
= "people/{guid}/{selector}/{pid}";
+
+ public static Request get() {
+ return get(VIEWER);
+ }
+
+ public static Request get(String guid) {
+ return get(guid, SELF);
+ }
+
+ public static Request get(String guid, String selector) {
+ Request request = new Request(restTemplate, "people.get", "GET");
+ request.setModelClass(Person.class);
+ request.setSelector(selector);
+ request.setGuid(guid);
+
+ return request;
+ }
+}
=======================================
--- /dev/null
+++ /branches/2009q4rewrite/java/src/org/opensocial/services/Service.java
Wed Oct 14 18:05:00 2009
@@ -0,0 +1,9 @@
+package org.opensocial.services;
+
+public class Service {
+
+ public static final String APP = "@app";
+ public static final String SELF = "@self";
+ public static final String VIEWER = "@me";
+ public static final String FRIENDS = "@friends";
+}