Implementing workflow run from external storage
Project: http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/commit/ca95c34a Tree: http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/tree/ca95c34a Diff: http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/diff/ca95c34a Branch: refs/heads/master Commit: ca95c34a1e51c1a2a401d4618e3258f6b2c091c4 Parents: 9c895c8 Author: larrytech7 <larrya...@gmail.com> Authored: Sat Jul 11 17:36:40 2015 +0100 Committer: larrytech7 <larrya...@gmail.com> Committed: Sat Jul 11 17:36:40 2015 +0100 ---------------------------------------------------------------------- .../activities/DashboardMainActivity.java | 2 + .../fragments/workflowdetails/RunFragment.java | 12 +- .../workflowdetails/WorkflowdetailFragment.java | 83 +----- .../apache/taverna/mobile/utils/RunTask.java | 93 ++++++ .../taverna/mobile/utils/WorkflowOpen.java | 289 +++++++++++++++++++ 5 files changed, 403 insertions(+), 76 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/ca95c34a/app/src/main/java/org/apache/taverna/mobile/activities/DashboardMainActivity.java ---------------------------------------------------------------------- diff --git a/app/src/main/java/org/apache/taverna/mobile/activities/DashboardMainActivity.java b/app/src/main/java/org/apache/taverna/mobile/activities/DashboardMainActivity.java index e5f245b..8a90059 100644 --- a/app/src/main/java/org/apache/taverna/mobile/activities/DashboardMainActivity.java +++ b/app/src/main/java/org/apache/taverna/mobile/activities/DashboardMainActivity.java @@ -54,6 +54,7 @@ import org.apache.taverna.mobile.R; import org.apache.taverna.mobile.fragments.FavoriteFragment; import org.apache.taverna.mobile.fragments.NavigationDrawerFragment; import org.apache.taverna.mobile.fragments.WorkflowItemFragment; +import org.apache.taverna.mobile.utils.WorkflowOpen; import java.io.File; @@ -168,6 +169,7 @@ public class DashboardMainActivity extends ActionBarActivity if(requestCode == SELECT_WORKFLOW){ String workflowPath = data.getData().getPath(); Toast.makeText(getBaseContext(), "Path: "+workflowPath, Toast.LENGTH_LONG).show(); + new WorkflowOpen(this).execute(workflowPath); } } } http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/ca95c34a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/RunFragment.java ---------------------------------------------------------------------- diff --git a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/RunFragment.java b/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/RunFragment.java index a55eed6..3b232c3 100644 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/RunFragment.java +++ b/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/RunFragment.java @@ -96,6 +96,12 @@ public class RunFragment extends Fragment implements View.OnClickListener{ } @Override + public void onPause() { + super.onPause(); + getActivity().finish(); + } + + @Override public void onResume() { super.onResume(); String runresult = getActivity().getIntent().getStringExtra("runresult"); @@ -147,12 +153,14 @@ public class RunFragment extends Fragment implements View.OnClickListener{ reloadRunResult(); return true; } + if(id == android.R.id.home){ + getActivity().finish(); + } return super.onOptionsItemSelected(item); } private void reloadRunResult(){ - //TODO reload the run results when refreshed Timer t = new Timer(); t.scheduleAtFixedRate(new RunTimerTask(getActivity(), run_id), 0, 5000); } @@ -163,7 +171,7 @@ public class RunFragment extends Fragment implements View.OnClickListener{ } public void updateRun(final JSONObject runInfo){ - + if(null != runInfo) getActivity().runOnUiThread(new Runnable() { @Override public void run() { http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/ca95c34a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragment.java ---------------------------------------------------------------------- diff --git a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragment.java b/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragment.java index 54325f4..5a5ee09 100644 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragment.java +++ b/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragment.java @@ -62,6 +62,7 @@ import org.apache.taverna.mobile.tavernamobile.TavernaPlayerAPI; import org.apache.taverna.mobile.tavernamobile.User; import org.apache.taverna.mobile.tavernamobile.Workflow; import org.apache.taverna.mobile.utils.DetailsLoader; +import org.apache.taverna.mobile.utils.RunTask; import org.apache.taverna.mobile.utils.WorkflowDownloadManager; import org.json.JSONArray; import org.json.JSONException; @@ -99,6 +100,7 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList static Animation zoomin; static Animation zoomout; public boolean isZoomIn; + public static String workflow_uri ; /** * Returns a new instance of this fragment for the given section @@ -201,8 +203,10 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList @Override public void onResume() { super.onResume(); - // if(!LOAD_STATE) - getActivity().getLoaderManager().initLoader(1, null, this).forceLoad(); + if(!LOAD_STATE) + workflow_uri = getActivity().getIntent().getStringExtra("uri"); + + getActivity().getLoaderManager().initLoader(1, null, this).forceLoad(); } @Override @@ -216,7 +220,7 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList progressDialog.show(); return new DetailsLoader(getActivity(), DetailsLoader.LOAD_TYPE.TYPE_WORKFLOW_DETAIL, - getActivity().getIntent().getStringExtra("uri")); + workflow_uri); } @Override @@ -454,6 +458,8 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList new RunTask(ctx).execute(json.toString()); } catch (JSONException e) { e.printStackTrace(); + }catch (Exception ex){ + ex.printStackTrace(); } } @@ -583,76 +589,5 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList } } - /** - * creates a new workflow run from the workflow on the player - */ - private class RunTask extends AsyncTask<String, Void, String>{ - - private Context context; - - private RunTask(Context ctx) { - this.context = ctx; - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - progressDialog.setMessage("Creating new run for the workflow"); - progressDialog.show(); - } - - @Override - protected String doInBackground(String... params) { - StringBuffer sb = new StringBuffer(); - try { - - URL workflowurl = new URL(new TavernaPlayerAPI(this.context).PLAYER_RUN_URL); - HttpURLConnection connection = (HttpURLConnection) workflowurl.openConnection(); - String userpass = "icep...@gmail.com" + ":" + "creationfox"; - String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT); - - connection.setRequestProperty("Authorization", basicAuth); - connection.setRequestProperty("Accept", "application/json"); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestMethod("POST"); - connection.connect(); //send request - DataOutputStream dos = new DataOutputStream(connection.getOutputStream()); - dos.writeBytes(params[0]);//write post data which is a formatted json data representing inputs to a run - - dos.flush(); - dos.close(); - - InputStream dis = connection.getInputStream(); - BufferedReader br = new BufferedReader(new InputStreamReader(dis)); - - String jsonData = ""; - while ((jsonData = br.readLine()) != null) { - sb.append(jsonData); - // - } - dis.close(); - br.close(); - Log.i("Run RESPONSE Code", "" + connection.getResponseCode()); - Log.i("Run RESPONSE Messsage", "" + connection.getResponseMessage()); - - return sb.toString(); - - }catch (IOException ex){ - ex.printStackTrace(); - } - return sb.toString(); - } - - @Override - protected void onPostExecute(String s) { - Log.i("RUN OutPut", s); - progressDialog.dismiss(); - //TODO startup the runActivity to display the run results - Intent runIntent = new Intent(); - runIntent.setClass(this.context, RunResult.class); - runIntent.putExtra("runresult", s); - startActivity(runIntent); - } - } } http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/ca95c34a/app/src/main/java/org/apache/taverna/mobile/utils/RunTask.java ---------------------------------------------------------------------- diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/RunTask.java b/app/src/main/java/org/apache/taverna/mobile/utils/RunTask.java new file mode 100644 index 0000000..14e0939 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/RunTask.java @@ -0,0 +1,93 @@ +package org.apache.taverna.mobile.utils; + +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; +import android.util.Base64; +import android.util.Log; + +import org.apache.taverna.mobile.activities.RunResult; +import org.apache.taverna.mobile.tavernamobile.TavernaPlayerAPI; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * Created by root on 7/11/15. + */ +public class RunTask extends AsyncTask<String, Void, String> { + + private Context context; + private ProgressDialog progressDialog; + + public RunTask(Context ctx) { + this.context = ctx; + progressDialog = new ProgressDialog(this.context); + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + progressDialog.setMessage("Creating new run for the workflow"); + progressDialog.show(); + } + + @Override + protected String doInBackground(String... params) { + StringBuffer sb = new StringBuffer(); + try { + + URL workflowurl = new URL(new TavernaPlayerAPI(this.context).PLAYER_RUN_URL); + HttpURLConnection connection = (HttpURLConnection) workflowurl.openConnection(); + String userpass = "icep...@gmail.com" + ":" + "creationfox"; + String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT); + + connection.setRequestProperty("Authorization", basicAuth); + connection.setRequestProperty("Accept", "application/json"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestMethod("POST"); + // connection.setDoInput(true); + // connection.setDoOutput(true); + connection.connect(); //send request + + DataOutputStream dos = new DataOutputStream(connection.getOutputStream()); + dos.writeBytes(params[0]);//write post data which is a formatted json data representing inputs to a run + + dos.flush(); + dos.close(); + + InputStream dis = connection.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(dis)); + + String jsonData = ""; + while ((jsonData = br.readLine()) != null) { + sb.append(jsonData); + // + } + dis.close(); + br.close(); + + return sb.toString(); + + }catch (IOException ex){ + ex.printStackTrace(); + } + return sb.toString(); + } + + @Override + protected void onPostExecute(String s) { + Log.i("RUN OutPut", s); +// progressDialog.dismiss(); + Intent runIntent = new Intent(); + runIntent.setClass(this.context, RunResult.class); + runIntent.putExtra("runresult", s); + this.context.startActivity(runIntent); + } +} http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/ca95c34a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowOpen.java ---------------------------------------------------------------------- diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowOpen.java b/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowOpen.java new file mode 100644 index 0000000..aaa13ff --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowOpen.java @@ -0,0 +1,289 @@ +package org.apache.taverna.mobile.utils; + +/** + * Created by Larry Akah on 7/11/15. + */ + +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.AsyncTask; +import android.util.Base64; +import android.util.Log; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.tavernamobile.TavernaPlayerAPI; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + *Read the selected xml file from storage and upload to player to generate workflowRun + */ +public class WorkflowOpen extends AsyncTask<String, Void, String> { + + private Context context; + private ProgressDialog progressDialog; + + public WorkflowOpen(Context context) { + this.context = context; + progressDialog = new ProgressDialog(this.context); + } + @Override + protected void onPreExecute() { + + progressDialog.setMessage("Uploading Workflow ... "); + progressDialog.show(); + } + + /** + * + * @param params path to workflow file to upload to player + * @return run framework used to create a new workflow run + */ + @Override + protected String doInBackground(String... params) { + StringBuffer sb = new StringBuffer(); + String str = ""; + try { + //prepare connection requests + File objectFile = new File(params[0]); //the resource xml file representing the workflow to be uploaded to the player + String playerurl = new TavernaPlayerAPI(this.context).PLAYER_BASE_URL+"workflows.json"; + URL posturl = new URL(playerurl); + HttpURLConnection connection = (HttpURLConnection) posturl.openConnection(); + + String user = "icep...@gmail.com" + ":" + "creationfox"; + String basicAuth = "Basic " + Base64.encodeToString(user.getBytes(), Base64.DEFAULT); + //read the file from remote resource and encode the stream with a base64 algorithm + + try { + BufferedReader br = new BufferedReader(new FileReader(objectFile)); + + while ((str = br.readLine()) != null) { + sb.append(str); + sb.append('\n'); + } + br.close(); + } + catch (IOException e) { + e.printStackTrace(); + } + + String data = "{\"document\":\"data:application/octet-stream;base64," + + Base64.encodeToString(sb.toString().getBytes("UTF-8"), Base64.URL_SAFE|Base64.NO_WRAP).replace('-','+')+"\"}"; + String post = "{\"workflow\":"+data+"}"; + //clear sb so that we can use it again to fetch results from this post request + sb.delete(0,sb.length()-1); + System.out.println("BODY=>"+post); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Authorization", basicAuth); + connection.setRequestProperty("Accept", "*/*"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("Content-Encoding", "UTF-8"); + connection.setUseCaches (false); + connection.setDoOutput(true); + connection.connect(); //send request + + DataOutputStream dos = new DataOutputStream(connection.getOutputStream()); + + dos.writeBytes(post);//write post data which is a formatted json data representing body of workflow + + dos.flush(); + dos.close(); + + InputStream dis = connection.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(dis)); + while ((str = br.readLine())!= null) + sb.append(str); + System.out.println("Post Response Code: "+connection.getResponseCode()); + System.out.println("Post response message: "+connection.getResponseMessage()); + connection.disconnect(); + }catch (IOException e){ + e.printStackTrace(); + sb.append("Error reading remote workflow. Please try again later"); + } + + return sb.toString(); + } + + /** + * Receives a result from the player as a json describing the workflow that has just been uploaded along with key components that + * can be used to generate a run from thw workflow. A run is started that would fetch and build a sample UI for a workflow run to be executed + * @param s the json result that describes the uploaded workflow + */ + @Override + protected void onPostExecute(String s) { + progressDialog.dismiss(); + System.out.println(s); + s = s.substring(1, s.length()); + try { + JSONObject workflowJson = new JSONObject(s); + new WorkflowRunTask(this.context).execute(workflowJson.getString("id")); + + } catch (JSONException e) { + e.printStackTrace(); + } + + } + + //create and return a new TextView + public TextView createTextView(Context mcontext, String placeholder){ + TextView tv = new TextView(mcontext); + tv.setText(placeholder); + tv.setMinLines(2); + + return tv; + } + + //create and return a new EdiText view + public EditText createEditText(Context ctx, int i){ + EditText edt; + edt = new EditText(ctx); + edt.setHint("Enter Value"); + edt.setMinLines(1); + edt.setId(i); + return edt; + } + + private class WorkflowRunTask extends AsyncTask<String, Void, String>{ + + private Context context; + private AlertDialog.Builder alertDialogBuilder; + private AlertDialog runDialog; + + private WorkflowRunTask(Context context) { + this.context = context; + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + progressDialog.setMessage(this.context.getResources().getString(R.string.fetchrun)); + progressDialog.show(); + } + + @Override + protected String doInBackground(String... params) { + StringBuffer sb = new StringBuffer(); + try { + + URL workflowurl = new URL(new TavernaPlayerAPI(this.context).PLAYER_RUN_FRAMEWORK_URL+params[0]); + HttpURLConnection connection = (HttpURLConnection) workflowurl.openConnection(); + String userpass = "icep...@gmail.com" + ":" + "creationfox"; + String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT); + + connection.setRequestProperty("Authorization", basicAuth); + connection.setRequestProperty("Accept", "application/json"); + connection.setRequestMethod("GET"); + connection.connect(); //send request + Log.i("RESPONSE Code", "" + connection.getResponseCode()); + Log.i("RESPONSE Messsage", "" + connection.getResponseMessage()); + Log.i("Authorization ", "" + connection.getRequestProperty("Authorization")); + + InputStream dis = connection.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(dis)); + + String jsonData = ""; + while ((jsonData = br.readLine()) != null) { + sb.append(jsonData); + } + dis.close(); + br.close(); + return sb.toString(); + + }catch (IOException ex){ + ex.printStackTrace(); + } + return sb.toString(); + } + + @Override + protected void onPostExecute(String result) { + //show the skeleton to the user in a dialog box + final Context ctx = this.context; + final LinearLayout ll = new LinearLayout(ctx); + ScrollView sv = new ScrollView(ctx); + ll.setOrientation(LinearLayout.VERTICAL); + sv.addView(ll); + + try { + final JSONObject json = new JSONObject(result); //main server response json + JSONObject mjson = json.getJSONObject("run"); //main framework response json + String name = mjson.getString("name"); //a name that can be configured or edited for the new run to be created + ll.addView(createTextView(ctx, name)); + final JSONArray attr_array = mjson.getJSONArray("inputs_attributes"); + for(int i=0; i<attr_array.length(); i++){ + JSONObject obj = attr_array.getJSONObject(i); + ll.addView(createTextView(ctx, obj.getString("name"))); + ll.addView(createEditText(ctx, i)); + } + + alertDialogBuilder = new AlertDialog.Builder(ctx); + alertDialogBuilder.setView(sv); + // alertDialogBuilder.setMessage(result); + alertDialogBuilder.setIcon(ctx.getResources().getDrawable(R.mipmap.ic_launcher)); + alertDialogBuilder.setTitle("New Workflow Run"); + alertDialogBuilder.setPositiveButton("Execute", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + int n = attr_array.length(); + for(int j=0; j<n; j++){ + try { + EditText inputText = (EditText) ll.findViewById(j); + String value = inputText.getText().toString();//get input entry entered by the user + JSONObject jojb = attr_array.getJSONObject(j); //get the input attributes provided by the skeleton + jojb.put("value", value); //replace value field in object with the entry provided by the user + attr_array.put(j, jojb); //replace the input entry with the new name/input json object + + } catch (JSONException e) { + e.printStackTrace(); + } + + } + try { + json.put("inputs_attributes", attr_array); + Log.i("RUN FRAMEWORK", json.toString(2)); + //start a run task to execute the run. + new RunTask(ctx).execute(json.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + + } + }); + alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialogInterface, int i) { + dialogInterface.dismiss(); + } + }); + + runDialog = alertDialogBuilder.create(); + + } catch (JSONException e) { + e.printStackTrace(); + } + progressDialog.dismiss(); + runDialog.show(); + } + } +} + + +