package com.robotoworks.mechanoid.ops;
import java.util.ArrayList;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
public class OperationResult implements Parcelable {
public static final String EXTRA_BATCH_RESULTS = "OperationResult.BATCH_RESULTS";
/**
* Represents a code indicating the operation completely successfully a result Bundle.
*/
public static final int RESULT_OK = 0;
/**
* Represents a code indicating the operation completed with an error.
*/
public static final int RESULT_ERROR = 1;
private int mResultCode = RESULT_OK;
private Throwable mError = null;
private Bundle mResultData = null;
private Intent mRequest = null;
private boolean mIsBatch;
private ArrayList<OperationResult> mBatchResults = new ArrayList<OperationResult>();
private boolean mBatchResultsOk = true;
private Object mObject;
/**
* Better to call release object
* and get the result of that which
* will save you memory from the log
* @return
*/
@SuppressWarnings("unchecked")
public <T> T getObject() {
return (T)mObject;
}
@SuppressWarnings("unchecked")
public <T> T releaseObject() {
Object obj = mObject;
mObject = null;
return (T)obj;
}
public void setObject(Object obj) {
mObject = obj;
}
/**
* <p>Associate an error to this result, it is a good idea
* to also set the result code to {@link #RESULT_ERROR}</p>
*
* @param error the error to associate to this result
*/
public void setError(Throwable error) {
mError = error;
}
/**
* <p>Set the result code, usually either {@link #RESULT_ERROR} or
* {@link #RESULT_OK} should be used.</p>
* @param resultCode
*/
public void setCode(int resultCode) {
mResultCode = resultCode;
}
/**
* @return A result code, can be user defined or either {@link #RESULT_ERROR}
* or {@link #RESULT_OK}.
*/
public int getCode() {
return mResultCode;
}
/**
* @return Get the exception associated to this result, usually when the
* {@link #RESULT_ERROR} is used, can be null
*/
public Throwable getError() {
return mError;
}
public Bundle getData() {
return mResultData;
}
/**
* <p>Some arbitrary user defined data</p>
* @param resultData
*/
public void setData(Bundle resultData) {
mResultData = resultData;
mBatchResultsOk = true;
mIsBatch = false;
ArrayList<Bundle> results = mResultData.getParcelableArrayList(EXTRA_BATCH_RESULTS);
if(results != null && results.size() > 0) {
mIsBatch = true;
for(Bundle result : results) {
OperationResult r = OperationResult.fromBundle(result);
mBatchResults.add(r);
if(!r.isOk()) {
mBatchResultsOk = false;
}
}
}
}
/**
* @return true if the result code is {@link #RESULT_OK}, false otherwise
*/
public boolean isOk() {
if(isBatch()) {
return mBatchResultsOk;
} else {
return mResultCode == RESULT_OK;
}
}
public boolean isBatch() {
if(mResultData == null) {
return false;
};
return mIsBatch;
}
public void setRequest(Intent request) {
mRequest = request;
}
public Intent getRequest() {
return mRequest;
}
public static final Parcelable.Creator<OperationResult> CREATOR =
new Parcelable.Creator<OperationResult>() {
public OperationResult createFromParcel(Parcel in) {
return new OperationResult(in);
}
public OperationResult[] newArray(int size) {
return new OperationResult[size];
}
};
public OperationResult(int resultCode) {
mResultCode = resultCode;
}
private OperationResult(Parcel in) {
mResultCode = in.readInt();
mError = (Throwable) in.readSerializable();
mResultData = in.readBundle();
mRequest = in.readParcelable(null);
mIsBatch = in.readInt() > 0 ? true : false;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mResultCode);
dest.writeSerializable(mError);
dest.writeBundle(mResultData);
dest.writeParcelable(mRequest, 0);
dest.writeInt(mIsBatch ? 1 : 0);
}
/**
* <p>Create an error result, the result code
* will be set to {@link #RESULT_ERROR}.</p>
* @param error The error that occurred during the operation
* @return A result that represents an error result of an operation
*/
public static OperationResult error(Throwable error) {
OperationResult result = new OperationResult(RESULT_ERROR);
result.setError(error);
return result;
}
/**
* <p>Create an error result, the result code
* will be set to {@link #RESULT_ERROR}.</p>
* @param error The error that occurred during the operation
* @param data The bundle that should be used as the result bundle, this gives an opportunity
* to add arbitrary data to the result, must not be null
* @return A result that represents an error result of an operation
*/
public static OperationResult error(Throwable error, Bundle data) {
OperationResult result = new OperationResult(RESULT_ERROR);
result.setError(error);
result.setData(data);
return result;
}
/**
* <p>Create an operation result Bundle as an OK result, which should indicate
* that the operation was a success, the result code will be set to {@link #RESULT_OK}.</p>
* @return A result that represents an operation that completed successfully
*/
public static OperationResult ok() {
return new OperationResult(RESULT_OK);
}
/**
* <p>Create an operation result Bundle as an OK result, which should indicate
* that the operation was a success, the result code will be set to {@link #RESULT_OK}.</p>
* @param data The bundle that should be used as the result bundle, this gives an opportunity
* to add arbitrary data to the result, must not be null
* @return A result that represents an operation result that completed successfully
*/
public static OperationResult ok(Bundle data) {
if(data == null) {
throw new RuntimeException("bundle cannot be null");
}
OperationResult result = new OperationResult(RESULT_OK);
result.setData(data);
return result;
}
public Bundle toBundle() {
Bundle bundle = new Bundle();
bundle.putParcelable(OperationResult.class.getName(), this);
return bundle;
}
public static OperationResult fromBundle(Bundle bundle) {
bundle.setClassLoader(OperationResult.class.getClassLoader());
return bundle.getParcelable(OperationResult.class.getName());
}
public ArrayList<OperationResult> getBatchResults() {
return mBatchResults;
}
}