/*
* Copyright (C) 2012 Eyal LEZMY (http://www.eyal.fr)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.eyal.lib.data.service.model;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Parcel;
import android.os.Parcelable;
import fr.eyal.lib.data.communication.rest.ParameterMap;
import fr.eyal.lib.data.service.ServiceHelper;
/**
* @author Eyal LEZMY
*/
public class DataLibRequest implements Parcelable{
public static final String TAG = "DataLibRequest";
//request's options
/**
* No option
*/
public static final int OPTION_NO_OPTION = 0x00000000;
/**
* Ask to conserve the cookies sent by the server
*/
public static final int OPTION_CONSERVE_COOKIE_ENABLED = 0x00000002;
/**
* Ask to NOT conserve the cookies sent by the server
*/
public static final int OPTION_CONSERVE_COOKIE_DISABLED = 0x00000001;
/**
* Ask to use the Parcelable method to send the information between the DataLibService
* and the ServiceHelper.
*/
public static final int OPTION_SEND_WITH_PARCELABLE_ENABLED = 0x00000200;
/**
* Ask to NOT use the Parcelable method to send the information between the DataLibService
* and the ServiceHelper.
*/
public static final int OPTION_SEND_WITH_PARCELABLE_DISABLED = 0x00000100;
/**
* Ask to NOT use the database to store the BusinessObjects.
* In this case the request option OPTION_SEND_WITH_PARCELABLE is also enabled.
*/
public static final int OPTION_DATABASE_CACHE_DISABLED = 0x00000010 | OPTION_SEND_WITH_PARCELABLE_ENABLED;
/**
* Ask to use the database to store the BusinessObjects.
*/
public static final int OPTION_DATABASE_CACHE_ENABLED = 0x00000020;
/**
* Ask to use a HttpRequest that will not check the host for a https connection
* <b>Not implemented yet</b>
*/
public static final int OPTION_HOST_VERIFIER_ENABLED = 0x00002000;
/**
* Ask to use a HttpRequest that will check the host for a https connection
* <b>Not implemented yet</b>
*/
public static final int OPTION_HOST_VERIFIER_DISABLED = 0x00001000;
/**
* Ask to add the the response result to the {@link ServiceHelper} cache
* <b>For now the helper cache is always enabled</b>
*/
public static final int OPTION_HELPER_CACHE_ENABLED = 0x00020000;
/**
* Ask to NOT add the the response result to the {@link ServiceHelper} cache
* <b>Not implemented yet, for now the helper cache is always enabled</b>
*/
public static final int OPTION_HELPER_CACHE_DISABLED = 0x00010000;
/**
* Ask to run the listener's callback on the UI Thread
* <b>Not implemented yet, for now the helper cache is always enabled</b>
*/
public static final int OPTION_RESPONSE_ON_UI_THREAD_ENABLED = 0x00200000;
/**
* Ask to <b>NOT</b> run the listener's callback on the UI Thread
* <b>Not implemented yet, for now the helper cache is always enabled</b>
*/
public static final int OPTION_RESPONSE_ON_UI_THREAD_DISABLED = 0x00100000;
/**
* Ask to not use the database to store the BusinessObjects. In this case the request
* option OPTION_SEND_WITH_PARCELABLE is also enabled.
*/
public static final int PARSE_TYPE_SAX_XML = 1;
/**
* Ask to use the Parcelable method to send the information between the DataLibService
* and the ServiceHelper.
*/
public static final int PARSE_TYPE_JSON_OBJECT = 2;
/**
* Ask to use the Parcelable method to send the information between the DataLibService
* and the ServiceHelper.
*/
public static final int PARSE_TYPE_IMAGE = 3;
//HTTP request type
public static final int HTTP_REST_GET = 0;
public static final int HTTP_REST_PUT = 1;
public static final int HTTP_REST_POST = 2;
public static final int HTTP_REST_DELETE = 3;
public static final int HTTP_REST_HEAD = 4;
/**
* Host to contact
*/
public String url;
/**
* Path of the request
*/
public String path;
/**
* parameters to send
*/
public ParameterMap params;
/**
* useragent to send to the distant server
*/
public String userAgent;
/**
* Intent recu du ServiceHelper
*/
public Intent intent;
/**
* Request options
*/
public int option;
/**
* An HashMap containing all the complex options of the request
*/
public ComplexOptions complexOptions;
/**
* request type (REST_GET, REST_POST, ..., SOAP)
*/
public int requestMethod;
/**
* Format expected from the webservice (XML, JSON, IMAGE, ...)
*/
public int parseType;
/**
* content type of the data to send
*/
public String contentType;
/**
* data to send (for PUT or POST request)
*/
public byte[] data;
/**
* The application's context of execution
*/
public Context context;
public DataLibRequest() {
option = OPTION_NO_OPTION;
parseType = PARSE_TYPE_SAX_XML;
}
public DataLibRequest(String url, ParameterMap params) {
this();
this.url = url;
this.params = params;
}
public DataLibRequest(String url, ParameterMap params, ComplexOptions options) {
this(url, params);
complexOptions = options;
}
/**
* This function tells if the DataLibRequest ask to conserve the cookie returned by the server.<br>
* If it is not specified, the option is considered as disabled.
*
* @return return true if the cookie have to be conserved or false if not
*/
public boolean isConservingTheCookies() {
return ((option & OPTION_CONSERVE_COOKIE_ENABLED) == OPTION_CONSERVE_COOKIE_ENABLED);
}
/**
* This function tells if it has been defined a specific behavior for the conserve the cookie option
*
* @return return true if a behavior is defined, false if not
*/
public boolean isDefinedBehaviorConservingTheCookies() {
return ((option & (OPTION_CONSERVE_COOKIE_ENABLED | OPTION_CONSERVE_COOKIE_DISABLED)) != 0);
}
/**
* This function tells if the DataLibRequest ask to not use the database to store
* the BusinessObjects.
* If its true, the request option OPTION_SEND_WITH_PARCELABLE is also enabled and the function
* isParcelableMethodEnabled return also true.<br>
* If it is not specified, the option is considered as enabled.
*
* @return return true if no data is stored
*/
public boolean isDatabaseCacheEnabled() {
return ((option & OPTION_DATABASE_CACHE_DISABLED) != OPTION_DATABASE_CACHE_DISABLED);
}
/**
* This function tells if the DataLibRequest ask to not use the database to store
* the BusinessObjects.
* If its true, the request option OPTION_SEND_WITH_PARCELABLE is also enabled and the function
* isParcelableMethodEnabled return also true.
*
* @return return true if a behavior is defined, false if not
*/
public boolean isDefinedBehaviorDatabaseCache() {
return ((option & (OPTION_DATABASE_CACHE_DISABLED | OPTION_DATABASE_CACHE_ENABLED)) != 0);
}
/**
* This function tells if the DataLibRequest ask to use the Parcelable method
* to send the information between the DataLibService and the ServiceHelper.<br>
* If it is not specified, the option is considered as disabled.
*
* @return return true if no data is stored
*/
public boolean isParcelableMethodEnabled() {
return ((option & OPTION_SEND_WITH_PARCELABLE_ENABLED) == OPTION_SEND_WITH_PARCELABLE_ENABLED);
}
/**
* This function tells if the DataLibRequest ask to use the Parcelable method
* to send the information between the DataLibService and the ServiceHelper
*
* @return return true if no data is stored
*/
public boolean isDefinedBehaviorParcelableMethod() {
return ((option & (OPTION_SEND_WITH_PARCELABLE_ENABLED | OPTION_SEND_WITH_PARCELABLE_DISABLED)) != 0);
}
/**
* This function tells if the DataLibRequest ask to disable the host verifier<br>
* If it is not specified, the option is considered as disabled.
*
* @return return true if the host verifier is enabled, false if not
*/
public boolean isHostVerifierEnabled() {
return ((option & OPTION_HOST_VERIFIER_ENABLED) == OPTION_HOST_VERIFIER_ENABLED);
}
/**
* This function tells if a behavior is defined for the host verifier
*
* @return return true if a behavior is defined, false if not
*/
public boolean isDefinedBehaviorHostVerifier() {
return ((option & (OPTION_HOST_VERIFIER_ENABLED | OPTION_HOST_VERIFIER_DISABLED)) != 0);
}
/**
* This function tells if the DataLibRequest ask to enable the {@link ServiceHelper} responses cache<br>
* If it is not specified, the option is considered as disabled.
*
* @return return true if it is enabled
*/
public boolean isServiceHelperCacheEnabled() {
return ((option & OPTION_HELPER_CACHE_ENABLED) == OPTION_HELPER_CACHE_ENABLED);
}
/**
* This function tells if a behavior is defined for the {@link ServiceHelper} responses cache
*
* @return return true if a behavior is defined, false if not
*/
public boolean isDefinedBehaviorServiceHelperCache() {
return ((option & (OPTION_HELPER_CACHE_ENABLED | OPTION_HELPER_CACHE_DISABLED)) != 0);
}
/**
* This function tells if the DataLibRequest has a specific option recorded
*
* @return return true if there is at least one option
*/
public boolean hasOptionEnabled() {
return (option != OPTION_NO_OPTION);
}
/**
* This function tells if the listener's callback has to been run on the UI Thread.<br>
* If it is not specified, the option is considered as disabled.
*
* @return return true if the listener's callback has to been run on the UI Thread
*/
public boolean isResponseRunningOnUIThread() {
return ((option & OPTION_RESPONSE_ON_UI_THREAD_ENABLED) == OPTION_RESPONSE_ON_UI_THREAD_ENABLED);
}
/**
* This function tells if a behavior is defined for the the listener's callback has to been run on the UI Thread.
*
* @return return true if a behavior is defined, false if not
*/
public boolean isDefinedResponseRunningOnUIThread() {
return ((option & (OPTION_RESPONSE_ON_UI_THREAD_ENABLED | OPTION_HELPER_CACHE_DISABLED)) != 0);
}
/**
* Compute the fingerprint of the request. This function is use when you want to compare this request with another
*
* @param keys the list of parameter you want to define as keys for the fingerprint
*
* @return returns the fingerprint of the request.
*/
public String getFingerprint(String[] keys) {
//assembling the data
StringBuilder builder = new StringBuilder();
builder.append(url);
builder.append(path);
builder.append(params.urlEncode(keys));
builder.append(userAgent);
builder.append(requestMethod);
builder.append(contentType);
builder.append(data);
//create the MD5 hash
MessageDigest digester;
try {
String finger = builder.toString();
byte[] bytes = finger.getBytes();
digester = MessageDigest.getInstance("MD5");
digester.update(bytes);
byte[] digest = digester.digest();
//create hexadecimal String
builder.setLength(0);
for (int i = 0; i < digest.length; i++)
builder.append(Integer.toHexString(0xFF & digest[i]));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return builder.toString();
}
/**
* Get the filename of the request
*
* @return the file name contained on the path
*/
public String getRequestFileName(){
String[] elements = url.split("/");
//we return the last element of the path
return elements[elements.length-1];
}
/**
* Inner class that contains the masks to filter the {@link DataLibRequest#option} variable
*
* @author Eyal
*
*/
public class Mask {
/**
* Ask to conserve the cookies sent by the server
*/
public static final int OPTION_CONSERVE_COOKIE = OPTION_CONSERVE_COOKIE_ENABLED | OPTION_CONSERVE_COOKIE_DISABLED;
/**
* Ask to use the Parcelable method to send the information between the DataLibService
* and the ServiceHelper.
*/
public static final int OPTION_SEND_WITH_PARCELABLE = DataLibRequest.OPTION_SEND_WITH_PARCELABLE_ENABLED;
/**
* Ask to NOT use the database to store the BusinessObjects.
* In this case the request option OPTION_SEND_WITH_PARCELABLE is also enabled.
*/
public static final int OPTION_DATABASE_CACHE = OPTION_DATABASE_CACHE_ENABLED | OPTION_DATABASE_CACHE_DISABLED;
/**
* Ask to use a HttpRequest that will not check the host for a https connection
* <b>Not implemented yet</b>
*/
public static final int OPTION_HOST_VERIFIER = OPTION_HOST_VERIFIER_ENABLED | OPTION_HOST_VERIFIER_DISABLED;
/**
* Ask to add the response result to the {@link ServiceHelper} cache
* <b>Not implemented yet</b>
*/
public static final int OPTION_HELPER_CACHE = OPTION_HELPER_CACHE_ENABLED | OPTION_HELPER_CACHE_DISABLED;
/**
* Ask to run the response listener's callback on the UI Thread
*/
public static final int OPTION_RESPONSE_ON_UI_THREAD = OPTION_RESPONSE_ON_UI_THREAD_ENABLED | OPTION_RESPONSE_ON_UI_THREAD_DISABLED;
}
/**
* PARCELABLE MANAGMENT
*/
public static final Parcelable.Creator<DataLibRequest> CREATOR = new Parcelable.Creator<DataLibRequest>() {
@Override
public DataLibRequest createFromParcel(final Parcel in) {
return new DataLibRequest(in);
}
@Override
public DataLibRequest[] newArray(final int size) {
return new DataLibRequest[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(final Parcel dest, final int flags) {
dest.writeString(url);
dest.writeString(path);
dest.writeParcelable(params, PARCELABLE_WRITE_RETURN_VALUE);
dest.writeString(userAgent);
dest.writeParcelable(intent, PARCELABLE_WRITE_RETURN_VALUE);
dest.writeInt(option);
dest.writeParcelable(complexOptions, PARCELABLE_WRITE_RETURN_VALUE);
dest.writeInt(requestMethod);
dest.writeInt(parseType);
dest.writeString(contentType);
dest.writeByteArray(data);
}
public DataLibRequest(final Parcel in) {
url = in.readString();
path = in.readString();
params = in.readParcelable(ParameterMap.class.getClassLoader());
userAgent = in.readString();
intent = in.readParcelable(Intent.class.getClassLoader());
option = in.readInt();
complexOptions = in.readParcelable(ComplexOptions.class.getClassLoader());
requestMethod = in.readInt();
parseType = in.readInt();
contentType = in.readString();
in.readByteArray(data);
}
}