| /* |
| * 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.apache.usergrid.android.sdk; |
| |
| import static org.apache.usergrid.android.sdk.utils.ObjectUtils.isEmpty; |
| import static org.apache.usergrid.android.sdk.utils.UrlUtils.addQueryParams; |
| import static org.apache.usergrid.android.sdk.utils.UrlUtils.encodeParams; |
| import static org.apache.usergrid.android.sdk.utils.UrlUtils.path; |
| |
| import java.io.BufferedReader; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.OutputStream; |
| import java.net.HttpURLConnection; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.EnumSet; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.StringTokenizer; |
| import java.util.UUID; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.Date; |
| |
| import android.location.Location; |
| import android.location.LocationManager; |
| import android.location.LocationListener; |
| import android.os.Build; |
| import android.os.Bundle; |
| import android.util.Log; |
| |
| import org.apache.usergrid.android.sdk.URLConnectionFactory; |
| import org.apache.usergrid.android.sdk.callbacks.ApiResponseCallback; |
| import org.apache.usergrid.android.sdk.callbacks.ClientAsyncTask; |
| import org.apache.usergrid.android.sdk.callbacks.GroupsRetrievedCallback; |
| import org.apache.usergrid.android.sdk.callbacks.QueryResultsCallback; |
| import org.apache.usergrid.android.sdk.entities.Activity; |
| import org.apache.usergrid.android.sdk.entities.Collection; |
| import org.apache.usergrid.android.sdk.entities.Device; |
| import org.apache.usergrid.android.sdk.entities.Entity; |
| import org.apache.usergrid.android.sdk.entities.Group; |
| import org.apache.usergrid.android.sdk.entities.Message; |
| import org.apache.usergrid.android.sdk.entities.User; |
| import org.apache.usergrid.android.sdk.response.ApiResponse; |
| import org.apache.usergrid.android.sdk.utils.DeviceUuidFactory; |
| import org.apache.usergrid.android.sdk.utils.JsonUtils; |
| import com.fasterxml.jackson.annotation.JsonInclude; |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import com.fasterxml.jackson.databind.node.JsonNodeFactory; |
| import com.fasterxml.jackson.databind.DeserializationFeature; |
| |
| |
| /** |
| * The UGClient class for accessing the Usergrid API. Start by instantiating this |
| * class though the appropriate constructor. Most calls to the API will be handled |
| * by the methods in this class. |
| * |
| * @see org.apache.usergrid.android.sdk.UGClient |
| * @see <a href="http://apigee.com/docs/app-services/content/installing-apigee-sdk-android">Usergrid SDK install guide</a> |
| */ |
| public class UGClient { |
| |
| /** |
| * Most current version of the Usergrid Android SDK |
| */ |
| public static final String SDK_VERSION = "0.0.8"; |
| /** |
| * Platform type of this SDK |
| */ |
| public static final String SDK_TYPE = "Android"; |
| |
| /** |
| * @y.exclude |
| */ |
| public static final String OPTION_KEY_BASE_URL = "baseURL"; |
| |
| /** |
| * @y.exclude |
| */ |
| public static boolean FORCE_PUBLIC_API = false; |
| |
| /** |
| * Public API |
| */ |
| public static String PUBLIC_API_URL = "https://api.usergrid.com"; |
| |
| /** |
| * Local API of standalone server |
| */ |
| public static String LOCAL_STANDALONE_API_URL = "http://localhost:8080"; |
| |
| /** |
| * Local API of Tomcat server in Eclipse |
| */ |
| public static String LOCAL_TOMCAT_API_URL = "http://localhost:8080/ROOT"; |
| |
| /** |
| * Local API |
| */ |
| public static String LOCAL_API_URL = LOCAL_STANDALONE_API_URL; |
| |
| /** |
| * Standard HTTP methods use in generic request methods |
| * @see apiRequest |
| * @see doHttpRequest |
| */ |
| protected static final String HTTP_METHOD_DELETE = "DELETE"; |
| /** |
| * Standard HTTP methods use in generic request methods |
| * @see apiRequest |
| * @see doHttpRequest |
| */ |
| protected static final String HTTP_METHOD_GET = "GET"; |
| /** |
| * Standard HTTP methods use in generic request methods |
| * @see apiRequest |
| * @see doHttpRequest |
| */ |
| protected static final String HTTP_METHOD_POST = "POST"; |
| /** |
| * Standard HTTP methods use in generic request methods |
| * @see apiRequest |
| * @see doHttpRequest |
| */ |
| protected static final String HTTP_METHOD_PUT = "PUT"; |
| |
| protected static final String LOGGING_TAG = "UGCLIENT"; |
| |
| private String apiUrl = PUBLIC_API_URL; |
| |
| private String organizationId; |
| private String applicationId; |
| private String clientId; |
| private String clientSecret; |
| |
| private User loggedInUser = null; |
| |
| private String accessToken = null; |
| |
| private String currentOrganization = null; |
| private URLConnectionFactory urlConnectionFactory = null; |
| |
| private LocationManager locationManager; |
| private UUID deviceID; |
| |
| /** |
| * Interface for EntityQuery and QueueQuery |
| */ |
| public interface Query { |
| |
| public ApiResponse getResponse(); |
| |
| public boolean more(); |
| |
| public Query next(); |
| |
| } |
| |
| /** |
| * @y.exclude |
| */ |
| public static boolean isUuidValid(UUID uuid) { |
| return( uuid != null ); |
| } |
| |
| protected static String arrayToDelimitedString(String[] arrayOfStrings, String delimiter) { |
| StringBuilder sb = new StringBuilder(); |
| |
| for( int i = 0; i < arrayOfStrings.length; ++i ) { |
| if( i > 0 ) { |
| sb.append(delimiter); |
| } |
| |
| sb.append(arrayOfStrings[i]); |
| } |
| |
| return sb.toString(); |
| } |
| |
| protected static String[] tokenizeToStringArray(String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) { |
| if (str == null) { |
| return null; |
| } |
| |
| StringTokenizer st = new StringTokenizer(str, delimiters); |
| |
| int numTokens = st.countTokens(); |
| List<String> listTokens; |
| |
| if( numTokens > 0 ) { |
| |
| listTokens = new ArrayList<String>(numTokens); |
| |
| while (st.hasMoreTokens()) { |
| |
| String token = st.nextToken(); |
| |
| if (trimTokens) { |
| token = token.trim(); |
| } |
| |
| if (!ignoreEmptyTokens || token.length() > 0) { |
| listTokens.add(token); |
| } |
| } |
| } else { |
| listTokens = new ArrayList<String>(); |
| } |
| |
| return listTokens.toArray(new String[listTokens.size()]); |
| } |
| |
| |
| /****************** CONSTRUCTORS ***********************/ |
| /****************** CONSTRUCTORS ***********************/ |
| |
| /** |
| * @y.exclude |
| */ |
| public UGClient() { |
| init(); |
| } |
| |
| /** |
| * Instantiate a data client for a specific app. This is used to call most |
| * SDK methods. |
| * |
| * @param organizationId the Usergrid organization name |
| * @param applicationId the Usergrid application id or name |
| */ |
| public UGClient(String organizationId, String applicationId) { |
| init(); |
| this.organizationId = organizationId; |
| this.applicationId = applicationId; |
| } |
| |
| /** |
| * Instantiate a data client for a specific app with a base URL other than the default |
| * api.usergrid.com. This is used to call most SDK methods. |
| * |
| * @param organizationId the Usergrid organization name |
| * @param applicationId the Usergrid application id or name |
| * @param baseURL the base URL to use for all API calls |
| */ |
| public UGClient(String organizationId, String applicationId, String baseURL) { |
| init(); |
| this.organizationId = organizationId; |
| this.applicationId = applicationId; |
| |
| if( baseURL != null ) { |
| this.setApiUrl(baseURL); |
| } |
| } |
| |
| public void init() { |
| } |
| |
| |
| /****************** ACCESSORS/MUTATORS ***********************/ |
| /****************** ACCESSORS/MUTATORS ***********************/ |
| |
| /** |
| * Sets a new URLConnectionFactory object in the UGClient |
| * |
| * @param urlConnectionFactory a new URLConnectionFactory object |
| * @y.exclude |
| */ |
| public void setUrlConnectionFactory(URLConnectionFactory urlConnectionFactory) { |
| this.urlConnectionFactory = urlConnectionFactory; |
| } |
| |
| /** |
| * @return the Usergrid API url (default: http://api.usergrid.com) |
| */ |
| public String getApiUrl() { |
| return apiUrl; |
| } |
| |
| /** |
| * Sets the base URL for API requests |
| * |
| * @param apiUrl the API base url to be set (default: http://api.usergrid.com) |
| */ |
| public void setApiUrl(String apiUrl) { |
| this.apiUrl = apiUrl; |
| } |
| |
| /** |
| * Sets the base URL for API requests and returns the updated UGClient object |
| * |
| * @param apiUrl the Usergrid API url (default: http://api.usergrid.com) |
| * @return UGClient object for method call chaining |
| */ |
| public UGClient withApiUrl(String apiUrl) { |
| this.apiUrl = apiUrl; |
| return this; |
| } |
| |
| |
| /** |
| * Sets the Usergrid organization ID and returns the UGClient object |
| * |
| * @param organizationId the organizationId to set |
| * @return the updated UGClient object |
| */ |
| public UGClient withOrganizationId(String organizationId){ |
| this.organizationId = organizationId; |
| return this; |
| } |
| |
| |
| |
| /** |
| * Gets the current Usergrid organization ID set in the UGClient |
| * |
| * @return the current organizationId |
| */ |
| public String getOrganizationId() { |
| return organizationId; |
| } |
| |
| /** |
| * Sets the Usergrid organization ID |
| * |
| * @param organizationId the organizationId to set |
| */ |
| public void setOrganizationId(String organizationId) { |
| this.organizationId = organizationId; |
| } |
| |
| /** |
| * Gets the current Usergrid application ID set in the UGClient |
| * |
| * @return the current organizationId or name |
| */ |
| public String getApplicationId() { |
| return applicationId; |
| } |
| |
| /** |
| * Sets the Usergrid application Id |
| * |
| * @param applicationId the application id or name |
| */ |
| public void setApplicationId(String applicationId) { |
| this.applicationId = applicationId; |
| } |
| |
| |
| /** |
| * Sets the Usergrid application ID and returns the UGClient object |
| * |
| * @param applicationId the application ID to set |
| * @return the updated UGClient object |
| */ |
| public UGClient withApplicationId(String applicationId) { |
| this.applicationId = applicationId; |
| return this; |
| } |
| |
| /** |
| * Gets the application (not organization) client ID credential for making calls as the |
| * application-owner. Not safe for most mobile use. |
| * @return the client id |
| */ |
| public String getClientId() { |
| return clientId; |
| } |
| |
| /** |
| * Sets the application (not organization) client ID credential, used for making |
| * calls as the application-owner. Not safe for most mobile use. |
| * @param clientId the client id |
| */ |
| public void setClientId(String clientId) { |
| this.clientId = clientId; |
| } |
| |
| /** |
| * Sets the client ID credential in the UGClient object. Not safe for most mobile use. |
| * |
| * @param clientId the client key id |
| * @return UGClient object for method call chaining |
| */ |
| public UGClient withClientId(String clientId) { |
| this.clientId = clientId; |
| return this; |
| } |
| |
| /** |
| * Gets the application (not organization) client secret credential for making calls as the |
| * application-owner. Not safe for most mobile use. |
| * @return the client secret |
| */ |
| public String getClientSecret() { |
| return clientSecret; |
| } |
| |
| /** |
| * Sets the application (not organization) client secret credential, used for making |
| * calls as the application-owner. Not safe for most mobile use. |
| * |
| * @param clientSecret the client secret |
| */ |
| public void setClientSecret(String clientSecret) { |
| this.clientSecret = clientSecret; |
| } |
| |
| /** |
| * Sets the client secret credential in the UGClient object. Not safe for most mobile use. |
| * |
| * @param clientSecret the client secret |
| * @return UGClient object for method call chaining |
| */ |
| public UGClient withClientSecret(String clientSecret) { |
| this.clientSecret = clientSecret; |
| return this; |
| } |
| |
| /** |
| * Gets the UUID of the logged-in user after a successful authorizeAppUser request |
| * @return the UUID of the logged-in user |
| */ |
| public User getLoggedInUser() { |
| return loggedInUser; |
| } |
| |
| /** |
| * Sets the UUID of the logged-in user. Usually not set by host application |
| * @param loggedInUser the UUID of the logged-in user |
| */ |
| public void setLoggedInUser(User loggedInUser) { |
| this.loggedInUser = loggedInUser; |
| } |
| |
| /** |
| * Gets the OAuth2 access token for the current logged-in user after a |
| * successful authorize request |
| * |
| * @return the OAuth2 access token |
| */ |
| public String getAccessToken() { |
| return accessToken; |
| } |
| |
| /** |
| * Saves the OAuth2 access token in the UGClient after a successful authorize |
| * request. Usually not set by host application. |
| * |
| * @param accessToken an OAuth2 access token |
| */ |
| public void setAccessToken(String accessToken) { |
| this.accessToken = accessToken; |
| } |
| |
| /** |
| * Gets the current organization from UGClient |
| * |
| * @return the currentOrganization |
| */ |
| public String getCurrentOrganization() { |
| return currentOrganization; |
| } |
| |
| /** |
| * Sets the current organizanization from UGClient |
| * |
| * @param currentOrganization The organization this data client should use. |
| */ |
| public void setCurrentOrganization(String currentOrganization) { |
| this.currentOrganization = currentOrganization; |
| } |
| |
| /****************** LOGGING ***********************/ |
| /****************** LOGGING ***********************/ |
| |
| |
| /** |
| * Logs a trace-level logging message with tag 'DATA_CLIENT' |
| * |
| * @param logMessage the message to log |
| */ |
| public void logTrace(String logMessage) { |
| if( logMessage != null ) { |
| Log.v(LOGGING_TAG,logMessage); |
| } |
| } |
| |
| /** |
| * Logs a debug-level logging message with tag 'DATA_CLIENT' |
| * |
| * @param logMessage the message to log |
| */ |
| public void logDebug(String logMessage) { |
| if( logMessage != null ) { |
| Log.d(LOGGING_TAG,logMessage); |
| } |
| } |
| |
| /** |
| * Logs an info-level logging message with tag 'DATA_CLIENT' |
| * |
| * @param logMessage the message to log |
| */ |
| public void logInfo(String logMessage) { |
| if( logMessage != null ) { |
| Log.i(LOGGING_TAG,logMessage); |
| } |
| } |
| |
| /** |
| * Logs a warn-level logging message with tag 'DATA_CLIENT' |
| * |
| * @param logMessage the message to log |
| */ |
| public void logWarn(String logMessage) { |
| if( logMessage != null ) { |
| Log.w(LOGGING_TAG,logMessage); |
| } |
| } |
| |
| /** |
| * Logs an error-level logging message with tag 'DATA_CLIENT' |
| * |
| * @param logMessage the message to log |
| */ |
| public void logError(String logMessage) { |
| if( logMessage != null ) { |
| Log.e(LOGGING_TAG,logMessage); |
| } |
| } |
| |
| /** |
| * Logs a debug-level logging message with tag 'DATA_CLIENT' |
| * |
| * @param logMessage the message to log |
| */ |
| public void writeLog(String logMessage) { |
| if( logMessage != null ) { |
| //TODO: do we support different log levels in this class? |
| Log.d(LOGGING_TAG, logMessage); |
| } |
| } |
| |
| /****************** API/HTTP REQUEST ***********************/ |
| /****************** API/HTTP REQUEST ***********************/ |
| |
| /** |
| * Forms and initiates a raw synchronous http request and processes the response. |
| * |
| * @param httpMethod the HTTP method in the format: |
| * HTTP_METHOD_<method_name> (e.g. HTTP_METHOD_POST) |
| * @param params the URL parameters to append to the request URL |
| * @param data the body of the request |
| * @param segments additional URL path segments to append to the request URL |
| * @return ApiResponse object |
| */ |
| public ApiResponse doHttpRequest(String httpMethod, Map<String, Object> params, Object data, String... segments) { |
| |
| ApiResponse response = null; |
| OutputStream out = null; |
| InputStream in = null; |
| HttpURLConnection conn = null; |
| |
| String urlAsString = path(apiUrl, segments); |
| |
| try { |
| String contentType = "application/json"; |
| if (httpMethod.equals(HTTP_METHOD_POST) && isEmpty(data) && !isEmpty(params)) { |
| data = encodeParams(params); |
| contentType = "application/x-www-form-urlencoded"; |
| } else { |
| urlAsString = addQueryParams(urlAsString, params); |
| } |
| |
| //logTrace("Invoking " + httpMethod + " to '" + urlAsString + "'"); |
| |
| URL url = new URL(urlAsString); |
| conn = (HttpURLConnection) url.openConnection(); |
| |
| conn.setRequestMethod(httpMethod); |
| conn.setRequestProperty("Content-Type", contentType); |
| conn.setUseCaches(false); |
| |
| if ((accessToken != null) && (accessToken.length() > 0)) { |
| String authStr = "Bearer " + accessToken; |
| conn.setRequestProperty("Authorization", authStr); |
| } |
| |
| conn.setDoInput(true); |
| |
| if (httpMethod.equals(HTTP_METHOD_POST) || httpMethod.equals(HTTP_METHOD_PUT)) { |
| if (isEmpty(data)) { |
| data = JsonNodeFactory.instance.objectNode(); |
| } |
| |
| String dataAsString = null; |
| |
| if ((data != null) && (!(data instanceof String))) { |
| ObjectMapper objectMapper = new ObjectMapper(); |
| objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
| dataAsString = objectMapper.writeValueAsString(data); |
| } else { |
| dataAsString = (String) data; |
| } |
| |
| //logTrace("Posting/putting data: '" + dataAsString + "'"); |
| |
| byte[] dataAsBytes = dataAsString.getBytes(); |
| |
| conn.setRequestProperty("Content-Length", Integer.toString(dataAsBytes.length)); |
| conn.setDoOutput(true); |
| |
| out = conn.getOutputStream(); |
| out.write(dataAsBytes); |
| out.flush(); |
| out.close(); |
| out = null; |
| } |
| |
| in = conn.getInputStream(); |
| if( in != null ) { |
| BufferedReader reader = new BufferedReader(new InputStreamReader(in)); |
| StringBuilder sb = new StringBuilder(); |
| String line; |
| |
| while( (line = reader.readLine()) != null ) { |
| sb.append(line); |
| sb.append('\n'); |
| } |
| |
| String responseAsString = sb.toString(); |
| |
| //logTrace("response from server: '" + responseAsString + "'"); |
| ObjectMapper objectMapper = new ObjectMapper(); |
| objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); |
| objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
| response = (ApiResponse) objectMapper.readValue(responseAsString, ApiResponse.class); |
| response.setRawResponse(responseAsString); |
| |
| response.setUGClient(this); |
| } else { |
| response = null; |
| logTrace("no response body from server"); |
| } |
| |
| //final int responseCode = conn.getResponseCode(); |
| //logTrace("responseCode from server = " + responseCode); |
| } |
| catch(Exception e) { |
| logError("Error " + httpMethod + " to '" + urlAsString + "'" ); |
| if( e != null ) { |
| e.printStackTrace(); |
| logError(e.getLocalizedMessage()); |
| } |
| response = null; |
| } |
| catch(Throwable t) { |
| logError("Error " + httpMethod + " to '" + urlAsString + "'" ); |
| if( t != null ) { |
| t.printStackTrace(); |
| logError(t.getLocalizedMessage()); |
| } |
| response = null; |
| } |
| finally { |
| try { |
| if( out != null ) { |
| out.close(); |
| } |
| |
| if( in != null ) { |
| in.close(); |
| } |
| |
| if( conn != null ) { |
| conn.disconnect(); |
| } |
| } catch(Exception ignored) { |
| } |
| } |
| |
| return response; |
| } |
| |
| |
| /** |
| * High-level synchronous API request. Implements the http request |
| * for most SDK methods by calling |
| * {@link #doHttpRequest(String,Map,Object,String...)} |
| * |
| * @param httpMethod the HTTP method in the format: |
| * HTTP_METHOD_<method_name> (e.g. HTTP_METHOD_POST) |
| * @param params the URL parameters to append to the request URL |
| * @param data the body of the request |
| * @param segments additional URL path segments to append to the request URL |
| * @return ApiResponse object |
| */ |
| public ApiResponse apiRequest(String httpMethod, |
| Map<String, Object> params, Object data, String... segments) { |
| ApiResponse response = null; |
| |
| response = doHttpRequest(httpMethod, params, data, segments); |
| |
| if( (response == null) ) { |
| logError("doHttpRequest returned null"); |
| } |
| |
| return response; |
| } |
| |
| protected void assertValidApplicationId() { |
| if (isEmpty(applicationId)) { |
| throw new IllegalArgumentException("No application id specified"); |
| } |
| } |
| |
| /****************** ROLES/PERMISSIONS ***********************/ |
| /****************** ROLES/PERMISSIONS ***********************/ |
| |
| /** |
| * Assigns permissions to the specified user, group, or role. |
| * |
| * @param entityType the entity type of the entity the permissions are being assigned to. 'user', 'group' and 'role' are valid. |
| * @param entityID the UUID of 'name' property of the entity the permissions are being assigned to. |
| * @param permissions a comma-separated list of the permissions to be assigned in the format: <operations>:<path>, e.g. get, put, post, delete: /users |
| * @throws IllegalArgumentException thrown if an entityType other than 'group' or 'user' is passed to the method |
| * @return ApiResponse object |
| */ |
| public ApiResponse assignPermissions(String entityType, String entityID, String permissions) { |
| |
| if (!entityType.substring(entityType.length() - 1 ).equals("s")) { |
| entityType += "s"; |
| } |
| |
| if (!validateTypeForPermissionsAndRoles(entityType, "permission")) { |
| throw new IllegalArgumentException("Permissions can only be assigned to group, user, or role entities"); |
| } |
| |
| Map<String, Object> data = new HashMap<String, Object>(); |
| if (permissions != null){ |
| data.put("permission", permissions); |
| } |
| |
| return apiRequest(HTTP_METHOD_POST, null, data, organizationId, applicationId, entityType, |
| entityID, "permissions"); |
| |
| } |
| |
| /** |
| * Assigns permissions to the specified user, group, or role. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param entityType the entity type of the entity the permissions are being assigned to. 'user', 'group' and 'role' are valid. |
| * @param entityID the UUID of 'name' property of the entity the permissions are being assigned to. |
| * @param permissions a comma-separated list of the permissions to be assigned in the format: <operations>:<path>, e.g. get, put, post, delete: /users |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void assignPermissionsAsync(final String entityType, |
| final String entityID, final String permissions, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return assignPermissions(entityType, entityID, permissions); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Removes permissions from the specified user, group or role. |
| * |
| * @param entityType the entity type of the entity the permissions are being removed from. 'user', 'group' and 'role' are valid. |
| * @param entityID the UUID of 'name' property of the entity the permissions are being removed from. |
| * @param permissions a comma-separated list of the permissions to be removed in the format: <operations>:<path>, e.g. get, put, post, delete: /users |
| * @throws IllegalArgumentException thrown if an entityType other than 'group' or 'user' is passed to the method |
| * @return ApiResponse object |
| */ |
| public ApiResponse removePermissions(String entityType, String entityID, String permissions) { |
| |
| if (!validateTypeForPermissionsAndRoles(entityType, "permission")) { |
| throw new IllegalArgumentException("Permissions can only be assigned to group, user, or role entities"); |
| } |
| |
| Map<String, Object> params = new HashMap<String, Object>(); |
| if (permissions != null){ |
| params.put("permission", permissions); |
| } |
| |
| return apiRequest(HTTP_METHOD_DELETE, params, null, organizationId, applicationId, entityType, |
| entityID, "permissions"); |
| |
| } |
| |
| /** |
| * Removes permissions from the specified user, group or role. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param entityType the entity type of the entity the permissions are being removed from. 'user', 'group', and 'role' are valid. |
| * @param entityID the UUID of 'name' property of the entity the permissions are being removed from. |
| * @param permissions a comma-separated list of the permissions to be removed in the format: <operations>:<path>, e.g. get, put, post, delete: /users |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void removePermissionsAsync(final String entityType, |
| final String entityID, final String permissions, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return removePermissions(entityType, entityID, permissions); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Creates a new role and assigns permissions to it. |
| * |
| * @param roleName the name of the new role |
| * @param permissions a comma-separated list of the permissions to be assigned in the format: <operations>:<path>, e.g. get, put, post, delete: /users |
| * @return ApiResponse object |
| */ |
| public ApiResponse createRole(String roleName, String permissions) { |
| |
| Map<String, Object> properties = new HashMap<String, Object>(); |
| properties.put("type", "role"); |
| properties.put("name", roleName); |
| |
| ApiResponse response = this.createEntity(properties); |
| |
| String uuid = null; |
| |
| if (response.getEntityCount() == 1){ |
| uuid = response.getFirstEntity().getUuid().toString(); |
| } |
| |
| return assignPermissions("role", uuid, permissions); |
| |
| } |
| |
| /** |
| * Creates a new role and assigns permissions to it. |
| * |
| * @param roleName the name of the new role |
| * @param permissions a comma-separated list of the permissions to be assigned in the format: <operations>:<path>, e.g. get, put, post, delete: /users |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void createRoleAsync(final String roleName, final String permissions, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return createRole(roleName, permissions); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Assigns a role to a user or group entity. |
| * |
| * @param roleName the name of the role to be assigned to the entity |
| * @param entityType the entity type of the entity the role is being assigned to. 'user' and 'group' are valid. |
| * @param entityID the UUID or 'name' property of the entity the role is being assigned to. |
| * @throws IllegalArgumentException thrown if an entityType other than 'group' or 'user' is passed to the method |
| * @return ApiResponse object |
| */ |
| public ApiResponse assignRole(String roleName, String entityType, String entityID) { |
| |
| if (!entityType.substring(entityType.length() - 1 ).equals("s")) { |
| entityType += "s"; |
| } |
| |
| if (!validateTypeForPermissionsAndRoles(entityType, "role")) { |
| throw new IllegalArgumentException("Permissions can only be assigned to a group or user"); |
| } |
| |
| return apiRequest(HTTP_METHOD_POST, null, null, organizationId, applicationId, "roles", roleName, |
| entityType, entityID); |
| |
| } |
| |
| /** |
| * Assigns a role to a user or group entity. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param roleName the name of the role to be assigned to the entity |
| * @param entityType the entity type of the entity the role is being assigned to. 'user' and 'group' are valid. |
| * @param entityID the UUID or 'name' property of the entity the role is being removed from. |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void assignRoleAsync(final String roleName, final String entityType, |
| final String entityID, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return assignRole(roleName, entityType, entityID); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Removes a role from a user or group entity. |
| * |
| * @param roleName the name of the role to be removed from the entity |
| * @param entityType the entity type of the entity the role is being removed from. 'user' and 'group' are valid. |
| * @param entityID the UUID or 'name' property of the entity the role is being removed from. |
| * @throws IllegalArgumentException thrown if an entityType other than 'group' or 'user' is passed to the method |
| * @return ApiResponse object |
| */ |
| public ApiResponse removeRole(String roleName, String entityType, String entityID) { |
| |
| if (!entityType.substring(entityType.length() - 1 ).equals("s")) { |
| entityType += "s"; |
| } |
| |
| if (!validateTypeForPermissionsAndRoles(entityType, "role")) { |
| throw new IllegalArgumentException("Permissions can only be removed from a group or user"); |
| } |
| |
| return apiRequest(HTTP_METHOD_DELETE, null, null, organizationId, applicationId, "roles", roleName, |
| entityType, entityID); |
| |
| } |
| |
| /** |
| * Removes a role from a user or group entity. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param roleName the name of the role to be removed from the entity |
| * @param entityType the entity type of the entity the role is being removed from. 'user' and 'group' are valid. |
| * @param entityID the UUID or 'name' property of the entity the role is being removed from. |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void removeRoleAsync(final String roleName, final String entityType, |
| final String entityID, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return removeRole(roleName, entityType, entityID); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Checks if a permission or role can be assigned to an entity |
| * @y.exclude |
| */ |
| private Boolean validateTypeForPermissionsAndRoles(String type, String permissionOrRole){ |
| ArrayList<String> validTypes = new ArrayList<String>(); |
| validTypes.add("groups"); |
| validTypes.add("users"); |
| |
| if (permissionOrRole.equals("permission")){ |
| validTypes.add("roles"); |
| } |
| |
| return validTypes.contains(type); |
| } |
| |
| /****************** LOG IN/LOG OUT/OAUTH ***********************/ |
| /****************** LOG IN/LOG OUT/OAUTH ***********************/ |
| |
| /** |
| * Logs the user in and get a valid access token. |
| * |
| * @param usernameOrEmail the username or email associated with the user entity in Usergrid |
| * @param password the user's Usergrid password |
| * @return non-null ApiResponse if request succeeds, check getError() for |
| * "invalid_grant" to see if access is denied. |
| */ |
| public ApiResponse authorizeAppUser(String usernameOrEmail, String password) { |
| validateNonEmptyParam(usernameOrEmail, "email"); |
| validateNonEmptyParam(password,"password"); |
| assertValidApplicationId(); |
| loggedInUser = null; |
| accessToken = null; |
| currentOrganization = null; |
| Map<String, Object> formData = new HashMap<String, Object>(); |
| formData.put("grant_type", "password"); |
| formData.put("username", usernameOrEmail); |
| formData.put("password", password); |
| ApiResponse response = apiRequest(HTTP_METHOD_POST, formData, null, |
| organizationId, applicationId, "token"); |
| if (response == null) { |
| return response; |
| } |
| if (!isEmpty(response.getAccessToken()) && (response.getUser() != null)) { |
| loggedInUser = response.getUser(); |
| accessToken = response.getAccessToken(); |
| currentOrganization = null; |
| logInfo("authorizeAppUser(): Access token: " + accessToken); |
| } else { |
| logInfo("authorizeAppUser(): Response: " + response); |
| } |
| return response; |
| } |
| |
| /** |
| * Log the user in and get a valid access token. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param usernameOrEmail the username or email associated with the user entity in Usergrid |
| * @param password the users Usergrid password |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void authorizeAppUserAsync(final String usernameOrEmail, |
| final String password, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return authorizeAppUser(usernameOrEmail, password); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Change the password for the currently logged in user. You must supply the |
| * old password and the new password. |
| * |
| * @param username the username or email address associated with the user entity in Usergrid |
| * @param oldPassword the user's old password |
| * @param newPassword the user's new password |
| * @return ApiResponse object |
| */ |
| public ApiResponse changePassword(String username, String oldPassword, |
| String newPassword) { |
| |
| Map<String, Object> data = new HashMap<String, Object>(); |
| data.put("newpassword", newPassword); |
| data.put("oldpassword", oldPassword); |
| |
| return apiRequest(HTTP_METHOD_POST, null, data, organizationId, applicationId, "users", |
| username, "password"); |
| |
| } |
| |
| public void changePasswordAsync(final String username, final String oldPassword, |
| final String newPassword, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return changePassword(username, oldPassword, newPassword); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Log the user in with their numeric pin-code and get a valid access token. |
| * |
| * @param email the email address associated with the user entity in Usergrid |
| * @param pin the pin associated with the user entity in Usergrid |
| * @return non-null ApiResponse if request succeeds, check getError() for |
| * "invalid_grant" to see if access is denied. |
| */ |
| public ApiResponse authorizeAppUserViaPin(String email, String pin) { |
| validateNonEmptyParam(email, "email"); |
| validateNonEmptyParam(pin, "pin"); |
| assertValidApplicationId(); |
| loggedInUser = null; |
| accessToken = null; |
| currentOrganization = null; |
| Map<String, Object> formData = new HashMap<String, Object>(); |
| formData.put("grant_type", "pin"); |
| formData.put("username", email); |
| formData.put("pin", pin); |
| ApiResponse response = apiRequest(HTTP_METHOD_POST, formData, null, |
| organizationId, applicationId, "token"); |
| if (response == null) { |
| return response; |
| } |
| if (!isEmpty(response.getAccessToken()) && (response.getUser() != null)) { |
| loggedInUser = response.getUser(); |
| accessToken = response.getAccessToken(); |
| currentOrganization = null; |
| logInfo("authorizeAppUser(): Access token: " + accessToken); |
| } else { |
| logInfo("authorizeAppUser(): Response: " + response); |
| } |
| return response; |
| } |
| |
| /** |
| * Log the user in with their numeric pin-code and get a valid access token. |
| * Executes asynchronously in background and the callbacks are called in the |
| * UI thread. |
| * |
| * @param email the email address associated with the user entity in Usergrid |
| * @param pin the pin associated with the user entity in Usergrid |
| * @param callback A callback for the async response. |
| */ |
| public void authorizeAppUserViaPinAsync(final String email, |
| final String pin, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return authorizeAppUserViaPin(email, pin); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Log the app in with it's application (not organization) client id and |
| * client secret key. Not recommended for production apps. Executes asynchronously |
| * in background and the callbacks are called in the UI thread. |
| * |
| * @param clientId the Usergrid application's client ID |
| * @param clientSecret the Usergrid application's client secret |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void authorizeAppClientAsync(final String clientId, |
| final String clientSecret, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| |
| @Override |
| public ApiResponse doTask() { |
| return authorizeAppClient(clientId, clientSecret); |
| } |
| }).execute(); |
| } |
| |
| private void validateNonEmptyParam(Object param, String paramName) { |
| if ( isEmpty(param) ) { |
| throw new IllegalArgumentException(paramName + " cannot be null or empty"); |
| } |
| } |
| |
| /** |
| * Log the user in with their Facebook access token retrieved via Facebook |
| * OAuth. Sets the user's identifier and Usergrid OAuth2 access token in UGClient |
| * if successfully authorized. |
| * |
| * @param fb_access_token the valid OAuth token returned by Facebook |
| * @return non-null ApiResponse if request succeeds, check getError() for |
| * "invalid_grant" to see if access is denied. |
| */ |
| public ApiResponse authorizeAppUserViaFacebook(String fb_access_token) { |
| validateNonEmptyParam(fb_access_token, "Facebook token"); |
| assertValidApplicationId(); |
| loggedInUser = null; |
| accessToken = null; |
| currentOrganization = null; |
| Map<String, Object> formData = new HashMap<String, Object>(); |
| formData.put("fb_access_token", fb_access_token); |
| ApiResponse response = apiRequest(HTTP_METHOD_POST, formData, null, |
| organizationId, applicationId, "auth", "facebook"); |
| if (response == null) { |
| return response; |
| } |
| if (!isEmpty(response.getAccessToken()) && (response.getUser() != null)) { |
| loggedInUser = response.getUser(); |
| accessToken = response.getAccessToken(); |
| currentOrganization = null; |
| logInfo("authorizeAppUserViaFacebook(): Access token: " |
| + accessToken); |
| } else { |
| logInfo("authorizeAppUserViaFacebook(): Response: " |
| + response); |
| } |
| return response; |
| } |
| |
| /** |
| * Log the user in with their Facebook access token retrieved via Facebook |
| * OAuth. Sets the user's identifier and Usergrid OAuth2 access token in UGClient |
| * if successfully authorized. Executes asynchronously in background and the |
| * callbacks are called in the UI thread. |
| * |
| * @param fb_access_token the valid OAuth token returned by Facebook |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void authorizeAppUserViaFacebookAsync(final String fb_access_token, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return authorizeAppUserViaFacebook(fb_access_token); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Log out a user and destroy the access token currently stored in UGClient |
| * on the server and in the UGClient. |
| * |
| * @param username The username to be logged out |
| * @return non-null ApiResponse if request succeeds |
| */ |
| public ApiResponse logOutAppUser(String username) { |
| String token = getAccessToken(); |
| Map<String,Object> params = new HashMap<String,Object>(); |
| params.put("token",token); |
| ApiResponse response = apiRequest(HTTP_METHOD_PUT, params, null, |
| organizationId, applicationId, "users",username,"revoketoken?"); |
| if (response == null) { |
| return response; |
| } else { |
| logInfo("logoutAppUser(): Response: " + response); |
| setAccessToken(null); |
| } |
| return response; |
| } |
| |
| /** |
| * Log out a user and destroy the access token currently stored in UGClient |
| * on the server and in the UGClient. |
| * Executes asynchronously in background and the callbacks are called in the |
| * UI thread. |
| * |
| * @param username The username to be logged out |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void logOutAppUserAsync(final String username, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return logOutAppUser(username); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Destroy a specific user token on the server. The token will also be cleared |
| * from the UGClient instance, if it matches the token provided. |
| * |
| * @param username The username to be logged out |
| * @param token The access token to be destroyed on the server |
| * @return non-null ApiResponse if request succeeds |
| */ |
| public ApiResponse logOutAppUserForToken(String username, String token) { |
| Map<String,Object> params = new HashMap<String,Object>(); |
| params.put("token",token); |
| ApiResponse response = apiRequest(HTTP_METHOD_PUT, params, null, |
| organizationId, applicationId, "users",username,"revoketoken?"); |
| if (response == null) { |
| return response; |
| } else { |
| logInfo("logoutAppWithTokenUser(): Response: " + response); |
| if (token.equals(getAccessToken())) { |
| setAccessToken(null); |
| } |
| } |
| return response; |
| } |
| |
| /** |
| * Destroy a specific user token on the server. The token will also be cleared |
| * from the UGClient instance, if it matches the token provided. |
| * Executes asynchronously in background and the callbacks are called in the UI thread. |
| * |
| * @param username The username to be logged out |
| * @param token The access token to be destroyed on the server |
| * @param callback A callback for the async response |
| */ |
| public void logOutAppUserForTokenAsync(final String username, final String token, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return logOutAppUserForToken(username, token); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Log out a user and destroy all associated tokens on the server. |
| * The token stored in UGClient will also be destroyed. |
| * |
| * @param username The username to be logged out |
| * @return non-null ApiResponse if request succeeds |
| */ |
| public ApiResponse logOutAppUserForAllTokens(String username) { |
| ApiResponse response = apiRequest(HTTP_METHOD_PUT, null, null, |
| organizationId, applicationId, "users",username,"revoketokens"); |
| if (response == null) { |
| return response; |
| } else { |
| logInfo("logoutAppUserForAllTokens(): Response: " + response); |
| setAccessToken(null); |
| } |
| return response; |
| } |
| |
| /** |
| * Log out a user and destroy all associated tokens on the server. |
| * The token stored in UGClient will also be destroyed. |
| * Executes asynchronously in background and the callbacks are called in the UI thread. |
| * |
| * @param username The username to be logged out |
| * @param callback A callback for the response |
| */ |
| public void logOutAppUserForAllTokensAsync(final String username, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return logOutAppUserForAllTokens(username); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Log the app in with it's application (not organization) client id and |
| * client secret key. Not recommended for production apps. |
| * |
| * @param clientId the Usergrid application's client ID |
| * @param clientSecret the Usergrid application's client secret |
| */ |
| public ApiResponse authorizeAppClient(String clientId, String clientSecret) { |
| validateNonEmptyParam(clientId, "client identifier"); |
| validateNonEmptyParam(clientSecret, "client secret"); |
| assertValidApplicationId(); |
| loggedInUser = null; |
| accessToken = null; |
| currentOrganization = null; |
| Map<String, Object> formData = new HashMap<String, Object>(); |
| formData.put("grant_type", "client_credentials"); |
| formData.put("client_id", clientId); |
| formData.put("client_secret", clientSecret); |
| ApiResponse response = apiRequest(HTTP_METHOD_POST, formData, null, |
| organizationId, applicationId, "token"); |
| if (response == null) { |
| return response; |
| } |
| if (!isEmpty(response.getAccessToken())) { |
| loggedInUser = null; |
| accessToken = response.getAccessToken(); |
| currentOrganization = null; |
| logInfo("authorizeAppClient(): Access token: " |
| + accessToken); |
| } else { |
| logInfo("authorizeAppClient(): Response: " + response); |
| } |
| return response; |
| } |
| |
| |
| /****************** GENERIC ENTITY MANAGEMENT ***********************/ |
| /****************** GENERIC ENTITY MANAGEMENT ***********************/ |
| |
| /** |
| * Create a new entity on the server. |
| * |
| * @param entity |
| * @return an ApiResponse with the new entity in it. |
| */ |
| public ApiResponse createEntity(Entity entity) { |
| assertValidApplicationId(); |
| if (isEmpty(entity.getType())) { |
| throw new IllegalArgumentException("Missing entity type"); |
| } |
| ApiResponse response = apiRequest(HTTP_METHOD_POST, null, entity, |
| organizationId, applicationId, entity.getType()); |
| return response; |
| } |
| |
| /** |
| * Create a new entity on the server from a set of properties. Properties |
| * must include a "type" property. |
| * |
| * @param properties |
| * @return an ApiResponse with the new entity in it. |
| */ |
| public ApiResponse createEntity(Map<String, Object> properties) { |
| assertValidApplicationId(); |
| if (isEmpty(properties.get("type"))) { |
| throw new IllegalArgumentException("Missing entity type"); |
| } |
| ApiResponse response = apiRequest(HTTP_METHOD_POST, null, properties, |
| organizationId, applicationId, properties.get("type").toString()); |
| return response; |
| } |
| |
| /** |
| * Create a new entity on the server. Executes asynchronously in background |
| * and the callbacks are called in the UI thread. |
| * |
| * @param entity An instance with data to use to create the entity |
| * @param callback A callback for the async response |
| */ |
| public void createEntityAsync(final Entity entity, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return createEntity(entity); |
| } |
| }).execute(); |
| } |
| |
| |
| /** |
| * Create a new entity on the server from a set of properties. Properties |
| * must include a "type" property. Executes asynchronously in background and |
| * the callbacks are called in the UI thread. |
| * |
| * @param properties The values to use, with keys as property names and values |
| * as property values |
| * @param callback A callback for the async response |
| */ |
| public void createEntityAsync(final Map<String, Object> properties, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return createEntity(properties); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Create a set of entities on the server from an ArrayList. Each item in the array |
| * contains a set of properties that define a entity. |
| * |
| * @param type The type of entities to create. |
| * @param entities A list of maps where keys are entity property names and values |
| * are property values. |
| * @return An instance with response data from the server. |
| */ |
| public ApiResponse createEntities(String type, ArrayList<Map<String, Object>> entities) { |
| assertValidApplicationId(); |
| if (isEmpty(type)) { |
| throw new IllegalArgumentException("Missing entity type"); |
| } |
| ApiResponse response = apiRequest(HTTP_METHOD_POST, null, entities, |
| organizationId, applicationId, type); |
| return response; |
| } |
| |
| /** |
| * Create a set of entities on the server from an ArrayList. Each item in the array |
| * contains a set of properties that define a entity. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param type The type of entities to create. |
| * @param entities A list of maps where keys are entity property names and values |
| * are property values. |
| * @param callback A callback for the async response |
| */ |
| public void createEntitiesAsync(final String type, final ArrayList<Map<String, Object>> entities, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return createEntities(type, entities); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Creates an object instance that corresponds to the provided entity type. |
| * Supported object types are Activity, Device, Group, Message, and User. |
| * All other types will return a generic Entity instance with no type assigned. |
| * |
| * @param type the entity type of which to create an object instance |
| * @return an object instance that corresponds to the type provided |
| */ |
| public Entity createTypedEntity(String type) { |
| Entity entity = null; |
| |
| if( Activity.isSameType(type) ) { |
| entity = new Activity(this); |
| } else if( Device.isSameType(type) ) { |
| entity = new Device(this); |
| } else if( Group.isSameType(type) ) { |
| entity = new Group(this); |
| } else if( Message.isSameType(type) ) { |
| entity = new Message(this); |
| } else if( User.isSameType(type) ) { |
| entity = new User(this); |
| } else { |
| entity = new Entity(this); |
| } |
| |
| return entity; |
| } |
| |
| /** |
| * Requests all entities of specified type that match the provided query string. |
| * |
| * @param type the entity type to be retrieved |
| * @param queryString a query string to send with the request |
| * @return a non-null ApiResponse object if successful |
| */ |
| public ApiResponse getEntities(String type,String queryString) |
| { |
| Map<String, Object> params = null; |
| |
| if (queryString.length() > 0) { |
| params = new HashMap<String, Object>(); |
| params.put("ql", queryString); |
| } |
| |
| return apiRequest(HTTP_METHOD_GET, // method |
| params, // params |
| null, // data |
| organizationId, |
| applicationId, |
| type); |
| } |
| |
| /** |
| * Asynchronously requests all entities of specified type that match the provided query string. |
| * |
| * @param type the entity type to be retrieved |
| * @param queryString a query string to send with the request |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void getEntitiesAsync(final String type, |
| final String queryString, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return getEntities(type, queryString); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Update an existing entity on the server. |
| * |
| * @param entityID the entity to update |
| * @param updatedProperties the new properties |
| * @return an ApiResponse with the updated entity in it. |
| */ |
| public ApiResponse updateEntity(String entityID, Map<String, Object> updatedProperties) { |
| assertValidApplicationId(); |
| if (isEmpty(updatedProperties.get("type"))) { |
| throw new IllegalArgumentException("Missing entity type"); |
| } |
| ApiResponse response = apiRequest(HTTP_METHOD_PUT, null, updatedProperties, |
| organizationId, applicationId, updatedProperties.get("type").toString(), entityID); |
| return response; |
| } |
| |
| |
| /** |
| * Update an existing entity on the server. Properties |
| * must include a "type" property. Executes asynchronously in background and |
| * the callbacks are called in the UI thread. |
| * |
| * @param entityID the entity to update |
| * @param updatedProperties the new properties |
| * @param callback A callback for the async response |
| */ |
| public void updateEntityAsync(final String entityID, final Map<String, Object> updatedProperties, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return updateEntity(entityID, updatedProperties); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Updates the password associated with a user entity |
| * |
| * @param usernameOrEmail the username or email address associated with the user entity |
| * @param oldPassword the user's old password |
| * @param newPassword the user's new password |
| * @return an ApiResponse with the updated entity in it. |
| */ |
| public ApiResponse updateUserPassword(String usernameOrEmail, String oldPassword, String newPassword) { |
| Map<String,Object> updatedProperties = new HashMap<String,Object>(); |
| updatedProperties.put("oldpassword", oldPassword); |
| updatedProperties.put("newpassword", newPassword); |
| return apiRequest(HTTP_METHOD_POST, null, updatedProperties, |
| organizationId, applicationId, "users", usernameOrEmail); |
| } |
| |
| |
| /** |
| * Remove an existing entity on the server. |
| * |
| * @param entityType the collection of the entity |
| * @param entityID the specific entity to delete |
| * @return an ApiResponse indicating whether the removal was successful |
| */ |
| public ApiResponse removeEntity(String entityType, String entityID) { |
| assertValidApplicationId(); |
| if (isEmpty(entityType)) { |
| throw new IllegalArgumentException("Missing entity type"); |
| } |
| ApiResponse response = apiRequest(HTTP_METHOD_DELETE, null, null, |
| organizationId, applicationId, entityType, entityID); |
| return response; |
| } |
| |
| /** |
| * Remove an existing entity on the server. |
| * Executes asynchronously in background and |
| * the callbacks are called in the UI thread. |
| * |
| * @param entityType the collection of the entity |
| * @param entityID the specific entity to delete |
| * @param callback A callback with the async response |
| */ |
| public void removeEntityAsync(final String entityType, final String entityID, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return removeEntity(entityType, entityID); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Perform a query request and return a query object. The Query object |
| * provides a simple way of dealing with result sets that need to be |
| * iterated or paged through. |
| * |
| * See {@link #doHttpRequest(String,Map,Object,String...)} for |
| * more on the parameters. |
| * |
| * @param httpMethod The HTTP method to use in the query |
| * @param params Query parameters. |
| * @param data The request body. |
| * @param segments Additional URL path segments to append to the request URL |
| * @return An instance representing query results |
| */ |
| public Query queryEntitiesRequest(String httpMethod, |
| Map<String, Object> params, Object data, String... segments) { |
| ApiResponse response = apiRequest(httpMethod, params, data, segments); |
| return new EntityQuery(response, httpMethod, params, data, segments); |
| } |
| |
| /** |
| * Perform a query request and return a query object. The Query object |
| * provides a simple way of dealing with result sets that need to be |
| * iterated or paged through. Executes asynchronously in background and the |
| * callbacks are called in the UI thread. |
| * |
| * See {@link #doHttpRequest(String,Map,Object,String...)} for |
| * more on the parameters. |
| * |
| * @param callback A callback for the async response |
| * @param httpMethod The HTTP method to use in the query |
| * @param params Query parameters. |
| * @param data The request body. |
| * @param segments Additional URL path segments to append to the request URL |
| */ |
| public void queryEntitiesRequestAsync(final QueryResultsCallback callback, |
| final String httpMethod, final Map<String, Object> params, |
| final Object data, final String... segments) { |
| (new ClientAsyncTask<Query>(callback) { |
| @Override |
| public Query doTask() { |
| return queryEntitiesRequest(httpMethod, params, data, segments); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Query object for handling the response from certain query requests |
| * @y.exclude |
| */ |
| private class EntityQuery implements Query { |
| final String httpMethod; |
| final Map<String, Object> params; |
| final Object data; |
| final String[] segments; |
| final ApiResponse response; |
| |
| private EntityQuery(ApiResponse response, String httpMethod, |
| Map<String, Object> params, Object data, String[] segments) { |
| this.response = response; |
| this.httpMethod = httpMethod; |
| this.params = params; |
| this.data = data; |
| this.segments = segments; |
| } |
| |
| private EntityQuery(ApiResponse response, EntityQuery q) { |
| this.response = response; |
| httpMethod = q.httpMethod; |
| params = q.params; |
| data = q.data; |
| segments = q.segments; |
| } |
| |
| /** |
| * Gets the API response from the last request |
| * |
| * @return an ApiResponse object |
| */ |
| public ApiResponse getResponse() { |
| return response; |
| } |
| |
| /** |
| * Checks if there are more results available based on whether a |
| * 'cursor' property was present in the last result set. |
| * |
| * @return true if the server indicates more results are available |
| */ |
| public boolean more() { |
| if ((response != null) && (response.getCursor() != null) |
| && (response.getCursor().length() > 0)) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Performs a request for the next set of results based on the cursor |
| * from the last result set. |
| * |
| * @return query that contains results and where to get more. |
| */ |
| public Query next() { |
| if (more()) { |
| Map<String, Object> nextParams = null; |
| if (params != null) { |
| nextParams = new HashMap<String, Object>(params); |
| } else { |
| nextParams = new HashMap<String, Object>(); |
| } |
| nextParams.put("cursor", response.getCursor()); |
| ApiResponse nextResponse = apiRequest(httpMethod, nextParams, data, |
| segments); |
| return new EntityQuery(nextResponse, this); |
| } |
| return null; |
| } |
| |
| } |
| |
| |
| /****************** USER ENTITY MANAGEMENT ***********************/ |
| /****************** USER ENTITY MANAGEMENT ***********************/ |
| |
| /** |
| * Creates a user entity. |
| * |
| * @param username required. The username to be associated with the user entity. |
| * @param name the user's full name. Can be null. |
| * @param email the user's email address. |
| * @param password the user's password |
| * @return an ApiResponse object |
| */ |
| public ApiResponse createUser(String username, String name, String email, |
| String password) { |
| Map<String, Object> properties = new HashMap<String, Object>(); |
| properties.put("type", "user"); |
| if (username != null) { |
| properties.put("username", username); |
| } |
| if (name != null) { |
| properties.put("name", name); |
| } |
| if (email != null) { |
| properties.put("email", email); |
| } |
| if (password != null) { |
| properties.put("password", password); |
| } |
| return createEntity(properties); |
| } |
| |
| /** |
| * Creates a user. Executes asynchronously in background and the callbacks |
| * are called in the UI thread. |
| * |
| * @param username required. The username to be associated with the user entity. |
| * @param name the user's full name. Can be null. |
| * @param email the user's email address. |
| * @param password the user's password. |
| * @param callback an ApiResponse callback for handling the async response. |
| */ |
| public void createUserAsync(final String username, final String name, |
| final String email, final String password, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return createUser(username, name, email, password); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Retrieves the /users collection. |
| * |
| * @return a Query object |
| */ |
| public Query queryUsers() { |
| Query q = queryEntitiesRequest(HTTP_METHOD_GET, null, null, |
| organizationId, applicationId, "users"); |
| return q; |
| } |
| |
| /** |
| * Retrieves the /users collection. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param callback a QueryResultsCallback object to handle the async response |
| */ |
| public void queryUsersAsync(QueryResultsCallback callback) { |
| queryEntitiesRequestAsync(callback, HTTP_METHOD_GET, null, null, |
| organizationId, applicationId, "users"); |
| } |
| |
| |
| /** |
| * Performs a query of the users collection using the provided query command. |
| * For example: "name contains 'ed'". |
| * |
| * @param ql the query to execute |
| * @return a Query object |
| */ |
| public Query queryUsers(String ql) { |
| Map<String, Object> params = new HashMap<String, Object>(); |
| params.put("ql", ql); |
| Query q = queryEntitiesRequest(HTTP_METHOD_GET, params, null,organizationId, |
| applicationId, "users"); |
| return q; |
| } |
| |
| /** |
| * Perform a query of the users collection using the provided query command. |
| * For example: "name contains 'ed'". Executes asynchronously in background |
| * and the callbacks are called in the UI thread. |
| * |
| * @param ql the query to execute |
| * @param callback a QueryResultsCallback object to handle the async response |
| */ |
| public void queryUsersAsync(String ql, QueryResultsCallback callback) { |
| Map<String, Object> params = new HashMap<String, Object>(); |
| params.put("ql", ql); |
| queryEntitiesRequestAsync(callback, HTTP_METHOD_GET, params, null, |
| organizationId, applicationId, "users"); |
| } |
| |
| /** |
| * Perform a query of the users collection within the specified distance of |
| * the specified location and optionally using the provided additional query. |
| * For example: "name contains 'ed'". |
| * |
| * @param distance distance from the location in meters |
| * @param latitude the latitude of the location to measure from |
| * @param longitude the longitude of the location to measure from |
| * @param ql an optional additional query to send with the request |
| * @return a Query object |
| */ |
| public Query queryUsersWithinLocation(float distance, float latitude, |
| float longitude, String ql) { |
| Map<String, Object> params = new HashMap<String, Object>(); |
| params.put("ql", |
| this.makeLocationQL(distance, latitude, longitude, ql)); |
| Query q = queryEntitiesRequest(HTTP_METHOD_GET, params, null, organizationId, |
| applicationId, "users"); |
| return q; |
| } |
| |
| |
| /****************** GROUP ENTITY MANAGEMENT ***********************/ |
| /****************** GROUP ENTITY MANAGEMENT ***********************/ |
| |
| /** |
| * Creates a group with the specified group path. Group paths can be slash |
| * ("/") delimited like file paths for hierarchical group relationships. |
| * |
| * @param groupPath the path to use for the new group. |
| * @return an ApiResponse object |
| */ |
| public ApiResponse createGroup(String groupPath) { |
| return createGroup(groupPath, null); |
| } |
| |
| /** |
| * Creates a group with the specified group path and group title. Group |
| * paths can be slash ("/") delimited like file paths for hierarchical group |
| * relationships. |
| * |
| * @param groupPath the path to use for the new group |
| * @param groupTitle the title to use for the new group |
| * @return an ApiResponse object |
| */ |
| public ApiResponse createGroup(String groupPath, String groupTitle) { |
| return createGroup(groupPath, groupTitle, null); |
| } |
| |
| /** |
| * Create a group with a path, title and name. Group |
| * paths can be slash ("/") delimited like file paths for hierarchical group |
| * relationships. |
| * |
| * @param groupPath the path to use for the new group |
| * @param groupTitle the title to use for the new group |
| * @param groupName the name to use for the new group |
| * @return an ApiResponse object |
| */ |
| public ApiResponse createGroup(String groupPath, String groupTitle, String groupName){ |
| Map<String, Object> data = new HashMap<String, Object>(); |
| data.put("type", "group"); |
| data.put("path", groupPath); |
| |
| if (groupTitle != null) { |
| data.put("title", groupTitle); |
| } |
| |
| if(groupName != null){ |
| data.put("name", groupName); |
| } |
| |
| return apiRequest(HTTP_METHOD_POST, null, data, organizationId, applicationId, "groups"); |
| } |
| |
| /** |
| * Creates a group with the specified group path. Group paths can be slash |
| * ("/") delimited like file paths for hierarchical group relationships. |
| * Executes asynchronously in background and the callbacks are called in the |
| * UI thread. |
| * |
| * @param groupPath the path to use for the new group. |
| * @param callback an ApiResponseCallback object to handle the async response |
| */ |
| public void createGroupAsync(String groupPath, |
| final ApiResponseCallback callback) { |
| createGroupAsync(groupPath, null, null); |
| } |
| |
| /** |
| * Creates a group with the specified group path and group title. Group |
| * paths can be slash ("/") deliminted like file paths for hierarchical |
| * group relationships. Executes asynchronously in background and the |
| * callbacks are called in the UI thread. |
| * |
| * @param groupPath the path to use for the new group. |
| * @param groupTitle the title to use for the new group. |
| * @param callback an ApiResponseCallback object to handle the async response |
| */ |
| public void createGroupAsync(final String groupPath, |
| final String groupTitle, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return createGroup(groupPath, groupTitle); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Gets the groups associated with a user entity |
| * |
| * @param userId the UUID of the user entity |
| * @return a map with the group path as the key and a Group object as the value |
| */ |
| public Map<String, Group> getGroupsForUser(String userId) { |
| ApiResponse response = apiRequest(HTTP_METHOD_GET, null, null, |
| organizationId, applicationId, "users", userId, "groups"); |
| Map<String, Group> groupMap = new HashMap<String, Group>(); |
| if (response != null) { |
| List<Group> groups = response.getEntities(Group.class); |
| for (Group group : groups) { |
| groupMap.put(group.getPath(), group); |
| } |
| } |
| return groupMap; |
| } |
| |
| /** |
| * Gets the groups associated with a user entity. Executes asynchronously in background and |
| * the callbacks are called in the UI thread. |
| * |
| * @param userId the UUID of the user entity |
| * @param callback a GroupsRetrievedCallback object to handle the async response |
| */ |
| public void getGroupsForUserAsync(final String userId, |
| final GroupsRetrievedCallback callback) { |
| (new ClientAsyncTask<Map<String, Group>>(callback) { |
| @Override |
| public Map<String, Group> doTask() { |
| return getGroupsForUser(userId); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Gets the user entities associated with the specified group. |
| * |
| * @param groupId UUID of the group entity |
| * @return a Query object with the results of the query |
| */ |
| public Query queryUsersForGroup(String groupId) { |
| Query q = queryEntitiesRequest(HTTP_METHOD_GET, null, null, organizationId, |
| applicationId, "groups", groupId, "users"); |
| return q; |
| } |
| |
| /** |
| * Gets the user entities associated with the specified group. Executes |
| * asynchronously in background and the callbacks are called in the UI thread. |
| * |
| * @param groupId UUID of the group entity |
| * @param callback a QueryResultsCallback object to handle the async response |
| */ |
| public void queryUsersForGroupAsync(String groupId, |
| QueryResultsCallback callback) { |
| queryEntitiesRequestAsync(callback, HTTP_METHOD_GET, null, null, |
| getApplicationId(), "groups", groupId, "users"); |
| } |
| |
| /** |
| * Connects a user entity to the specified group entity. |
| * |
| * @param userId UUID of the user entity |
| * @param groupId UUID of the group entity |
| * @return an ApiResponse object |
| */ |
| public ApiResponse addUserToGroup(String userId, String groupId) { |
| return apiRequest(HTTP_METHOD_POST, null, null, organizationId, applicationId, "groups", |
| groupId, "users", userId); |
| } |
| |
| /** |
| * Connects a user entity to the specified group entity. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param userId UUID of the user entity |
| * @param groupId UUID of the group entity |
| * @param callback an ApiResponseCallback object to handle the async response |
| */ |
| public void addUserToGroupAsync(final String userId, final String groupId, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return addUserToGroup(userId, groupId); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Disconnects a user entity from the specified group entity. |
| * |
| * @param userId UUID of the user entity |
| * @param groupId UUID of the group entity |
| * @return an ApiResponse object |
| */ |
| public ApiResponse removeUserFromGroup(String userId, String groupId) { |
| return apiRequest(HTTP_METHOD_DELETE, null, null, organizationId, applicationId, "groups", |
| groupId, "users", userId); |
| } |
| |
| /** |
| * Disconnects a user entity from the specified group entity. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param userId UUID of the user entity |
| * @param groupId UUID of the group entity |
| * @param callback an ApiResponseCallback object to handle the async response |
| */ |
| public void removeUserFromGroupAsync(final String userId, final String groupId, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return removeUserFromGroup(userId, groupId); |
| } |
| }).execute(); |
| } |
| |
| /****************** ACTIVITY ENTITY MANAGEMENT ***********************/ |
| /****************** ACTIVITY ENTITY MANAGEMENT ***********************/ |
| |
| /** |
| * Get a user's activity feed. Returned as a query to ease paging. |
| * |
| * @param userId UUID of user entity |
| * @return a Query object |
| */ |
| public Query queryActivityFeedForUser(String userId) { |
| Query q = queryEntitiesRequest(HTTP_METHOD_GET, null, null, |
| organizationId, applicationId, "users", userId, "feed"); |
| return q; |
| } |
| |
| /** |
| * Get a user's activity feed. Returned as a query to ease paging. Executes |
| * asynchronously in background and the callbacks are called in the UI |
| * thread. |
| * |
| * |
| * @param userId UUID of user entity |
| * @param callback a QueryResultsCallback object to handle the async response |
| */ |
| public void queryActivityFeedForUserAsync(final String userId, final QueryResultsCallback callback) { |
| (new ClientAsyncTask<Query>(callback) { |
| @Override |
| public Query doTask() { |
| return queryActivityFeedForUser(userId); |
| } |
| }).execute(); |
| } |
| |
| |
| /** |
| * Posts an activity to a user entity's activity stream. Activity must already be created. |
| * |
| * @param userId |
| * @param activity |
| * @return An instance with the server response |
| */ |
| public ApiResponse postUserActivity(String userId, Activity activity) { |
| return apiRequest(HTTP_METHOD_POST, null, activity, organizationId, applicationId, "users", |
| userId, "activities"); |
| } |
| |
| /** |
| * Creates and posts an activity to a user entity's activity stream. |
| * |
| * @param verb |
| * @param title |
| * @param content |
| * @param category |
| * @param user |
| * @param object |
| * @param objectType |
| * @param objectName |
| * @param objectContent |
| * @return |
| */ |
| public ApiResponse postUserActivity(String verb, String title, |
| String content, String category, User user, Entity object, |
| String objectType, String objectName, String objectContent) { |
| Activity activity = Activity.newActivity(this, verb, title, content, |
| category, user, object, objectType, objectName, objectContent); |
| return postUserActivity(user.getUuid().toString(), activity); |
| } |
| |
| /** |
| * Creates and posts an activity to a user. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param verb |
| * @param title |
| * @param content |
| * @param category |
| * @param user |
| * @param object |
| * @param objectType |
| * @param objectName |
| * @param objectContent |
| * @param callback |
| */ |
| public void postUserActivityAsync(final String verb, final String title, |
| final String content, final String category, final User user, |
| final Entity object, final String objectType, |
| final String objectName, final String objectContent, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return postUserActivity(verb, title, content, category, user, |
| object, objectType, objectName, objectContent); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Posts an activity to a group. Activity must already be created. |
| * |
| * @param groupId |
| * @param activity |
| * @return |
| */ |
| public ApiResponse postGroupActivity(String groupId, Activity activity) { |
| return apiRequest(HTTP_METHOD_POST, null, activity, organizationId, applicationId, "groups", |
| groupId, "activities"); |
| } |
| |
| /** |
| * Creates and posts an activity to a group. |
| * |
| * @param groupId |
| * @param verb |
| * @param title |
| * @param content |
| * @param category |
| * @param user |
| * @param object |
| * @param objectType |
| * @param objectName |
| * @param objectContent |
| * @return |
| */ |
| public ApiResponse postGroupActivity(String groupId, String verb, String title, |
| String content, String category, User user, Entity object, |
| String objectType, String objectName, String objectContent) { |
| Activity activity = Activity.newActivity(this, verb, title, content, |
| category, user, object, objectType, objectName, objectContent); |
| return postGroupActivity(groupId, activity); |
| } |
| |
| /** |
| * Creates and posts an activity to a group. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param groupId |
| * @param verb |
| * @param title |
| * @param content |
| * @param category |
| * @param user |
| * @param object |
| * @param objectType |
| * @param objectName |
| * @param objectContent |
| * @param callback |
| */ |
| public void postGroupActivityAsync(final String groupId, final String verb, final String title, |
| final String content, final String category, final User user, |
| final Entity object, final String objectType, |
| final String objectName, final String objectContent, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return postGroupActivity(groupId, verb, title, content, category, user, |
| object, objectType, objectName, objectContent); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Post an activity to the stream. |
| * |
| * @param activity |
| * @return |
| */ |
| public ApiResponse postActivity(Activity activity) { |
| return createEntity(activity); |
| } |
| |
| /** |
| * Creates and posts an activity to a group. |
| * |
| * @param verb |
| * @param title |
| * @param content |
| * @param category |
| * @param user |
| * @param object |
| * @param objectType |
| * @param objectName |
| * @param objectContent |
| * @return |
| */ |
| public ApiResponse postActivity(String verb, String title, |
| String content, String category, User user, Entity object, |
| String objectType, String objectName, String objectContent) { |
| Activity activity = Activity.newActivity(this, verb, title, content, |
| category, user, object, objectType, objectName, objectContent); |
| return createEntity(activity); |
| } |
| |
| /** |
| * Get a group's activity feed. Returned as a query to ease paging. |
| * |
| * @return |
| */ |
| public Query queryActivity() { |
| Query q = queryEntitiesRequest(HTTP_METHOD_GET, null, null, |
| organizationId, applicationId, "activities"); |
| return q; |
| } |
| |
| |
| |
| /** |
| * Get a group's activity feed. Returned as a query to ease paging. |
| * |
| * @param groupId |
| * @return |
| */ |
| public Query queryActivityFeedForGroup(String groupId) { |
| Query q = queryEntitiesRequest(HTTP_METHOD_GET, null, null, |
| organizationId, applicationId, "groups", groupId, "feed"); |
| return q; |
| } |
| |
| /** |
| * Get a group's activity feed. Returned as a query to ease paging. Executes |
| * asynchronously in background and the callbacks are called in the UI |
| * thread. |
| * |
| * |
| * @param groupId |
| * @param callback |
| */ |
| public void queryActivityFeedForGroupAsync(final String groupId, |
| final QueryResultsCallback callback) { |
| (new ClientAsyncTask<Query>(callback) { |
| @Override |
| public Query doTask() { |
| return queryActivityFeedForGroup(groupId); |
| } |
| }).execute(); |
| } |
| |
| |
| /****************** ENTITY CONNECTIONS ***********************/ |
| /****************** ENTITY CONNECTIONS ***********************/ |
| |
| /** |
| * Connect two entities together. |
| * |
| * @param connectingEntityType The type of the first entity. |
| * @param connectingEntityId The ID of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param connectedEntityId The ID of the second entity. |
| * @return An instance with the server's response. |
| */ |
| public ApiResponse connectEntities(String connectingEntityType, |
| String connectingEntityId, String connectionType, |
| String connectedEntityId) { |
| return apiRequest(HTTP_METHOD_POST, null, null, organizationId, applicationId, |
| connectingEntityType, connectingEntityId, connectionType, |
| connectedEntityId); |
| } |
| |
| /** |
| * Connect two entities together |
| * |
| * @param connectorType The type of the first entity in the connection. |
| * @param connectorID The first entity's ID. |
| * @param connectionType The type of connection to make. |
| * @param connecteeType The type of the second entity. |
| * @param connecteeID The second entity's ID |
| * @return An instance with the server's response. |
| */ |
| public ApiResponse connectEntities(String connectorType, |
| String connectorID, |
| String connectionType, |
| String connecteeType, |
| String connecteeID) { |
| return apiRequest(HTTP_METHOD_POST, null, null, organizationId, applicationId, |
| connectorType, connectorID, connectionType, connecteeType, connecteeID); |
| } |
| |
| |
| /** |
| * Connect two entities together. Executes asynchronously in background and |
| * the callbacks are called in the UI thread. |
| * |
| * @param connectingEntityType The type of the first entity. |
| * @param connectingEntityId The UUID or 'name' property of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param connectedEntityId The UUID of the second entity. |
| * @param callback A callback with the async response. |
| */ |
| public void connectEntitiesAsync(final String connectingEntityType, |
| final String connectingEntityId, final String connectionType, |
| final String connectedEntityId, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return connectEntities(connectingEntityType, |
| connectingEntityId, connectionType, connectedEntityId); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Connect two entities together. Allows the 'name' of the connected entity |
| * to be specified but requires the type also be specified. Executes asynchronously |
| * in background and the callbacks are called in the UI thread. |
| * |
| * @param connectingEntityType The type of the first entity. |
| * @param connectingEntityId The UUID or 'name' property of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param connectedEntityType The type of connection between the entities. |
| * @param connectedEntityId The UUID or 'name' property of the second entity. |
| * @param callback A callback with the async response. |
| */ |
| public void connectEntitiesAsync(final String connectingEntityType, |
| final String connectingEntityId, final String connectionType, |
| final String connectedEntityType, final String connectedEntityId, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return connectEntities(connectingEntityType, |
| connectingEntityId, connectionType, connectedEntityType, connectedEntityId); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Disconnect two entities. |
| * |
| * @param connectingEntityType The collection name or UUID of the first entity. |
| * @param connectingEntityId The name or UUID of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param connectedEntityId The name or UUID of the second entity. |
| * @return An instance with the server's response. |
| */ |
| public ApiResponse disconnectEntities(String connectingEntityType, |
| String connectingEntityId, String connectionType, |
| String connectedEntityId) { |
| return apiRequest(HTTP_METHOD_DELETE, null, null, organizationId, applicationId, |
| connectingEntityType, connectingEntityId, connectionType, |
| connectedEntityId); |
| } |
| |
| /** |
| * Disconnect two entities. Executes asynchronously in background and the |
| * callbacks are called in the UI thread. |
| * |
| * @param connectingEntityType The collection name or UUID of the first entity. |
| * @param connectingEntityId The name or UUID of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param connectedEntityId The name or UUID of the second entity. |
| */ |
| public void disconnectEntitiesAsync(final String connectingEntityType, |
| final String connectingEntityId, final String connectionType, |
| final String connectedEntityId, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return disconnectEntities(connectingEntityType, |
| connectingEntityId, connectionType, connectedEntityId); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Disconnect two entities. |
| * |
| * @param connectingEntityType The collection name or UUID of the first entity. |
| * @param connectingEntityId The name or UUID of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param connectedEntityType The collection name or UUID of the second entity. |
| * @param connectedEntityId The name or UUID of the second entity. |
| * @return An instance with the server's response. |
| */ |
| public ApiResponse disconnectEntities(String connectingEntityType, |
| String connectingEntityId, String connectionType, |
| String connectedEntityType, String connectedEntityId) { |
| return apiRequest(HTTP_METHOD_DELETE, null, null, organizationId, applicationId, |
| connectingEntityType, connectingEntityId, connectionType, |
| connectedEntityType, connectedEntityId); |
| } |
| |
| /** |
| * Disconnect two entities. Executes asynchronously in background and the |
| * callbacks are called in the UI thread. |
| * |
| * @param connectingEntityType The collection name or UUID of the first entity. |
| * @param connectingEntityId The name or UUID of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param connectedEntityType The collection name or UUID of the second entity. |
| * @param connectedEntityId The name or UUID of the second entity. |
| * @param callback A callback with the async response. |
| */ |
| public void disconnectEntitiesAsync(final String connectingEntityType, |
| final String connectingEntityId, final String connectionType, |
| final String connectedEntityType, final String connectedEntityId, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return disconnectEntities(connectingEntityType, |
| connectingEntityId, connectionType, connectedEntityType, connectedEntityId); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Queries for entities connected with <em>connectionType</em> |
| * to the entity whose ID is <em>connectingEntityId</em>. Use the |
| * <em>ql</em> parameter to specify a query string for further |
| * filtering. |
| * |
| * @param connectingEntityType The type of the first entity. |
| * @param connectingEntityId The ID of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param ql The string (if any) that should follow the "ql" |
| * in the request URL |
| * @return |
| */ |
| public Query queryEntityConnections(String connectingEntityType, |
| String connectingEntityId, String connectionType, String ql) { |
| Map<String, Object> params = new HashMap<String, Object>(); |
| params.put("ql", ql); |
| Query q = queryEntitiesRequest(HTTP_METHOD_GET, params, null, |
| organizationId, applicationId, connectingEntityType, connectingEntityId, |
| connectionType); |
| return q; |
| } |
| |
| /** |
| * Queries for entities connected with <em>connectionType</em> |
| * to the entity whose ID is <em>connectingEntityId</em>. Use the |
| * <em>ql</em> parameter to specify a query string for further |
| * filtering. Executes asynchronously in background and |
| * the callbacks are called in the UI thread. |
| * |
| * @param connectingEntityType The type of the first entity. |
| * @param connectingEntityId The ID of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param ql The string (if any) that should follow the "ql" |
| * in the request URL |
| * @param callback A callback for the async response. |
| */ |
| public void queryEntityConnectionsAsync(String connectingEntityType, |
| String connectingEntityId, String connectionType, String ql, |
| QueryResultsCallback callback) { |
| Map<String, Object> params = new HashMap<String, Object>(); |
| params.put("ql", ql); |
| queryEntitiesRequestAsync(callback, HTTP_METHOD_GET, params, null, |
| getOrganizationId(), getApplicationId(), connectingEntityType, connectingEntityId, |
| connectionType); |
| } |
| |
| protected String makeLocationQL(float distance, double latitude, |
| double longitude, String ql) { |
| String within = String.format("within %d of %d , %d", distance, |
| latitude, longitude); |
| ql = ql == null ? within : within + " and " + ql; |
| return ql; |
| } |
| |
| /** |
| * Queries for entities connected with <em>connectionType</em> |
| * to the entity whose ID is <em>connectingEntityId</em> and |
| * within distance of a specific point. |
| * |
| * @param connectingEntityType The type of the first entity. |
| * @param connectingEntityId The ID of the first entity. |
| * @param connectionType The type of connection between the entities. |
| * @param distance The distance in meters from the specified latitude and |
| * longitude. |
| * @param latitude The latitude of the point from which to |
| * measure distance. |
| * @param longitude The longitude of the ponit from which to |
| * measure distance. |
| * @return An instance with the query results. |
| */ |
| public Query queryEntityConnectionsWithinLocation( |
| String connectingEntityType, String connectingEntityId, |
| String connectionType, float distance, float latitude, |
| float longitude, String ql) { |
| Map<String, Object> params = new HashMap<String, Object>(); |
| params.put("ql", makeLocationQL(distance, latitude, longitude, ql)); |
| Query q = queryEntitiesRequest(HTTP_METHOD_GET, params, null, organizationId, |
| applicationId, connectingEntityType, connectingEntityId, |
| connectionType); |
| return q; |
| } |
| |
| /** |
| * Queries for entities connected with <em>connectionType</em> |
| * to the entity whose ID is <em>connectingEntityId</em> and |
| * within distance of a specific point. Executes asynchronously in |
| * background and the callbacks are called in the UI thread. |
| * |
| * @param connectingEntityType The type of the first entity |
| * @param connectingEntityId The ID of the first entity |
| * @param connectionType The type of connection between the entities |
| * @param distance The distance in meters from the specified latitude and |
| * longitude |
| * @param location a Location object |
| * @param ql an optional query to add to the request |
| * @param callback A callback for the async response |
| */ |
| public void queryEntityConnectionsWithinLocationAsync( |
| String connectingEntityType, String connectingEntityId, |
| String connectionType, float distance, Location location, |
| String ql, QueryResultsCallback callback) { |
| Map<String, Object> params = new HashMap<String, Object>(); |
| params.put("ql", makeLocationQL(distance, location.getLatitude(), location.getLongitude(), ql)); |
| params.put("ql", ql); |
| queryEntitiesRequestAsync(callback, HTTP_METHOD_GET, params, null, |
| getOrganizationId(), getApplicationId(), connectingEntityType, connectingEntityId, |
| connectionType); |
| } |
| |
| /****************** MESSAGE QUEUES ***********************/ |
| /****************** MESSAGE QUEUES ***********************/ |
| |
| private String normalizeQueuePath(String path) { |
| return arrayToDelimitedString( |
| tokenizeToStringArray(path, "/", true, true), "/"); |
| } |
| |
| public ApiResponse postMessage(String path, Map<String, Object> message) { |
| return apiRequest(HTTP_METHOD_POST, null, message, organizationId, applicationId, |
| "queues", normalizeQueuePath(path)); |
| } |
| |
| public ApiResponse postMessage(String path, |
| List<Map<String, Object>> messages) { |
| return apiRequest(HTTP_METHOD_POST, null, messages, organizationId, applicationId, |
| "queues", normalizeQueuePath(path)); |
| } |
| |
| public enum QueuePosition { |
| START("start"), END("end"), LAST("last"), CONSUMER("consumer"); |
| |
| private final String shortName; |
| |
| QueuePosition(String shortName) { |
| this.shortName = shortName; |
| } |
| |
| static Map<String, QueuePosition> nameMap = new ConcurrentHashMap<String, QueuePosition>(); |
| |
| static { |
| for (QueuePosition op : EnumSet.allOf(QueuePosition.class)) { |
| if (op.shortName != null) { |
| nameMap.put(op.shortName, op); |
| } |
| } |
| } |
| |
| public static QueuePosition find(String s) { |
| if (s == null) { |
| return null; |
| } |
| return nameMap.get(s); |
| } |
| |
| @Override |
| public String toString() { |
| return shortName; |
| } |
| } |
| |
| public ApiResponse getMessages(String path, String consumer, UUID last, |
| Long time, Integer prev, Integer next, Integer limit, |
| QueuePosition pos, Boolean update, Boolean sync) { |
| Map<String, Object> params = new HashMap<String, Object>(); |
| if (consumer != null) { |
| params.put("consumer", consumer); |
| } |
| if (last != null) { |
| params.put("last", last); |
| } |
| if (time != null) { |
| params.put("time", time); |
| } |
| if (prev != null) { |
| params.put("prev", prev); |
| } |
| if (next != null) { |
| params.put("next", next); |
| } |
| if (limit != null) { |
| params.put("limit", limit); |
| } |
| if (pos != null) { |
| params.put("pos", pos.toString()); |
| } |
| if (update != null) { |
| params.put("update", update); |
| } |
| if (sync != null) { |
| params.put("synchronized", sync); |
| } |
| return apiRequest(HTTP_METHOD_GET, params, null, organizationId, applicationId, |
| "queues", normalizeQueuePath(path)); |
| } |
| |
| public ApiResponse addSubscriber(String publisherQueue, |
| String subscriberQueue) { |
| return apiRequest(HTTP_METHOD_POST, null, null, organizationId, applicationId, "queues", |
| normalizeQueuePath(publisherQueue), "subscribers", |
| normalizeQueuePath(subscriberQueue)); |
| } |
| |
| public ApiResponse removeSubscriber(String publisherQueue, |
| String subscriberQueue) { |
| return apiRequest(HTTP_METHOD_DELETE, null, null, organizationId, applicationId, |
| "queues", normalizeQueuePath(publisherQueue), "subscribers", |
| normalizeQueuePath(subscriberQueue)); |
| } |
| |
| private class QueueQuery implements Query { |
| final String httpMethod; |
| final Map<String, Object> params; |
| final Object data; |
| final String queuePath; |
| final ApiResponse response; |
| |
| private QueueQuery(ApiResponse response, String httpMethod, |
| Map<String, Object> params, Object data, String queuePath) { |
| this.response = response; |
| this.httpMethod = httpMethod; |
| this.params = params; |
| this.data = data; |
| this.queuePath = normalizeQueuePath(queuePath); |
| } |
| |
| private QueueQuery(ApiResponse response, QueueQuery q) { |
| this.response = response; |
| httpMethod = q.httpMethod; |
| params = q.params; |
| data = q.data; |
| queuePath = q.queuePath; |
| } |
| |
| /** |
| * @return the api response of the last request |
| */ |
| public ApiResponse getResponse() { |
| return response; |
| } |
| |
| /** |
| * @return true if the server indicates more results are available |
| */ |
| public boolean more() { |
| if ((response != null) && (response.getCursor() != null) |
| && (response.getCursor().length() > 0)) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Performs a request for the next set of results |
| * |
| * @return query that contains results and where to get more from. |
| */ |
| public Query next() { |
| if (more()) { |
| Map<String, Object> nextParams = null; |
| if (params != null) { |
| nextParams = new HashMap<String, Object>(params); |
| } else { |
| nextParams = new HashMap<String, Object>(); |
| } |
| nextParams.put("start", response.getCursor()); |
| ApiResponse nextResponse = apiRequest(httpMethod, nextParams, data, |
| queuePath); |
| return new QueueQuery(nextResponse, this); |
| } |
| return null; |
| } |
| |
| } |
| |
| public Query queryQueuesRequest(String httpMethod, |
| Map<String, Object> params, Object data, String queuePath) { |
| ApiResponse response = apiRequest(httpMethod, params, data, queuePath); |
| return new QueueQuery(response, httpMethod, params, data, queuePath); |
| } |
| |
| |
| /****************** COLLECTION MANAGEMENT ***********************/ |
| /****************** COLLECTION MANAGEMENT ***********************/ |
| |
| /** |
| * Gets a collection of type <em>type</em>. |
| * |
| * @param type The entity type to return in the collection. |
| * @return A collection of the specified type. |
| */ |
| public Collection getCollection(String type) |
| { |
| return getCollection(type,null); |
| } |
| |
| /** |
| * Gets a collection of type <em>type</em>, with entities |
| * filtered using a query string created from keys and values |
| * in <em>qs</em>. |
| * |
| * @param type The entity type to return in the collection. |
| * @param qs A query string specifying how to filter the entities |
| * included in the collection. |
| * @return A collection of the specified type. |
| */ |
| public Collection getCollection(String type,Map<String,Object> qs) |
| { |
| return new Collection(this,type,qs); |
| } |
| |
| /** |
| * Asynchronously gets a collection of type <em>type</em>, with entities |
| * filtered using a query string created from keys and values |
| * in <em>qs</em>. |
| * |
| * @param type The entity type to return in the collection. |
| * @param qs A query string specifying how to filter the entities |
| * included in the collection. |
| * @param callback A callback instance to use for the response. |
| */ |
| public void getCollectionAsync(final String type, final Map<String,Object> qs, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return getCollection(type, qs).fetch(); |
| } |
| }).execute(); |
| } |
| |
| |
| /****************** DEVICE ENTITY MANAGEMENT ***********************/ |
| /****************** DEVICE ENTITY MANAGEMENT ***********************/ |
| |
| /** |
| * Creates or updates a device entity using the provided deviceId, and saves the device model, |
| * device platform, and OS version in the entity. |
| * If an entity does not exist for the device, it is created with a UUID equal to deviceId. |
| * |
| * @param deviceId the device entity's UUID |
| * @param properties additional properties to save in the device entity. |
| * @return a Device object if success. Models the Usergrid device entity. |
| */ |
| public ApiResponse registerDevice(UUID deviceId, Map<String, Object> properties) { |
| assertValidApplicationId(); |
| if (properties == null) { |
| properties = new HashMap<String, Object>(); |
| } |
| properties.put("refreshed", System.currentTimeMillis()); |
| |
| // add device meta-data |
| properties.put("deviceModel", Build.MODEL); |
| properties.put("devicePlatform", "android"); |
| properties.put("deviceOSVersion", Build.VERSION.RELEASE); |
| |
| ApiResponse response = apiRequest(HTTP_METHOD_PUT, null, properties, |
| organizationId, applicationId, "devices", deviceId.toString()); |
| return response; |
| } |
| |
| /** |
| * Creates or updates a device entity using the provided deviceId, and saves the device model, |
| * device platform, and OS version in the entity. |
| * If an entity does not exist for the device, it is created with a UUID equal to deviceId. |
| * Executes asynchronously in background and the callbacks are called in the UI thread. |
| * |
| * @param deviceId the device entity's UUID |
| * @param properties additional properties to save in the device entity |
| * @param callback a DeviceRegistrationCallback to handle the async response |
| */ |
| public void registerDeviceAsync(final UUID deviceId, |
| final Map<String, Object> properties, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return registerDevice(deviceId, properties); |
| } |
| }).execute(); |
| } |
| |
| |
| /****************** EVENT ENTITY MANAGEMENT ***********************/ |
| /****************** EVENT ENTITY MANAGEMENT ***********************/ |
| |
| /** |
| * Creates an Event entity from properties specified in <em>mapEvent</em>. |
| * If no timestamp property value is provided, one is assigned by the server. |
| * |
| * @param mapEvent A Map instance whose keys are property names and values |
| * are property values. |
| * @return An API response from the server. |
| */ |
| public ApiResponse createEvent(Map<String,Object> mapEvent) |
| { |
| if (mapEvent != null) { |
| boolean needTypeSet = true; |
| |
| if (mapEvent.containsKey("type")) { |
| Object typeValue = mapEvent.get("type"); |
| if (typeValue != null) { |
| if (typeValue instanceof String) { |
| String typeValueString = (String) typeValue; |
| if (typeValueString.equals("event") || typeValueString.equals("events")) { |
| needTypeSet = false; |
| } |
| } |
| } |
| } |
| |
| if (needTypeSet) { |
| mapEvent.put("type", "events"); |
| } |
| |
| if (!mapEvent.containsKey("timestamp")) { |
| // let the server assign the timestamp |
| mapEvent.put("timestamp", "0"); |
| } |
| } |
| |
| return createEntity(mapEvent); |
| } |
| |
| /** |
| * Creates an Event entity from properties specified in <em>mapEvent</em> and |
| * using <em>timestamp</em> as the event's timestamp property value. |
| * |
| * @param mapEvent A Map instance whose keys are property names and values |
| * are property values. |
| * @param timestamp An instance with the event timestamp value. |
| * @return An API response from the server. |
| */ |
| public ApiResponse createEvent(Map<String,Object> mapEvent, Date timestamp) |
| { |
| if (mapEvent == null) { |
| mapEvent = new HashMap<String,Object>(); |
| } |
| |
| populateTimestamp(timestamp, mapEvent); |
| return createEvent(mapEvent); |
| } |
| |
| /** |
| * Creates an Event entity from properties specified in <em>mapEvent</em>, adding a |
| * counters property from values specified in <em>counterIncrement</em>. |
| * |
| * @param mapEvent The map containing property values for the new entity. |
| * @param counterIncrement An instance with a counter name and increment value. |
| * @return An API response from the server. |
| */ |
| public ApiResponse createEvent(Map<String,Object> mapEvent, CounterIncrement counterIncrement) |
| { |
| if (mapEvent == null) { |
| mapEvent = new HashMap<String,Object>(); |
| } |
| |
| populateTimestamp(null, mapEvent); |
| populateCounter(counterIncrement, mapEvent); |
| return createEvent(mapEvent); |
| } |
| |
| /** |
| * Asynchronously creates an Event entity from properties specified in <em>mapEvent</em>, |
| * adding a counters property from values specified in <em>counterIncrement</em>. |
| * |
| * @param mapEvent The map containing property values for the new entity. |
| * @param counterIncrement An instance with a counter name and increment value. |
| * @param callback The response callback. |
| */ |
| public void createEventAsync(final Map<String,Object> mapEvent, final CounterIncrement counterIncrement, final ApiResponseCallback callback) |
| { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return createEvent(mapEvent,counterIncrement); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Creates an Event entity from properties specified in <em>mapEvent</em> and |
| * using <em>timestamp</em> as the event's timestamp property value. This adds |
| * a counters property from values specified in <em>counterIncrement</em> |
| * |
| * @param mapEvent A Map instance whose keys are property names and values |
| * are property values. |
| * @param timestamp An instance with the event timestamp value. |
| * @param counterIncrement An instance with a counter name and increment value. |
| * @return An API response from the server. |
| */ |
| public ApiResponse createEvent(Map<String,Object> mapEvent, Date timestamp, CounterIncrement counterIncrement) |
| { |
| if (mapEvent == null) { |
| mapEvent = new HashMap<String,Object>(); |
| } |
| |
| populateTimestamp(timestamp, mapEvent); |
| populateCounter(counterIncrement, mapEvent); |
| return createEvent(mapEvent); |
| } |
| |
| /** |
| * Creates an Event entity from properties specified in <em>mapEvent</em> and |
| * using <em>timestamp</em> as the event's timestamp property value. This adds |
| * counters properties from values specified in <em>counterIncrements</em> |
| * |
| * @param mapEvent A Map instance whose keys are property names and values |
| * are property values. |
| * @param timestamp An instance with the event timestamp value. |
| * @param counterIncrements A list of instances with a counter name and increment value. |
| * @return An API response from the server. |
| */ |
| public ApiResponse createEvent(Map<String,Object> mapEvent, Date timestamp, List<CounterIncrement> counterIncrements) |
| { |
| if (mapEvent == null) { |
| mapEvent = new HashMap<String,Object>(); |
| } |
| |
| populateTimestamp(timestamp, mapEvent); |
| |
| if (counterIncrements != null) { |
| for (CounterIncrement counterIncrement : counterIncrements) { |
| populateCounter(counterIncrement, mapEvent); |
| } |
| } |
| |
| return createEvent(mapEvent); |
| } |
| |
| /** |
| * Adds the value of <em>timestamp</em> as the value of a timestamp |
| * key in <em>mapEvent</em>. |
| * |
| * @param timestamp The value that should be used for the timestamp key. |
| * @param mapEvent The map to which the timestamp key should be added. |
| */ |
| protected void populateTimestamp(Date timestamp, Map<String,Object> mapEvent) |
| { |
| if (timestamp != null) { |
| mapEvent.put("timestamp", "" + timestamp.getTime()); |
| } else { |
| // let the server assign the timestamp |
| mapEvent.put("timestamp", "0"); |
| } |
| } |
| |
| /** |
| * Adds the counter name and increment value from <em>counterIncrement</em> as the Map |
| * value of a "counters" key in <em>mapEvent</em>. If <em>counterIncrement</em> has no |
| * counter name, no key/value is added. |
| * |
| * @param counterIncrement An instance containing a counter name and increment value. |
| * @param mapEvent The map to which the counters key/value should be added. |
| */ |
| protected void populateCounter(CounterIncrement counterIncrement, Map<String,Object> mapEvent) |
| { |
| if ((counterIncrement != null) && (mapEvent != null)) { |
| String counterName = counterIncrement.getCounterName(); |
| if ((counterName != null) && (counterName.length() > 0)) { |
| Map<String, Object> mapCounters = null; |
| |
| Object existingCounters = mapEvent.get("counters"); |
| |
| if (existingCounters != null) { |
| if (existingCounters instanceof Map) { |
| try { |
| mapCounters = (Map<String,Object>) existingCounters; |
| } catch (Throwable t) { |
| mapCounters = null; |
| } |
| } |
| } |
| |
| if (null == mapCounters) { |
| mapCounters = new HashMap<String,Object>(); |
| } |
| |
| mapCounters.put(counterName, new Long(counterIncrement.getCounterIncrementValue())); |
| mapEvent.put("counters", mapCounters); |
| } |
| } |
| } |
| |
| /** |
| * Requests one or more counters |
| * |
| * @param counterArray an ArrayList of counter names to be retrieved |
| * @return an ApiResponse object |
| */ |
| public ApiResponse getCounters(ArrayList<String> counterArray) |
| { |
| String counters = null; |
| |
| if (counterArray != null) { |
| counters = "?counter=" + counterArray.get(0); |
| for (int i = 1; i < counterArray.size(); i++) { |
| counters += "&counter="; |
| counters += counterArray.get(i); |
| } |
| } |
| |
| return apiRequest(HTTP_METHOD_GET, // method |
| null, // params |
| null, // data |
| organizationId, |
| applicationId, |
| "counters", |
| counters); |
| } |
| |
| /** |
| * Asynchronously requests one or more counters |
| * |
| * @param type the entity type to be retrieved |
| * @param counterArray an ArrayList of counter names to be retrieved |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void getCountersAsync(final ArrayList<String> counterArray, |
| final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return getCounters(counterArray); |
| } |
| }).execute(); |
| } |
| |
| /** |
| * Requests one or more counters for a given time inteval and resolution, e.g. day, hour, etc. |
| * |
| * @param counterArray an ArrayList of counter names to be retrieved |
| * @param startTime a Date object specifying the start time to retrieve counter data for |
| * @param endTime a Date object specifying the end time to retrieve counter data for |
| * @param resolution the resolution of the result set. Results can be returned for the following: |
| * all, minute, five_minutes, half_hour, hour, day, six_day, week, month |
| * @param callback an ApiResponseCallback to handle the async response |
| * @return an ApiResponse object |
| */ |
| public ApiResponse getCountersForInterval(ArrayList<String> counterArray, |
| Date startTime, Date endTime, String resolution) |
| { |
| String counters = null; |
| |
| if (counterArray != null) { |
| counters = "?counter=" + counterArray.get(0); |
| for (int i = 1; i < counterArray.size(); i++) { |
| counters += "&counter="; |
| counters += counterArray.get(i); |
| } |
| |
| if (startTime != null) { |
| counters += "&start_time="; |
| counters += startTime.getTime(); |
| } |
| |
| if (endTime != null) { |
| counters += "&end_time="; |
| counters += endTime.getTime(); |
| } |
| |
| counters += "&resolution="; |
| counters += resolution; |
| } |
| |
| return apiRequest(HTTP_METHOD_GET, // method |
| null, // params |
| null, // data |
| organizationId, |
| applicationId, |
| "counters", |
| counters); |
| } |
| |
| /** |
| * Asynchronously requests one or more counters for a given time inteval and resolution, e.g. day, hour, etc. |
| * |
| * @param counterArray an ArrayList of counter names to be retrieved |
| * @param startTime a Date object specifying the start time to retrieve counter data for |
| * @param endTime a Date object specifying the end time to retrieve counter data for |
| * @param resolution the resolution of the result set. Results can be returned for the following: |
| * all, minute, five_minutes, half_hour, hour, day, six_day, week, month |
| * @param callback an ApiResponseCallback to handle the async response |
| */ |
| public void getCountersForIntervalAsync(final ArrayList<String> counterArray, final Date startTime, |
| final Date endTime, final String resolution, final ApiResponseCallback callback) { |
| (new ClientAsyncTask<ApiResponse>(callback) { |
| @Override |
| public ApiResponse doTask() { |
| return getCountersForInterval(counterArray, startTime, endTime, resolution); |
| } |
| }).execute(); |
| } |
| } |
| |
| |