Created
November 11, 2013 14:16
-
-
Save diego-aslz/7413791 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package br.com.clouded.web.service.support; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.Date; | |
import java.util.List; | |
import org.apache.http.HttpResponse; | |
import org.apache.http.HttpStatus; | |
import org.apache.http.NameValuePair; | |
import org.apache.http.StatusLine; | |
import org.apache.http.client.ClientProtocolException; | |
import org.apache.http.client.HttpClient; | |
import org.apache.http.client.methods.HttpGet; | |
import org.apache.http.client.methods.HttpPost; | |
import org.apache.http.client.utils.URLEncodedUtils; | |
import org.apache.http.entity.StringEntity; | |
import org.apache.http.impl.client.DefaultHttpClient; | |
import org.apache.http.message.BasicNameValuePair; | |
import org.joda.time.DateTime; | |
import org.json.JSONArray; | |
import org.json.JSONException; | |
import br.com.clouded.droid.db.DBHelper; | |
import br.com.clouded.droid.gsonadapters.DateTimeTypeConverter; | |
import br.com.clouded.droid.models.specific.Server; | |
import br.com.clouded.droid.util.CloudroidSession; | |
import br.com.clouded.droid.util.CloudroidUtils; | |
import br.com.clouded.droid.util.SyncDateFormat; | |
import br.com.clouded.web.util.URLConsts; | |
import com.google.gson.Gson; | |
import com.google.gson.GsonBuilder; | |
/** | |
* Classe genérica de comunicação com o WEB Service. Cada serviço (especificação de {@link CloudedService }) se comunica com um, e apenas um, | |
* <i>controller</i> do servidor. Esta classe não pode ser instanciada, ela deve ser herdada e implementada. | |
* | |
* @author Diego Aguir Selzlein | |
* | |
*/ | |
public abstract class CloudedService<T> { | |
protected HttpClient httpclient = new DefaultHttpClient(); | |
protected Server server; | |
protected DBHelper dbHelper; | |
public CloudedService(DBHelper dbHelper, Server server) { | |
this.dbHelper = dbHelper; | |
this.server = server; | |
} | |
protected String stringFrom(HttpResponse response) throws IOException { | |
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
response.getEntity().writeTo(out); | |
out.close(); | |
return out.toString(); | |
} | |
/** | |
* Converte a resposta HTTP em um vetor de bytes. Este método foi criado para evitar repetição de código. | |
* @param response Resposta HTTP. | |
* @return Vetor de bytes da resposta. | |
* @throws IOException | |
* @throws JSONException | |
*/ | |
protected ByteArrayOutputStream bytesFrom(HttpResponse response) throws IOException { | |
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
response.getEntity().writeTo(out); | |
out.close(); | |
return out; | |
} | |
/** | |
* Método genérico que converte resposta HTTP recebida do servidor em um vetor de objetos JSON. | |
* Caso um objeto possua especificidades que devem ser tratadas, este método deve ser sobrescrito | |
* na classe que herda {@link CloudedService} para fazê-lo. | |
* @param response Resposta HTTP recebida do servidor. | |
* @return Vetor de objetos JSON. | |
* @throws IOException | |
* @throws JSONException | |
*/ | |
protected JSONArray arrayFrom(HttpResponse response) throws IOException, JSONException { | |
return new JSONArray(bytesFrom(response).toString()); | |
} | |
/** | |
* Deve ser implementado na classe que herda {@link CloudedService} para retornar o endereço do servidor | |
* de onde todos os objetos podem ser obtidos (correspondente à ação <i>index</i>. | |
* @param server Servidor de conexão. | |
* @return Endereço da ação <i>index</i> do <i>controller</i> correspondente a esta classe. | |
*/ | |
protected abstract String urlIndex(Server server); | |
/** | |
* Deve ser implementado na classe que herda {@link CloudedService} para retornar o endereço do servidor | |
* para criação de novos objetos (correspondente à ação <i>create</i>. | |
* @param server Servidor de conexão. | |
* @return Endereço da ação <i>create</i> do <i>controller</i> correspondente a esta classe. | |
*/ | |
protected String urlCreate(Server server) { | |
return null; | |
} | |
/** | |
* Deve ser implementado na classe que herda {@link CloudedService} para retornar o endereço do servidor | |
* de onde um o objeto pode ser obtido através de seu ID (correspondente à ação <i>show</i>. | |
* @param server Servidor de conexão. | |
* @param id ID do objeto cujo endereço deve ser retornado. | |
* @return Endereço da ação <i>show</i> do objeto de ID parametrizado do <i>controller</i> correspondente a esta classe. | |
*/ | |
protected abstract String urlGet(Server server, long id); | |
/** | |
* Obtém do servidor objeto com ID parametrizado. Autenticação será feita com o <i>token</i> do usuário corrente em {@link CloudroidSession}. | |
* @param server Servidor de conexão. | |
* @param id ID do objeto desejado | |
* @return Objeto obtido. | |
* @throws Exception | |
*/ | |
public T get(long id) throws Exception { | |
return get(id, CloudroidSession.getInstance().getCurrentUser().getToken()); | |
} | |
/** | |
* Obtém do servidor objeto com ID parametrizado. Autenticação será feita com o <i>token</i> parametrizado. | |
* @param server Servidor de conexão. | |
* @param id ID do objeto desejado | |
* @param token <i>Token</i> de autenticação do usuário. | |
* @return Objeto obtido. | |
* @throws IOException | |
* @throws ClientProtocolException | |
* @throws Exception | |
*/ | |
public T get(long id, String token) throws ClientProtocolException, IOException { | |
String uri = urlGet(server, id) + URLConsts.SUFIX + "?"; | |
List<NameValuePair> params = new ArrayList<NameValuePair>(); | |
addAuthParams(token, params); | |
uri += URLEncodedUtils.format(params, "utf-8"); | |
HttpGet get = new HttpGet(uri); | |
HttpResponse r = httpclient.execute(get); | |
StatusLine statusLine = r.getStatusLine(); | |
if (statusLine.getStatusCode() == HttpStatus.SC_OK) | |
return fromJSON(stringFrom(r)); | |
else | |
throw new RuntimeException("Erro de servidor. Por favor, contate os responsáveis" + | |
" pelo sistema."); | |
} | |
/** | |
* Obtém do servidor todos os objetos tratados por este serviço que foram atualizados a partir da data parametrizada. | |
* Autenticação será feita com o <i>token</i> parametrizado. | |
* @param server Servidor de conexão. | |
* @param base Data base para a busca. | |
* @param token <i>Token</i> de autenticação do usuário. | |
* @return | |
* @throws Exception | |
*/ | |
public List<T> index(Date base, String token) throws Exception { | |
SyncDateFormat df = new SyncDateFormat(); | |
String uri = urlIndex(server) + URLConsts.SUFIX + "?"; | |
List<NameValuePair> params = new ArrayList<NameValuePair>(); | |
addAuthParams(token, params); | |
params.add(new BasicNameValuePair("base", df.format(base))); | |
uri += URLEncodedUtils.format(params, "utf-8"); | |
HttpGet get = new HttpGet(uri); | |
HttpResponse r = httpclient.execute(get); | |
StatusLine statusLine = r.getStatusLine(); | |
if (statusLine.getStatusCode() == HttpStatus.SC_OK) { | |
List<T> result = new ArrayList<T>(); | |
JSONArray ar = arrayFrom(r); | |
for (int i = 0; i < ar.length(); i++) | |
result.add(fromJSON(ar.getJSONObject(i).toString())); | |
return result; | |
} else | |
throw new Exception("Erro de servidor. Por favor, contate os responsáveis" + | |
" pelo sistema."); | |
} | |
protected void addAuthParams(String token, List<NameValuePair> params) { | |
params.add(new BasicNameValuePair("auth", token)); | |
params.add(new BasicNameValuePair("device", CloudroidUtils.getDeviceId())); | |
} | |
public T create(T t, String token) throws Exception { | |
String uri = urlCreate(server) + URLConsts.SUFIX + "?"; | |
List<NameValuePair> params = new ArrayList<NameValuePair>(); | |
addAuthParams(token, params); | |
uri += URLEncodedUtils.format(params, "utf-8"); | |
HttpPost post = new HttpPost(uri); | |
post.setHeader("Accept", "application/json"); | |
post.setHeader("Content-type", "application/json"); | |
post.setEntity(new StringEntity(toJson(t))); | |
HttpResponse r = httpclient.execute(post); | |
StatusLine statusLine = r.getStatusLine(); | |
if (statusLine.getStatusCode() == HttpStatus.SC_CREATED) { | |
return fromJSON(stringFrom(r)); | |
} else | |
throw new Exception("Erro de servidor. Por favor, contate os responsáveis" + | |
" pelo sistema."); | |
} | |
/** | |
* Deve ser implementado na classe que especializa {@link CloudedService} para retornar uma nova instância do objeto tratado por ela. | |
* @return Novo objeto da classe tratada por este serviço. | |
*/ | |
protected abstract T newObject(); | |
/** | |
* Retorna a classe a qual o serviço trata. | |
* @return | |
*/ | |
public abstract Class<T> getClazz(); | |
/** | |
* Deve ser sobrescrito nos serviços que herdam deste para personalizar a geração do JSON | |
* do objeto. | |
* @param builder | |
* @return | |
*/ | |
public Gson writeGsonAdapters(GsonBuilder builder) { | |
builder.registerTypeAdapter(DateTime.class, new DateTimeTypeConverter()); | |
return builder.create(); | |
} | |
/** | |
* Converte o objeto parametrizado em JSON. | |
* @param t | |
* @return | |
*/ | |
public String toJson(T t) { | |
Gson gson = writeGsonAdapters(new GsonBuilder()); | |
return gson.toJson(t); | |
} | |
/** | |
* Carrega objeto a partir de uma String JSON. | |
* @param model | |
* @param json | |
* @return | |
*/ | |
public T fromJSON(String json) { | |
Gson gson = writeGsonAdapters(new GsonBuilder()); | |
return gson.fromJson(json, getClazz()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment