package ch.bfh.sokoban.db;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import ch.bfh.sokoban.lib.jsonJava.JSONArray;
import ch.bfh.sokoban.lib.jsonJava.JSONException;
import ch.bfh.sokoban.lib.jsonJava.JSONObject;
public class RequestSender
{
// local variables
// private static ArrayList<NameValuePair> nameValuePairs;
private static JSONArray jsonArray;
private static JSONObject jsonObject;
private static boolean hasInsertedId = false;
private static Cryptor cryptor = new Cryptor();
/**
* Connect to the given server and call the php - file <br/>
* returns the data which are send back from the server, in the Options - object <br/>
* @param options
* @throws LazyException
*/
public static void requestSend(Options options)
{
//Add elements for the php
addOptions(options);
hasInsertedId = options.hasInsertId();
readReturnValues(options.getLazyAnswer(), getDatabaseData(options.getLazyAnswer(), options.getScriptLocation()));
}
//Private Methodes
/**
* Add the database options for the php - file to a nameValuePair
*/
private static void addOptions(Options options)
{
jsonObject = new JSONObject();
jsonArray = new JSONArray();
try
{
jsonObject.put("query", options.getSql());
jsonObject.put("usesInsertId", Boolean.toString(options.hasInsertId()));
jsonArray.put(jsonObject);
}
catch (JSONException e)
{
options.getLazyAnswer().setError(true);
options.getLazyAnswer().setErrorMessage(e.getMessage());
e.printStackTrace();
}
}
/**
* Make a connection with the server and submit the nameValuePair - object, if the server returns a result, it's saved in an InputStream object, <br/>
* if there is no result, the input stream is null <br/>
* @param lazyAnswer <br/>
* @param scriptLocation <br/>
* @return the result from the server as an InputStream object or null, if there is no result from the server
* @throws LazyException
*/
private static InputStream getDatabaseData(LazyAnswer lazyAnswer, String scriptLocation)
{
InputStream inputStream = null;
// System.out.println("out: "+jsonObject.toString());
jsonObject = cryptor.jsonObjectEncrypt(jsonObject);
// System.out.println("out#: "+jsonObject.toString());
//http post
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(scriptLocation);
// add the given parameters to the httppost object
httppost.setHeader("json", jsonObject.toString());
httppost.getParams().setParameter("jsonpost", jsonArray);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
}
catch(Exception e)
{
lazyAnswer.setError(true);
lazyAnswer.setErrorMessage(e.toString());
lazyAnswer.setNetworkError(true);
}
return inputStream;
}
/**
* Reads the returns from the database in a JSONArray in the lazyAnswer - object <br/>
* @param lazyAnswer for the return value <br/>
* @param inputStream has the returns from the database <br/>
* @throws LazyException
*/
private static void readReturnValues(LazyAnswer lazyAnswer, InputStream inputStream)
{
JSONArray jsonArr = null;
if(!lazyAnswer.hasError() && inputStream != null )
{
//convert response to string
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"utf-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
String result = "";
while ((line = reader.readLine()) != null)
{
sb.append(line);
//System.out.println("line: "+line);
}
inputStream.close();
result=sb.toString();
if(!result.equals("") && result.length()>0 && result.indexOf("[") != -1)
{
result = result.substring(result.indexOf("["),result.length());
jsonArr = new JSONArray(result);
// System.out.println("in#: "+jsonArr.toString());
jsonArr = cryptor.jsonArrayDecrypt(jsonArr);
// System.out.println("in: "+jsonArr.toString());
}
else
{
lazyAnswer.setError(true);
lazyAnswer.setErrorMessage("The returned String is empty or doesn't contain a JSONArray");
}
}
catch(UnsupportedEncodingException e)
{
lazyAnswer.setError(true);
lazyAnswer.setErrorMessage(e.toString());
} catch (IOException e) {
lazyAnswer.setError(true);
lazyAnswer.setErrorMessage(e.getMessage());
}
}
setLazyAnswer(lazyAnswer, jsonArr);
}
/**
* Split the result from the database into the right result for the user <br />
* @param lazyAnswer in this object the answer is inserted <br />
* @param jsonArr in this object is the result from the database, as defined <br />
* {'exceptionFlag' => 'false','exceptionText' => '','insertId' => 'no insert id'} <br />
* {"id":"3","user":"12","article":"gold","quantity":"10"} <br />
* {"id":"4","user":"13","article":"b3","quantity":"5"} <br />
* {"id":"5","user":"15","article":"h7","quantity":"6"} <br />
* ...
*/
private static void setLazyAnswer(LazyAnswer lazyAnswer, JSONArray jsonArr)
{
JSONArray jsonAnswer = new JSONArray();
try
{
// Get the error message
JSONObject obj = jsonArr.getJSONObject(0);
lazyAnswer.setError(obj.getBoolean("exceptionFlag"));
if(lazyAnswer.hasError()) {
lazyAnswer.setErrorMessage(obj.getString("exceptionText"));
}
// Add the insertedId to the array if the user want it
if(hasInsertedId)
jsonAnswer.put(new JSONObject().put("insertedId", String.valueOf(obj.getInt("insertId"))));
for(int i = 1; i < jsonArr.length(); i++)
{
obj = jsonArr.getJSONObject(i);
jsonAnswer.put(obj);
}
}
catch(JSONException e)
{
lazyAnswer.setError(true);
lazyAnswer.setErrorMessage(e.getMessage());
}
catch(NullPointerException e)
{
/* Don't do anything, cause JSONObject is empty */
}
lazyAnswer.setReturn(jsonAnswer);
}
}