package com.jobmineplus.mobile.widgets; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Queue; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import com.jobmineplus.mobile.activities.jbmnpls.JbmnplsActivityBase; import com.jobmineplus.mobile.exceptions.JbmnplsCancelledException; import com.jobmineplus.mobile.exceptions.JbmnplsLoggedOutException; import com.jobmineplus.mobile.exceptions.JbmnplsLostStateException; import com.jobmineplus.mobile.exceptions.JbmnplsParsingException; import com.jobmineplus.mobile.widgets.table.SimpleHtmlParser; public abstract class JbmnplsRequestQueue<TProgress> { // Task Response states protected static final int NO_PROBLEM = 0; protected static final int UNKNOWN_COMMAND = 1; protected static final int LOGOUT_RESULT = 2; protected static final int LOST_STATE_RESULT = 3; protected static final int CANCELLED = 4; protected static final int PARSING_ERROR = 5; protected static final int INACTIVE_ERROR = 6; protected static final String LOST_STATE_STRING = "return to your most recent active page"; protected static final String EXCEPTION_STRING = "uw_exception.html"; protected final Queue<Task> taskQueue = new LinkedList<Task>(); private RequestTask currentTask; protected JbmnplsHttpClient client; private final String url; private final JbmnplsActivityBase activity; private final JbmnplsRequestQueue<TProgress> self; // Post Request States private String stateNum; private final String icsID; public JbmnplsRequestQueue(JbmnplsActivityBase a, JbmnplsHttpClient c, String postUrl, String stateNumber, String id) { url = postUrl; activity = a; self = this; client = c; stateNum = stateNumber; icsID = id; } // Accessors public int getCurrentCommand() { return currentTask != null ? currentTask.currentCommand : -1; } public boolean isRunning() { return currentTask != null ? currentTask.isRunning() : false; } public void cancelCurrent(boolean mayInterruptIfRunning) { if (currentTask != null) { currentTask.cancel(mayInterruptIfRunning); } } protected JbmnplsActivityBase getActivity() { return activity; } // Abstract Task Functions protected abstract Integer doInBackground(Integer...params) throws IOException; protected abstract boolean checkForInActivity(); // Optional Task Functions protected void onPreExecute() { } protected void onProgressUpdate(TProgress...values) { } protected void onPostExecute(Integer result) { } protected void onCancelled() { } protected void onCancelled(Integer result) { } // Public task methods public void addTask(int jobCode) { addTask(jobCode, null); } public void addTask(int jobCode, String message) { addTask(jobCode, message, null); } public void addTask(int jobCode, String message, int...moreData) { taskQueue.add(new Task(jobCode, message, moreData)); runTask(); } public void runTask() { if (!taskQueue.isEmpty() && (currentTask == null || !currentTask.isRunning())) { Task taskInfo = taskQueue.poll(); currentTask = new RequestTask(taskInfo.message); // Add extra data if exists Integer[] params = null; int[] extra = taskInfo.extraData; if (extra != null) { params = new Integer[extra.length + 1]; params[0] = taskInfo.jobCode; for (int i = 0; i < extra.length; i++) { params[i + 1] = extra[i]; } } else { params = new Integer[]{taskInfo.jobCode}; } currentTask.execute(params); } } public void cancelAllTasks() { taskQueue.clear(); if (currentTask != null) { currentTask.cancel(true); } } // Call these functions within doInBackground protected String doPost(String icAction, NameValuePair... moreData) throws JbmnplsLoggedOutException, IOException { return doPost(icAction, Arrays.asList(moreData)); } protected String doPost(String icAction, List<NameValuePair> moreData) throws JbmnplsLoggedOutException, IOException { String response = currentTask.response; // Create the post data final List<NameValuePair> postData = moreData != null ? new ArrayList<NameValuePair>(moreData) : new ArrayList<NameValuePair>(moreData); postData.add(new BasicNameValuePair("ICAction", icAction)); postData.add(new BasicNameValuePair("ICElementNum", "0")); postData.add(new BasicNameValuePair("ICAJAX", "1")); postData.add(new BasicNameValuePair("ICStateNum", stateNum)); postData.add(new BasicNameValuePair("ICSID", icsID)); // Do Post response = client.postJobmineHtml(postData, url); // Check response for authorization if (response == null) { throw new JbmnplsCancelledException(); } else if (response.contains(EXCEPTION_STRING)) { throw new JbmnplsParsingException("Jobmine threw an exception."); } else if (response.contains(LOST_STATE_STRING)) { throw new JbmnplsLostStateException(); } // Find the new state number SimpleHtmlParser parser = new SimpleHtmlParser(response); int startIndex = parser.skipText("ICStateNum", "="); int endIndex = response.indexOf(";", startIndex); if (endIndex == -1) { throw new JbmnplsParsingException("Cannot find state number"); } stateNum = response.substring(startIndex, endIndex); return response; } // Request Task that gets spawned by this class private final class RequestTask extends ProgressDialogAsyncTaskBase<Integer, TProgress, Integer> { private String response; private int currentCommand; public RequestTask(String message) { super(activity, message, message != null); } @Override protected void onPreExecute() { super.onPreExecute(); self.onPreExecute(); } @Override protected Integer doInBackground(Integer... params) { if (checkForInActivity()) { return INACTIVE_ERROR; } if (!client.verifyLogin()) { return LOGOUT_RESULT; } currentCommand = params[0]; Integer result = NO_PROBLEM; try { result = self.doInBackground(params); } catch (JbmnplsCancelledException e) { return CANCELLED; } catch (JbmnplsLoggedOutException e) { e.printStackTrace(); return LOGOUT_RESULT; } catch (JbmnplsLostStateException e) { e.printStackTrace(); return LOST_STATE_RESULT; } catch (JbmnplsParsingException e) { e.printStackTrace(); return PARSING_ERROR; } catch (IOException e) { e.printStackTrace(); return PARSING_ERROR; } return result; } @Override protected void onProgressUpdate(TProgress... values) { super.onProgressUpdate(values); self.onProgressUpdate(values); } @Override protected void onPostExecute(Integer result) { super.onPostExecute(result); self.onPostExecute(result); // Execute next task in the list runTask(); } @Override protected void onCancelled() { super.onCancelled(); self.onCancelled(); } @Override protected void onCancelled(Integer result) { super.onCancelled(result); self.onCancelled(result); } } private final class Task { public int jobCode; public String message; public int[] extraData; public Task(int code, String msg, int... data) { jobCode = code; message = msg; extraData = data; } } }