/* Copyright (c) 2009 Google Inc.
*
* Licensed 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;
import org.opensocial.http.HttpResponseMessage;
import org.opensocial.models.Model;
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;
/**
* OpenSocial data response; encapsulates all information returned by a
* provider after processing a data request sent from a {@link Client}.
*
* @author Jason Cooper
*/
public class Response {
private Long startIndex;
private Long totalResults;
private Long itemsPerPage;
private String statusLink;
private Boolean isFiltered;
private List<Model> entries;
/**
* Creates and returns a new {@link Response}.
*/
public Response() {
entries = new ArrayList<Model>();
}
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);
}
/**
* Parses the raw response data received from a provider and returns the
* parsed data as a {@link Response}. Only JSON-encoded responses are
* supported at present.
*
* @param request original {@link Request} for which the response
* data was returned
* @param responseMessage {@link HttpResponseMessage} object containing raw,
* unparsed response data
* @param version latest OpenSocial specification supported by the
* provider that returned the response data, e.g.
* "0.9"
* @return new Response object encapsulating parsed response
* data
*/
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;
}
/**
* Returns the value of the "startIndex" field contained within the
* provider's response or null if no such property was returned.
*/
public Long getStartIndex() {
return startIndex;
}
/**
* Returns the value of the "totalResults" field contained within the
* provider's response or null if no such property was returned.
*/
public Long getTotalResults() {
return totalResults;
}
public Long getItemsPerPage() {
return itemsPerPage;
}
/**
* Returns the value of the "statusLink" field contained within the
* provider's response or null if no such property was returned.
*/
public String getStatusLink() {
return statusLink;
}
/**
* Returns the value of the "isFiltered" field contained within the
* provider's response or null if no such property was returned.
*/
public Boolean isFiltered() {
return isFiltered;
}
/**
* Returns a {@link List} of all entry objects (e.g. people, activities)
* parsed from the provider's response; if the raw response contained no
* entry objects, an empty list is returned. The List type depends on the
* Service used to create the request; e.g. a List of Persons is returned
* if the executed {@link Request} was generated by a PeopleService method.
*/
public <T extends Model> List<T> getEntries() {
return (List<T>) entries;
}
/**
* Returns a single entry object (e.g. person, activity) parsed from the
* response or null if the response contained no entry objects. Equivalent
* to calling getEntries.get(0) except no exception is thrown if no entries
* were parsed. The type of object returned depends on the Service used to
* create the request; e.g. a Person is returned if the executed
* {@link Request} was generated by a PeopleService method.
*/
public <T extends Model> T getEntry() {
if (entries == null || entries.size() == 0) {
return null;
}
return (T) entries.get(0);
}
/**
* Parses the passed Object as a Long if necessary, then sets this as the
* value of the startIndex field; this method is required by the response
* parser and should not be called by clients directly.
*
* @param startIndex String or Number object to parse as a Long and store
*/
public void setStartIndex(Object startIndex) {
this.startIndex = getLongValue(startIndex);
}
/**
* Parses the passed Object as a Long if necessary, then sets this as the
* value of the totalResults field; this method is required by the response
* parser and should not be called by clients directly.
*
* @param totalResults String or Number object to parse as a Long and store
*/
public void setTotalResults(Object totalResults) {
this.totalResults = getLongValue(totalResults);
}
/**
* Parses the passed Object as a Long if necessary, then sets this as the
* value of the itemsPerPage field; this method is required by the response
* parser and should not be called by clients directly.
*
* @param itemsPerPage String or Number object to parse as a Long and store
*/
public void setItemsPerPage(Object itemsPerPage) {
this.itemsPerPage = getLongValue(itemsPerPage);
}
/**
* Casts the passed Object as a String and sets this as the value of the
* statusLink field; this method is required by the response parser and
* should not be called by clients directly.
*
* @param statusLink String object to store
*/
public void setStatusLink(Object statusLink) {
this.statusLink = (String) statusLink;
}
/**
* Parses the passed Object as a Boolean if necessary, then sets this as the
* value of the isFiltered field; this method is required by the response
* parser and should not be called by clients directly.
*
* @param isFiltered String or Boolean object to parse as a Boolean and store
*/
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 instanceof Number) {
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;
}
}