/** * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. * * You are hereby granted a non-exclusive, worldwide, royalty-free license to use, * copy, modify, and distribute this software in source code or binary form for use * in connection with the web services and APIs provided by Facebook. * * As with any software that integrates with the Facebook platform, your use of * this software is subject to the Facebook Developer Principles and Policies * [http://developers.facebook.com/policy/]. This copyright notice shall be * included in all copies or substantial portions of the software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.facebook; import android.os.Handler; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; /** * RequestBatch contains a list of Request objects that can be sent to Facebook in a single * round-trip. */ public class GraphRequestBatch extends AbstractList<GraphRequest> { private static AtomicInteger idGenerator = new AtomicInteger(); private Handler callbackHandler; private List<GraphRequest> requests = new ArrayList<GraphRequest>(); private int timeoutInMilliseconds = 0; private final String id = Integer.valueOf(idGenerator.incrementAndGet()).toString(); private List<Callback> callbacks = new ArrayList<Callback>(); private String batchApplicationId; /** * Constructor. Creates an empty batch. */ public GraphRequestBatch() { this.requests = new ArrayList<GraphRequest>(); } /** * Constructor. * @param requests the requests to add to the batch */ public GraphRequestBatch(Collection<GraphRequest> requests) { this.requests = new ArrayList<GraphRequest>(requests); } /** * Constructor. * @param requests the requests to add to the batch */ public GraphRequestBatch(GraphRequest... requests) { this.requests = Arrays.asList(requests); } /** * Constructor. * @param requests the requests to add to the batch */ public GraphRequestBatch(GraphRequestBatch requests) { this.requests = new ArrayList<GraphRequest>(requests); this.callbackHandler = requests.callbackHandler; this.timeoutInMilliseconds = requests.timeoutInMilliseconds; this.callbacks = new ArrayList<Callback>(requests.callbacks); } /** * Gets the timeout to wait for responses from the server before a timeout error occurs. * @return the timeout, in milliseconds; 0 (the default) means do not timeout */ public int getTimeout() { return timeoutInMilliseconds; } /** * Sets the timeout to wait for responses from the server before a timeout error occurs. * @param timeoutInMilliseconds the timeout, in milliseconds; 0 means do not timeout */ public void setTimeout(int timeoutInMilliseconds) { if (timeoutInMilliseconds < 0) { throw new IllegalArgumentException("Argument timeoutInMilliseconds must be >= 0."); } this.timeoutInMilliseconds = timeoutInMilliseconds; } /** * Adds a batch-level callback which will be called when the entire batch has finished * executing. * * @param callback the callback */ public void addCallback(Callback callback) { if (!callbacks.contains(callback)) { callbacks.add(callback); } } /** * Removes a batch-level callback. * * @param callback the callback */ public void removeCallback(Callback callback) { callbacks.remove(callback); } @Override public final boolean add(GraphRequest request) { return requests.add(request); } @Override public final void add(int location, GraphRequest request) { requests.add(location, request); } @Override public final void clear() { requests.clear(); } @Override public final GraphRequest get(int i) { return requests.get(i); } @Override public final GraphRequest remove(int location) { return requests.remove(location); } @Override public final GraphRequest set(int location, GraphRequest request) { return requests.set(location, request); } @Override public final int size() { return requests.size(); } final String getId() { return id; } final Handler getCallbackHandler() { return callbackHandler; } final void setCallbackHandler(Handler callbackHandler) { this.callbackHandler = callbackHandler; } final List<GraphRequest> getRequests() { return requests; } final List<Callback> getCallbacks() { return callbacks; } /** * Getter for the batch application id. * @return the batch application id. */ final public String getBatchApplicationId() { return batchApplicationId; } /** * Setter for the batch application id. * @param batchApplicationId The batch application id. */ final public void setBatchApplicationId(String batchApplicationId) { this.batchApplicationId = batchApplicationId; } /** * Executes this batch on the current thread and returns the responses. * <p/> * This should only be used if you have transitioned off the UI thread. * * @return a list of Response objects representing the results of the requests; responses are * returned in the same order as the requests were specified. * @throws FacebookException If there was an error in the protocol used to communicate * with the service * @throws IllegalArgumentException if the passed in RequestBatch is empty * @throws NullPointerException if the passed in RequestBatch or any of its contents are * null */ public final List<GraphResponse> executeAndWait() { return executeAndWaitImpl(); } /** * Executes this batch asynchronously. This function will return immediately, and the batch will * be processed on a separate thread. In order to process results of a request, or determine * whether a request succeeded or failed, a callback must be specified (see * {@link GraphRequest#setCallback(GraphRequest.Callback)}) * <p/> * This should only be called from the UI thread. * * @return a RequestAsyncTask that is executing the request * * @throws IllegalArgumentException if this batch is empty * @throws NullPointerException if any of the contents of this batch are null */ public final GraphRequestAsyncTask executeAsync() { return executeAsyncImpl(); } /** * Specifies the interface that consumers of the RequestBatch class can implement in order to be * notified when the entire batch completes execution. It will be called after all per-Request * callbacks are called. */ public interface Callback { /** * The method that will be called when a batch completes. * * @param batch the RequestBatch containing the Requests which were executed */ void onBatchCompleted(GraphRequestBatch batch); } /** * Specifies the interface that consumers of the RequestBatch class can implement in order to be * notified when the batch makes progress. The frequency of the callbacks can be controlled * using {@link FacebookSdk#setOnProgressThreshold(long)}. */ public interface OnProgressCallback extends Callback { /** * The method that will be called when a batch makes progress. * * @param batch the RequestBatch containing the Requests which were executed * @param current the current value of the progress * @param max the max (target) value of the progress */ void onBatchProgress(GraphRequestBatch batch, long current, long max); } List<GraphResponse> executeAndWaitImpl() { return GraphRequest.executeBatchAndWait(this); } GraphRequestAsyncTask executeAsyncImpl() { return GraphRequest.executeBatchAsync(this); } }