Implementing workflow run creation over Taverna Player
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/8d1bf189 Tree: http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/tree/8d1bf189 Diff: http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/diff/8d1bf189 Branch: refs/heads/master Commit: 8d1bf189a51f8fc14b99fe9faf389e6ba0b2ab64 Parents: d743850 Author: larrytech7 <larrya...@gmail.com> Authored: Thu Jul 2 01:02:15 2015 +0100 Committer: larrytech7 <larrya...@gmail.com> Committed: Thu Jul 2 01:02:15 2015 +0100 ---------------------------------------------------------------------- .../activities/WorkflowDetailActivity.java | 3 - .../mobile/fragments/WorkflowItemFragment.java | 44 +++++++- .../workflowdetails/WorkflowdetailFragment.java | 103 ++++++++++++++++++- .../mobile/tavernamobile/TavernaPlayerAPI.java | 8 ++ app/src/main/res/values/strings.xml | 6 ++ app/src/main/res/xml/pref_general.xml | 47 ++++++++- 6 files changed, 203 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/8d1bf189/app/src/main/java/org/apache/taverna/mobile/activities/WorkflowDetailActivity.java ---------------------------------------------------------------------- diff --git a/app/src/main/java/org/apache/taverna/mobile/activities/WorkflowDetailActivity.java b/app/src/main/java/org/apache/taverna/mobile/activities/WorkflowDetailActivity.java index 7c43b73..b0ccb12 100644 --- a/app/src/main/java/org/apache/taverna/mobile/activities/WorkflowDetailActivity.java +++ b/app/src/main/java/org/apache/taverna/mobile/activities/WorkflowDetailActivity.java @@ -31,10 +31,8 @@ import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBarActivity; -import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; -import android.view.Window; import org.apache.taverna.mobile.R; import org.apache.taverna.mobile.fragments.workflowdetails.WorkflowAboutFragment; @@ -141,7 +139,6 @@ public class WorkflowDetailActivity extends ActionBarActivity { return ""; } - } } http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/8d1bf189/app/src/main/java/org/apache/taverna/mobile/fragments/WorkflowItemFragment.java ---------------------------------------------------------------------- diff --git a/app/src/main/java/org/apache/taverna/mobile/fragments/WorkflowItemFragment.java b/app/src/main/java/org/apache/taverna/mobile/fragments/WorkflowItemFragment.java index b206f01..bd0742d 100644 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/WorkflowItemFragment.java +++ b/app/src/main/java/org/apache/taverna/mobile/fragments/WorkflowItemFragment.java @@ -30,6 +30,13 @@ import android.app.SearchManager; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.graphics.RectF; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.Fragment; @@ -59,6 +66,7 @@ import org.apache.taverna.mobile.tavernamobile.Workflow; import org.apache.taverna.mobile.utils.AvatarLoader; import org.apache.taverna.mobile.utils.WorkflowLoader; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; @@ -333,6 +341,8 @@ public class WorkflowItemFragment extends Fragment implements SwipeRefreshLayout connection.connect(); InputStream input = connection.getInputStream(); myBitmap = BitmapFactory.decodeStream(input); + input.close(); + } catch (IOException e) { e.printStackTrace(); } @@ -343,7 +353,39 @@ public class WorkflowItemFragment extends Fragment implements SwipeRefreshLayout protected void onPostExecute(Bitmap bitmap) { img.setImageBitmap(bitmap); /// img.setBackground(); - notify(); +// notify(); + } + private Bitmap ProcessingBitmap(Bitmap bmp){ + Bitmap bm1 = null; + Bitmap newBitmap = null; + + bm1 = bmp; + int w = bm1.getWidth(); + int h = bm1.getHeight(); + + Bitmap.Config config = bm1.getConfig(); + if(config == null){ + config = Bitmap.Config.ARGB_8888; + } + + newBitmap = Bitmap.createBitmap(w, h, config); + Canvas newCanvas = new Canvas(newBitmap); + newCanvas.drawColor(Color.WHITE); + + Paint paint = new Paint(); + paint.setColor(Color.TRANSPARENT); + Rect frame = new Rect( + (int)(w*0.05), + (int)(w*0.05), + (int)(w*0.95), + (int)(h*0.95)); + RectF frameF = new RectF(frame); + newCanvas.drawRoundRect(frameF, (float)(w*0.5), (float)(h*0.05), paint); + + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN)); + newCanvas.drawBitmap(bm1, 0, 0, paint); + + return newBitmap; } } } http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/8d1bf189/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 8d96e13..c052870 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 @@ -76,6 +76,7 @@ import org.w3c.dom.Text; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -160,7 +161,8 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList switch(view.getId()){ case R.id.run_wk: //TODO implement functionality to issue a run request to the Taverna PLAYER to run the current workflow - new WorkflowRunTask(getActivity()).execute(""+WORKFLO_ID); + //new WorkflowRunTask(getActivity()).execute(""+WORKFLO_ID); + new WorkflowProcessTask(getActivity()).execute(download_url); break; case R.id.download_wk: // start the android Download manager to start downloading a remote workflow file @@ -305,6 +307,7 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList } }); } + private static class LoadImageThread extends AsyncTask<String, Void, Bitmap>{ ImageView imageView; String src ; @@ -355,7 +358,7 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList edt.setId(i); return edt; } -//fetch and compute the framework on which the run inputs are to be built and entered + //fetch and compute the framework on which the run inputs are to be built and entered private class WorkflowRunTask extends AsyncTask<String, Void, String>{ private Context context; @@ -477,7 +480,100 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList runDialog.show(); } } - //Send request for the execution of a run on the server through the player + + /** + * Send request for the execution of a run on a Taverna server through the Taverna player using the Player API + * This process passes through several steps,\n + * 1- Downloading and caching a local version of the workflow whose run we need \n + * 2- uploading the workflow through the portal to register it so a run can be generated from it. The request requires some authentication + * 3- Retrieving the results and extracting data required to create a run (the workflow_id) as provided by the results + * 4- Posting a run request to the player so that a new run can be created and started + * 5- retrieving a run framework so that users can know what types of input is expected for a successful run + * 6- retrieving and displaying run results + */ + private class WorkflowProcessTask extends AsyncTask<String, Void, String>{ + + private Context context; + + private WorkflowProcessTask(Context context) { + this.context = context; + } + + @Override + protected void onPreExecute() { + progressDialog.setMessage("Uploading Workflow ... "); + progressDialog.show(); + } + + @Override + protected String doInBackground(String... params) { + StringBuffer sb = new StringBuffer(); + try { + //prepare connection requests + URL workflowurl = new URL(params[0]); //the resource xml file representing the workflow to be uploaded to the player + URL posturl = new URL(new TavernaPlayerAPI(this.context).PLAYER_BASE_URL+"workflows.json"); + HttpURLConnection connection = (HttpURLConnection) posturl.openConnection(); + HttpURLConnection wconn = (HttpURLConnection) workflowurl.openConnection(); + wconn.setRequestMethod("GET"); + wconn.setDoOutput(true); + wconn.setRequestProperty("Accept", "application/xml"); + //wconn.setConnectTimeout(60000); + wconn.connect(); + + 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 + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(wconn.getInputStream())); + String str = ""; + while ((str = bufferedReader.readLine()) != null) + sb.append(str); //in this string builder we have read the .t2flow or xml workflow from remote resource. Now we need to post that to the player. + bufferedReader.close(); + + //prepare post json data + JSONObject postJson = new JSONObject(); + JSONObject datajson = new JSONObject(); + datajson.put("document", "data:application/octet-stream;base64,"+Base64.encodeToString(sb.toString().getBytes(), Base64.DEFAULT)+""); + postJson.put("workflow",datajson.toString()); + //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(postJson.toString(2)); + 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(postJson.toString());//write post data which is a formatted json data representing body of workflow + //dos.writeUTF(""); + 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()); + }catch (IOException e){ + e.printStackTrace(); + sb.append("Error reading remote workflow. Please try again later"); + } catch (JSONException e) { + e.printStackTrace(); + sb.append("Invalid data format: JSON DATA"); + } + return sb.toString(); + } + + @Override + protected void onPostExecute(String s) { + System.out.println(s); + progressDialog.dismiss(); + } + } + /** + * creates a new workflow run from the + */ private class RunTask extends AsyncTask<String, Void, String>{ private Context context; @@ -542,6 +638,7 @@ public class WorkflowdetailFragment extends Fragment implements View.OnClickList protected void onPostExecute(String s) { Log.i("RUN OutPut", s); progressDialog.dismiss(); + //TODO startup the runActivity to display the run results } } } http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/8d1bf189/app/src/main/java/org/apache/taverna/mobile/tavernamobile/TavernaPlayerAPI.java ---------------------------------------------------------------------- diff --git a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/TavernaPlayerAPI.java b/app/src/main/java/org/apache/taverna/mobile/tavernamobile/TavernaPlayerAPI.java index 63d3b06..0b16de1 100644 --- a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/TavernaPlayerAPI.java +++ b/app/src/main/java/org/apache/taverna/mobile/tavernamobile/TavernaPlayerAPI.java @@ -75,6 +75,14 @@ public class TavernaPlayerAPI { return PLAYER_RUN_FRAMEWORK_URL; } + public static String getPlayerUserName(Context c){ + return PreferenceManager.getDefaultSharedPreferences(c).getString("pref_user","default"); + } + + public static String getPlayerUserPassword(Context c){ + return PreferenceManager.getDefaultSharedPreferences(c).getString("pref_password","default"); + } + public static class Authenticator extends java.net.Authenticator{ private String username, password; http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/8d1bf189/app/src/main/res/values/strings.xml ---------------------------------------------------------------------- diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dc320b3..3bf6202 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -88,5 +88,11 @@ limitations under the License. <string name="about">Mobile Application for managing Taverna workflows on the fly.<br/> View, run and download workflows at a convenience on your android mobile<br/> device. \n\n <br/><b>Developed at Apache Taverna and Powered by MyExperiment</b><br/></string> + <string name="playerconfig">Configure Player Account</string> + <string name="playerconfig_summary">Set username/password used to login to Taverna player portal</string> + <string name="playeruser">Username/email</string> + <string name="playerpass">Password</string> + <string name="myexperimenttitle">Configure MyExperiment Account</string> + <string name="myexperimentsummary">Set username/password used to login to MyExperiment</string> </resources> http://git-wip-us.apache.org/repos/asf/incubator-taverna-mobile/blob/8d1bf189/app/src/main/res/xml/pref_general.xml ---------------------------------------------------------------------- diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index cfa5985..03a0b11 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -28,6 +28,51 @@ android:capitalize="words" android:singleLine="true" android:maxLines="1" /> - + <PreferenceCategory + android:icon="@drawable/gear_icon" + android:summary="@string/playerconfig_summary" + android:title="@string/playerconfig"> + <EditTextPreference + android:key="pref_user" + android:title="@string/playeruser" + android:summary="@string/pref_server_des" + android:defaultValue="@string/pref_server_default" + android:selectAllOnFocus="true" + android:inputType="textEmailAddress|textPersonName" + android:singleLine="true" + android:maxLines="1" /> + <EditTextPreference + android:key="pref_password" + android:title="@string/playerpass" + android:summary="@string/pref_server_des" + android:defaultValue="@string/pref_server_default" + android:selectAllOnFocus="true" + android:inputType="textPassword" + android:singleLine="true" + android:maxLines="1" /> + </PreferenceCategory> + <PreferenceCategory + android:icon="@drawable/gear_icon" + android:summary="@string/myexperimentsummary" + android:title="@string/myexperimenttitle"> + <EditTextPreference + android:key="myexperimentuser" + android:title="@string/playeruser" + android:summary="@string/pref_server_des" + android:defaultValue="@string/pref_server_default" + android:selectAllOnFocus="true" + android:inputType="textEmailAddress|textPersonName" + android:singleLine="true" + android:maxLines="1" /> + <EditTextPreference + android:key="myexperimentpass" + android:title="@string/playerpass" + android:summary="@string/pref_server_des" + android:defaultValue="@string/pref_server_default" + android:selectAllOnFocus="true" + android:inputType="textPassword" + android:singleLine="true" + android:maxLines="1" /> + </PreferenceCategory> </PreferenceScreen>