diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..61018a7d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ +Please make sure these boxes are checked before submitting your pull request - thanks! + +- [ ] Apply the `AndroidStyle.xml` style template to your code in Android Studio. + +- [ ] Run the checks with `./gradlew check` to make sure you didn't break anything + +- [ ] If you have multiple commits please combine them into one commit by squashing them. \ No newline at end of file diff --git a/.gitignore b/.gitignore index f8b44c36..ece08a20 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,11 @@ /.idea/workspace.xml /.idea/libraries .DS_Store -/build -/.idea/ +build/ +.idea/ /app/build /app/app.iml /simple-xml-2.7.1 - +incubator-taverna-mobile.iml +TavernaMobile2.iml +projectFilesBackup/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..39f1ba8a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,34 @@ +## Licensed to the Apache Software Foundation (ASF) under one +## or more contributor license agreements. See the NOTICE file +## distributed with this work for additional information +## regarding copyright ownership. The ASF licenses this file +## to you under the Apache License, Version 2.0 (the +## "License"); you may not use this file except in compliance +## with the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, +## software distributed under the License is distributed on an +## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +## KIND, either express or implied. See the License for the +## specific language governing permissions and limitations +## under the License. + +language: android +jdk: oraclejdk8 +android: + components: + - tools + - extra-android-support + - extra-google-google_play_services + - extra-android-m2repository + - extra-google-m2repository + - build-tools-28.0.3 + - android-28 + +before_install: + - yes | sdkmanager "platforms;android-28" + - gradle -b wrapper.gradle wrapper + +script: "./gradlew build --stacktrace" diff --git a/AndroidStyle.xml b/AndroidStyle.xml new file mode 100644 index 00000000..ff32f74d --- /dev/null +++ b/AndroidStyle.xml @@ -0,0 +1,151 @@ + + + + \ No newline at end of file diff --git a/DISCLAIMER b/DISCLAIMER index 3e3a5cee..aa10f6e0 100644 --- a/DISCLAIMER +++ b/DISCLAIMER @@ -1,10 +1,2 @@ -Apache Taverna is an effort undergoing incubation at the Apache Software -Foundation (ASF), sponsored by the Apache Incubator PMC. - -Incubation is required of all newly accepted projects until a further review -indicates that the infrastructure, communications, and decision making process -have stabilized in a manner consistent with other successful ASF projects. - -While incubation status is not necessarily a reflection of the completeness -or stability of the code, it does indicate that the project has yet to be -fully endorsed by the ASF. +Taverna is no longer maintained and this code base +is provided for archive purposes only. diff --git a/NOTICE b/NOTICE index 2755a6bf..2311d4dd 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,6 @@ +This product is based on: Apache Taverna Mobile -Copyright 2015-2016 The Apache Software Foundation +Copyright 2015-2020 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/README.md b/README.md index 99f7787d..bbab7da3 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,45 @@ See the License for the specific language governing permissions and limitations under the License. --> -# Apache Taverna Mobile -Apache Taverna Mobile is an Android app -for controlling an [Apache Taverna Server](http://taverna.incubator.apache.org/documentation/server/) + + + +## Taverna Project Retired + +> tl;dr: The Taverna code base is **no longer maintained** +> and is provided here for archival purposes. + +From 2014 till 2020 this code base was maintained by the +[Apache Incubator](https://incubator.apache.org/) project _Apache Taverna (incubating)_ +(see [web archive](https://web.archive.org/web/20200312133332/https://taverna.incubator.apache.org/) +and [podling status](https://incubator.apache.org/projects/taverna.html)). + +In 2020 the Taverna community +[voted](https://lists.apache.org/thread.html/r559e0dd047103414fbf48a6ce1bac2e17e67504c546300f2751c067c%40%3Cdev.taverna.apache.org%3E) +to **retire** Taverna as a project and withdraw the code base from the Apache Software Foundation. + +This code base remains available under the Apache License 2.0 +(see _License_ below), but is now simply called +_Taverna_ rather than ~~Apache Taverna (incubating)~~. + +While the code base is no longer actively maintained, +Pull Requests are welcome to the +[GitHub organization taverna](http://github.com/taverna/), +which may infrequently be considered by remaining +volunteer caretakers. + + +### Previous releases + +This code has not yet been formally released. + + +# Taverna Mobile + +Taverna Mobile is an Android app for controlling an [Taverna Server](https://web.archive.org/web/*/https://taverna.incubator.apache.org/documentation/server/) for remotely running -[Apache Taverna](http://taverna.incubator.apache.org/) workflows. +[Taverna](https://web.archive.org/web/*/https://taverna.incubator.apache.org/) workflows. It can also talk to a [Taverna Player](https://github.com/myGrid/taverna-player-portal). @@ -29,7 +62,7 @@ This module was created during Google Summer of Code 2015. ## License -(c) 2015-2016 Apache Software Foundation +(c) 2015-2020 Apache Software Foundation This product includes software developed at The [Apache Software Foundation](http://www.apache.org/). @@ -44,41 +77,31 @@ details about embedded third-party libraries and source code. # Contribute -Please subscribe to and contact the -[dev@taverna](http://taverna.incubator.apache.org/community/lists#dev mailing list) -for any questions, suggestions and discussions about -Apache Taverna Mobile. - -Bugs and feature plannings are tracked in the Jira -[Issue tracker](https://issues.apache.org/jira/browse/TAVERNA/component/12326901) -under the `TAVERNA` component _GSOC Taverna Mobile._ Feel free -to add an issue! - -To suggest changes to this source code, feel free to raise a -[GitHub pull request](https://github.com/apache/incubator-taverna-mobile/pulls). Any contributions received are assumed to be covered by the [Apache License -2.0](https://www.apache.org/licenses/LICENSE-2.0). We might ask you -to sign a [Contributor License Agreement](https://www.apache.org/licenses/#clas) -before accepting a larger contribution. +2.0](https://www.apache.org/licenses/LICENSE-2.0). + # Building and install requirements -* Android Studio at least version 1.1.0 -* Android Build tools version 21.1.2+ -* gradle version 1.1.0+ +* Android Studio at least version 3.0.0+ +* Android Build tools version 28 +* Android SDK for API 28 +* gradle version 4.10.1 (a higher version might work) +Use `gradle wrapper --gradle-version 4.10.1` to create the gradle wrapper. Do not commit the `gradlew` file or the `gradle` directory to the repository. * Support libraries for CardViews and recycler views. These are already configured in the gradle files Import the project as Android Studio Project into Android Studio after downloading from the github repository. Create and startup a virtual device or connecct your mobile device if ready. -Once the devices are ready, build and run the project. Select the target devvice on which to install and launch the app. +Once the devices are ready, build and run the project. Select the target device on which to install and launch the app. Once installed, you get a flash screen containing the logo and Name of the app and some powered by Text. +* Also import AndroidStyle.xml to your android studio's codestyle. ( You can found this file at the project's root [file link](https://github.com/apache/incubator-taverna-mobile/blob/master/AndroidStyle.xml)) # Usage | Quick start ## Launch and Login -Launch the application to get started. For first time use when the application is started, you will be prompted with a login screen. This login accepts MyExperiment accounts. You will need to first create one such account in order to login. You can decide whether to remain logged-in or be logged-out when your session expires. You can also configure the login persistence from the settings option in the menu after you login. +Launch the application to get started. For first time use when the application is started, you will be prompted with tutorial screens which explains the usage of the applicationn and then you prompted to login screen. This login accepts MyExperiment accounts. You will need to first create one such account [here](https://www.myexperiment.org/users/new) in order to login. You can decide whether to remain logged-in or be logged-out when your session expires. You can also configure the login persistence from the settings option in the menu after you login. A successful login would lead you to a dashboard or home screen of the application. Users need to go to the settings page and configure their Taverna Player accounts and mount points to indicate which server should be used to run their workflows. This setting could change per organisation. @@ -87,20 +110,23 @@ Users need to go to the settings page and configure their Taverna Player account The dashboard has two swipeable tabs. These tabs represent screens that hosts workflow streams. once logged-in a stream of workflows should appear on the first screen(Wrofklows). The second tab holds workflows that have been favorited or saved for offline reference. On the first tab, you could pull down to referesh initial workflows. To load more workflows, just scroll to the end of the current stream. more workflows would be loaded and added to the current ones as the user reaches the end of the current stream. -The search bar icon allows you to search and find workfows by author or by name. the results are provided in real-time in the first tab (First page). -To mark a workflow as favorite, you can just tap the favorite button for the given workflow. +The search bar icon allows you to search and find workfows by author or by name. The results are provided in real-time in the first tab (First page). ## Workflow Detail -To view details and actually run a workflow, click the view button for the given workflow. Details are fetched from myxperiment and presented on the current page. The details page has three main swipeable tabs. The second tab shows a list of the runs performed on this workflow and the last tab is for some policy information. On the first page of the details, users can initiate a workflow run, download a workflow or mark them as favorite with the appropriate button. +To view details and actually run a workflow, click the view button for the given workflow. Details are fetched from myxperiment and presented on the current page. The details page has three main swipeable tabs. The second tab shows a list of the runs performed on this workflow and the last tab is for some policy information. On the first page of the details, users can initiate a workflow run, download a workflow or mark them as favorite with the appropriate button.To mark a workflow as favorite, you can just tap the favorite toggle button for the given workflow. ## Application Menus The navigation drawer can be pulled out from the home page by swiping the extreme left of screen across the screen. This menu contains the following items: - - Workflows: enters the workflow screen from any other screen. - - Open workflow: prompts users to pick a workflow to run from an external storage location or Dropbox. - - Usage: presents usrs with usage dialog with usage information. - - About: presents an about dialog for the application. + - All Workflows: Enters the workflow screen from any other screen where all the workflows are avialable. + - My Workflows: Presents all the workflows created by you. + - Favourite Workflows: Presents all the workflows which you marked as favorite. + - Announcement: List all the announcements about Taverna. + - Usage: Presents users usage information using usage activity. + - About: Presents an about dialog box for the application. + - Licence info: Presents a dialogue box with licence file of everything. + - Apache Licence/Notice: Presents a dialouge box of terms and conditions, reproduction, and distribution. - Settings: Provides a settings page for users to configure preference paramters an options like player portal location and credentials. - Logout: Logs a user out of the application and closes the app. @@ -143,7 +169,7 @@ testing from a mobile/tablet, you may have to use WiFi to get access to the Taverna Server on the local network. You can alternatively install the [Taverna -Server](http://taverna.incubator.apache.org/download/server/) WAR file in your +Server](https://web.archive.org/web/*/https://taverna.incubator.apache.org/download/server/) WAR file in your favourite servlet container, e.g. [Apache Tomcat](http://tomcat.apache.org/) - see the [Taverna Server installation guide](https://launchpad.net/taverna-server/2.5.x/2.5.4/+download/install.pdf) for details. diff --git a/TavernaMobile2.iml b/TavernaMobile2.iml deleted file mode 100644 index 0bb6048a..00000000 --- a/TavernaMobile2.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/app/build.gradle b/app/build.gradle index 110480ab..145d2afb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,27 +1,70 @@ apply plugin: 'com.android.application' -apply plugin: 'com.neenbedankt.android-apt' +apply plugin: 'com.jakewharton.butterknife' +apply from: '../config/quality/quality.gradle' android { - compileSdkVersion 23 - buildToolsVersion "21.1.2" + compileSdkVersion rootProject.ext.compileSdkVersion + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } useLibrary 'org.apache.http.legacy' lintOptions { abortOnError false } defaultConfig { - applicationId "mobile.taverna.apache.org.tavernamobile" - minSdkVersion 16 - targetSdkVersion 21 + applicationId "org.apache.taverna.mobile" + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" + multiDexEnabled true + testInstrumentationRunner 'org.apache.taverna.mobile.runner.RxAndroidJUnitRunner' + } + + sourceSets { + def commonTestDir = 'src/commonTest/java' + + main { + java.srcDirs = ['src/main/java'] + } + androidTest { + java.srcDirs = ['src/androidTest/java/'] + java.srcDir commonTestDir + resources.srcDirs += 'src/commonTest/resources' + + } + test { + java.srcDirs = ['src/test/java/'] + java.srcDir commonTestDir + resources.srcDirs += 'src/commonTest/resources' + } } + buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } + debug { + debuggable true + } + } + + testOptions { + unitTests.returnDefaultValues = true } + + packagingOptions { + exclude 'META-INF/rxjava.properties' + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + buildToolsVersion rootProject.ext.buildToolsVersion } repositories { jcenter() @@ -29,33 +72,95 @@ repositories { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.3.0' - compile 'com.android.support:cardview-v7:23.3.0' - compile 'com.android.support:recyclerview-v7:23.3.0' - compile 'com.android.support:support-v4:23.3.0' - compile files('libs/dropbox-android-sdk-1.6.3.jar') - compile 'com.android.support:design:23.3.0' - - compile 'com.squareup.retrofit2:retrofit:2.0.2' - compile "com.squareup.retrofit2:adapter-rxjava:2.0.2" - compile('com.squareup.retrofit2:converter-simplexml:2.0.2') { + implementation fileTree(dir: 'libs', include: ['*.jar']) + //Dependencies for support library + implementation "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion" + implementation "com.android.support:cardview-v7:$rootProject.supportLibraryVersion" + implementation "com.android.support:recyclerview-v7:$rootProject.supportLibraryVersion" + implementation "com.android.support:support-v4:$rootProject.supportLibraryVersion" + implementation "com.android.support:support-annotations:$rootProject.supportLibraryVersion" + + implementation "com.android.support:design:$rootProject.supportLibraryVersion" + implementation "com.android.support:preference-v7:$rootProject.supportLibraryVersion" + implementation "com.android.support:preference-v14:$rootProject.supportLibraryVersion" + + //Dependencies for retofit and okhhtp3 + implementation "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersionLatest" + implementation "com.squareup.retrofit2:adapter-rxjava2:$rootProject.retrofitVersionLatest" + implementation "com.squareup.okhttp3:logging-interceptor:$rootProject.okHttp3Version" + implementation "com.squareup.retrofit2:converter-gson:$rootProject.retrofitVersionLatest" + + implementation("com.squareup.retrofit2:converter-simplexml:$rootProject.retrofitVersionLatest") { exclude group: 'xpp3', module: 'xpp3' exclude group: 'stax', module: 'stax-api' exclude group: 'stax', module: 'stax' } - compile 'com.jakewharton:butterknife:8.0.1' - apt 'com.jakewharton:butterknife-compiler:8.0.1' + //Dependencies for butterknife + implementation "com.jakewharton:butterknife:$rootProject.butterKnifeVersion" + annotationProcessor "com.jakewharton:butterknife-compiler:$rootProject.butterKnifeVersion" - compile 'io.reactivex:rxandroid:1.2.0' -// Because RxAndroid releases are few and far between, it is recommended you also -// explicitly depend on RxJava's latest version for bug fixes and new features. - compile 'io.reactivex:rxjava:1.1.4' + implementation "io.reactivex.rxjava2:rxjava:$rootProject.rxJava2Version" + implementation "io.reactivex.rxjava2:rxandroid:$rootProject.rxJava2Version" - compile('org.simpleframework:simple-xml:2.7.+'){ + implementation("org.simpleframework:simple-xml:2.7.1") { exclude module: 'stax' exclude module: 'stax-api' exclude module: 'xpp3' } + + implementation "com.android.support:customtabs:$rootProject.supportLibraryVersion" + implementation 'com.github.bumptech.glide:glide:3.6.0' + implementation 'com.caverock:androidsvg:1.2.1' + + //Dependencies for dbflow + annotationProcessor "com.github.Raizlabs.DBFlow:dbflow-processor:$rootProject.raizLabsDBFlow" + implementation "com.github.Raizlabs.DBFlow:dbflow-core:$rootProject.raizLabsDBFlow" + implementation "com.github.Raizlabs.DBFlow:dbflow:$rootProject.raizLabsDBFlow" + + //Dependencies for db debug + implementation "com.facebook.stetho:stetho:$rootProject.stetho" + implementation "com.facebook.stetho:stetho-okhttp3:$rootProject.stetho" + + //Dependencies for Image zoom + implementation "com.github.chrisbanes:PhotoView:1.2.6" + implementation "com.android.support:multidex:1.0.2" + implementation "com.google.code.gson:gson:2.8.2" + + implementation 'de.hdodenhof:circleimageview:2.2.0' + implementation "com.anton46:stepsview:0.0.2" + + //Dependencies for LeakCanary + debugImplementation "com.squareup.leakcanary:leakcanary-android:$rootProject.leakcanary" + releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$rootProject.leakcanary" + testImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$rootProject.leakcanary" + + //Dependencies for JUNit and unit tests. + testImplementation "junit:junit:4.12" + testImplementation "org.mockito:mockito-core:2.8.47" + + androidTestImplementation "junit:junit:4.12" + androidTestImplementation "org.mockito:mockito-core:2.8.47" + + androidTestImplementation "org.mockito:mockito-android:2.8.47" + androidTestImplementation "com.android.support:support-annotations:$rootProject.supportLibraryVersion" + androidTestImplementation("com.android.support.test.espresso:espresso-contrib:$rootProject.espresso") { + exclude group: 'com.android.support', module: 'appcompat' + exclude group: 'com.android.support', module: 'support-v4' + exclude group: 'com.android.support', module: 'recyclerview-v7' + } + androidTestImplementation "com.android.support.test.espresso:espresso-core:$rootProject.espresso" + androidTestImplementation ("com.android.support.test.espresso:espresso-intents:$rootProject.espresso") + + androidTestImplementation "com.android.support.test:runner:$rootProject.runner" + androidTestImplementation "com.android.support.test:rules:$rootProject.runner" + + //Dependencies for Dagger 2 + implementation "com.google.dagger:dagger:$rootProject.dagger" + testImplementation "com.google.dagger:dagger:$rootProject.dagger" + androidTestImplementation "com.google.dagger:dagger:$rootProject.dagger" + annotationProcessor "com.google.dagger:dagger-compiler:$rootProject.dagger" + androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:$rootProject.dagger" + testAnnotationProcessor "com.google.dagger:dagger-compiler:$rootProject.dagger" + } diff --git a/app/libs/dropbox-android-sdk-1.6.3.jar b/app/libs/dropbox-android-sdk-1.6.3.jar deleted file mode 100644 index 1a0ee368..00000000 Binary files a/app/libs/dropbox-android-sdk-1.6.3.jar and /dev/null differ diff --git a/app/libs/json_simple-1.1.jar b/app/libs/json_simple-1.1.jar deleted file mode 100644 index f395f414..00000000 Binary files a/app/libs/json_simple-1.1.jar and /dev/null differ diff --git a/app/libs/sjxp-2.2.jar b/app/libs/sjxp-2.2.jar deleted file mode 100644 index 67960bc4..00000000 Binary files a/app/libs/sjxp-2.2.jar and /dev/null differ diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/DashboardActivityTest.java b/app/src/androidTest/java/org/apache/taverna/mobile/DashboardActivityTest.java new file mode 100644 index 00000000..5e6f7212 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/DashboardActivityTest.java @@ -0,0 +1,296 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile; + +import android.support.test.espresso.contrib.DrawerActions; +import android.support.test.espresso.contrib.NavigationViewActions; +import android.support.test.espresso.intent.Intents; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.view.Gravity; + +import org.apache.taverna.mobile.ui.DashboardActivity; +import org.apache.taverna.mobile.ui.login.LoginActivity; +import org.apache.taverna.mobile.ui.usage.UsageActivity; +import org.apache.taverna.mobile.ui.userprofile.UserProfileActivity; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.os.SystemClock.sleep; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.contrib.DrawerMatchers.isClosed; +import static android.support.test.espresso.contrib.DrawerMatchers.isOpen; +import static android.support.test.espresso.intent.Intents.intended; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; + + +@RunWith(AndroidJUnit4.class) +public class DashboardActivityTest { + + @Rule + public ActivityTestRule mActivityTestRule + = new ActivityTestRule<>(DashboardActivity.class); + + @Before + public void setUp() { + mActivityTestRule.getActivity() + .getSupportFragmentManager().beginTransaction(); + } + + /** + * Check if the username, password and userAvatar are visible and verify when click on + * userAvatar UserProfileActivity will open + */ + @Test + public void checkAllViewsVisible_and_OnClickAvatar_openUserProfileActivity() throws Exception { + + Intents.init(); + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + //Please Login first otherwise it will not find username and email + onView(withId(R.id.nav_user_avatar)).check(matches((isDisplayed()))); + onView(withId(R.id.nav_user_name)).check(matches((isDisplayed()))); + onView(withId(R.id.nav_user_email)).check(matches((isDisplayed()))); + + onView(withId(R.id.nav_user_avatar)).perform(click()); + + intended(hasComponent(UserProfileActivity.class.getName())); + Intents.release(); + } + + /** + * Checks if the Workflow fragment is launched when we click on Workflow in nav drawer + */ + @Test + public void onClickNavAllWorkflows_openWorkflowsFragment() throws Exception { + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.nav_workflows)); + + onView(withId(R.id.frame_container)).check(matches((isDisplayed()))); + + } + + /** + * Checks if the myWorkflow fragment is launched when we click on myWorkflow in nav drawer. + * Without login, The app does not have any user then it also does not have any myworkflow + * Without login it will fail + */ + @Test + public void onClickNavMyWorkflows_openMyWorkflowActivity() throws Exception { + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.nav_my_workflows)); + + onView(withId(R.id.frame_container)).check(matches((isDisplayed()))); + + } + + /** + * Checks if the favoriteWorkflow fragment is launched when we click on + * favoriteWorkflow in nav drawer + */ + @Test + public void onClickNavFavWorkflows_openFavoriteWorkflowActivity() throws Exception { + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.nav_favourite_workflow)); + + sleep(3000); + + onView(withId(R.id.frame_container)).check(matches((isDisplayed()))); + + } + + /** + * Checks if the Announcement fragment is launched when we click on + * announcement in nav drawer + */ + @Test + public void onClickNavAnnouncement_openAnnouncementActivity() throws Exception { + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.nav_announcement)); + + sleep(3000); + + onView(withId(R.id.frame_container)).check(matches((isDisplayed()))); + + } + + /** + * Checks if the usage activity is launched when we click on usage in nav drawer + */ + @Test + public void onClickNavUsage_openUsageActivity() throws Exception { + + Intents.init(); + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.nav_usage)); + + intended(hasComponent(UsageActivity.class.getName())); + + Intents.release(); + } + + /** + * Checks if the About dialouge is launched when we click on about in nav drawer + */ + @Test + public void onClickNavAbout_checkAboutDialogue() throws Exception { + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.nav_about)); + + onView(withId(R.id.about_dialouge_layout)).check(matches((isDisplayed()))); + + } + + /** + * Checks if the Licence dialouge is launched when we click on licence in nav drawer + */ + @Test + public void onClickNavLicence_openLicenceDialouge() throws Exception { + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.os_licences)); + + onView(withText(R.string.title_nav_os_licences)).check(matches(isDisplayed())); + + } + + /** + * Checks if the Licence dialogue is launched when we click on licence in nav drawer + */ + @Test + public void onClickNavApacheLicence_openApacheLicence_NoticeDialouge() throws Exception { + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.apache_licences)); + + onView(withText(R.string.title_nav_apache_licences)).check(matches(isDisplayed())); + + } + + /** + * Checks if the setting fragment is launched + * when we click on settings in navigation drawer + */ + @Test + public void onClickNavSetting_openSettingFragment() throws Exception { + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.nav_settings)); + + onView(withId(R.id.frame_container)).check(matches((isDisplayed()))); + + } + + /** + * Checks if the login is launched when click on logout in nav drawer and click on + * sign out in alert dialouge box + */ + @Test + public void onClickLogout_ClickSignOut_OpenLoginScreen() throws Exception { + + Intents.init(); + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.nav_logout)); + + onView(withId(android.R.id.button1)).perform(click()); + + intended(hasComponent(LoginActivity.class.getName())); + + Intents.release(); + } + + /** + * Checks if alert dialogue box is dismiss when click on cancel in logout alert sign in box + */ + @Test + public void onClickLogout_clickCancel_dismissDialogueBoz() throws Exception { + + Intents.init(); + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + onView(withId(R.id.nav_view)) + .perform(NavigationViewActions.navigateTo(R.id.nav_logout)); + + onView(withId(android.R.id.button2)).perform(click()); + + onView(withId(R.id.drawer_layout)) + .check(matches(isOpen(Gravity.LEFT))); + + Intents.release(); + } + + +} \ No newline at end of file diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/TestComponentRule.java b/app/src/androidTest/java/org/apache/taverna/mobile/TestComponentRule.java new file mode 100644 index 00000000..9c5b5f87 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/TestComponentRule.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile; + +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.injection.component.DaggerTestComponent; +import org.apache.taverna.mobile.injection.component.TestComponent; +import org.apache.taverna.mobile.injection.module.ApplicationTestModule; + + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import android.content.Context; + +import java.util.concurrent.Callable; + +import io.reactivex.Scheduler; +import io.reactivex.android.plugins.RxAndroidPlugins; +import io.reactivex.functions.Function; +import io.reactivex.plugins.RxJavaPlugins; +import io.reactivex.schedulers.Schedulers; + +public class TestComponentRule implements TestRule { + + private final TestComponent mTestComponent; + private final Context mContext; + + private Scheduler schedulerInstance = Schedulers.trampoline(); + + private Function schedulerMapper = new Function() { + @Override + public Scheduler apply(Scheduler scheduler) throws Exception { + return schedulerInstance; + } + }; + private Function, Scheduler> schedulerMapperLazy = + new Function, Scheduler>() { + + + @Override + public Scheduler apply(Callable schedulerCallable) throws Exception { + return schedulerInstance; + } + }; + + public TestComponentRule(Context context) { + mContext = context; + TavernaApplication application = TavernaApplication.get(context); + mTestComponent = DaggerTestComponent.builder() + .applicationTestModule(new ApplicationTestModule(application)) + .build(); + } + + public Context getContext() { + return mContext; + } + + public DataManager getMockDataManager() { + return mTestComponent.dataManager(); + } + + @Override + public Statement apply(final Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + RxAndroidPlugins.reset(); + RxAndroidPlugins.setInitMainThreadSchedulerHandler(schedulerMapperLazy); + + RxJavaPlugins.reset(); + RxJavaPlugins.setIoSchedulerHandler(schedulerMapper); + RxJavaPlugins.setNewThreadSchedulerHandler(schedulerMapper); + RxJavaPlugins.setComputationSchedulerHandler(schedulerMapper); + + TavernaApplication application = TavernaApplication.get(mContext); + application.setComponent(mTestComponent); + + base.evaluate(); + application.setComponent(null); + RxAndroidPlugins.reset(); + RxJavaPlugins.reset(); + } + }; + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/announcement/AnnouncementActivityTest.java b/app/src/androidTest/java/org/apache/taverna/mobile/announcement/AnnouncementActivityTest.java new file mode 100644 index 00000000..d763b7f1 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/announcement/AnnouncementActivityTest.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.announcement; + +import org.apache.taverna.mobile.FakeRemoteDataSource; +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.SingleFragmentActivity; +import org.apache.taverna.mobile.TestComponentRule; +import org.apache.taverna.mobile.data.model.Announcements; +import org.apache.taverna.mobile.ui.anouncements.AnnouncementFragment; +import org.apache.taverna.mobile.utils.RecyclerViewItemCountAssertion; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; +import org.mockito.Mockito; + +import android.content.Intent; +import android.support.test.InstrumentationRegistry; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import java.util.HashMap; +import java.util.Map; + +import io.reactivex.Observable; + +import static android.os.SystemClock.sleep; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; + +@RunWith(AndroidJUnit4.class) +public class AnnouncementActivityTest { + + private Announcements announcements; + private Map option; + + private final TestComponentRule component = + new TestComponentRule(InstrumentationRegistry.getTargetContext()); + private final ActivityTestRule mAnnouncementActivityTestRule = + new ActivityTestRule(SingleFragmentActivity.class, + false, false) { + @Override + protected Intent getActivityIntent() { + + return new Intent(InstrumentationRegistry.getTargetContext(), + SingleFragmentActivity.class); + } + }; + + /** + * TestComponentRule needs to go first to make sure the Dagger ApplicationTestComponent is set + * in the Application before any Activity is launched. + */ + @Rule + public final TestRule chain = RuleChain.outerRule(component) + .around(mAnnouncementActivityTestRule); + + + @Before + public void setUp() { + announcements = FakeRemoteDataSource.getAnnouncements(); + option = new HashMap<>(); + option.put("order", "reverse"); + option.put("page", String.valueOf(1)); + } + + @Test + public void CheckIfRecyclerViewIsLoaded() { + + + Mockito.when(component.getMockDataManager().getAllAnnouncement(option)) + .thenReturn(Observable.just(announcements)); + mAnnouncementActivityTestRule.launchActivity(null); + mAnnouncementActivityTestRule.getActivity().setFragment(new AnnouncementFragment()); + + onView(withId(R.id.rv_movies)).check(new RecyclerViewItemCountAssertion(5)); + + + + } + + +} diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragmentTest.java b/app/src/androidTest/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragmentTest.java index 634d1056..1c9657c3 100644 --- a/app/src/androidTest/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragmentTest.java +++ b/app/src/androidTest/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragmentTest.java @@ -1,3 +1,28 @@ +/* +* Apache Taverna Mobile +* Copyright 2016 The Apache Software Foundation + +* This product includes software developed at +* The Apache Software Foundation (http://www.apache.org/). + +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + package org.apache.taverna.mobile.fragments.workflowdetails; import junit.framework.TestCase; diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/injection/component/TestComponent.java b/app/src/androidTest/java/org/apache/taverna/mobile/injection/component/TestComponent.java new file mode 100644 index 00000000..76ac0e86 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/injection/component/TestComponent.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.injection.component; + +import org.apache.taverna.mobile.injection.module.ApplicationTestModule; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = ApplicationTestModule.class) +public interface TestComponent extends ApplicationComponent { + +} \ No newline at end of file diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/injection/module/ApplicationTestModule.java b/app/src/androidTest/java/org/apache/taverna/mobile/injection/module/ApplicationTestModule.java new file mode 100644 index 00000000..e8a683f3 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/injection/module/ApplicationTestModule.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.injection.module; + +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.injection.ApplicationContext; +import org.mockito.Mockito; + +import android.app.Application; +import android.content.Context; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class ApplicationTestModule { + + private final Application mApplication; + + public ApplicationTestModule(Application application) { + mApplication = application; + } + + @Provides + Application provideApplication() { + return mApplication; + } + + @Provides + @ApplicationContext + Context provideContext() { + return mApplication; + } + + /************* MOCKS *************/ + + @Provides + @Singleton + DataManager provideDataManager() { + return Mockito.mock(DataManager.class); + } + + +} \ No newline at end of file diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/login/LoginActivityTest.java b/app/src/androidTest/java/org/apache/taverna/mobile/login/LoginActivityTest.java new file mode 100644 index 00000000..b94a5e76 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/login/LoginActivityTest.java @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.login; + +import org.apache.taverna.mobile.FakeRemoteDataSource; +import org.apache.taverna.mobile.TestComponentRule; + +import org.apache.taverna.mobile.R; + +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.ui.login.LoginActivity; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; +import org.mockito.Mockito; + +import android.content.Intent; +import android.support.test.InstrumentationRegistry; +import android.support.test.espresso.Espresso; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import io.reactivex.Observable; + +import static android.os.SystemClock.sleep; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; +import static android.support.test.espresso.action.ViewActions.typeText; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.core.AllOf.allOf; + +@RunWith(AndroidJUnit4.class) +public class LoginActivityTest { + + private User testUser; + + + private final TestComponentRule component = + new TestComponentRule(InstrumentationRegistry.getTargetContext()); + private final ActivityTestRule mLoginActivityActivityTestRule = + new ActivityTestRule(LoginActivity.class, false, false) { + @Override + protected Intent getActivityIntent() { + + return new Intent(InstrumentationRegistry.getTargetContext(), LoginActivity + .class); + } + }; + + /** + * TestComponentRule needs to go first to make sure the Dagger ApplicationTestComponent is set + * in the Application before any Activity is launched. + */ + @Rule + public final TestRule chain = RuleChain.outerRule(component) + .around(mLoginActivityActivityTestRule); + + @Before + public void setUp() { + testUser = FakeRemoteDataSource.getLoginUser(); + } + + /** + * Checks if all the views are visible on the login activity + */ + @Test + public void checkAllViewAreVisible() throws Exception { + mLoginActivityActivityTestRule.launchActivity(null); + onView(withId(R.id.logo)).check(matches(isDisplayed())); + onView(withId(R.id.tvAppName)).check(matches(withText(R.string.app_name))); + onView(withId(R.id.loginlayout)).check(matches(isDisplayed())); + onView(withId(R.id.myExperimentIcon)).check(matches(isDisplayed())); + onView(withId(R.id.input_layout_email)).check(matches(isDisplayed())); + onView(withId(R.id.input_layout_password)).check(matches(isDisplayed())); + onView(withId(R.id.etEmail)).check(matches(isDisplayed())); + onView(withId(R.id.etPassword)).check(matches(isDisplayed())); + Espresso.closeSoftKeyboard(); + onView(withId(R.id.bLogin)).check(matches(isDisplayed())); + onView(withId(R.id.bRegister)).check(matches(isDisplayed())); + } + + /** + * This test demonstrates that when user enters the invalid username and password both then + * it verify if the correct snackbar is shown or not + */ + @Test + public void invalidLoginCredentials_showErrorSnackBar() throws Exception { + + testUser = new User(); + Mockito.when(component.getMockDataManager() + .getLoginUserDetail("Basic cG9zdG1hbjpwYXNzd29yZA==", true)) + .thenReturn(Observable.error(new Throwable())); + mLoginActivityActivityTestRule.launchActivity(null); + + onView(withId(R.id.etEmail)) + .perform(typeText("postman"), closeSoftKeyboard()); + onView(withId(R.id.etPassword)) + .perform(typeText("password"), closeSoftKeyboard()); + + onView(withId(R.id.bLogin)).perform(click()); + + onView(allOf(withId(android.support.design.R.id.snackbar_text), + withText("Please enter valid credential"))) + .check(matches(isDisplayed())); + } + + /** + * This test demonstrates that when user enters the valid/invalid password and empty username + * then it verify if the correct snackbar is shown or not + */ + @Test + public void emptyUsername_invalidCredentials_showErrorSnackBar() throws Exception { + + testUser = new User(); + Mockito.when(component.getMockDataManager() + .getLoginUserDetail("Basic OnRlc3QNCg==", true)) + .thenReturn(Observable.just(testUser)); + mLoginActivityActivityTestRule.launchActivity(null); + + onView(withId(R.id.etEmail)) + .perform(typeText(""), closeSoftKeyboard()); + onView(withId(R.id.etPassword)) + .perform(typeText("test"), closeSoftKeyboard()); + onView(withId(R.id.bLogin)).perform(click()); + sleep(2000); + + onView(allOf(withId(android.support.design.R.id.snackbar_text), + withText("Please enter valid credential"))) + .check(matches(isDisplayed())); + } + + /** + * This test demonstrates that when user enters the valid/invalid username and empty password + * then it verify if the correct snackbar is shown or not + */ + @Test + public void invalidPassword_invalidLoginCredentials_showErrorSnackBar() throws Exception { + + testUser = new User(); + Mockito.when(component.getMockDataManager() + .getLoginUserDetail("Basic dGVzdDoNCg==", true)) + .thenReturn(Observable.just(testUser)); + mLoginActivityActivityTestRule.launchActivity(null); + + onView(withId(R.id.etEmail)) + .perform(typeText("test"), closeSoftKeyboard()); + onView(withId(R.id.etPassword)) + .perform(typeText(""), closeSoftKeyboard()); + + onView(withId(R.id.bLogin)).perform(click()); + sleep(2000); + + onView(allOf(withId(android.support.design.R.id.snackbar_text), + withText("Please enter valid credential"))) + .check(matches(isDisplayed())); + } + + /** + * This test demonstrates that when user does not enters anything inside the username + * and password then it verify if the correct snackbar is shown or not + */ + @Test + public void nullLoginCredentials_showErrorSnackBar() throws Exception { + + mLoginActivityActivityTestRule.launchActivity(null); + + onView(withId(R.id.etEmail)) + .perform(typeText(""), closeSoftKeyboard()); + onView(withId(R.id.etPassword)) + .perform(typeText(""), closeSoftKeyboard()); + + onView(withId(R.id.bLogin)).perform(click()); + + onView(allOf(withId(android.support.design.R.id.snackbar_text), + withText("Please enter valid credential"))) + .check(matches(isDisplayed())); + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/runner/RxAndroidJUnitRunner.java b/app/src/androidTest/java/org/apache/taverna/mobile/runner/RxAndroidJUnitRunner.java new file mode 100644 index 00000000..42b320c5 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/runner/RxAndroidJUnitRunner.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.runner; + +import org.apache.taverna.mobile.utils.RxEspressoScheduleHandler; + +import android.os.Bundle; +import android.support.test.espresso.Espresso; + +import io.reactivex.plugins.RxJavaPlugins; + +public class RxAndroidJUnitRunner extends UnlockDeviceAndroidJUnitRunner { + + @Override + public void onCreate(Bundle arguments) { + super.onCreate(arguments); + + RxEspressoScheduleHandler rxEspressoScheduleHandler = new RxEspressoScheduleHandler(); + RxJavaPlugins.setScheduleHandler(rxEspressoScheduleHandler); + Espresso.registerIdlingResources(rxEspressoScheduleHandler.getIdlingResource()); + } + +} \ No newline at end of file diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/runner/UnlockDeviceAndroidJUnitRunner.java b/app/src/androidTest/java/org/apache/taverna/mobile/runner/UnlockDeviceAndroidJUnitRunner.java new file mode 100644 index 00000000..9760a4a4 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/runner/UnlockDeviceAndroidJUnitRunner.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.runner; + +import android.annotation.SuppressLint; +import android.app.Application; +import android.app.KeyguardManager; +import android.content.Context; +import android.os.PowerManager; +import android.support.test.runner.AndroidJUnitRunner; + +public class UnlockDeviceAndroidJUnitRunner extends AndroidJUnitRunner { + + private PowerManager.WakeLock mWakeLock; + + @SuppressLint("MissingPermission") + @Override + public void onStart() { + Application application = (Application) getTargetContext().getApplicationContext(); + String simpleName = UnlockDeviceAndroidJUnitRunner.class.getSimpleName(); + // Unlock the device so that the tests can input keystrokes. + ((KeyguardManager) application.getSystemService(Context.KEYGUARD_SERVICE)) + .newKeyguardLock(simpleName) + .disableKeyguard(); + // Wake up the screen. + PowerManager powerManager = ((PowerManager) application.getSystemService(Context + .POWER_SERVICE)); + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | + PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, simpleName); + mWakeLock.acquire(); + super.onStart(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mWakeLock.release(); + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/tutorial/TutorialActivityTest.java b/app/src/androidTest/java/org/apache/taverna/mobile/tutorial/TutorialActivityTest.java new file mode 100644 index 00000000..8762f7fc --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/tutorial/TutorialActivityTest.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.tutorial; + +import android.support.test.espresso.intent.Intents; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.login.LoginActivity; +import org.apache.taverna.mobile.ui.tutorial.TutorialActivity; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.swipeLeft; +import static android.support.test.espresso.action.ViewActions.swipeRight; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.intent.Intents.intended; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.CoreMatchers.not; + +@RunWith(AndroidJUnit4.class) +public class TutorialActivityTest { + + @Rule + public ActivityTestRule mActivityTestRule + = new ActivityTestRule<>(TutorialActivity.class); + + @Before + public void setUp() { + mActivityTestRule.getActivity() + .getSupportFragmentManager().beginTransaction(); + } + + /** + * Check all the views present are visible + */ + @Test + public void CheckAllViewAreVisible() throws Exception { + + onView(withId(R.id.layoutDots)).check(matches((isDisplayed()))); + onView(withId(R.id.btn_next)).check(matches((isDisplayed()))); + onView(withId(R.id.btn_skip)).check(matches((isDisplayed()))); + onView(withId(R.id.layoutDots)).check(matches((isDisplayed()))); + onView(withId(R.id.slide_pager)).check(matches((isDisplayed()))); + } + + /** + * Checks while clicking on skip button should start login activity + */ + @Test + public void clickingSkip_shouldStartLoginActivity() throws Exception { + + Intents.init(); + onView(withId(R.id.btn_skip)).perform(click()); + intended(hasComponent(LoginActivity.class.getName())); + Intents.release(); + } + + /** + * Check swipes are working on tutorial screens and on last tutorial screen while clicking on + * GOT IT it should go to login activity + */ + @Test + public void clickingNext_shouldGotoNextTutorial_onClickGotIt_ShouldGoToLoginActivity() + throws Exception { + + Intents.init(); + onView(withText(R.string.next)).check(matches(isDisplayed())); + onView(withId(R.id.slide_pager)).perform(swipeLeft()); + onView(withId(R.id.slide_pager)).perform(swipeLeft()); + onView(withId(R.id.slide_pager)).perform(swipeLeft()); + onView(withId(R.id.slide_pager)).perform(swipeLeft()); + onView(withText("SKIP")).check(matches(not(isDisplayed()))); + onView(withText("GOT IT")).check(matches(isDisplayed())); + onView(withText("GOT IT")).perform(click()); + intended(hasComponent(LoginActivity.class.getName())); + Intents.release(); + + } + + /** + * First it swipes two times and then swipe back. Then this test will check while clicking + * on the skip button should go the login activity + */ + @Test + public void swipeRightLeft_clickOnSkip_shouldGoToLoginActivity() throws Exception { + + Intents.init(); + onView(withText(R.string.next)).check(matches(isDisplayed())); + onView(withId(R.id.slide_pager)).perform(swipeLeft()); + onView(withId(R.id.slide_pager)).perform(swipeLeft()); + onView(withId(R.id.slide_pager)).perform(swipeRight()); + onView(withText("SKIP")).check(matches(isDisplayed())); + onView(withId(R.id.btn_skip)).perform(click()); + intended(hasComponent(LoginActivity.class.getName())); + Intents.release(); + } + +} diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/utils/RecyclerViewItemCountAssertion.java b/app/src/androidTest/java/org/apache/taverna/mobile/utils/RecyclerViewItemCountAssertion.java new file mode 100644 index 00000000..88f40014 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/utils/RecyclerViewItemCountAssertion.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + +import android.support.test.espresso.NoMatchingViewException; +import android.support.test.espresso.ViewAssertion; +import android.support.test.espresso.matcher.ViewMatchers; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import static org.hamcrest.Matchers.equalTo; + + +public class RecyclerViewItemCountAssertion implements ViewAssertion { + private final int expectedCount; + + public RecyclerViewItemCountAssertion(int expectedCount) { + this.expectedCount = expectedCount; + } + + @Override + public void check(View view, NoMatchingViewException noViewFoundException) { + if (noViewFoundException != null) { + throw noViewFoundException; + } + + RecyclerView recyclerView = (RecyclerView) view; + RecyclerView.Adapter adapter = recyclerView.getAdapter(); + ViewMatchers.assertThat(adapter.getItemCount(), equalTo(5)); + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/org/apache/taverna/mobile/utils/RxEspressoScheduleHandler.java b/app/src/androidTest/java/org/apache/taverna/mobile/utils/RxEspressoScheduleHandler.java new file mode 100644 index 00000000..9c609724 --- /dev/null +++ b/app/src/androidTest/java/org/apache/taverna/mobile/utils/RxEspressoScheduleHandler.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + +import android.support.annotation.NonNull; +import android.support.test.espresso.IdlingResource; +import android.support.test.espresso.contrib.CountingIdlingResource; + + +import io.reactivex.functions.Function; +public class RxEspressoScheduleHandler implements Function { + + private final CountingIdlingResource mCountingIdlingResource = + new CountingIdlingResource("rxJava"); + + @Override + public Runnable apply(@NonNull final Runnable runnable) throws Exception { + return new Runnable() { + @Override + public void run() { + mCountingIdlingResource.increment(); + + try { + runnable.run(); + } finally { + mCountingIdlingResource.decrement(); + } + } + }; + } + + public IdlingResource getIdlingResource() { + return mCountingIdlingResource; + } + +} \ No newline at end of file diff --git a/app/src/commonTest/java/org/apache/taverna/mobile/FakeRemoteDataSource.java b/app/src/commonTest/java/org/apache/taverna/mobile/FakeRemoteDataSource.java new file mode 100644 index 00000000..383ab0b1 --- /dev/null +++ b/app/src/commonTest/java/org/apache/taverna/mobile/FakeRemoteDataSource.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile; + +import org.apache.taverna.mobile.data.model.Announcements; +import org.apache.taverna.mobile.data.model.DetailAnnouncement; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.data.model.Workflows; + +public class FakeRemoteDataSource { + + private static TestDataFactory mTestDataFactory = new TestDataFactory(); + + + public static Announcements getAnnouncements() { + return mTestDataFactory.getObjectTypeBean(Announcements.class, FakeXMLName + .ANNOUNCEMENTS_XML); + } + + public static DetailAnnouncement getAnnouncement() { + return mTestDataFactory.getObjectTypeBean(DetailAnnouncement.class, + FakeXMLName.ANNOUNCEMENT_XML); + } + + public static Workflows getWorkflowList() { + return mTestDataFactory.getObjectTypeBean(Workflows.class, FakeXMLName.WORKFLOWS_XML); + } + + + public static User getLoginUser() { + return mTestDataFactory.getObjectTypeBean(User.class, FakeXMLName.USER_XML); + } +} \ No newline at end of file diff --git a/app/src/commonTest/java/org/apache/taverna/mobile/FakeXMLName.java b/app/src/commonTest/java/org/apache/taverna/mobile/FakeXMLName.java new file mode 100644 index 00000000..60edcae5 --- /dev/null +++ b/app/src/commonTest/java/org/apache/taverna/mobile/FakeXMLName.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile; + +public class FakeXMLName { + + public static final String ANNOUNCEMENTS_XML = "announcements.xml"; + public static final String ANNOUNCEMENT_XML = "announcement.xml"; + public static final String WORKFLOWS_XML = "workflows.xml"; + public static final String USER_XML = "user.xml"; +} \ No newline at end of file diff --git a/app/src/commonTest/java/org/apache/taverna/mobile/TestDataFactory.java b/app/src/commonTest/java/org/apache/taverna/mobile/TestDataFactory.java new file mode 100644 index 00000000..b1aabba1 --- /dev/null +++ b/app/src/commonTest/java/org/apache/taverna/mobile/TestDataFactory.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile; + +import android.util.Log; + +import org.simpleframework.xml.Serializer; +import org.simpleframework.xml.core.Persister; + +import java.io.InputStream; +import java.io.InputStreamReader; + +public class TestDataFactory { + + private static final String TAG = TestDataFactory.class.getSimpleName(); + + public T getObjectTypeBean(Class model, String jsonName) { + + InputStream in = getClass().getClassLoader().getResourceAsStream(jsonName); + Serializer serializer = new Persister(); + T xmlBean = null; + try { + xmlBean = serializer.read(model, new InputStreamReader(in)); + } catch (Exception e) { + Log.e(TAG, "getObjectTypeBean: ", e); + } + + return xmlBean; + } + +} \ No newline at end of file diff --git a/app/src/main/res/values-sw600dp/refs.xml b/app/src/commonTest/resources/announcement.xml similarity index 53% rename from app/src/main/res/values-sw600dp/refs.xml rename to app/src/commonTest/resources/announcement.xml index 32bdd106..aecc3a26 100644 --- a/app/src/main/res/values-sw600dp/refs.xml +++ b/app/src/commonTest/resources/announcement.xml @@ -1,9 +1,5 @@ + - - - - @layout/fragment_item_grid - - \ No newline at end of file + + 1 + David De Roure + myExperiment in IEEE Intelligent Systems + <p>myExperiment is discussed by Jim Hendler in his article <i>Reinventing Academic Publishing, Part 3 </i>in IEEE Intelligent Systems January/February 2008, page 2-3.</p> + Sat Mar 08 10:56:15 +0000 2008 + \ No newline at end of file diff --git a/app/src/commonTest/resources/announcements.xml b/app/src/commonTest/resources/announcements.xml new file mode 100644 index 00000000..9d4c3ad9 --- /dev/null +++ b/app/src/commonTest/resources/announcements.xml @@ -0,0 +1,22 @@ + + + + New announcements feature! + New reviews feature! + New updates and additions + Updated Group sharing! + myExperiment mentioned in Nature magazine! + \ No newline at end of file diff --git a/app/src/main/res/values-large/refs.xml b/app/src/commonTest/resources/user.xml similarity index 58% rename from app/src/main/res/values-large/refs.xml rename to app/src/commonTest/resources/user.xml index 32bdd106..02192e23 100644 --- a/app/src/main/res/values-large/refs.xml +++ b/app/src/commonTest/resources/user.xml @@ -1,9 +1,5 @@ + - - - - @layout/fragment_item_grid - - \ No newline at end of file + + 65265 + 2016-04-27 04:48:05 UTC + Sagar Sagar + + + + + + + \ No newline at end of file diff --git a/app/src/commonTest/resources/workflows.xml b/app/src/commonTest/resources/workflows.xml new file mode 100644 index 00000000..26901f19 --- /dev/null +++ b/app/src/commonTest/resources/workflows.xml @@ -0,0 +1,111 @@ + + + + + Get ontology parents + Taverna 2 + Kristina Hettne + 2015-11-16 09:56:17 UTC + http://www.myexperiment.org/workflows/4766/versions/2/previews/full + http://www.myexperiment.org/workflows/4766/download/Get_ontology_parents-v.t2flow + + + Texture classification: Knime Image Analytics + KNIME + Insilicoconsulting + 2015-11-10 08:28:37 UTC + http://www.myexperiment.org/workflows/4764/versions/1/previews/full + + http://www.myexperiment.org/workflows/4764/download/Texture_classification__Knime_Image_Analytics-v.zip + + + + + Define one query and retrieve Molecular Interactions from PSICQUIC Services (filtered by tag) registered in the PSICQUIC registry. + + Taverna 2 + Maximilian Koch + 2015-11-05 23:35:13 UTC + http://www.myexperiment.org/workflows/4763/versions/1/previews/full + + http://www.myexperiment.org/workflows/4763/download/Define_one_query_and_retrieve_Molecular_Interactions_from_PSICQUIC_Services__filtered_by_tag__registered_in_the_PSICQUIC_registry.-v.t2flow + + + + Query for all PISCQUIC services (Name+URL) + Taverna 2 + Maximilian Koch + 2015-11-05 23:01:06 UTC + http://www.myexperiment.org/workflows/4761/versions/1/previews/full + + http://www.myexperiment.org/workflows/4761/download/Query_for_all_PISCQUIC_services__Name_URL_-v.t2flow + + + + Query PSICQUIC and filter by idA and idB (REST) + Taverna 2 + Maximilian Koch + 2015-11-05 22:53:27 UTC + http://www.myexperiment.org/workflows/4760/versions/1/previews/full + + http://www.myexperiment.org/workflows/4760/download/Query_PSICQUIC_and_filter_by_idA_and_idB__REST_-v.t2flow + + + + FInd/filter idA and idB from MITAB + Taverna 2 + Maximilian Koch + 2015-11-05 22:27:17 UTC + http://www.myexperiment.org/workflows/4759/versions/1/previews/full + http://www.myexperiment.org/workflows/4759/download/FInd_filter_idA_and_idB_from_MITAB-v.t2flow + + + Get all PSICQUIC + Bioinformatics + Maximilian Koch + 2015-11-04 18:10:28 UTC + http://www.myexperiment.org/workflows/4755/versions/1/previews/full + http://www.myexperiment.org/workflows/4755/download/Get_all_PSICQUIC-v.t2flow + + + + KNIME workflow used to collate data for the paper 'Selectivity profiling of BCRP versus P-gp inhibition: from automated collection of polypharmacology data to multi-label learning' by F. Montanari, B. Zdrazil et al., J. Cheminform., 2016, PMID: 26855674 + + KNIME + Barbara Zdrazil + 2015-11-02 19:13:35 UTC + http://www.myexperiment.org/workflows/4754/versions/1/previews/full + + http://www.myexperiment.org/workflows/4754/download/KNIME_workflow_used_to_collate_data_for_the_paper__Selectivity_profiling_of_BCRP_versus_P-gp_inhibition__from_automated_collection_of_polypharmacology_data_to_multi-label_learning__by_F._Montanari__B._Zdrazil_et_al.__J._Cheminform.__2016__PMID__26855674_-v.zip + + + + Pubmed -Google Tag Cloud + KNIME + Insilicoconsulting + 2015-11-01 17:38:29 UTC + http://www.myexperiment.org/workflows/4753/versions/1/previews/full + http://www.myexperiment.org/workflows/4753/download/Pubmed_-Google_Tag_Cloud_-v.zip + + + Author Citation Network + Taverna 2 + Magnus Palmblad + 2015-10-20 10:10:33 UTC + http://www.myexperiment.org/workflows/4750/versions/1/previews/full + http://www.myexperiment.org/workflows/4750/download/Author_Citation_Network-v.t2flow + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9590e792..4e09b399 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,10 +1,5 @@ + package="org.apache.taverna.mobile"> - - + + + + + android:name=".TavernaApplication" + android:allowBackup="true" + android:icon="@mipmap/ic_launcher" + android:largeHeap="true" + android:label="@string/app_name" + android:theme="@style/Theme.Taverna" + android:networkSecurityConfig="@xml/network_security_config"> + android:name=".ui.login.LoginActivity" + android:label="@string/app_name"> + android:name=".ui.FlashScreenActivity"> - + - + + android:name=".ui.tutorial.TutorialActivity" + android:theme="@style/Tutorial.Theme.Taverna" + android:label="@string/title_activity_flash_screen"> + + - + + android:name="android.app.searchable" + android:resource="@xml/searchable"/> + + + android:name=".activities.SettingsActivity" + android:label="@string/title_activity_settings" + android:parentActivityName=".ui.DashboardActivity"> + android:name="android.support.PARENT_ACTIVITY" + android:value="org.apache.taverna.mobile.ui.DashboardActivity"/> - - - - - + android:name=".ui.workflowdetail.WorkflowDetailActivity" + android:label="@string/title_activity_run_result" + android:parentActivityName=".ui.DashboardActivity"> + android:name="android.support.PARENT_ACTIVITY" + android:value="org.apache.taverna.mobile.ui.DashboardActivity"/> + + android:parentActivityName=".ui.DashboardActivity"> - - - - - - - - - + android:value="org.apache.taverna.mobile.ui.DashboardActivity"/> + + + + + + + + + - + \ No newline at end of file diff --git a/app/src/main/assets/apache_licence_notice.html b/app/src/main/assets/apache_licence_notice.html new file mode 100644 index 00000000..70c75e68 --- /dev/null +++ b/app/src/main/assets/apache_licence_notice.html @@ -0,0 +1,239 @@ + + + + + + + + + +Apache Licence +
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+    
+ +Notice +
+
+    Apache Taverna Mobile
+Copyright 2015-2019 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+myExperiment's Logo is nothing to do with Apache Taverna and is copyright myExperiment.
+
+
+ + \ No newline at end of file diff --git a/app/src/main/assets/licences.html b/app/src/main/assets/licences.html new file mode 100644 index 00000000..e9820ff2 --- /dev/null +++ b/app/src/main/assets/licences.html @@ -0,0 +1,350 @@ + + + + + + + + + +Glide +
+License for everything not in third_party and not otherwise marked:
+
+Copyright 2014 Google, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice, this list of
+         conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright notice, this list
+         of conditions and the following disclaimer in the documentation and/or other materials
+         provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those of the
+authors and should not be interpreted as representing official policies, either expressed
+or implied, of Google, Inc.
+---------------------------------------------------------------------------------------------
+License for third_party/disklrucache:
+
+Copyright 2012 Jake Wharton
+Copyright 2011 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+---------------------------------------------------------------------------------------------
+License for third_party/gif_decoder:
+
+Copyright (c) 2013 Xcellent Creations, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+---------------------------------------------------------------------------------------------
+License for third_party/gif_encoder/AnimatedGifEncoder.java and
+third_party/gif_encoder/LZWEncoder.java:
+
+No copyright asserted on the source code of this class. May be used for any
+purpose, however, refer to the Unisys LZW patent for restrictions on use of
+the associated LZWEncoder class. Please forward any corrections to
+kweiner@fmsware.com.
+
+-----------------------------------------------------------------------------
+License for third_party/gif_encoder/NeuQuant.java
+
+Copyright (c) 1994 Anthony Dekker
+
+NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. See
+"Kohonen neural networks for optimal colour quantization" in "Network:
+Computation in Neural Systems" Vol. 5 (1994) pp 351-367. for a discussion of
+the algorithm.
+
+Any party obtaining a copy of these files from the author, directly or
+indirectly, is granted, free of charge, a full and unrestricted irrevocable,
+world-wide, paid up, royalty-free, nonexclusive right and license to deal in
+this software and documentation files (the "Software"), including without
+limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons who
+receive copies from any such party to do so, with the only requirement being
+that this copyright notice remain intact.
+
+ +appcompat, cardview, recyclerview, support, design, multidex, Gson +
+Copyright 2008 Google, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+ +Retrofit, RXJava Adapter +
+Copyright 2013 Square, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+ +OKHttp, Logging Interceptor, Simple XML Converter +
+Copyright 2014 Square, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+LeakCanary +
+Copyright 2015 Square, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Butterknife, Butterknife Compiler +
+Copyright 2013 Jake Wharton
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+RxAndroid +
+Copyright 2015 The RxAndroid authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+RxJava +
+Copyright 2013 Netflix, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Simple XML +
+Copyright unknown
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Android SVG +
+Copyright unknown
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+ +Photo View +
+Copyright 2016 Chris Banes
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+ +Steps View +
+Copyright 2015 Anton Nurdin Tuhadiansyah
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+ +DBFlow, DBFlow Processor, DBDlow Core +
+Copyright (c) 2014 Raizlabs
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+Stetho, Stetho OKHttp +
+Copyright (c) 2015, Facebook, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+ * Neither the name Facebook nor the names of its contributors may be used to
+   endorse or promote products derived from this software without specific
+   prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ + \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/SingleFragmentActivity.java b/app/src/main/java/org/apache/taverna/mobile/SingleFragmentActivity.java new file mode 100644 index 00000000..a075ecb8 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/SingleFragmentActivity.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import org.apache.taverna.mobile.ui.base.BaseActivity; + +public class SingleFragmentActivity extends BaseActivity { + FrameLayout content; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + content = new FrameLayout(this); + content.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + content.setId(R.id.container1); + setContentView(content); + } + + public void setFragment(Fragment fragment) { + + getSupportFragmentManager().beginTransaction() + .add(R.id.container1, fragment, "TEST") + .commit(); + } + + public void replaceFragment(Fragment fragment) { + getSupportFragmentManager().beginTransaction() + .replace(R.id.container1, fragment).commit(); + } + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/TavernaApplication.java b/app/src/main/java/org/apache/taverna/mobile/TavernaApplication.java new file mode 100644 index 00000000..a0bd6966 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/TavernaApplication.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile; + + +import com.facebook.stetho.Stetho; +import com.raizlabs.android.dbflow.config.FlowConfig; +import com.raizlabs.android.dbflow.config.FlowManager; +import com.squareup.leakcanary.LeakCanary; + +import org.apache.taverna.mobile.injection.component.ApplicationComponent; +import org.apache.taverna.mobile.injection.component.DaggerApplicationComponent; +import org.apache.taverna.mobile.injection.module.ApplicationModule; + +import android.app.Application; +import android.content.Context; + +public class TavernaApplication extends Application { + + ApplicationComponent mApplicationComponent; + + public static TavernaApplication get(Context context) { + return (TavernaApplication) context.getApplicationContext(); + } + + @Override + public void onCreate() { + super.onCreate(); + + FlowManager.init(new FlowConfig.Builder(this).build()); + if (BuildConfig.DEBUG) { + Stetho.initializeWithDefaults(this); + } + + if (LeakCanary.isInAnalyzerProcess(this)) { + return; + } + LeakCanary.install(this); + + } + + public ApplicationComponent getComponent() { + if (mApplicationComponent == null) { + mApplicationComponent = DaggerApplicationComponent.builder() + .applicationModule(new ApplicationModule(this)) + .build(); + } + return mApplicationComponent; + } + + + public void setComponent(ApplicationComponent applicationComponent) { + mApplicationComponent = applicationComponent; + } + +} 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 deleted file mode 100644 index 1d74cbd2..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/activities/DashboardMainActivity.java +++ /dev/null @@ -1,307 +0,0 @@ -package org.apache.taverna.mobile.activities; - -/** - * Apache Taverna Mobile -* Copyright 2015 The Apache Software Foundation - -* This product includes software developed at -* The Apache Software Foundation (http://www.apache.org/). - -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -*/ - -import android.app.Dialog; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; -import android.preference.PreferenceManager; -import android.support.design.widget.NavigationView; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentTransaction; -import android.support.v4.view.GravityCompat; -import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.view.Menu; -import android.view.MenuItem; -import android.webkit.MimeTypeMap; -import android.widget.TableLayout; -import android.widget.Toast; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.fragments.Workflow_viewpager; -import org.apache.taverna.mobile.ui.anouncements.AnnouncementFragment; -import org.apache.taverna.mobile.utils.WorkflowOpen; - -import java.io.File; - -public class DashboardMainActivity extends AppCompatActivity -{ - - /** - * Used to store the last screen title. For use in {@link #restoreActionBar()}. - */ - private CharSequence mTitle = "Dashboard"; - private final int SELECT_WORKFLOW = 10; - public static final String APP_DIRECTORY_NAME = "TavernaMobile"; - private Dialog aboutDialog; - private DrawerLayout mDrawerLayout; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_dashboard_main); - - NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); - if (navigationView != null) { - setupDrawerContent(navigationView); - } - - - mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); - - setUpWorkflowDirectory(this); - aboutDialog = new Dialog(this); - - /** - * Setting the Fragment in FrameLayout - */ - if (savedInstanceState == null) { - - FragmentManager fragmentManager = getSupportFragmentManager(); - Fragment fragment; - - fragment = new Workflow_viewpager(); - fragmentManager.beginTransaction() - .replace(R.id.frame_container, fragment) - .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE) - .commit(); - - - } - - } - - - /** - * - * @param navigationView Design Support NavigationView OnClick Listener Event - */ - private void setupDrawerContent(final NavigationView navigationView) { - navigationView.setNavigationItemSelectedListener( - new NavigationView.OnNavigationItemSelectedListener() - { - - @Override - public boolean onNavigationItemSelected(MenuItem menuItem) - { - - - FragmentManager fragmentManager = getSupportFragmentManager(); - Fragment fragment; - - switch (menuItem.getItemId()) - { - case R.id.nav_dashboard: - - fragment = new Workflow_viewpager(); - fragmentManager.beginTransaction() - .replace(R.id.frame_container, fragment) - .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE) - .commit(); - - menuItem.setChecked(true); - mDrawerLayout.closeDrawers(); - return true; - case R.id.nav_announcement: - - fragment = new AnnouncementFragment(); - fragmentManager.beginTransaction() - .replace(R.id.frame_container, fragment) - .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE) - .commit(); - - menuItem.setChecked(true); - mDrawerLayout.closeDrawers(); - return true; - - case R.id.nav_openworkflow: - - Intent workflowSelectIntent = - new Intent(Intent.ACTION_GET_CONTENT) - .setDataAndTypeAndNormalize(Uri.parse(String.format("%s%s%s", - Environment.getExternalStorageDirectory(), - File.separator, APP_DIRECTORY_NAME)), - "application/vnd.taverna.t2flow+xml"); - - Intent loadWorkflowIntent = Intent.createChooser(workflowSelectIntent, - "Choose Workflow (t2flow or xml)"); - startActivityForResult(loadWorkflowIntent, SELECT_WORKFLOW); - menuItem.setChecked(true); - mDrawerLayout.closeDrawers(); - return true; - case R.id.nav_usage: - - aboutDialog.setCanceledOnTouchOutside(true); - aboutDialog.setTitle("Usage"); - aboutDialog.setContentView(R.layout.usage_layout); - aboutDialog.show(); - - menuItem.setChecked(true); - mDrawerLayout.closeDrawers(); - return true; - - case R.id.nav_about: - - TableLayout about = (TableLayout) getLayoutInflater().inflate(R.layout.about, null); - - aboutDialog.setCanceledOnTouchOutside(true); - aboutDialog.setTitle("About Taverna Mobile"); - aboutDialog.setContentView(about); - aboutDialog.show(); - - menuItem.setChecked(true); - mDrawerLayout.closeDrawers(); - return true; - - case R.id.nav_settings: - - startActivity(new Intent(getApplicationContext(), SettingsActivity.class)); - overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right); - - menuItem.setChecked(true); - mDrawerLayout.closeDrawers(); - return true; - - case R.id.nav_logout: - - finish(); - menuItem.setChecked(true); - mDrawerLayout.closeDrawers(); - return true; - - } - return true; - } - }); - } - - - - - - @Override - public void onActivityResult(int requestCode , int resultCode, Intent data){ - if(resultCode == RESULT_OK){ - if(requestCode == SELECT_WORKFLOW){ - String workflowPath = data.getData().getPath(); - // Toast.makeText(getBaseContext(), "Path: "+workflowPath, Toast.LENGTH_LONG).show(); - String type = getMimeType(data.getData().getPath()); - if (type == "text/xml" || type == "application/vnd.taverna.t2flow+xml"){ - - new WorkflowOpen(this).execute(workflowPath); - }else { - Toast.makeText(getBaseContext(), "Invalid worklow. Please try again", Toast.LENGTH_LONG).show(); - - } - } - } - } - - /** - * Return the mimetype of the file selected to be run as a workflow - * @param url the path to the seleted file - * @return the mimetype of the file selected - */ - private String getMimeType(String url) { - String type = null; - String extension = MimeTypeMap.getFileExtensionFromUrl(url); - if (extension != null) { - type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - } - return type; - } - - - - public void restoreActionBar() { - ActionBar actionBar = getSupportActionBar(); - actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); - actionBar.setDisplayShowTitleEnabled(true); - actionBar.setTitle(mTitle); - } - - private void setUpWorkflowDirectory(Context context){ - - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); - if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - File workflowDirectory = new File(Environment.getExternalStorageDirectory()+File.separator+APP_DIRECTORY_NAME); - if (!workflowDirectory.exists()) { - boolean state = workflowDirectory.mkdirs(); - if (state) { - Toast.makeText(context, "Storage Ready", Toast.LENGTH_SHORT).show(); - sp.edit().putString(APP_DIRECTORY_NAME, workflowDirectory.getAbsolutePath()).commit(); - Toast.makeText(context, "Home dir: "+workflowDirectory.getAbsolutePath(), Toast.LENGTH_LONG).show(); - } else { //directory can't be created either because of restricted access or lack of an external storage media. - //we assume the lack of secondary storage so we have to switch to internal storage - // File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.)) - // Toast.makeText(context, "Storage Error. Directory not created", Toast.LENGTH_SHORT).show(); - } -// workflowDirectory.list(); - }else { - // Toast.makeText(context, "Directory exists. Home dir: "+workflowDirectory.getAbsolutePath(), Toast.LENGTH_LONG).show(); - sp.edit().putString(APP_DIRECTORY_NAME, workflowDirectory.getAbsolutePath()).commit(); - /*else { - File mainDir = new File(Environment.getExternalStorageDirectory() + File.separator + APP_DIRECTORY_NAME); - if (mainDir.mkdirs()) - sp.edit().putString(APP_DIRECTORY_NAME, mainDir.getAbsolutePath()).commit(); - else - Toast.makeText(context, "Workflow home not created. Permission issues", Toast.LENGTH_SHORT).show(); - }*/ - } - }else{//use internal memory to save the data - File home = context.getDir("Workflows", Context.MODE_PRIVATE); - sp.edit().putString(APP_DIRECTORY_NAME, home.getAbsolutePath()).commit(); - // Toast.makeText(context, "Home dir: "+home.getAbsolutePath(), Toast.LENGTH_LONG).show(); - } - } - - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.dashboard_main, menu); - restoreActionBar(); - return true; - } - - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - mDrawerLayout.openDrawer(GravityCompat.START); - return true; - } - return super.onOptionsItemSelected(item); - } - -} diff --git a/app/src/main/java/org/apache/taverna/mobile/activities/FlashScreenActivity.java b/app/src/main/java/org/apache/taverna/mobile/activities/FlashScreenActivity.java deleted file mode 100644 index e56ce4a0..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/activities/FlashScreenActivity.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.apache.taverna.mobile.activities; - -/* -* Apache Taverna Mobile -* Copyright 2015 The Apache Software Foundation - -* This product includes software developed at -* The Apache Software Foundation (http://www.apache.org/). - -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -*/ - -import android.content.Context; -import android.content.Intent; -import android.os.Handler; -import android.preference.PreferenceManager; -import android.support.v7.app.ActionBarActivity; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; - -import org.apache.taverna.mobile.R; - -public class FlashScreenActivity extends ActionBarActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_flash_screen); - //getSupportActionBar().hide(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - return false; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - - return super.onOptionsItemSelected(item); - } - @Override - public void onResume(){ - super.onResume(); - final Context context = this; - //setup initial app settings - if(!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("pref_set", false)){ - PreferenceManager.getDefaultSharedPreferences(context).edit().putString("pref_server_url", "http://heater.cs.man.ac.uk:8090/taverna-2.5.4/").commit(); - PreferenceManager.getDefaultSharedPreferences(context).edit().putString("pref_player_url", "http://heater.cs.man.ac.uk:3000/").commit(); - }else{ - PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean("pref_set", true).commit(); - } - Handler mhandler = new Handler(); - mhandler.postDelayed(new Runnable() { - @Override - public void run() { - if(!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("pref_logged_in", false)) { - startActivity(new Intent(FlashScreenActivity.this, LoginActivity.class)); - (FlashScreenActivity.this).finish(); - }else{ - startActivity(new Intent(FlashScreenActivity.this, DashboardMainActivity.class)); - (FlashScreenActivity.this).finish(); - } - } - }, 2500); - - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/activities/LoginActivity.java b/app/src/main/java/org/apache/taverna/mobile/activities/LoginActivity.java deleted file mode 100644 index 4a67b48c..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/activities/LoginActivity.java +++ /dev/null @@ -1,249 +0,0 @@ -package org.apache.taverna.mobile.activities; - -/* -* Apache Taverna Mobile -* Copyright 2015 The Apache Software Foundation - -* This product includes software developed at -* The Apache Software Foundation (http://www.apache.org/). - -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -*/ - -import android.app.Activity; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.Intent; -import android.os.AsyncTask; -import android.preference.PreferenceManager; -import android.support.v7.app.ActionBarActivity; -import android.support.v4.app.Fragment; -import android.os.Bundle; -import android.text.TextUtils; -import android.util.Base64; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.Toast; - -import org.apache.taverna.mobile.R; -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.HttpUtil; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.Authenticator; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - - -public class LoginActivity extends ActionBarActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_login); - //getSupportActionBar().hide(); - if (savedInstanceState == null) { - getSupportFragmentManager().beginTransaction() - .add(R.id.container, new LoginFragment()) - .commit(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - return false; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return super.onOptionsItemSelected(item); - } - - /** - * A placeholder fragment containing a simple view. - */ - public static class LoginFragment extends Fragment implements View.OnClickListener{ - - private View rootView; - private Button loginButton; - private EditText email, password; - private boolean logginRemain; - private CheckBox loginCheck; - - public LoginFragment() { - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - rootView = inflater.inflate(R.layout.fragment_login, container, false); - email = (EditText) rootView.findViewById(R.id.editTextUsername); - password = (EditText) rootView.findViewById(R.id.edittextPassword); - loginCheck = (CheckBox) rootView.findViewById(R.id.rememberCheckbox); - loginButton = (Button) rootView.findViewById(R.id.loginbutton); - loginButton.setOnClickListener(this); - return rootView; - } - - @Override - public void onClick(View view) { - int i = view.getId(); - if (i == R.id.loginbutton) { - logginRemain = loginCheck.isChecked(); - if (logginRemain) { - PreferenceManager.getDefaultSharedPreferences(getActivity()).edit().putBoolean("pref_logged_in",true).apply(); - } else { - PreferenceManager.getDefaultSharedPreferences(getActivity()).edit().putBoolean("pref_logged_in",false).apply(); - } - if (email.getText().toString().isEmpty()) { - email.setError(getString(R.string.emailerr)); - } else if (password.getText().toString().isEmpty()) { - password.setError(getString(R.string.passworderr)); - } else { - // login request - new LoginTask(getActivity()).execute(email.getText().toString(), password.getText().toString()); - } - - } - } - - private class LoginTask extends AsyncTask{ - private Context context; - private ProgressDialog pd; - String cookie; - String userurl; - - private LoginTask(Context context) { - this.context = context; - pd = new ProgressDialog(this.context); - pd.setMessage("Logging in"); - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - pd.setCancelable(false); - pd.show(); - } - - @Override - protected String doInBackground(String... params) { - //http://sandbox.myexperiment.org/users - - String whoAmI = "http://www.myexperiment.org/whoami.xml"; - - String response = null; - HttpURLConnection con = null; - try { - URL url = new URL(whoAmI); - con = (HttpURLConnection) url.openConnection(); - String userName = params[0]; - String password = params[1]; - boolean redirect = false; - - String authentication = userName + ":" + password; - con.setRequestMethod("GET"); - con.setRequestProperty("Authorization", "Basic " + Base64.encodeToString(authentication.getBytes(), Base64.DEFAULT)); - con.setInstanceFollowRedirects(true); - HttpURLConnection.setFollowRedirects(true); - con.connect(); - int status = con.getResponseCode(); - response = String.valueOf(status); - if(status != HttpURLConnection.HTTP_OK){ - if (status == HttpURLConnection.HTTP_MOVED_PERM || - status == HttpURLConnection.HTTP_MOVED_TEMP || - status == HttpURLConnection.HTTP_SEE_OTHER || status == 307){ - redirect = true; - } - - } - System.out.println("Status code: "+status); - if(redirect) { - // get redirect url from "location" header field - String newUrl = con.getHeaderField("Location"); - this.userurl = newUrl; - // get the cookie needed, for login - String cookies = con.getHeaderField("Set-Cookie"); - this.cookie = cookies; - // open the new connection again - con = (HttpURLConnection) new URL(newUrl).openConnection(); - con.setRequestProperty("Cookie", cookies); - System.out.println("Redirect to URL : " + newUrl); - con.connect(); - } - BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); - StringBuilder sb = new StringBuilder(); - String s = ""; - while((s = br.readLine())!= null ){ - sb.append(s); - } - br.close(); - System.out.println("data: "+sb.toString()); - - con.disconnect(); - - return response; - - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - return response; - } - - @Override - protected void onPostExecute(String response) { - pd.dismiss(); - if(response != null) { - switch(Integer.parseInt(response)){ - case 401: - Toast.makeText(getActivity(), getActivity().getString(R.string.auth_err), Toast.LENGTH_LONG).show(); - break; - case 200: - case 307: - this.context.startActivity(new Intent(this.context, DashboardMainActivity.class)); - getActivity().overridePendingTransition(R.anim.abc_slide_in_bottom, R.anim.abc_slide_out_top); - getActivity().finish(); - break; - } - }else{ - Toast.makeText(getActivity(), getActivity().getString(R.string.servererr), Toast.LENGTH_LONG).show(); - } - } - } - } - -} diff --git a/app/src/main/java/org/apache/taverna/mobile/activities/RunResult.java b/app/src/main/java/org/apache/taverna/mobile/activities/RunResult.java deleted file mode 100644 index 54593444..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/activities/RunResult.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.apache.taverna.mobile.activities; - -import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; -import android.view.Menu; -import android.view.MenuItem; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.fragments.workflowdetails.RunFragment; - -public class RunResult extends ActionBarActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_run_result); - if (savedInstanceState == null) { - getSupportFragmentManager().beginTransaction() - .add(R.id.container, RunFragment.newInstance()) - .commit(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - return false; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - - this.finish(); - - return super.onOptionsItemSelected(item); - } - -} diff --git a/app/src/main/java/org/apache/taverna/mobile/activities/SettingsActivity.java b/app/src/main/java/org/apache/taverna/mobile/activities/SettingsActivity.java deleted file mode 100644 index 4a5048de..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/activities/SettingsActivity.java +++ /dev/null @@ -1,244 +0,0 @@ -package org.apache.taverna.mobile.activities; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceActivity; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.support.annotation.NonNull; -import android.support.v4.app.NavUtils; -import android.view.MenuItem; - -import org.apache.taverna.mobile.R; - -import java.util.List; - -/** - * A {@link PreferenceActivity} that presents a set of application settings. On - * handset devices, settings are presented as a single list. On tablets, - * settings are split by category, with category headers shown to the left of - * the list of settings. - *

- * See - * Android Design: Settings for design guidelines and the Settings - * API Guide for more information on developing a Settings UI. - */ -public class SettingsActivity extends PreferenceActivity { - /** - * Determines whether to always show the simplified settings UI, where - * settings are presented in a single list. When false, settings are shown - * as a master/detail two-pane view on tablets. When true, a single pane is - * shown on tablets. - */ - private static final boolean ALWAYS_SIMPLE_PREFS = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // setupActionBar(); - } - - /** - * Set up the {@link android.app.ActionBar}, if the API is available. - */ - /* @NonNull - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - private void setupActionBar() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - // Show the Up button in the action bar. - getActionBar().setDisplayHomeAsUpEnabled(true); - } - } -*/ - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - if (id == android.R.id.home) { - // This ID represents the Home or Up button. In the case of this - // activity, the Up button is shown. Use NavUtils to allow users - // to navigate up one level in the application structure. For - // more details, see the Navigation pattern on Android Design: - // - // http://developer.android.com/design/patterns/navigation.html#up-vs-back - // - // TODO: If Settings has multiple levels, Up should navigate up - // that hierarchy. - NavUtils.navigateUpFromSameTask(this); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - - setupSimplePreferencesScreen(); - } - - /** - * Shows the simplified settings UI if the device configuration if the - * device configuration dictates that a simplified, single-pane UI should be - * shown. - */ - private void setupSimplePreferencesScreen() { - if (!isSimplePreferences(this)) { - return; - } - - // In the simplified UI, fragments are not used at all and we instead - // use the older PreferenceActivity APIs. - - // Add 'general' preferences. - addPreferencesFromResource(R.xml.pref_general); - - // Bind the summaries of EditText/List/Dialog/Ringtone preferences to - // their values. When their values change, their summaries are updated - // to reflect the new value, per the Android Design guidelines. - bindPreferenceSummaryToValue(findPreference("pref_server_url")); - bindPreferenceSummaryToValue(findPreference("pref_player_url")); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean onIsMultiPane() { - return isXLargeTablet(this) && !isSimplePreferences(this); - } - - /** - * Helper method to determine if the device has an extra-large screen. For - * example, 10" tablets are extra-large. - */ - private static boolean isXLargeTablet(Context context) { - return (context.getResources().getConfiguration().screenLayout - & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; - } - - /** - * Determines whether the simplified settings UI should be shown. This is - * true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device - * doesn't have newer APIs like {@link PreferenceFragment}, or the device - * doesn't have an extra-large screen. In these cases, a single-pane - * "simplified" settings UI should be shown. - */ - private static boolean isSimplePreferences(Context context) { - return ALWAYS_SIMPLE_PREFS - || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB - || !isXLargeTablet(context); - } - - /** - * {@inheritDoc} - */ - @Override - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void onBuildHeaders(List

target) { - if (!isSimplePreferences(this)) { - loadHeadersFromResource(R.xml.pref_headers, target); - } - } - - /** - * A preference value change listener that updates the preference's summary - * to reflect its new value. - */ - private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - String stringValue = value.toString(); - - if (preference instanceof ListPreference) { - // For list preferences, look up the correct display value in - // the preference's 'entries' list. - ListPreference listPreference = (ListPreference) preference; - int index = listPreference.findIndexOfValue(stringValue); - - // Set the summary to reflect the new value. - preference.setSummary( - index >= 0 - ? listPreference.getEntries()[index] - : null); - - } else { - // For all other preferences, set the summary to the value's - // simple string representation. - preference.setSummary(stringValue); - } - return true; - } - }; - - /** - * Binds a preference's summary to its value. More specifically, when the - * preference's value is changed, its summary (line of text below the - * preference title) is updated to reflect the value. The summary is also - * immediately updated upon calling this method. The exact display format is - * dependent on the type of preference. - * - * @see #sBindPreferenceSummaryToValueListener - */ - private static void bindPreferenceSummaryToValue(Preference preference) { - // Set the listener to watch for value changes. - preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); - - // Trigger the listener immediately with the preference's - // current value. - sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, - PreferenceManager - .getDefaultSharedPreferences(preference.getContext()) - .getString(preference.getKey(), "")); - } - - /** - * This fragment shows general preferences only. It is used when the - * activity is showing a two-pane settings UI. - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public static class GeneralPreferenceFragment extends PreferenceFragment { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.pref_general); - - // Bind the summaries of EditText/List/Dialog/Ringtone preferences - // to their values. When their values change, their summaries are - // updated to reflect the new value, per the Android Design - // guidelines. - bindPreferenceSummaryToValue(findPreference("pref_server_url")); - bindPreferenceSummaryToValue(findPreference("pref_player_url")); - } - } - -} 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 deleted file mode 100644 index 170621b6..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/activities/WorkflowDetailActivity.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.apache.taverna.mobile.activities; - -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.os.Bundle; -import android.support.v4.app.Fragment; -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.Menu; -import android.view.MenuItem; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.fragments.workflowdetails.WorkflowAboutFragment; -import org.apache.taverna.mobile.fragments.workflowdetails.WorkflowLicenceFragment; -import org.apache.taverna.mobile.fragments.workflowdetails.WorkflowRunHistoryFragment; -import org.apache.taverna.mobile.fragments.workflowdetails.WorkflowdetailFragment; - -import java.util.Locale; - -public class WorkflowDetailActivity extends ActionBarActivity { - - /** - * The {@link android.support.v4.view.PagerAdapter} that will provide - * fragments for each of the sections. We use a - * {@link FragmentPagerAdapter} derivative, which will keep every - * loaded fragment in memory. If this becomes too memory intensive, it - * may be best to switch to a - * {@link android.support.v4.app.FragmentStatePagerAdapter}. - */ - SectionsPagerAdapter mSectionsPagerAdapter; - - /** - * The {@link ViewPager} that will host the section contents. - */ - ViewPager mViewPager; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_workflow_detail); - // Create the adapter that will return a fragment for each of the three - // primary sections of the activity. - mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - - // Set up the ViewPager with the sections adapter. - mViewPager = (ViewPager) findViewById(R.id.pager); - mViewPager.setAdapter(mSectionsPagerAdapter); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - return false; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - if(item.getItemId() == android.R.id.home){ - finish(); - this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.slide_out_right ); - } - return super.onOptionsItemSelected(item); - } - @Override - public void onBackPressed(){ - finish(); - this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.slide_out_right ); - } - - /** - * A {@link FragmentPagerAdapter} that returns a fragment corresponding to - * one of the sections/tabs/pages. - */ - public class SectionsPagerAdapter extends FragmentPagerAdapter { - - public SectionsPagerAdapter(FragmentManager fm) { - super(fm); - } - - @Override - public Fragment getItem(int position) { - switch(position +1){ - case 1: - return WorkflowdetailFragment.newInstance(position + 1); - case 2: - //System.out.println(""+getIntent().getStringExtra("wtitle")); - return WorkflowRunHistoryFragment.newInstance(getIntent().getStringExtra("wtitle")); - case 3: - return WorkflowLicenceFragment.newInstance("",""); - case 4: - return WorkflowAboutFragment.newInstance("",""); - } - return WorkflowdetailFragment.newInstance(position + 1); - } - - @Override - public int getCount() { - // Show 4 total pages. - return 3; - } - - @Override - public CharSequence getPageTitle(int position) { - Locale l = Locale.getDefault(); - switch (position) { - case 0: - return getString(R.string.detail_title_section1).toUpperCase(l); - case 1: - return getString(R.string.detail_title_section2).toUpperCase(l); - case 2: - return getString(R.string.detail_title_section3).toUpperCase(l); - case 3: - return getString(R.string.detail_title_section4).toUpperCase(l); - } - return ""; - } - } - -} diff --git a/app/src/main/java/org/apache/taverna/mobile/adapters/FavoriteWorkflowAdapter.java b/app/src/main/java/org/apache/taverna/mobile/adapters/FavoriteWorkflowAdapter.java deleted file mode 100644 index a32be485..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/adapters/FavoriteWorkflowAdapter.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.apache.taverna.mobile.adapters; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.app.Dialog; -import android.content.Context; -import android.content.SharedPreferences; -import android.graphics.Color; -import android.preference.PreferenceManager; -import android.support.design.widget.FloatingActionButton; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.utils.Workflow_DB; -import org.json.JSONException; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Larry Akah on 6/9/15. - */ -public class FavoriteWorkflowAdapter extends RecyclerView.Adapter { - - private Context context; - private List> dataSet; - public Workflow_DB favDB; - - public FavoriteWorkflowAdapter(Context c, List> data) { - context = c; - dataSet = data; - favDB = new Workflow_DB(context, WorkflowAdapter.WORKFLOW_FAVORITE_KEY); - } - - @Override - public FViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { - View itemview = LayoutInflater.from(context).inflate(R.layout.favorite_item_layout, viewGroup, false); - FViewHolder vh = new FViewHolder(itemview); - return vh; - } - /** - * Register a new observer to listen for data changes. - *

- *

The adapter may publish a variety of events describing specific changes. - * Not all adapters may support all change types and some may fall back to a generic - * {@link android.support.v7.widget.RecyclerView.AdapterDataObserver#onChanged() - * "something changed"} event if more specific data is not available.

- *

- *

Components registering observers with an adapter are responsible for - * {@link #unregisterAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver) - * unregistering} those observers when finished.

- * - * @param observer Observer to register - * @see #unregisterAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver) - */ - @Override - public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer) { - super.registerAdapterDataObserver(observer); - //observer.onChanged(); - } - /** - * Unregister an observer currently listening for data changes. - *

- *

The unregistered observer will no longer receive events about changes - * to the adapter.

- * - * @param observer Observer to unregister - * @see #registerAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver) - */ - @Override - public void unregisterAdapterDataObserver(RecyclerView.AdapterDataObserver observer) { - super.unregisterAdapterDataObserver(observer); - } - - @Override - public void onBindViewHolder(FViewHolder fViewHolder, int i) { - //get data 0,1,3 from set; - final ArrayList data = dataSet.get(i); - - //String[] mdata = dataSet.get(i); - fViewHolder.author.setText((CharSequence) data.get(6)); - fViewHolder.title.setText((CharSequence) data.get(2)); - fViewHolder.dateMarked.setText((CharSequence) data.get(4)); - fViewHolder.btn_delete.setOnClickListener(new FloatingActionButton.OnClickListener() { - @Override - public void onClick(View view) { - try { - Toast.makeText(context, String.format("%s", "Removed "),Toast.LENGTH_SHORT).show(); - //removeMarkedWorkflow(String.valueOf(data.get(0))); - favDB.delete(String.valueOf(data.get(0))); - notifyDataSetChanged(); - } catch (JSONException e) { - e.printStackTrace(); - }catch(Exception ex){ - ex.printStackTrace(); - } - - } - }); - fViewHolder.btn_view_fav.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Dialog d = new Dialog(context); - TextView textView = new TextView(context); - String text = "Author -> "+ (String) data.get(6) + "\nTitle: "+data.get(2)+"\nDescription\n"+data.get(3); - textView.setText(text); - textView.setTextSize(22); - textView.setTextColor(Color.BLACK); - d.setTitle(""+data.get(2)); - d.setContentView(textView); - d.show(); - } - }); - } - //remove a workflow from the marked state - private void removeMarkedWorkflow(String strToRemove){ - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); - char[] charsequence = sharedPreferences.getString(WorkflowAdapter.FAVORITE_LIST_DB, "").toCharArray(); - for(int i=0; i getDataItemAt(int position){ - return dataSet.size() == 0? null: dataSet.get(position); - } - - public class FViewHolder extends RecyclerView.ViewHolder { - - public final ImageView favorite_thumb; - public final TextView author, title, dateMarked;// dateAdd; - public final FloatingActionButton btn_delete; - public final Button btn_view_fav; - public FViewHolder(View itemView) { - super(itemView); - favorite_thumb = (ImageView) itemView.findViewById(R.id.author_profile_image); - author = (TextView) itemView.findViewById(R.id.author); - title = (TextView) itemView.findViewById(R.id.favorite_title); - dateMarked = (TextView) itemView.findViewById(R.id.date_set); - btn_delete = (FloatingActionButton) itemView.findViewById(R.id.favoriteButtonDelete); - btn_view_fav = (Button) itemView.findViewById(R.id.buttonOpenFavorite); - } - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/adapters/RunAdapter.java b/app/src/main/java/org/apache/taverna/mobile/adapters/RunAdapter.java deleted file mode 100644 index e22d2e15..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/adapters/RunAdapter.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.apache.taverna.mobile.adapters; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import android.content.Context; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.TextView; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.tavernamobile.Runs; - -import java.util.List; - - -/** - * Created by root on 6/14/15. - */ -public class RunAdapter extends RecyclerView.Adapter { - private Context context; - private List runList; - - public RunAdapter(Context context, List runs) { - this.context = context; - this.runList = runs; - } - - /** - * Called when RecyclerView needs a new {@link android.support.v7.widget.RecyclerView.ViewHolder} of the given type to represent - * an item. - *

- * This new ViewHolder should be constructed with a new View that can represent the items - * of the given type. You can either create a new View manually or inflate it from an XML - * layout file. - *

- * The new ViewHolder will be used to display items of the adapter using - * . Since it will be re-used to display different - * items in the data set, it is a good idea to cache references to sub views of the View to - * avoid unnecessary {@link android.view.View#findViewById(int)} calls. - * - * @param parent The ViewGroup into which the new View will be added after it is bound to - * an adapter position. - * @param viewType The view type of the new View. - * @return A new ViewHolder that holds a View of the given view type. - * @see #getItemViewType(int) - */ - @Override - public RunHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View v = LayoutInflater.from(context).inflate(R.layout.workflow_run_item,parent, false); - return new RunHolder(v); - } - - /** - * Called by RecyclerView to display the data at the specified position. This method - * should update the contents of the {@link android.support.v7.widget.RecyclerView.ViewHolder#itemView} to reflect the item at - * the given position. - *

- * Note that unlike {@link android.widget.ListView}, RecyclerView will not call this - * method again if the position of the item changes in the data set unless the item itself - * is invalidated or the new position cannot be determined. For this reason, you should only - * use the position parameter while acquiring the related data item inside this - * method and should not keep a copy of it. If you need the position of an item later on - * (e.g. in a click listener), use {@link android.support.v7.widget.RecyclerView.ViewHolder#getAdapterPosition()} which will have - * the updated adapter position. - * - * @param holder The ViewHolder which should be updated to represent the contents of the - * item at the given position in the data set. - * @param position The position of the item within the adapter's data set. - */ - @Override - public void onBindViewHolder(RunHolder holder, int position) { - Runs lRun = runList.get(position); - holder.runtitle.setText(lRun.getRun_name()); - holder.runstarted.setText(lRun.getRun_started_date()); - holder.runfinished.setText(lRun.getRun_ended_date()); - holder.runAuthor.setText("Author->"+lRun.getRun_author()); - switch(lRun.getState()){ - case RUNNING: - holder.runStatus.setImageResource(android.R.drawable.presence_busy); - holder.textState.setText("Running"); - break; - case FINISHED: - holder.runStatus.setImageResource(android.R.drawable.presence_online); - holder.textState.setText("Finished"); - break; - case FAILED: - holder.runStatus.setImageResource(android.R.drawable.presence_offline); - holder.textState.setText("Failed"); - break; - } - - } - - public List getRunList(){ - return this.runList; - } - - public void setRunList(List runList) { - this.runList = runList; - } - - /** - * Returns the total number of items in the data set hold by the adapter. - * - * @return The total number of items in this adapter. - */ - @Override - public int getItemCount() { - //return 0; - return runList.size(); - } - - public static class RunHolder extends RecyclerView.ViewHolder { - public final TextView runtitle, runstarted, runfinished,textState,runAuthor; - public final ImageButton runStatus; - - public RunHolder(View itemView) { - super(itemView); - runtitle = (TextView) itemView.findViewById(R.id.runtitle); - runAuthor = (TextView) itemView.findViewById(R.id.run_authorTextview); - runstarted = (TextView) itemView.findViewById(R.id.runstarted); - runfinished = (TextView) itemView.findViewById(R.id.runfinished); - runStatus = (ImageButton) itemView.findViewById(R.id.imageButtonState); - textState = (TextView) itemView.findViewById(R.id.textState); - } - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/adapters/SliderMenuAdapter.java b/app/src/main/java/org/apache/taverna/mobile/adapters/SliderMenuAdapter.java deleted file mode 100644 index 9b702a1f..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/adapters/SliderMenuAdapter.java +++ /dev/null @@ -1,113 +0,0 @@ -package org.apache.taverna.mobile.adapters; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.TextView; - -import org.apache.taverna.mobile.R; - -import java.util.List; - -/** - * Created by root on 6/7/15. - */ -public class SliderMenuAdapter extends BaseAdapter{ - - private List dataItems; - private Context context; - - public SliderMenuAdapter(Context c,List items){ - dataItems = items; - context = c; - } - - @Override - public int getCount() { - return dataItems.size(); - } - - @Override - public String getItem(int i) { - return dataItems.get(i); - } - - @Override - public long getItemId(int i) { - return 0; - } - - @Override - public View getView(int i, View view, ViewGroup viewGroup) { - - View menuitemview = LayoutInflater.from(context).inflate(R.layout.menu_item_layout, viewGroup, false); - - ImageView menuicon = (ImageView) menuitemview.findViewById(R.id.menuIcon); - TextView menuitem = (TextView) menuitemview.findViewById(R.id.menuItemText); - switch(i +1){ - case 1: - menuicon.setImageResource(R.mipmap.ic_dashboard_home); - menuitem.setText(dataItems.get(i)); - break; - case 2: - menuicon.setImageResource(R.mipmap.ic_openwk); - menuitem.setText(dataItems.get(i)); - break; - case 3: - menuicon.setImageResource(R.mipmap.ic_usage); - menuitem.setText(dataItems.get(i)); - break; - case 4: - menuicon.setImageResource(R.mipmap.ic_about); - menuitem.setText(dataItems.get(i)); - break; - case 5: - menuicon.setImageResource(R.mipmap.ic_workflows); - menuitem.setText(dataItems.get(i)); - break; - case 6: - menuicon.setImageResource(R.mipmap.ic_logout); - menuitem.setText(dataItems.get(i)); - break; - } - return menuitemview; - } - - public static class ViewHolder{ - public final ImageView menuicon; - public final TextView menuitem; - - public ViewHolder(View view){ - menuicon = (ImageView) view.findViewById(R.id.menuIcon); - menuitem = (TextView) view.findViewById(R.id.menuItemText); - } - - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/adapters/WorkflowAdapter.java b/app/src/main/java/org/apache/taverna/mobile/adapters/WorkflowAdapter.java deleted file mode 100644 index 13944223..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/adapters/WorkflowAdapter.java +++ /dev/null @@ -1,324 +0,0 @@ -package org.apache.taverna.mobile.adapters; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.AsyncTask; -import android.preference.PreferenceManager; -import android.support.v7.widget.RecyclerView; -import android.text.Html; -import android.text.util.Linkify; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; - -import com.thebuzzmedia.sjxp.rule.IRule; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.activities.WorkflowDetailActivity; -import org.apache.taverna.mobile.fragments.workflowdetails.WorkflowdetailFragment; -import org.apache.taverna.mobile.tavernamobile.User; -import org.apache.taverna.mobile.tavernamobile.Workflow; -import org.apache.taverna.mobile.utils.Workflow_DB; -import org.apache.taverna.mobile.utils.xmlparsers.MyExperimentXmlParserRules; -import org.apache.taverna.mobile.utils.xmlparsers.WorkflowDetailParser; -import org.json.JSONException; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -/** - * Created by Larry Akah on 6/8/15. - */ -public class WorkflowAdapter extends RecyclerView.Adapter{ - private Context context; - private List workflowList; //workflow data to bind to the UI - private WorkflowAdapter.ViewHolder mViewHolder; - public static final String WORKFLOW_FAVORITE_KEY = "WORKFLOW_FAVORITES"; //workflow key used to save workflows when marked as favorites - public static final String FAVORITE_LIST_DB = "FAVORITE_LIST"; - public Workflow_DB favDB; //favorited keeps items that have been favorited in order to identify them during - // display in the list. - public WorkflowAdapter(Context c, List wk) { - context = c; - workflowList = wk; - favDB = new Workflow_DB(context, WORKFLOW_FAVORITE_KEY); - } - - public WorkflowAdapter(Context c){ - context = c; - workflowList = new ArrayList(); - favDB = new Workflow_DB(context, WORKFLOW_FAVORITE_KEY); - } - - public void addItems(List workflow, int position) throws ClassCastException{ - //add items to the current list of list - //workflowList.add(position,workflow); - workflowList.addAll(workflow); - notifyItemRangeInserted(position + 24, 25); - } - - public void removeItem(Workflow workflow){ - workflowList.remove(workflow); - //notifyItemRemoved(); - } - - /** - * Register a new observer to listen for data changes. - *

- *

The adapter may publish a variety of events describing specific changes. - * Not all adapters may support all change types and some may fall back to a generic - * {@link android.support.v7.widget.RecyclerView.AdapterDataObserver#onChanged() - * "something changed"} event if more specific data is not available.

- *

- *

Components registering observers with an adapter are responsible for - * {@link #unregisterAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver) - * unregistering} those observers when finished.

- * - * @param observer Observer to register - * @see #unregisterAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver) - */ - @Override - public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer) { - super.registerAdapterDataObserver(observer); - } - - /** - * Unregister an observer currently listening for data changes. - *

- *

The unregistered observer will no longer receive events about changes - * to the adapter.

- * - * @param observer Observer to unregister - * @see #registerAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver) - */ - @Override - public void unregisterAdapterDataObserver(RecyclerView.AdapterDataObserver observer) { - super.unregisterAdapterDataObserver(observer); - } - - @Override - public WorkflowAdapter.ViewHolder onCreateViewHolder(ViewGroup parentViewGroup, int viewType) { - View v = LayoutInflater.from(context).inflate(R.layout.workflow_item_layout,parentViewGroup,false); - mViewHolder = new ViewHolder(v); - return mViewHolder; - } - - /** - * Bind data set items for each data - * @param viewHolder the recycled view used to bind data (Overwrite data values) - * @param i position of data in the dataset to use. - */ - @Override - public void onBindViewHolder(final ViewHolder viewHolder, int i) { - - final long wid = workflowList.get(i).getId(); - final String author = workflowList.get(i).getWorkflow_author(); -// final String author = workflowList.get(i).getUploader().getName(); - final String title = workflowList.get(i).getWorkflow_title(); - String description = workflowList.get(i).getWorkflow_description(); - final String uri = workflowList.get(i).getWorkflow_details_url(); - final String desc_full = description; - - if(description.length() > 80) description = description.substring(0, 79)+" ..."; - viewHolder.author_name.setHint(author); - viewHolder.wk_title.setHint(title); - viewHolder.wk_description.setText(description); - Linkify.addLinks(viewHolder.wk_description, Linkify.WEB_URLS); - - final Intent it = new Intent(); - System.out.println("Workflow_uri:"+uri); - it.setClass(context, WorkflowDetailActivity.class); -// it.putExtra("workflowid", workflow.get(i).getId()); //workflow_url - it.putExtra("uri",uri);//uri - it.putExtra("wtitle", title); //pass this workflow's title to the detail activity so the corresponding run can be fetched - it.putExtra("wid", wid); - WorkflowdetailFragment.WORKFLO_ID = title;//workflow.get(i).getId(); - - //determine whether to mark button as favorited or not - final String favs = PreferenceManager.getDefaultSharedPreferences(context).getString(FAVORITE_LIST_DB, ""); - String[] ids = favs.split(","); - if(ids.length > 0) { - for (String id : ids) - if (id.equalsIgnoreCase("" + wid)){ - viewHolder.btn_mark_workflow.setBackgroundResource(R.drawable.abc_list_selector_disabled_holo_light); - break; - } - } - - viewHolder.btn_view_workflow.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - context.startActivity(it); - ((Activity) context).overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.fade_out); - } - }); - - viewHolder.btn_mark_workflow.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - ArrayList mfav = new ArrayList(); - //save current workflow as favorite - mfav.add(wid); mfav.add(author);mfav.add(title);mfav.add(desc_full); - mfav.add(SimpleDateFormat.getDateTimeInstance().format(new Date())); - mfav.add(uri); - mfav.add(viewHolder.author_name.getText()); - int saved = favDB.insert(mfav); - - if(saved >0) { - viewHolder.btn_mark_workflow.setBackgroundResource(R.drawable.abc_list_selector_disabled_holo_light); - - PreferenceManager.getDefaultSharedPreferences(context).edit().putString(FAVORITE_LIST_DB, favs+wid+",").apply(); - //refresh fragment since data has changed - FavoriteWorkflowAdapter favoriteWorkflowAdapter = (FavoriteWorkflowAdapter) ((RecyclerView) ((Activity) context).findViewById(R.id.favoriteList)).getAdapter(); - //try { - if(null != favoriteWorkflowAdapter) - favoriteWorkflowAdapter.notifyDataSetChanged(); - //}catch(NullPointerException np){ - // np.printStackTrace(); - // } - Toast.makeText(context, "Workflow marked as favorite", Toast.LENGTH_SHORT).show(); - }else if(saved == -1){ - Toast.makeText(context,"Sorry! This workflow has already been marked as a favourite",Toast.LENGTH_SHORT).show(); - }else - Toast.makeText(context,"Error! Please try again",Toast.LENGTH_SHORT).show(); - - } - }); - viewHolder.wk_showmore.setText(Html.fromHtml(context.getResources().getString(R.string.seemore))); - viewHolder.wk_showmore.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (viewHolder.infolayout.getVisibility() == View.GONE) - viewHolder.infolayout.setVisibility(View.VISIBLE); - else - viewHolder.infolayout.setVisibility(View.GONE); - } - }); - - synchronized (this){ - new DetailLinkLoader(viewHolder).execute(uri, String.valueOf(i)); - } - } - - public void setData(List workflowList){ - this.workflowList = workflowList; - } - @Override - public long getItemId(int i) { - return workflowList.get(i).getId(); - } - - @Override - public int getItemCount() { - return workflowList.size(); - } - - public Workflow getItem(int position){ - return workflowList.get(position); - } - - public void addWorkflow(Workflow wk){ - workflowList.add(wk); - } - - public static class ViewHolder extends RecyclerView.ViewHolder { - public final ImageView author_profile; - public final TextView author_name, wk_title,wk_showmore,wk_description; - public final Button btn_view_workflow; - public final Button btn_download_workflow; - public final Button btn_mark_workflow; - public final LinearLayout infolayout; - - public ViewHolder(View v) { - super(v); - infolayout = (LinearLayout) v.findViewById(R.id.layoutinfo); - //cache text fields - author_profile = (ImageView) v.findViewById(R.id.author_profile_image); - author_name = (TextView) v.findViewById(R.id.workflow_author); - wk_title = (TextView) v.findViewById(R.id.workflow_title); - wk_showmore = (TextView) v.findViewById(R.id.show_more); - // wk_created = (TextView) v.findViewById(R.id.workflow_datecreated); - // wk_modified = (TextView) v.findViewById(R.id.workflow_dateupdated); - wk_description = (TextView) v.findViewById(R.id.workflow_brief_description); - //cache buttons - btn_download_workflow = (Button) v.findViewById(R.id.button_download_workflow); - btn_mark_workflow = (Button) v.findViewById(R.id.button_mark_workflow); - btn_view_workflow = (Button) v.findViewById(R.id.button_view_workflow); - } - } - - /** - * Loads partially details of a given workflow to retrieve author information - */ - private class DetailLinkLoader extends AsyncTask{ - ViewHolder mViewHolder; - - public DetailLinkLoader(ViewHolder vh){ - this.mViewHolder = vh; - } - - @Override - protected Void doInBackground(String ... strings) { - URL url = null; - HttpURLConnection connection = null; - try { - url = new URL(strings[0]); //fetch workflow detail - connection = (HttpURLConnection) url.openConnection(); - connection.setDoInput(true); - connection.connect(); - InputStream input = connection.getInputStream(); - IRule avatarRule = new MyExperimentXmlParserRules.UploaderRule(IRule.Type.ATTRIBUTE,"/workflow/uploader", "resource","uri","id"); - IRule uploaderRule = new MyExperimentXmlParserRules.UploaderRule(IRule.Type.CHARACTER,"/workflow/uploader"); - WorkflowDetailParser detailMinParser = new WorkflowDetailParser(new IRule[]{avatarRule,uploaderRule}); - detailMinParser.parse(input, new User(strings[1], this.mViewHolder)); - - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - - } - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/broadcastreceivers/WorkflowDownloadReceiver.java b/app/src/main/java/org/apache/taverna/mobile/broadcastreceivers/WorkflowDownloadReceiver.java deleted file mode 100644 index 0657b468..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/broadcastreceivers/WorkflowDownloadReceiver.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.apache.taverna.mobile.broadcastreceivers; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import android.app.DownloadManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.utils.WorkflowDownloadManager; - -public class WorkflowDownloadReceiver extends BroadcastReceiver { - public WorkflowDownloadReceiver() { - } - - @Override - public void onReceive(Context context, Intent intent) { - - long receivedID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1L); - DownloadManager mgr = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); - WorkflowDownloadManager wdm = new WorkflowDownloadManager(context, mgr); - - DownloadManager.Query query = new DownloadManager.Query(); //ask for information about the download queue - query.setFilterById(receivedID); - Cursor cur = mgr.query(query); - int index = cur.getColumnIndex(DownloadManager.COLUMN_STATUS); -// String workflow = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME)); - - if(cur.moveToFirst()) { - if(cur.getInt(index) == DownloadManager.STATUS_SUCCESSFUL){ - wdm.sendNotification(context.getResources().getString(R.string.downloadcomplete)); - }else{ - wdm.sendNotification(context.getResources().getString(R.string.downloadfailed)); - } - }else{ - wdm.sendNotification(context.getResources().getString(R.string.downloadfailed)); - } - cur.close(); - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/customviews/WorkflowPreviewImageView.java b/app/src/main/java/org/apache/taverna/mobile/customviews/WorkflowPreviewImageView.java deleted file mode 100644 index 5f5276ea..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/customviews/WorkflowPreviewImageView.java +++ /dev/null @@ -1,295 +0,0 @@ -package org.apache.taverna.mobile.customviews; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Matrix; -import android.graphics.PointF; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.ScaleGestureDetector; -import android.view.View; -import android.widget.ImageView; - -/** - * Created by Akah Harvey on 6/29/15. - */ -public class WorkflowPreviewImageView extends ImageView{ - Matrix matrix = new Matrix(); - - static final int NONE = 0; - static final int DRAG = 1; - static final int ZOOM = 2; - static final int CLICK = 3; - int mode = NONE; - - PointF last = new PointF(); - PointF start = new PointF(); - float minScale = 1f; - float maxScale = 4f; - float[] m; - - float redundantXSpace, redundantYSpace; - float width, height; - float saveScale = 1f; - float right, bottom, origWidth, origHeight, bmWidth, bmHeight; - - ScaleGestureDetector mScaleDetector; - Context context; - - public WorkflowPreviewImageView(Context context, AttributeSet attr) - { - super(context, attr); - super.setClickable(true); - this.context = context; - mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); - matrix.setTranslate(1f, 1f); - m = new float[9]; - setImageMatrix(matrix); - setScaleType(ScaleType.MATRIX); - - setOnTouchListener(new OnTouchListener() - { - - @Override - public boolean onTouch(View v, MotionEvent event) - { - mScaleDetector.onTouchEvent(event); - - matrix.getValues(m); - float x = m[Matrix.MTRANS_X]; - float y = m[Matrix.MTRANS_Y]; - PointF curr = new PointF(event.getX(), event.getY()); - - switch (event.getAction()) - { - //when one finger is touching - //set the mode to DRAG - case MotionEvent.ACTION_DOWN: - last.set(event.getX(), event.getY()); - start.set(last); - mode = DRAG; - break; - //when two fingers are touching - //set the mode to ZOOM - case MotionEvent.ACTION_POINTER_DOWN: - last.set(event.getX(), event.getY()); - start.set(last); - mode = ZOOM; - break; - //when a finger moves - //If mode is applicable move image - case MotionEvent.ACTION_MOVE: - //if the mode is ZOOM or - //if the mode is DRAG and already zoomed - if (mode == ZOOM || (mode == DRAG && saveScale > minScale)) - { - float deltaX = curr.x - last.x;// x difference - float deltaY = curr.y - last.y;// y difference - float scaleWidth = Math.round(origWidth * saveScale);// width after applying current scale - float scaleHeight = Math.round(origHeight * saveScale);// height after applying current scale - //if scaleWidth is smaller than the views width - //in other words if the image width fits in the view - //limit left and right movement - if (scaleWidth < width) - { - deltaX = 0; - if (y + deltaY > 0) - deltaY = -y; - else if (y + deltaY < -bottom) - deltaY = -(y + bottom); - } - //if scaleHeight is smaller than the views height - //in other words if the image height fits in the view - //limit up and down movement - else if (scaleHeight < height) - { - deltaY = 0; - if (x + deltaX > 0) - deltaX = -x; - else if (x + deltaX < -right) - deltaX = -(x + right); - } - //if the image doesnt fit in the width or height - //limit both up and down and left and right - else - { - if (x + deltaX > 0) - deltaX = -x; - else if (x + deltaX < -right) - deltaX = -(x + right); - - if (y + deltaY > 0) - deltaY = -y; - else if (y + deltaY < -bottom) - deltaY = -(y + bottom); - } - //move the image with the matrix - matrix.postTranslate(deltaX, deltaY); - //set the last touch location to the current - last.set(curr.x, curr.y); - } - break; - //first finger is lifted - case MotionEvent.ACTION_UP: - mode = NONE; - int xDiff = (int) Math.abs(curr.x - start.x); - int yDiff = (int) Math.abs(curr.y - start.y); - if (xDiff < CLICK && yDiff < CLICK) - performClick(); - break; - // second finger is lifted - case MotionEvent.ACTION_POINTER_UP: - mode = NONE; - break; - } - setImageMatrix(matrix); - invalidate(); - return true; - } - - }); - } - - @Override - public void setImageBitmap(Bitmap bm) - { - super.setImageBitmap(bm); - bmWidth = bm.getWidth(); - bmHeight = bm.getHeight(); - } - - public void setMaxZoom(float x) - { - maxScale = x; - } - - private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener - { - - @Override - public boolean onScaleBegin(ScaleGestureDetector detector) - { - mode = ZOOM; - return true; - } - - @Override - public boolean onScale(ScaleGestureDetector detector) - { - float mScaleFactor = detector.getScaleFactor(); - float origScale = saveScale; - saveScale *= mScaleFactor; - if (saveScale > maxScale) - { - saveScale = maxScale; - mScaleFactor = maxScale / origScale; - } - else if (saveScale < minScale) - { - saveScale = minScale; - mScaleFactor = minScale / origScale; - } - right = width * saveScale - width - (2 * redundantXSpace * saveScale); - bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); - if (origWidth * saveScale <= width || origHeight * saveScale <= height) - { - matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2); - if (mScaleFactor < 1) - { - matrix.getValues(m); - float x = m[Matrix.MTRANS_X]; - float y = m[Matrix.MTRANS_Y]; - if (mScaleFactor < 1) - { - if (Math.round(origWidth * saveScale) < width) - { - if (y < -bottom) - matrix.postTranslate(0, -(y + bottom)); - else if (y > 0) - matrix.postTranslate(0, -y); - } - else - { - if (x < -right) - matrix.postTranslate(-(x + right), 0); - else if (x > 0) - matrix.postTranslate(-x, 0); - } - } - } - } - else - { - matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY()); - matrix.getValues(m); - float x = m[Matrix.MTRANS_X]; - float y = m[Matrix.MTRANS_Y]; - if (mScaleFactor < 1) { - if (x < -right) - matrix.postTranslate(-(x + right), 0); - else if (x > 0) - matrix.postTranslate(-x, 0); - if (y < -bottom) - matrix.postTranslate(0, -(y + bottom)); - else if (y > 0) - matrix.postTranslate(0, -y); - } - } - return true; - } - } - - @Override - protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) - { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - width = MeasureSpec.getSize(widthMeasureSpec); - height = MeasureSpec.getSize(heightMeasureSpec); - //Fit to screen. - float scale; - float scaleX = width / bmWidth; - float scaleY = height / bmHeight; - scale = Math.min(scaleX, scaleY); - matrix.setScale(scale, scale); - setImageMatrix(matrix); - saveScale = 1f; - - // Center the image - redundantYSpace = height - (scale * bmHeight) ; - redundantXSpace = width - (scale * bmWidth); - redundantYSpace /= 2; - redundantXSpace /= 2; - - matrix.postTranslate(redundantXSpace, redundantYSpace); - - origWidth = width - 2 * redundantXSpace; - origHeight = height - 2 * redundantYSpace; - right = width * saveScale - width - (2 * redundantXSpace * saveScale); - bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); - setImageMatrix(matrix); - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/DataManager.java b/app/src/main/java/org/apache/taverna/mobile/data/DataManager.java index d41accf6..707857c1 100644 --- a/app/src/main/java/org/apache/taverna/mobile/data/DataManager.java +++ b/app/src/main/java/org/apache/taverna/mobile/data/DataManager.java @@ -1,34 +1,223 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.taverna.mobile.data; -import org.apache.taverna.mobile.data.model.DetailAnnouncement; +import org.apache.taverna.mobile.data.local.DBHelper; +import org.apache.taverna.mobile.data.local.PreferencesHelper; import org.apache.taverna.mobile.data.model.Announcements; +import org.apache.taverna.mobile.data.model.DetailAnnouncement; +import org.apache.taverna.mobile.data.model.License; +import org.apache.taverna.mobile.data.model.PlayerWorkflow; +import org.apache.taverna.mobile.data.model.PlayerWorkflowDetail; +import org.apache.taverna.mobile.data.model.Search; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.data.model.Workflows; import org.apache.taverna.mobile.data.remote.BaseApiManager; -import rx.Observable; +import java.util.List; +import java.util.Map; -/** - * Created by Sagar - */ +import javax.inject.Inject; +import javax.inject.Singleton; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.functions.Function; +import okhttp3.RequestBody; +import okhttp3.ResponseBody; + +@Singleton public class DataManager { - public BaseApiManager mBaseApiManager = new BaseApiManager(); + private BaseApiManager mBaseApiManager; + + private DBHelper mDBHelper; + + private PreferencesHelper mPreferencesHelper; + + @Inject + public DataManager(BaseApiManager baseApiManager, DBHelper dbHelper, PreferencesHelper + mPreferencesHelper) { + this.mPreferencesHelper = mPreferencesHelper; + this.mBaseApiManager = baseApiManager; + this.mDBHelper = dbHelper; + } + + public DBHelper getDBHelper() { + return mDBHelper; + } - public DataManager(){ + /** + * @return PreferenceHelper + */ + public PreferencesHelper getPreferencesHelper() { + return mPreferencesHelper; } /** - * * @return List of all Announcement */ - public Observable getAllAnnouncement(int pageNumber){ - return mBaseApiManager.getTavernaApi().getAllAnnouncements(pageNumber); + public Observable getAllAnnouncement(Map options) { + return mBaseApiManager.getTavernaApi().getAllAnnouncements( options); } /** - * * @return Detail of Announcement */ - public Observable getAnnouncementDetail(String id){ + public Observable getAnnouncementDetail(String id) { return mBaseApiManager.getTavernaApi().getAnnouncement(id); } + + /** + * @return List of all Workflow + */ + public Observable getAllWorkflow(Map options) { + return mBaseApiManager.getTavernaApi().getAllWorkflows(options) + .concatMap(new Function>() { + @Override + public ObservableSource apply(Workflows workflows) + throws Exception { + return mDBHelper.syncWorkflows(workflows); + } + }); + } + + /** + * @return Detail of Workflow + */ + + public Observable getDetailWorkflow(String id, Map options) { + return mBaseApiManager.getTavernaApi().getDetailWorkflow(id, options) + .concatMap(new Function>() { + @Override + public ObservableSource apply(Workflow workflow) + throws Exception { + return mDBHelper.syncWorkflow(workflow); + } + }); + } + + /** + * @return Detail of User + */ + + public Observable getUserDetail(String id, Map options) { + return mBaseApiManager.getTavernaApi().getUserDetail(id, options); + } + + /** + * @return Detail of Licence + */ + + public Observable getLicenseDetail(String id, Map options) { + return mBaseApiManager.getTavernaApi().getLicenseDetail(id, options); + } + + /** + * @return Is Workflow toggle Favourite or not + */ + + public Observable setFavoriteWorkflow(String id) { + return mDBHelper.setFavouriteWorkflow(id); + } + + /** + * @return Is Workflow Favourite or not + */ + + public Observable getFavoriteWorkflow(String id) { + return mDBHelper.getFavouriteWorkflow(id); + } + + /** + * @return Favourite Workflow list + */ + + public Observable> getFavoriteWorkflowList() { + return mDBHelper.getFavouriteWorkflow(); + } + + /** + * @param id is the id of workflow + * @return Favourite Workflow Detail from DBhelper + */ + + public Observable getFavoriteDetailWorkflow(String id) { + return mDBHelper.getFavouriteWorkflowDetail(id); + } + + /** + * @param credentials is base64 encoded credential + * @param flagLogin is used to maintain the Remain login or not + * @return User Detail if valid credentials + */ + + public Observable getLoginUserDetail(String credentials, final boolean flagLogin) { + return mBaseApiManager.getTavernaApi().getLoginUserDetail(credentials) + .concatMap(new Function>() { + @Override + public ObservableSource apply(User user) throws Exception { + mPreferencesHelper.setLoggedInFlag(flagLogin); + return mPreferencesHelper.saveUserDetail(user); + } + }); + } + + /** + * @param url is Workflow's content xml URL + * @return OkHTTP ResponseBody of download file + */ + public Observable downloadWorkflowContent(String url) { + return mBaseApiManager.getTavernaApi().downloadWorkflowContent(url); + } + + /** + * @param body is body of upload workflow's detail + * @param baseAuth is base64 encoded credential + * @return Workflow's ID + */ + public Observable uploadWorkflowContent(RequestBody body, String baseAuth) { + return mBaseApiManager.getTavernaPlayerApi().uploadWorkflow(body, baseAuth); + } + + /** + * @param credentials is base64 encoded credential + * @param flagLogin is used to maintain the Remain login or not + * @return okHTTP ResponseBody + */ + + public Observable authPlayerUserLoginDetail(final String credentials, + final boolean flagLogin) { + return mBaseApiManager.getTavernaPlayerApi().playerlogin(credentials); + + } + + public Observable getWorkflowDetail(int id) { + return mBaseApiManager.getTavernaPlayerApi().getWorkflowDetail(id); + } + + public Observable getMyWorkflows(String userID, Map options) { + return mBaseApiManager.getTavernaApi().getUserDetail(userID, options); + } + + public Observable getSearchWorkflowResult(Map options) { + return mBaseApiManager.getTavernaApi().getSearchWorkflowResult(options); + } } \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/local/DBHelper.java b/app/src/main/java/org/apache/taverna/mobile/data/local/DBHelper.java new file mode 100644 index 00000000..352c1d8d --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/local/DBHelper.java @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.local; + +import android.support.annotation.Nullable; + +import com.raizlabs.android.dbflow.sql.language.SQLite; + +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.data.model.Workflow_Table; +import org.apache.taverna.mobile.data.model.Workflows; + +import java.util.List; +import java.util.concurrent.Callable; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; + + +@Singleton +public class DBHelper { + + public static final String SVG_URI = "svgURI"; + + public static final String JPG_URI = "jpgURI"; + + @Inject + public DBHelper() { + + } + + @Nullable + public Observable syncWorkflows(final Workflows workflows) { + return Observable.defer(new Callable>() { + @Override + public ObservableSource call() throws Exception { + + for (Workflow workflow : workflows.getWorkflowList()) { + if (!workflow.exists()) { + workflow.setFavourite(false); + workflow.save(); + } else { + + updateWorkflow(workflow).save(); + } + } + + return Observable.just(workflows); + } + }); + } + + private Workflow updateWorkflow(Workflow workflow) { + + Workflow workflow1 = SQLite.select() + .from(Workflow.class) + .where(Workflow_Table.id.eq(workflow.getId())) + .querySingle(); + + if (workflow1 != null) { + if (workflow.getDescription() != null) { + + workflow1.setDescription(workflow.getDescription()); + } + if (workflow.getUpdatedAt() != null) { + + workflow1.setUpdatedAt(workflow.getUpdatedAt()); + } + if (workflow.getSvgUri() != null) { + + workflow1.setSvgUri(workflow.getSvgUri()); + } + if (workflow.getLicenseType() != null) { + + workflow1.setLicenseType(workflow.getLicenseType()); + } + if (workflow.getContentUri() != null) { + + workflow1.setContentUri(workflow.getContentUri()); + } + if (workflow.getContentType() != null) { + + workflow1.setContentUri(workflow.getContentType()); + } + if (workflow.getElementId() != null) { + + workflow1.setElementId(workflow.getElementId()); + } + workflow1.setFavourite(workflow1.isFavourite()); + workflow1.setTitle(workflow.getTitle()); + workflow1.setType(workflow.getType()); + workflow1.setUploader(workflow.getUploader()); + workflow1.setPreviewUri(workflow.getPreviewUri()); + workflow1.setCreatedAt(workflow.getCreatedAt()); + workflow1.setResource(workflow.getResource()); + workflow1.setUri(workflow.getUri()); + workflow1.setId(workflow.getId()); + workflow1.setVersion(workflow.getVersion()); + + } + return workflow1; + } + + public Observable syncWorkflow(final Workflow workflow) { + return Observable.defer(new Callable>() { + @Override + public ObservableSource call() throws Exception { + if (!workflow.exists()) { + workflow.save(); + } else { + updateWorkflow(workflow).save(); + } + return Observable.just(workflow); + } + }); + } + + public Observable setFavouriteWorkflow(final String id) { + return Observable.defer(new Callable>() { + @Override + public ObservableSource call() throws Exception { + return Observable.just(updateFavouriteWorkflow(id)); + } + }); + } + + + public Observable getFavouriteWorkflow(final String id) { + return Observable.defer(new Callable>() { + @Override + public ObservableSource call() throws Exception { + Workflow workflow = SQLite.select() + .from(Workflow.class) + .where(Workflow_Table.id.eq(id)) + .querySingle(); + if (workflow != null) { + return Observable.just(workflow.isFavourite()); + } else { + return Observable.just(null); + } + } + }); + } + + public boolean updateFavouriteWorkflow(String id) { + + Workflow workflow1 = SQLite.select() + .from(Workflow.class) + .where(Workflow_Table.id.eq(id)) + .querySingle(); + + if (workflow1 != null) { + workflow1.setFavourite(!workflow1.isFavourite()); + workflow1.save(); + return true; + } + + return false; + } + + public Observable> getFavouriteWorkflow() { + return Observable.defer(new Callable>>() { + @Override + public ObservableSource> call() throws Exception { + return Observable.just(SQLite.select() + .from(Workflow.class) + .where(Workflow_Table.favourite.eq(true)) + .queryList()); + } + }); + } + + public Observable getFavouriteWorkflowDetail(final String id) { + return Observable.defer(new Callable>() { + @Override + public ObservableSource call() throws Exception { + return Observable.just(SQLite.select() + .from(Workflow.class) + .where(Workflow_Table.id.eq(id)) + .querySingle()); + } + }); + } + + + + public void clearFavouriteWorkflow() { + List workflowList = SQLite.select() + .from(Workflow.class) + .where(Workflow_Table.favourite.eq(true)) + .queryList(); + + for (Workflow workflow : workflowList) { + workflow.setFavourite(!workflow.isFavourite()); + workflow.save(); + } + + } + + +} + diff --git a/app/src/main/java/org/apache/taverna/mobile/data/local/PreferencesHelper.java b/app/src/main/java/org/apache/taverna/mobile/data/local/PreferencesHelper.java new file mode 100644 index 00000000..3fafe7cb --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/local/PreferencesHelper.java @@ -0,0 +1,230 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.local; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.injection.ApplicationContext; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import java.util.concurrent.Callable; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; + +@Singleton +public class PreferencesHelper { + + public static final String PREF_KEY_PLAYER_LOGGED_IN = "pref_player_logged_in"; + + public static final String PREF_KEY_PLAYER_URL = "pref_key_player_url"; + + private static final String PREF_KEY_USER_ID = "pref_user_id"; + + private static final String PREF_KEY_USER_NAME = "pref_user_name"; + + private static final String PREF_KEY_USER_DESCRIPTION = "pref_user_description"; + + private static final String PREF_KEY_USER_EMAIL = "pref_user_email"; + + private static final String PREF_KEY_USER_AVATAR = "pref_user_avatar"; + + private static final String PREF_KEY_USER_CITY = "pref_user_city"; + + private static final String PREF_KEY_USER_COUNTRY = "pref_user_country"; + + private static final String PREF_KEY_USER_WEBSITE = "pref_user_website"; + + private static final String PREF_KEY_PLAYER_CREDENTIAL = "pref_player_credential"; + private static final String PREF_KEY_LOGGED_IN = "pref_key_logged_in"; + + public static final String PLAYER_DEFAULT_URL = "http://139.59.28.12:3000/"; + + public static final String PREF_KEY_PLAYER_USER_EMAIL = "pref_user"; + + public static final String PREF_KEY_PLAYER_USER_PASSWORD = "pref_password"; + + private static final String IS_FIRST_TIME_LAUNCH = "IsFirstTimeLaunch"; + + private final SharedPreferences sharedPref; + private Context mContext; + + @Inject + public PreferencesHelper(@ApplicationContext Context context) { + sharedPref = PreferenceManager.getDefaultSharedPreferences(context); + mContext = context; + } + + public void clear() { + sharedPref.edit().clear().apply(); + } + + public boolean isLoggedInFlag() { + return sharedPref.getBoolean(mContext.getString(R.string.pref_key_logged_in), false); + } + + public void setLoggedInFlag(Boolean flag) { + sharedPref.edit().putBoolean(mContext.getString(R.string.pref_key_logged_in), flag).apply(); + } + + public String getUserWebsite() { + return sharedPref.getString(PREF_KEY_USER_WEBSITE, null); + } + + private void setUserWebsite(String website) { + sharedPref.edit().putString(PREF_KEY_USER_WEBSITE, website).apply(); + } + + public String getUserCountry() { + return sharedPref.getString(PREF_KEY_USER_COUNTRY, null); + } + + private void setUserCountry(String country) { + sharedPref.edit().putString(PREF_KEY_USER_COUNTRY, country).apply(); + } + + public String getUserCity() { + return sharedPref.getString(PREF_KEY_USER_CITY, null); + } + + private void setUserCity(String city) { + sharedPref.edit().putString(PREF_KEY_USER_CITY, city).apply(); + } + + public String getUserID() { + return sharedPref.getString(PREF_KEY_USER_ID, null); + } + + private void setUserID(String userID) { + sharedPref.edit().putString(PREF_KEY_USER_ID, userID).apply(); + } + + public String getUserName() { + return sharedPref.getString(PREF_KEY_USER_NAME, null); + } + + private void setUserName(String userName) { + sharedPref.edit().putString(PREF_KEY_USER_NAME, userName).apply(); + + } + + public String getUserDescription() { + return sharedPref.getString(PREF_KEY_USER_DESCRIPTION, null); + } + + private void setUserDescription(String userDescription) { + sharedPref.edit().putString(PREF_KEY_USER_DESCRIPTION, userDescription).apply(); + } + + public String getPlayerUserEmail() { + return sharedPref.getString(mContext.getString(R.string.pref_key_player_user), ""); + } + + public String getPlayerUserPassword() { + return sharedPref.getString(mContext.getString(R.string.pref_key_player_password), ""); + } + + public String getUserEmail() { + return sharedPref.getString(PREF_KEY_USER_EMAIL, null); + } + + private void setUserEmail(String userEmail) { + sharedPref.edit().putString(PREF_KEY_USER_EMAIL, userEmail).apply(); + } + + public String getUserAvatarUrl() { + return sharedPref.getString(PREF_KEY_USER_AVATAR, null); + } + + private void setUserAvatar(String userAvatar) { + sharedPref.edit().putString(PREF_KEY_USER_AVATAR, userAvatar).apply(); + } + + public void setFirstTimeLaunch(boolean isFirstTime) { + sharedPref.edit().putBoolean(IS_FIRST_TIME_LAUNCH, isFirstTime); + sharedPref.edit().commit(); + } + + public boolean isFirstTimeLaunch() { + return sharedPref.getBoolean(IS_FIRST_TIME_LAUNCH, true); + } + + public Observable saveUserDetail(final User user) { + return Observable.defer(new Callable>() { + @Override + public ObservableSource call() throws Exception { + if (user.getElementId() != null) { + setUserID(user.getElementId()); + } + if (user.getName() != null) { + setUserName(user.getName()); + } + if (user.getDescription() != null) { + setUserDescription(user.getDescription()); + } + if (user.getEmail() != null) { + setUserEmail(user.getEmail()); + } + if (user.getAvatar().getResource() != null) { + setUserAvatar(user.getAvatar().getResource()); + } + if (user.getCity() != null) { + setUserCity(user.getCity()); + } + if (user.getCountry() != null) { + setUserCountry(user.getCountry()); + } + if (user.getWebsite() != null) { + setUserWebsite(user.getWebsite()); + } + + return Observable.just(user); + } + }); + } + + public boolean isUserPlayerLoggedInFlag() { + return sharedPref.getBoolean(PREF_KEY_PLAYER_LOGGED_IN, false); + } + + public void setUserPlayerLoggedInFlag(Boolean flag) { + sharedPref.edit().putBoolean(PREF_KEY_PLAYER_LOGGED_IN, flag).apply(); + + } + + public void setUserPlayerLoggedInFlagAndCredential(Boolean flag, String credential) { + sharedPref.edit().putBoolean(PREF_KEY_PLAYER_LOGGED_IN, flag).apply(); + sharedPref.edit().putString(PREF_KEY_PLAYER_CREDENTIAL, credential).apply(); + } + + public String getUserPlayerCredential() { + return sharedPref.getString(PREF_KEY_PLAYER_CREDENTIAL, ""); + } + + public String getPlayerURL() { + return sharedPref.getString(mContext.getString(R.string.pref_key_player_url), + PLAYER_DEFAULT_URL); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/local/TavernaBaseModel.java b/app/src/main/java/org/apache/taverna/mobile/data/local/TavernaBaseModel.java new file mode 100644 index 00000000..09a22c21 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/local/TavernaBaseModel.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.local; + +import com.raizlabs.android.dbflow.structure.BaseModel; + + +public class TavernaBaseModel extends BaseModel { +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/local/TavernaDatabase.java b/app/src/main/java/org/apache/taverna/mobile/data/local/TavernaDatabase.java new file mode 100644 index 00000000..a27fc0ff --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/local/TavernaDatabase.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.local; + +import com.raizlabs.android.dbflow.annotation.Database; + +@Database(name = TavernaDatabase.NAME, + version = TavernaDatabase.VERSION, + foreignKeysSupported = true) +public class TavernaDatabase { + + + public static final String NAME = "Taverna"; + + + public static final int VERSION = 1; +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Announcement.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Announcement.java index 7f32e5a0..b9ab3cf5 100644 --- a/app/src/main/java/org/apache/taverna/mobile/data/model/Announcement.java +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Announcement.java @@ -1,24 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.taverna.mobile.data.model; -import android.os.Parcel; -import android.os.Parcelable; - import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Text; -/** - * Created by Sagar - */ +import android.os.Parcel; +import android.os.Parcelable; + public class Announcement implements Parcelable { @Attribute(name = "resource", required = false) String resource; - @Attribute(name = "uri", required = false) String uri; - @Attribute(name = "id", required = false) String id; @@ -33,7 +46,6 @@ public void setContent(String content) { this.content = content; } - public String getResource() { return this.resource; } @@ -42,7 +54,6 @@ public void setResource(String _value) { this.resource = _value; } - public String getUri() { return this.uri; } @@ -51,7 +62,6 @@ public void setUri(String _value) { this.uri = _value; } - public String getId() { return this.id; } @@ -60,7 +70,6 @@ public void setId(String _value) { this.id = _value; } - @Override public int describeContents() { return 0; @@ -77,14 +86,15 @@ public void writeToParcel(Parcel dest, int flags) { public Announcement() { } - protected Announcement(Parcel in) { + public Announcement(Parcel in) { this.resource = in.readString(); this.uri = in.readString(); this.id = in.readString(); this.content = in.readString(); } - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public static final Parcelable.Creator CREATOR = new Parcelable + .Creator() { @Override public Announcement createFromParcel(Parcel source) { return new Announcement(source); diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Announcements.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Announcements.java index 01454daa..c66b3e00 100644 --- a/app/src/main/java/org/apache/taverna/mobile/data/model/Announcements.java +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Announcements.java @@ -1,27 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.taverna.mobile.data.model; -import android.os.Parcel; -import android.os.Parcelable; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; +import android.os.Parcel; +import android.os.Parcelable; + import java.util.List; -/** - * Created by Sagar - */ @Root(name = "announcements") public class Announcements implements Parcelable { @ElementList(name = "announcement", inline = true, required = false) List announcement; + public List getAnnouncement() { + return this.announcement; + } - - - public List getAnnouncement() { return this.announcement; } - public void setAnnouncement(List _value) { this.announcement = _value; } - + public void setAnnouncement(List _value) { + this.announcement = _value; + } @Override public int describeContents() { @@ -40,7 +57,8 @@ protected Announcements(Parcel in) { this.announcement = in.createTypedArrayList(Announcement.CREATOR); } - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public static final Parcelable.Creator CREATOR = new Parcelable + .Creator() { @Override public Announcements createFromParcel(Parcel source) { return new Announcements(source); diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Author.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Author.java index 111f64fd..595d63e6 100644 --- a/app/src/main/java/org/apache/taverna/mobile/data/model/Author.java +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Author.java @@ -1,82 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.taverna.mobile.data.model; +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Text; + import android.os.Parcel; import android.os.Parcelable; -import org.simpleframework.xml.Attribute; -import org.simpleframework.xml.Text; -/** - * Created by Sagar - */ public class Author implements Parcelable { - @Attribute(name="resource", required = false) - String resource; + @Attribute(name = "resource", required = false) + String resource; + @Attribute(name = "uri", required = false) + String uri; - @Attribute(name="uri", required = false) - String uri; + @Attribute(name = "id", required = false) + String id; + @Text + String content; - @Attribute(name="id", required = false) - String id; + public String getContent() { + return content; + } - @Text - String content; + public void setContent(String content) { + this.content = content; + } - public String getContent() { - return content; - } - public void setContent(String content) { - this.content = content; - } + public String getResource() { + return this.resource; + } + public void setResource(String _value) { + this.resource = _value; + } - public String getResource() { return this.resource; } - public void setResource(String _value) { this.resource = _value; } + public String getUri() { + return this.uri; + } + public void setUri(String _value) { + this.uri = _value; + } - public String getUri() { return this.uri; } - public void setUri(String _value) { this.uri = _value; } + public String getId() { + return this.id; + } + public void setId(String _value) { + this.id = _value; + } - public String getId() { return this.id; } - public void setId(String _value) { this.id = _value; } + @Override + public int describeContents() { + return 0; + } + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); + dest.writeString(this.content); + } - @Override - public int describeContents() { - return 0; - } + public Author() { + } - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(this.resource); - dest.writeString(this.uri); - dest.writeString(this.id); - dest.writeString(this.content); - } + protected Author(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); + this.content = in.readString(); + } - public Author() { + public static final Creator CREATOR = new Creator() { + @Override + public Author createFromParcel(Parcel source) { + return new Author(source); } - protected Author(Parcel in) { - this.resource = in.readString(); - this.uri = in.readString(); - this.id = in.readString(); - this.content = in.readString(); + @Override + public Author[] newArray(int size) { + return new Author[size]; } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public Author createFromParcel(Parcel source) { - return new Author(source); - } - - @Override - public Author[] newArray(int size) { - return new Author[size]; - } - }; + }; } \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Avatar.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Avatar.java new file mode 100644 index 00000000..3dd069a0 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Avatar.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + + +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Root; + +import android.os.Parcel; +import android.os.Parcelable; + +@Root(name = "avatar") +public class Avatar implements Parcelable { + + @Attribute(name = "resource", required = false) + private String resource; + + @Attribute(name = "uri", required = false) + private String uri; + + @Attribute(name = "id", required = false) + private String id; + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); + } + + public Avatar() { + } + + protected Avatar(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public Avatar createFromParcel(Parcel source) { + return new Avatar(source); + } + + @Override + public Avatar[] newArray(int size) { + return new Avatar[size]; + } + }; +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/DetailAnnouncement.java b/app/src/main/java/org/apache/taverna/mobile/data/model/DetailAnnouncement.java index d291fe36..10d9718c 100644 --- a/app/src/main/java/org/apache/taverna/mobile/data/model/DetailAnnouncement.java +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/DetailAnnouncement.java @@ -1,18 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.taverna.mobile.data.model; -import android.os.Parcel; -import android.os.Parcelable; - import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; -/** - * Created by Sagar - */ +import android.os.Parcel; +import android.os.Parcelable; + + @Root(name = "announcement") public class DetailAnnouncement implements Parcelable { + @Attribute(name = "resource", required = false) + String resource; + + @Attribute(name = "uri", required = false) + String uri; + + @Attribute(name = "id", required = false) + String id; + @Element(name = "author") private Author author; @@ -25,17 +50,6 @@ public class DetailAnnouncement implements Parcelable { @Element(name = "created-at") private String date; - @Attribute(name = "resource", required = false) - String resource; - - - @Attribute(name = "uri", required = false) - String uri; - - - @Attribute(name = "id", required = false) - String id; - @Element(name = "id") private String idElement; @@ -55,7 +69,6 @@ public void setResource(String _value) { this.resource = _value; } - public String getUri() { return this.uri; } @@ -64,7 +77,6 @@ public void setUri(String _value) { this.uri = _value; } - public String getId() { return this.id; } @@ -73,7 +85,6 @@ public void setId(String _value) { this.id = _value; } - public Author getAuthor() { return author; } @@ -106,7 +117,6 @@ public void setDate(String date) { this.date = date; } - @Override public int describeContents() { return 0; @@ -114,13 +124,13 @@ public int describeContents() { @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); dest.writeParcelable(this.author, flags); dest.writeString(this.title); dest.writeString(this.text); dest.writeString(this.date); - dest.writeString(this.resource); - dest.writeString(this.uri); - dest.writeString(this.id); dest.writeString(this.idElement); } @@ -128,17 +138,17 @@ public DetailAnnouncement() { } protected DetailAnnouncement(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); this.author = in.readParcelable(Author.class.getClassLoader()); this.title = in.readString(); this.text = in.readString(); this.date = in.readString(); - this.resource = in.readString(); - this.uri = in.readString(); - this.id = in.readString(); this.idElement = in.readString(); } - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public static final Creator CREATOR = new Creator() { @Override public DetailAnnouncement createFromParcel(Parcel source) { return new DetailAnnouncement(source); diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/InputsAttribute.java b/app/src/main/java/org/apache/taverna/mobile/data/model/InputsAttribute.java new file mode 100644 index 00000000..cb642260 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/InputsAttribute.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class InputsAttribute implements Parcelable { + + @SerializedName("name") + @Expose + private String name; + + @SerializedName("value") + @Expose + private Object value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.name); + } + + public InputsAttribute() { + } + + protected InputsAttribute(Parcel in) { + this.name = in.readString(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public InputsAttribute createFromParcel(Parcel source) { + return new InputsAttribute(source); + } + + @Override + public InputsAttribute[] newArray(int size) { + return new InputsAttribute[size]; + } + }; +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/License.java b/app/src/main/java/org/apache/taverna/mobile/data/model/License.java new file mode 100644 index 00000000..7b2f84fa --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/License.java @@ -0,0 +1,174 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + + +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Element; + +import android.os.Parcel; +import android.os.Parcelable; + +public class License implements Parcelable { + + @Attribute(name = "resource", required = false) + private String resource; + + @Attribute(name = "uri", required = false) + private String uri; + + @Attribute(name = "id", required = false) + private String id; + + @Element(name = "id", required = false) + private String elementId; + + @Element(name = "unique-name", required = false) + private String uniqueName; + + @Element(name = "title", required = false) + private String title; + + @Element(name = "description", required = false) + private String description; + + @Element(name = "url", required = false) + private String url; + + @Element(name = "created-at", required = false) + private String createdAt; + + public String getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getElementId() { + return elementId; + } + + public void setElementId(String elementId) { + this.elementId = elementId; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUniqueName() { + return uniqueName; + } + + public void setUniqueName(String uniqueName) { + this.uniqueName = uniqueName; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); + dest.writeString(this.elementId); + dest.writeString(this.uniqueName); + dest.writeString(this.title); + dest.writeString(this.description); + dest.writeString(this.url); + dest.writeString(this.createdAt); + } + + public License() { + } + + protected License(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); + this.elementId = in.readString(); + this.uniqueName = in.readString(); + this.title = in.readString(); + this.description = in.readString(); + this.url = in.readString(); + this.createdAt = in.readString(); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public License createFromParcel(Parcel source) { + return new License(source); + } + + @Override + public License[] newArray(int size) { + return new License[size]; + } + }; +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/LicenseType.java b/app/src/main/java/org/apache/taverna/mobile/data/model/LicenseType.java new file mode 100644 index 00000000..c76e31d7 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/LicenseType.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + + +import com.raizlabs.android.dbflow.annotation.Column; +import com.raizlabs.android.dbflow.annotation.ModelContainer; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; + +import org.apache.taverna.mobile.data.local.TavernaBaseModel; +import org.apache.taverna.mobile.data.local.TavernaDatabase; +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Text; + +import android.os.Parcel; +import android.os.Parcelable; + +@Table(database = TavernaDatabase.class) +@ModelContainer +public class LicenseType extends TavernaBaseModel implements Parcelable { + + @Column + @Attribute(name = "resource", required = false) + String resource; + + @Column + @Attribute(name = "uri", required = false) + String uri; + + @PrimaryKey + @Attribute(name = "id", required = false) + String id; + + @Column + @Text(required = false) + String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); + dest.writeString(this.content); + } + + public LicenseType() { + } + + protected LicenseType(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); + this.content = in.readString(); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public LicenseType createFromParcel(Parcel source) { + return new LicenseType(source); + } + + @Override + public LicenseType[] newArray(int size) { + return new LicenseType[size]; + } + }; +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/PlayerWorkflow.java b/app/src/main/java/org/apache/taverna/mobile/data/model/PlayerWorkflow.java new file mode 100644 index 00000000..dd13c516 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/PlayerWorkflow.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class PlayerWorkflow implements Parcelable { + + @SerializedName("id") + @Expose + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeValue(this.id); + } + + public PlayerWorkflow() { + } + + protected PlayerWorkflow(Parcel in) { + this.id = (Integer) in.readValue(Integer.class.getClassLoader()); + } + + public static final Parcelable.Creator CREATOR = new Parcelable + .Creator() { + @Override + public PlayerWorkflow createFromParcel(Parcel source) { + return new PlayerWorkflow(source); + } + + @Override + public PlayerWorkflow[] newArray(int size) { + return new PlayerWorkflow[size]; + } + }; +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/PlayerWorkflowDetail.java b/app/src/main/java/org/apache/taverna/mobile/data/model/PlayerWorkflowDetail.java new file mode 100644 index 00000000..fc943587 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/PlayerWorkflowDetail.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class PlayerWorkflowDetail implements Parcelable { + + @SerializedName("run") + @Expose + private Run run; + + public Run getRun() { + return run; + } + + public void setRun(Run run) { + this.run = run; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(this.run, flags); + } + + public PlayerWorkflowDetail() { + } + + protected PlayerWorkflowDetail(Parcel in) { + this.run = in.readParcelable(Run.class.getClassLoader()); + } + + public static final Parcelable.Creator CREATOR = new Parcelable + .Creator() { + @Override + public PlayerWorkflowDetail createFromParcel(Parcel source) { + return new PlayerWorkflowDetail(source); + } + + @Override + public PlayerWorkflowDetail[] newArray(int size) { + return new PlayerWorkflowDetail[size]; + } + }; +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Run.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Run.java new file mode 100644 index 00000000..6e22d9a0 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Run.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.ArrayList; +import java.util.List; + +public class Run implements Parcelable { + + @SerializedName("workflow_id") + @Expose + private Integer workflowId; + + @SerializedName("name") + @Expose + private String name; + + @SerializedName("inputs_attributes") + @Expose + private List inputsAttributes = new ArrayList(); + + public Integer getWorkflowId() { + return workflowId; + } + + public void setWorkflowId(Integer workflowId) { + this.workflowId = workflowId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getInputsAttributes() { + return inputsAttributes; + } + + public void setInputsAttributes(List inputsAttributes) { + this.inputsAttributes = inputsAttributes; + } + + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeValue(this.workflowId); + dest.writeString(this.name); + dest.writeList(this.inputsAttributes); + } + + public Run() { + } + + protected Run(Parcel in) { + this.workflowId = (Integer) in.readValue(Integer.class.getClassLoader()); + this.name = in.readString(); + this.inputsAttributes = new ArrayList(); + in.readList(this.inputsAttributes, InputsAttribute.class.getClassLoader()); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public Run createFromParcel(Parcel source) { + return new Run(source); + } + + @Override + public Run[] newArray(int size) { + return new Run[size]; + } + }; +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Search.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Search.java new file mode 100644 index 00000000..c3210098 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Search.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + +import java.util.List; + +@Root(name = "workflows") +public class Search { + + @Attribute(name = "query", required = false) + String query; + + @Attribute(name = "type", required = false) + String type; + + @ElementList(name = "workflow", inline = true, required = false) + List WorkflowList; + + public String getQuery() { + return query; + } + + public String getType() { + return type; + } + + public List getWorkflowList() { + return WorkflowList; + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Tag.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Tag.java new file mode 100644 index 00000000..e7a7b7e0 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Tag.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + + +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Root; +import org.simpleframework.xml.Text; + +import android.os.Parcel; +import android.os.Parcelable; +@Root(name = "tag") +public class Tag implements Parcelable { + + @Attribute(name = "resource", required = false) + String resource; + + @Attribute(name = "uri", required = false) + String uri; + + @Attribute(name = "id", required = false) + String id; + + @Text + String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); + dest.writeString(this.content); + } + + public Tag() { + } + + protected Tag(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); + this.content = in.readString(); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public Tag createFromParcel(Parcel source) { + return new Tag(source); + } + + @Override + public Tag[] newArray(int size) { + return new Tag[size]; + } + }; +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/TutorialSliderEnum.java b/app/src/main/java/org/apache/taverna/mobile/data/model/TutorialSliderEnum.java new file mode 100644 index 00000000..ec30eb6a --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/TutorialSliderEnum.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + + +import org.apache.taverna.mobile.R; + +public enum TutorialSliderEnum { + + SLIDE1(R.layout.tutorial_slide1), + SLIDE2(R.layout.tutorial_slide2), + SLIDE3(R.layout.tutorial_slide3), + SLIDE4(R.layout.tutorial_slide4); + + private int layoutId; + + TutorialSliderEnum(int layout_Id) { + layoutId = layout_Id; + } + + public int getLayoutId() { + return layoutId; + } + + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Type.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Type.java new file mode 100644 index 00000000..0137c08c --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Type.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + +import com.raizlabs.android.dbflow.annotation.Column; +import com.raizlabs.android.dbflow.annotation.ModelContainer; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; + +import org.apache.taverna.mobile.data.local.TavernaBaseModel; +import org.apache.taverna.mobile.data.local.TavernaDatabase; +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Root; +import org.simpleframework.xml.Text; + +import android.os.Parcel; +import android.os.Parcelable; + +@Table(database = TavernaDatabase.class) +@ModelContainer +@Root(name = "type") +public class Type extends TavernaBaseModel implements Parcelable { + + @Column + @Attribute(name = "resource", required = false) + String resource; + + @Column + @Attribute(name = "uri", required = false) + String uri; + + @PrimaryKey + @Attribute(name = "id", required = false) + String id; + + @Column + @Text + String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); + dest.writeString(this.content); + } + + public Type() { + } + + protected Type(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); + this.content = in.readString(); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public Type createFromParcel(Parcel source) { + return new Type(source); + } + + @Override + public Type[] newArray(int size) { + return new Type[size]; + } + }; +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Uploader.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Uploader.java new file mode 100644 index 00000000..f1fc3be9 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Uploader.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + +import com.raizlabs.android.dbflow.annotation.Column; +import com.raizlabs.android.dbflow.annotation.ModelContainer; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; + +import org.apache.taverna.mobile.data.local.TavernaBaseModel; +import org.apache.taverna.mobile.data.local.TavernaDatabase; +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Root; +import org.simpleframework.xml.Text; + +import android.os.Parcel; +import android.os.Parcelable; + +@Table(database = TavernaDatabase.class) +@ModelContainer +@Root(name = "uploader") +public class Uploader extends TavernaBaseModel implements Parcelable { + + @Column + @Attribute(name = "resource", required = false) + String resource; + + @Column + @Attribute(name = "uri", required = false) + String uri; + + @PrimaryKey + @Attribute(name = "id", required = false) + String id; + + @Column + @Text + String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); + dest.writeString(this.content); + } + + public Uploader() { + } + + protected Uploader(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); + this.content = in.readString(); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public Uploader createFromParcel(Parcel source) { + return new Uploader(source); + } + + @Override + public Uploader[] newArray(int size) { + return new Uploader[size]; + } + }; +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/User.java b/app/src/main/java/org/apache/taverna/mobile/data/model/User.java new file mode 100644 index 00000000..c052f1a4 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/User.java @@ -0,0 +1,226 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + +import android.os.Parcel; +import android.os.Parcelable; + +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +@Root(name = "user") +public class User implements Parcelable { + + @Attribute(name = "resource", required = false) + private String resource; + + @Attribute(name = "uri", required = false) + private String uri; + + @Attribute(name = "id", required = false) + private String id; + + @Element(name = "id", required = false) + private String elementId; + + @Element(name = "created-at", required = false) + private String createdAt; + + @Element(name = "name", required = false) + private String name; + + @Element(name = "description", required = false) + private String description; + + @Element(name = "email", required = false) + private String email; + + @Element(name = "city", required = false) + private String city; + + @Element(name = "country", required = false) + private String country; + + @Element(name = "website", required = false) + private String website; + + @Element(name = "avatar", required = false) + private Avatar avatar; + + @Element(name = "workflows", required = false) + private Workflows workflows; + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getElementId() { + return elementId; + } + + public void setElementId(String elementId) { + this.elementId = elementId; + } + + public String getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getWebsite() { + return website; + } + + public void setWebsite(String website) { + this.website = website; + } + + public Avatar getAvatar() { + return avatar; + } + + public void setAvatar(Avatar avatar) { + this.avatar = avatar; + } + + public User() { + } + + public Workflows getWorkflows() { + return workflows; + } + + public void setWorkflows(Workflows workflows) { + this.workflows = workflows; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); + dest.writeString(this.elementId); + dest.writeString(this.createdAt); + dest.writeString(this.name); + dest.writeString(this.description); + dest.writeString(this.email); + dest.writeString(this.city); + dest.writeString(this.country); + dest.writeString(this.website); + dest.writeParcelable(this.avatar, flags); + dest.writeParcelable(this.workflows, flags); + } + + protected User(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); + this.elementId = in.readString(); + this.createdAt = in.readString(); + this.name = in.readString(); + this.description = in.readString(); + this.email = in.readString(); + this.city = in.readString(); + this.country = in.readString(); + this.website = in.readString(); + this.avatar = in.readParcelable(Avatar.class.getClassLoader()); + this.workflows = in.readParcelable(Workflows.class.getClassLoader()); + } + + public static final Creator CREATOR = new Creator() { + @Override + public User createFromParcel(Parcel source) { + return new User(source); + } + + @Override + public User[] newArray(int size) { + return new User[size]; + } + }; +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Workflow.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Workflow.java new file mode 100644 index 00000000..a6140427 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Workflow.java @@ -0,0 +1,325 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + + +import android.os.Parcel; +import android.os.Parcelable; + +import com.raizlabs.android.dbflow.annotation.Column; +import com.raizlabs.android.dbflow.annotation.ForeignKey; +import com.raizlabs.android.dbflow.annotation.ModelContainer; +import com.raizlabs.android.dbflow.annotation.PrimaryKey; +import com.raizlabs.android.dbflow.annotation.Table; + +import org.apache.taverna.mobile.data.local.TavernaBaseModel; +import org.apache.taverna.mobile.data.local.TavernaDatabase; +import org.simpleframework.xml.Attribute; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + +import java.util.List; + + +@Table(database = TavernaDatabase.class) +@ModelContainer +@Root(name = "workflow") +public class Workflow extends TavernaBaseModel implements Parcelable { + + @Column + @Attribute(name = "resource", required = false) + String resource; + + @Column + @Attribute(name = "uri", required = false) + String uri; + + @PrimaryKey + @Attribute(name = "id", required = false) + String id; + + @Column + @Attribute(name = "version", required = false) + String version; + + @Column + @Element(name = "id", required = false) + String elementId; + + @Column + @Element(name = "title", required = false) + String title; + + @Column + @Element(name = "description", required = false) + String description; + + @Column + @ForeignKey(saveForeignKeyModel = true) + @Element(name = "type", required = false) + Type type; + + @Column + @ForeignKey(saveForeignKeyModel = true) + @Element(name = "uploader", required = false) + Uploader uploader; + + @Column + @Element(name = "created-at", required = false) + String createdAt; + + @Column + @Element(name = "updated-at", required = false) + String updatedAt; + + @Column + @Element(name = "preview", required = false) + String previewUri; + + @Column + @Element(name = "svg", required = false) + String svgUri; + + @Column + @ForeignKey(saveForeignKeyModel = true) + @Element(name = "license-type", required = false) + LicenseType licenseType; + + @Column + @Element(name = "content-uri", required = false) + String contentUri; + + @Column + @Element(name = "content-type", required = false) + String contentType; + + @ElementList(name = "tags", required = false) + List tag; + + @Column(defaultValue = "0") + Boolean favourite; + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getContentUri() { + return contentUri; + } + + public void setContentUri(String contentUri) { + this.contentUri = contentUri; + } + + public String getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getElementId() { + return elementId; + } + + public void setElementId(String elementId) { + this.elementId = elementId; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public LicenseType getLicenseType() { + return licenseType; + } + + public void setLicenseType(LicenseType licenseType) { + this.licenseType = licenseType; + } + + public String getPreviewUri() { + return previewUri; + } + + public void setPreviewUri(String previewUri) { + this.previewUri = previewUri; + } + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getSvgUri() { + return svgUri; + } + + public void setSvgUri(String svgUri) { + this.svgUri = svgUri; + } + + public List getTag() { + return tag; + } + + public void setTag(List tag) { + this.tag = tag; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public Uploader getUploader() { + return uploader; + } + + public void setUploader(Uploader uploader) { + this.uploader = uploader; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; + } + + public boolean isFavourite() { + return favourite; + } + + public void setFavourite(boolean favourite) { + this.favourite = favourite; + } + + public Workflow() { + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.resource); + dest.writeString(this.uri); + dest.writeString(this.id); + dest.writeString(this.version); + dest.writeString(this.elementId); + dest.writeString(this.title); + dest.writeString(this.description); + dest.writeParcelable(this.type, flags); + dest.writeParcelable(this.uploader, flags); + dest.writeString(this.createdAt); + dest.writeString(this.updatedAt); + dest.writeString(this.previewUri); + dest.writeString(this.svgUri); + dest.writeParcelable(this.licenseType, flags); + dest.writeString(this.contentUri); + dest.writeString(this.contentType); + dest.writeTypedList(this.tag); + dest.writeByte(this.favourite ? (byte) 1 : (byte) 0); + } + + protected Workflow(Parcel in) { + this.resource = in.readString(); + this.uri = in.readString(); + this.id = in.readString(); + this.version = in.readString(); + this.elementId = in.readString(); + this.title = in.readString(); + this.description = in.readString(); + this.type = in.readParcelable(Type.class.getClassLoader()); + this.uploader = in.readParcelable(Uploader.class.getClassLoader()); + this.createdAt = in.readString(); + this.updatedAt = in.readString(); + this.previewUri = in.readString(); + this.svgUri = in.readString(); + this.licenseType = in.readParcelable(LicenseType.class.getClassLoader()); + this.contentUri = in.readString(); + this.contentType = in.readString(); + this.tag = in.createTypedArrayList(Tag.CREATOR); + this.favourite = in.readByte() != 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public Workflow createFromParcel(Parcel source) { + return new Workflow(source); + } + + @Override + public Workflow[] newArray(int size) { + return new Workflow[size]; + } + }; +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/model/Workflows.java b/app/src/main/java/org/apache/taverna/mobile/data/model/Workflows.java new file mode 100644 index 00000000..4863eb4e --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/model/Workflows.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.model; + + +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.List; + +@Root(name = "workflows") +public class Workflows implements Parcelable { + + @ElementList(name = "workflow", inline = true, required = false) + List WorkflowList; + + public List getWorkflowList() { + return WorkflowList; + } + + public void setWorkflowList(List workflowList) { + WorkflowList = workflowList; + } + + public Workflows() { + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeList(this.WorkflowList); + } + + protected Workflows(Parcel in) { + this.WorkflowList = new ArrayList(); + in.readList(this.WorkflowList, Workflow.class.getClassLoader()); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Workflows createFromParcel(Parcel source) { + return new Workflows(source); + } + + @Override + public Workflows[] newArray(int size) { + return new Workflows[size]; + } + }; +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/remote/APIEndPoint.java b/app/src/main/java/org/apache/taverna/mobile/data/remote/APIEndPoint.java new file mode 100644 index 00000000..a64ffd72 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/remote/APIEndPoint.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.remote; + +//This class contains all the Constants for API End Points + +public class APIEndPoint { + + public static final String ALL_ANNOUNCEMENT = "announcements.xml"; + public static final String ANNOUNCEMENT = "announcement.xml"; + public static final String ALL_WORKFLOW = "workflows.xml"; + public static final String WORKFLOW = "workflow.xml"; + public static final String USER = "user.xml"; + public static final String LICENSE = "license.xml"; + public static final String WHOAMI = "whoami.xml"; + public static final String SEARCH = "search.xml"; + + public static final String XML_ACCEPT_HEADER = "Accept: application/xml"; + public static final String JSON_ACCEPT_HEADER = "Accept: application/json"; + public static final String JSON_CONTENT_HEADER = "Content-Type: application/json"; + public static final String UTF_CONTENT_ENCODING_HEADER = "Content-Encoding: UTF-8"; + + public static final String MY_WORKFLOWS = "user.xml"; + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/remote/BaseApiManager.java b/app/src/main/java/org/apache/taverna/mobile/data/remote/BaseApiManager.java index ec97b34d..83fe64b9 100644 --- a/app/src/main/java/org/apache/taverna/mobile/data/remote/BaseApiManager.java +++ b/app/src/main/java/org/apache/taverna/mobile/data/remote/BaseApiManager.java @@ -1,38 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.taverna.mobile.data.remote; +import org.apache.taverna.mobile.data.local.PreferencesHelper; + +import javax.inject.Inject; +import javax.inject.Singleton; + import retrofit2.Retrofit; -import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.simplexml.SimpleXmlConverterFactory; -/** - * @author Sagar - */ + +@Singleton public class BaseApiManager { - String ENDPOINT = "http://www.myexperiment.org/"; + public static final String MY_EXPERIMENT_END_POINT = "http://www.myexperiment.org/"; - public TavernaService mTavernaService; - public BaseApiManager(){ + PreferencesHelper mPreferencesHelper; - mTavernaService = createApi(TavernaService.class,ENDPOINT); + @Inject + public BaseApiManager(PreferencesHelper preferencesHelper) { + mPreferencesHelper = preferencesHelper; } - /******** Helper class that sets up a new services *******/ + /******** + * Helper class that sets up a new services with simplexml converter factory + *******/ - private T createApi(Class clazz, String ENDPOINT) { + private T createSimpleXMLApi(Class clazz, String ENDPOINT) { Retrofit retrofit = new Retrofit.Builder() .baseUrl(ENDPOINT) .addConverterFactory(SimpleXmlConverterFactory.create()) - .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .client(new TavernaOkHttpClient().getTavernaOkHttpClient()) .build(); - return retrofit.create(clazz); + return retrofit.create(clazz); + } + + /******** + * Helper class that sets up a new services with gson converter factory + *******/ + + private T createJsonApi(Class clazz, String ENDPOINT) { + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl(ENDPOINT) + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .client(new TavernaOkHttpClient().getTavernaOkHttpClient()) + .build(); + + return retrofit.create(clazz); + } + + public TavernaService getTavernaApi() { + return createSimpleXMLApi(TavernaService.class, MY_EXPERIMENT_END_POINT); } - public TavernaService getTavernaApi(){ - return mTavernaService; + public TavernaPlayerService getTavernaPlayerApi() { + return createJsonApi(TavernaPlayerService.class, mPreferencesHelper.getPlayerURL()); } } \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaOkHttpClient.java b/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaOkHttpClient.java new file mode 100644 index 00000000..f0650a56 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaOkHttpClient.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.remote; + +import com.facebook.stetho.okhttp3.StethoInterceptor; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; + +public class TavernaOkHttpClient { + + + public OkHttpClient getTavernaOkHttpClient() { + + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + + //Enable Full Body Logging + HttpLoggingInterceptor logger = new HttpLoggingInterceptor(); + logger.setLevel(HttpLoggingInterceptor.Level.BODY); + + //Interceptor :> Full Body Logger + builder.addInterceptor(logger); + + builder.addNetworkInterceptor(new StethoInterceptor()); + return builder.build(); + + } +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaPlayerService.java b/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaPlayerService.java new file mode 100644 index 00000000..24eeee93 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaPlayerService.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.data.remote; + + +import org.apache.taverna.mobile.data.model.PlayerWorkflow; +import org.apache.taverna.mobile.data.model.PlayerWorkflowDetail; + +import io.reactivex.Observable; +import okhttp3.RequestBody; +import okhttp3.ResponseBody; +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.Headers; +import retrofit2.http.POST; +import retrofit2.http.Query; + + +public interface TavernaPlayerService { + + @POST("/workflows.json") + @Headers({ + APIEndPoint.JSON_CONTENT_HEADER, + APIEndPoint.JSON_ACCEPT_HEADER, + APIEndPoint.UTF_CONTENT_ENCODING_HEADER}) + Observable uploadWorkflow(@Body RequestBody body, @Header("Authorization") + String authorization); + + @POST("/users/sign_in") + @Headers({APIEndPoint.XML_ACCEPT_HEADER}) + Observable playerlogin(@Header("Authorization") String + authorization); + + + @GET("/runs/new") + @Headers({ + APIEndPoint.JSON_CONTENT_HEADER, + APIEndPoint.JSON_ACCEPT_HEADER}) + Observable getWorkflowDetail(@Query("workflow_id") int id); +} diff --git a/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaService.java b/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaService.java index f4834903..a505b0ea 100644 --- a/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaService.java +++ b/app/src/main/java/org/apache/taverna/mobile/data/remote/TavernaService.java @@ -1,21 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.taverna.mobile.data.remote; -import org.apache.taverna.mobile.data.model.DetailAnnouncement; import org.apache.taverna.mobile.data.model.Announcements; +import org.apache.taverna.mobile.data.model.DetailAnnouncement; +import org.apache.taverna.mobile.data.model.License; +import org.apache.taverna.mobile.data.model.Search; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.data.model.Workflows; + +import java.util.Map; +import io.reactivex.Observable; +import okhttp3.ResponseBody; import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.Headers; import retrofit2.http.Query; -import rx.Observable; +import retrofit2.http.QueryMap; +import retrofit2.http.Url; -/** - * Created by Sagar - */ public interface TavernaService { - @GET("/announcements.xml") - Observable getAllAnnouncements(@Query("page") int pageNumber); + @GET(APIEndPoint.ALL_ANNOUNCEMENT) + Observable getAllAnnouncements(@QueryMap Map options); - @GET("/announcement.xml") + @GET(APIEndPoint.ANNOUNCEMENT) Observable getAnnouncement(@Query("id") String id); + + @GET(APIEndPoint.ALL_WORKFLOW) + Observable getAllWorkflows(@QueryMap Map options); + + @GET(APIEndPoint.WORKFLOW) + Observable getDetailWorkflow(@Query("id") String id + , @QueryMap Map options); + + @GET(APIEndPoint.USER) + Observable getUserDetail(@Query("id") String id + , @QueryMap Map options); + + @GET(APIEndPoint.LICENSE) + Observable getLicenseDetail(@Query("id") String id + , @QueryMap Map options); + + @GET(APIEndPoint.WHOAMI) + Observable getLoginUserDetail(@Header("Authorization") String credentials); + + @GET + @Headers(APIEndPoint.XML_ACCEPT_HEADER) + Observable downloadWorkflowContent(@Url String workflowContentUrl); + + + @GET(APIEndPoint.MY_WORKFLOWS) + Observable getMyWorkflows(@Query("id") String id, + @QueryMap Map options); + + @GET(APIEndPoint.SEARCH) + Observable getSearchWorkflowResult(@QueryMap Map options); + } \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/fragments/FavoriteFragment.java b/app/src/main/java/org/apache/taverna/mobile/fragments/FavoriteFragment.java deleted file mode 100644 index dccaa015..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/FavoriteFragment.java +++ /dev/null @@ -1,228 +0,0 @@ -package org.apache.taverna.mobile.fragments; - -/* -* Apache Taverna Mobile -* Copyright 2015 The Apache Software Foundation - -* This product includes software developed at -* The Apache Software Foundation (http://www.apache.org/). - -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -*/ - -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.ContextMenu; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.TextView; -import android.widget.Toast; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.adapters.FavoriteWorkflowAdapter; -import org.apache.taverna.mobile.adapters.WorkflowAdapter; -import org.apache.taverna.mobile.utils.Workflow_DB; -import org.json.JSONException; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Created by Larry Akah on 6/6/15. - */ -public class FavoriteFragment extends Fragment implements RecyclerView.OnCreateContextMenuListener{ - /** - * The fragment argument representing the section number for this - * fragment. - */ - private static final String ARG_SECTION_NUMBER = "SECTION_NUMBER"; - public FavoriteWorkflowAdapter favoriteAdapter; - private RecyclerView wFavoriteListView; - private RecyclerView.AdapterDataObserver dataObserver; - public Workflow_DB myWorkflowDb; - - /** - * Returns a new instance of this fragment for the given section - * number. - */ - public static FavoriteFragment newInstance(int sectionNumber) { - FavoriteFragment fragment = new FavoriteFragment(); - Bundle args = new Bundle(); - args.putInt(ARG_SECTION_NUMBER, sectionNumber); - fragment.setArguments(args); - - return fragment; - } - - public FavoriteFragment() { - } - - @Override - public void onCreate(Bundle savedInstanceState){ - super.onCreate(savedInstanceState); - dataObserver = new RecyclerView.AdapterDataObserver(){ - @Override - public void onChanged() { - super.onChanged(); - // Toast.makeText(getActivity(), "data changed", Toast.LENGTH_SHORT).show(); - setUpFavoriteData(); - setUpListView(); - } - }; - setUpFavoriteData(); - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_dashboard_main, container, false); - wFavoriteListView = (RecyclerView)rootView.findViewById(R.id.favoriteList); - wFavoriteListView.setHasFixedSize(true); - wFavoriteListView.setLayoutManager(new LinearLayoutManager(getActivity())); - wFavoriteListView.setAdapter(favoriteAdapter); - return rootView; - } - - /** - * Prepare the data to be used in the list as favorite items - */ - private void setUpFavoriteData(){ - myWorkflowDb = new Workflow_DB(getActivity(), WorkflowAdapter.WORKFLOW_FAVORITE_KEY); - try { - List> mfavorites = myWorkflowDb.get(); - favoriteAdapter = new FavoriteWorkflowAdapter(getActivity(), mfavorites); - favoriteAdapter.registerAdapterDataObserver(dataObserver); - } catch (JSONException e) { - e.printStackTrace(); - favoriteAdapter = new FavoriteWorkflowAdapter(getActivity(), Collections.>emptyList()); - favoriteAdapter.registerAdapterDataObserver(dataObserver); - } - } - - /** - * Populate the listview using the adapter - */ - private void setUpListView(){ - wFavoriteListView.setAdapter(favoriteAdapter); - } - /** - * Called when a context menu for the {@code view} is about to be shown. - * Unlike {@link #onCreateOptionsMenu}, this will be called every - * time the context menu is about to be shown and should be populated for - * the view (or item inside the view for {@link android.widget.AdapterView} subclasses, - * this can be found in the {@code menuInfo})). - *

- * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an - * item has been selected. - *

- * The default implementation calls up to - * {@link android.app.Activity#onCreateContextMenu Activity.onCreateContextMenu}, though - * you can not call this implementation if you don't want that behavior. - *

- * It is not safe to hold onto the context menu after this method returns. - * {@inheritDoc} - * - * @param menu - * @param v - * @param menuInfo - */ - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - // super.onCreateContextMenu(menu, v, menuInfo); - menu.add("View"); - menu.add("Remove"); - menu.setHeaderIcon(R.mipmap.ic_launcher); - menu.setHeaderTitle("Favorite"); - - } - - /** - * This hook is called whenever an item in a context menu is selected. The - * default implementation simply returns false to have the normal processing - * happen (calling the item's Runnable or sending a message to its Handler - * as appropriate). You can use this method for any items for which you - * would like to do processing without those other facilities. - *

- * Use {@link android.view.MenuItem#getMenuInfo()} to get extra information set by the - * View that added this menu item. - *

- * Derived classes should call through to the base class for it to perform - * the default menu handling. - * - * @param item The context menu item that was selected. - * @return boolean Return false to allow normal context menu processing to - * proceed, true to consume it here. - */ - @Override - public boolean onContextItemSelected(MenuItem item) { - String title = (String) item.getTitle(); - if(title.equals("View")){ - Toast.makeText(getActivity(),"View", Toast.LENGTH_SHORT).show(); - return true; - } - else if (title.equals("Remove")){ - Toast.makeText(getActivity(),"Removing", Toast.LENGTH_SHORT).show(); - return true; - }else - return super.onContextItemSelected(item); - } - - /** - * Called when the fragment is visible to the user and actively running. - * This is generally - * tied to {@link android.app.Activity#onResume() Activity.onResume} of the containing - * Activity's lifecycle. - */ - @Override - public void onResume() { - super.onResume(); - // setUpListView(); - //wFavoriteListView.setOnCreateContextMenuListener(this); - //registerForContextMenu(wFavoriteListView); - - } - - /** - * Called when the fragment is no longer in use. This is called - * after {@link #onStop()} and before {@link #onDetach()}. - */ - @Override - public void onDestroy() { - super.onDestroy(); - favoriteAdapter.unregisterAdapterDataObserver(dataObserver); - unregisterForContextMenu(wFavoriteListView); - } - - /** - * Causes the empty textView to be set and become visible - */ - private void setEmptyText(){ - View emptyView = wFavoriteListView.getChildAt(1); - if(emptyView instanceof TextView){ - emptyView.setVisibility(View.VISIBLE); - } - } - -} 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 deleted file mode 100644 index 2b833742..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/WorkflowItemFragment.java +++ /dev/null @@ -1,458 +0,0 @@ -package org.apache.taverna.mobile.fragments; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.app.Activity; -import android.app.ProgressDialog; -import android.app.SearchManager; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.util.LruCache; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.DefaultItemAnimator; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.SearchView; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.activities.DashboardMainActivity; -import org.apache.taverna.mobile.adapters.WorkflowAdapter; -import org.apache.taverna.mobile.tavernamobile.User; -import org.apache.taverna.mobile.tavernamobile.Workflow; -import org.apache.taverna.mobile.utils.AvatarLoader; -import org.apache.taverna.mobile.utils.WorkflowLoader; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.List; - -/** - * A fragment representing a list of Items. - *

- * Large screen devices (such as tablets) are supported by replacing the ListView - * with a GridView. - *

- */ -public class WorkflowItemFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener,SearchView.OnQueryTextListener { - - // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER - private static final String ARG_PARAM1 = "param1"; - private static final String ARG_PARAM2 = "param2"; - - private Animation in; - private ProgressDialog mProgressDialog; //progressbar used to indicate the state of the workflow loaders - - private String mParam1; - private String mParam2; - - /** - * The fragment's ListView/GridView. - */ - private static RecyclerView mListView; - private SwipeRefreshLayout swipeRefreshLayout; - - private static View rootView; - public static Context cx; - private static boolean STATE_ON = false; - private static TextView noDataText; - private static LruCache avatarCache; - private LinearLayoutManager mLinearLayoutManager; - private static WorkflowAdapter workflowAdapter; - - //variables for controlling the infinite scroll mechanism - private static int previousTotal = 0; - private int visibleThreshold = 3; - private int firstVisibleItem, visibleItemCount, totalItemCount; - private int currentPage = 1; - private boolean loading = true; - private InfiniteScrollListener scrollListener; - private RecyclerView.AdapterDataObserver workflowObserver; - //variables controlling the different kinds of data loading - public static boolean isLoadMoreData = false; - public static boolean isRefreshData = false; - - public static WorkflowItemFragment newInstance(String param1, String param2) { - WorkflowItemFragment fragment = new WorkflowItemFragment(); - Bundle args = new Bundle(); - args.putString(ARG_PARAM1, param1); - args.putString(ARG_PARAM2, param2); - fragment.setArguments(args); - return fragment; - } - - /** - * Mandatory empty constructor for the fragment manager to instantiate the - * fragment (e.g. upon screen orientation changes). - */ - public WorkflowItemFragment() { - } - - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - cx = getActivity(); - mLinearLayoutManager = new LinearLayoutManager(cx); - scrollListener = new InfiniteScrollListener(); - workflowObserver= new RecyclerView.AdapterDataObserver() { - - @Override - public void onItemRangeInserted(int positionStart, int itemCount) { - super.onItemRangeInserted(positionStart, itemCount); - mListView.swapAdapter(workflowAdapter,false); - Toast.makeText(getActivity(), "adding more workflows to listview", Toast.LENGTH_SHORT).show(); - } - }; - workflowAdapter = new WorkflowAdapter(getActivity()); - workflowAdapter.registerAdapterDataObserver(workflowObserver); - - if (getArguments() != null) { - mParam1 = getArguments().getString(ARG_PARAM1); - mParam2 = getArguments().getString(ARG_PARAM2); - } - in = AnimationUtils.loadAnimation(getActivity(),android.R.anim.slide_in_left); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { - rootView = inflater.inflate(R.layout.fragment_item, container, false); - noDataText = (TextView) rootView.findViewById(android.R.id.empty); - swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh); - swipeRefreshLayout.setOnRefreshListener(this); - - // Set the adapter - mListView = (RecyclerView) rootView.findViewById(android.R.id.list); - mListView.setHasFixedSize(true); - mListView.setLayoutManager(mLinearLayoutManager); - mListView.setAnimation(in); - mListView.setAdapter(workflowAdapter); - mListView.setOnScrollListener(scrollListener); - mListView.setItemAnimator(new DefaultItemAnimator()); - - final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); - // Use 1/8th of the available memory for this memory cache. up to 4MB for high screen densities and 1.2Mb for low sds - final int cacheSize = maxMemory / 8; - avatarCache = new LruCache(cacheSize){ - @Override - protected int sizeOf(String key, Bitmap bitmap){ - // The cache size will be measured in kilobytes - return bitmap.getByteCount() / 1024; - } - }; - - return rootView; - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - - // ((DashboardMainActivity) activity).onSectionAttached(1); - } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() - + " must implement OnFragmentInteractionListener"); - } - } - - /** - * Called when the view previously created by {@link #onCreateView} has - * been detached from the fragment. The next time the fragment needs - * to be displayed, a new view will be created. This is called - * after {@link #onStop()} and before {@link #onDestroy()}. It is called - * regardless of whether {@link #onCreateView} returned a - * non-null view. Internally it is called after the view's state has - * been saved but before it has been removed from its parent. - */ - @Override - public void onDestroyView() { - super.onDestroyView(); - rootView = null; - } - - @Override - public void onResume() { - super.onResume(); - if(!STATE_ON) { - new WorkflowLoader(getActivity(), swipeRefreshLayout).execute(""+currentPage); - - if (mListView.getAdapter().getItemCount() == 0) { - mListView.setVisibility(View.GONE); - noDataText.setVisibility(View.VISIBLE); - - } else { - mListView.setVisibility(View.VISIBLE); - noDataText.setVisibility(View.GONE); - } - } -// ((RecyclerView)(getActivity()).findViewById(R.id.favoriteList)).getAdapter().notifyDataSetChanged(); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - STATE_ON = true; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - //menu.clear(); - if(menu.size() == 1) { - //get the searchview and set the searchable configuration - SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); - SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); - //assuming this activity is the searchable activity - searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName())); - searchView.setSubmitButtonEnabled(true); - searchView.setOnQueryTextListener(this); -// searchView.setOnSearchClickListener(this); -// searchView.setIconifiedByDefault(false); - MenuItem mit = menu.add("Refresh"); - mit.setIcon(android.R.drawable.stat_notify_sync); - mit.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if(item.getTitle().equals("Refresh")){ - new WorkflowLoader(getActivity(),swipeRefreshLayout).execute("1"); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onDestroy() { - super.onDetach(); - // workflowAdapter.unregisterAdapterDataObserver(workflowObserver); - } - - //handle a request to query for given workflows - private void performSearch(String search){ - WorkflowAdapter ladapter = new WorkflowAdapter(getActivity()); - WorkflowAdapter wk = workflowAdapter; - - if(!TextUtils.isEmpty(search)) { - if (null != wk) - for (int i = 0; i < wk.getItemCount(); i++) { - Workflow workflow = wk.getItem(i); - if (workflow.getWorkflow_title().toLowerCase().contains(search.toLowerCase())) { - ladapter.addWorkflow(workflow); - } - } - - mListView.swapAdapter(ladapter, true); - if (ladapter.getItemCount() == 0) - Toast.makeText(getActivity(), "No workflows found matching criteria", Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onRefresh() { - isRefreshData = true; - isLoadMoreData = false; - - new WorkflowLoader(getActivity(),swipeRefreshLayout).execute(""+1); - } - - /** - * Search action triggered, handle the search request. Filter the workflows by name/title and swap current adapter with the new adapter - * @param query Search string criteria - * @return whether or not user handled request 'manually' - */ - @Override - public boolean onQueryTextSubmit(String query) { - performSearch(query); - return true; - } - - @Override - public boolean onQueryTextChange(String s) { - performSearch(s); - return true; - } - - public static void updateWorkflowUI(final List data) { - - ((Activity)cx).runOnUiThread(new Runnable() { - @Override - public void run() { - WorkflowItemFragment.workflowAdapter = new WorkflowAdapter(cx,data); - if(isLoadMoreData) { - isLoadMoreData = false; - isRefreshData = false; - ((WorkflowAdapter)mListView.getAdapter()).addItems(data, previousTotal); - }else - mListView.swapAdapter(workflowAdapter, false); - - if(WorkflowItemFragment.workflowAdapter.getItemCount() == 0){ - mListView.setVisibility(View.GONE); - noDataText.setVisibility(View.VISIBLE); - // Toast.makeText(cx, cx.getResources().getString(R.string.err_workflow_conn), Toast.LENGTH_LONG).show(); - }else{ - mListView.setVisibility(View.VISIBLE); - noDataText.setVisibility(View.GONE); - } - } - }); - } - - public static void startLoadingAvatar(final User author) { - - ((Activity)cx).runOnUiThread(new Runnable() { - @Override - public void run() { - synchronized (this) { - author.getUserViewHolder().author_name.setText(author.getName()); - //((TextView) rootView.findViewById(R.id.workflow_author)).setText(author.getName()); - //check whether avatar is already in the cache before trying to download it from remote resource - if(avatarCache.get(author.getDetails_uri()) == null) - new AvatarLoader(author.getUserViewHolder()).execute(author.getDetails_uri(), author.getRow_id()); - else{ - author.getUserViewHolder().author_profile.setImageBitmap(avatarCache.get(author.getDetails_uri())); -// ((ImageView) rootView.findViewById(R.id.author_profile_image)).setImageBitmap(avatarCache.get(author.getDetails_uri())); - } - System.out.println("Author cached ID "+author.getDetails_uri()+"\n Name: "+author.getName()); - } - } - }); - } - - /** - * Called when avatar xml has finished parsing. fetches the avatar remotely and updates the item in the list view - * @param author the author avatar to load - */ - public static void updateAvatar(final User author) { - - ((Activity)cx).runOnUiThread(new Runnable() { - @Override - public void run() { - // new LoadAuthorAvatar((ImageView) rootView.findViewById(R.id.author_profile_image),author.getDetails_uri()).execute(author.getAvatar_url()); - new LoadAuthorAvatar( author.getUserViewHolder().author_profile,author.getDetails_uri()).execute(author.getAvatar_url()); - } - }); - } - /** - * Load the Author Avatar from a background Task - */ - private static class LoadAuthorAvatar extends AsyncTask { - ImageView img; - String row_id_as_key; - - public LoadAuthorAvatar(ImageView imageView, String rowid) { - img = imageView; - row_id_as_key = rowid; - } - - @Override - protected Bitmap doInBackground(String... strings) { - Bitmap myBitmap = null; - try { - URL url = new URL(strings[0]); - HttpURLConnection connection = null; - connection = (HttpURLConnection) url.openConnection(); - connection.setDoInput(true); - connection.connect(); - InputStream input = connection.getInputStream(); - myBitmap = BitmapFactory.decodeStream(input); - input.close(); - - } catch (IOException e) { - e.printStackTrace(); - } - return myBitmap; - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - img.setImageBitmap(bitmap); - //cache this image for faster loading next time - try { - avatarCache.put(row_id_as_key, bitmap); - - }catch(NullPointerException np){ - - } - } - } - - private class InfiniteScrollListener extends RecyclerView.OnScrollListener{ - /** - * Callback method to be invoked when the RecyclerView has been scrolled. This will be - * called after the scroll has completed. - *

- * This callback will also be called if visible item range changes after a layout - * calculation. In that case, dx and dy will be 0. - * - * @param recyclerView The RecyclerView which scrolled. - * @param dx The amount of horizontal scroll. - * @param dy The amount of vertical scroll. - */ - @Override - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - visibleItemCount = mListView.getChildCount(); - totalItemCount = mLinearLayoutManager.getItemCount(); - firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition(); - if(loading){ - if(totalItemCount > previousTotal){ - loading = false; - previousTotal = totalItemCount; - } - } - if(!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem+visibleThreshold)){ - //list has reached end, load more. - Toast.makeText(getActivity(), "Loading more", Toast.LENGTH_SHORT).show(); - isLoadMoreData = true; - currentPage++; - new WorkflowLoader(getActivity(),swipeRefreshLayout).execute(""+currentPage); - System.out.println(currentPage); - loading = true; - } - } - - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/fragments/Workflow_viewpager.java b/app/src/main/java/org/apache/taverna/mobile/fragments/Workflow_viewpager.java deleted file mode 100644 index 753645f8..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/Workflow_viewpager.java +++ /dev/null @@ -1,113 +0,0 @@ -package org.apache.taverna.mobile.fragments; - -import android.os.Bundle; -import android.support.design.widget.TabLayout; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentPagerAdapter; -import android.support.v4.view.ViewPager; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.support.v4.app.FragmentManager; -import org.apache.taverna.mobile.R; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by rajan on 8/3/16. - */ -public class Workflow_viewpager extends Fragment{ - - private final String LOG_TAG = getClass().getSimpleName(); - - ViewPager viewPager; - TabLayout tabLayout; - - - public static Workflow_viewpager getInstance(int position) { - Workflow_viewpager myFragment = new Workflow_viewpager(); - Bundle args = new Bundle(); - args.putInt("position", position); - myFragment.setArguments(args); - return myFragment; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View workflow_pager = inflater.inflate(R.layout.viewpager_workflow, container, false); - - /** - * Setting the tool bar in MainActivity for all fragment - */ - Toolbar toolbar = (Toolbar) workflow_pager.findViewById(R.id.toolbar); - ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); - - final ActionBar ab = ((AppCompatActivity) getActivity()).getSupportActionBar(); - ab.setHomeAsUpIndicator(R.drawable.ic_menu); - ab.setDisplayHomeAsUpEnabled(true); - - - viewPager = (ViewPager) workflow_pager.findViewById(R.id.mviewpager); - final Adapter adapter = new Adapter(getChildFragmentManager()); - - /** - * Dynamically Adding tabs - * To add the new Tab "Go to res/values/category_id and add new title and category id" - */ - adapter.addFragment(new WorkflowItemFragment() , getResources().getString(R.string.title_explore)); - adapter.addFragment(new FavoriteFragment(), getResources().getString(R.string.title_favorite)); - - viewPager.setAdapter(adapter); - viewPager.setOffscreenPageLimit(2); - tabLayout = (TabLayout) workflow_pager.findViewById(R.id.mtablayout); - tabLayout.setupWithViewPager(viewPager); - - return workflow_pager; - } - - - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) - { - super.onViewCreated(view, savedInstanceState); - Log.i(LOG_TAG, "Workflow_viewpager.onCreate"); - - } - - static class Adapter extends FragmentPagerAdapter - { - private final List mFragments = new ArrayList<>(); - private final List mFragmentTitles = new ArrayList<>(); - - public Adapter(FragmentManager fm) { - super(fm); - } - - public void addFragment(Fragment fragment, String title) { - mFragments.add(fragment); - mFragmentTitles.add(title); - } - - @Override - public Fragment getItem(int position) { - return mFragments.get(position); - } - - @Override - public int getCount() { - return mFragments.size(); - } - - - - @Override - public CharSequence getPageTitle(int position) { - return mFragmentTitles.get(position); - } - } -} 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 deleted file mode 100644 index 8d1fb52c..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/RunFragment.java +++ /dev/null @@ -1,279 +0,0 @@ -package org.apache.taverna.mobile.fragments.workflowdetails; - - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.text.method.ScrollingMovementMethod; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageButton; -import android.widget.TextView; -import android.widget.Toast; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.tavernamobile.TavernaPlayerAPI; -import org.apache.taverna.mobile.utils.WorkflowDownloadManager; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Timer; -import java.util.TimerTask; - -import static org.apache.taverna.mobile.activities.DashboardMainActivity.APP_DIRECTORY_NAME; - -/** - * A simple {@link Fragment} subclass. - * Use the {@link RunFragment#newInstance} factory method to - * create an instance of this fragment. - */ -public class RunFragment extends Fragment implements View.OnClickListener{ - - private View rootView; - private TextView runIdTextView,runNameTextView; - private ImageButton status; - private TextView runStateTextView, runStartTime,runEndTime, runInputsText; - private Button downloadOutput,downloadLogs; - private int run_id; - private String run_output_url = ""; - private String run_logs_url = ""; - - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @return A new instance of fragment RunFragment. - */ - public static RunFragment newInstance() { - RunFragment fragment = new RunFragment(); - Bundle args = new Bundle(); - fragment.setArguments(args); - return fragment; - } - - public RunFragment() { - // Required empty public constructor - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - rootView = inflater.inflate(R.layout.fragment_run_result, container, false); - runIdTextView = (TextView) rootView.findViewById(R.id.textview_runid); - runNameTextView = (TextView) rootView.findViewById(R.id.textView_runName); - status = (ImageButton) rootView.findViewById(R.id.statusButton); - runStateTextView = (TextView) rootView.findViewById(R.id.statusTextView); - runStartTime = (TextView) rootView.findViewById(R.id.start_time); - runEndTime = (TextView) rootView.findViewById(R.id.runfinish); - runInputsText = (TextView) rootView.findViewById(R.id.runinputsTextView); - downloadOutput = (Button) rootView.findViewById(R.id.buttonWorkflowDownloadOutput); - downloadLogs = (Button) rootView.findViewById(R.id.downloadRunLogs); - - return rootView; - } - - @Override - public void onCreateOptionsMenu(Menu menu,MenuInflater menuInflater) { - // Inflate the menu; this adds items to the action bar if it is present. - menuInflater.inflate(R.menu.run_result, menu); - return; - } - - @Override - public void onResume() { - super.onResume(); - String runresult = getActivity().getIntent().getStringExtra("runresult"); - try{ - JSONObject resultObject = new JSONObject(runresult); - String runName = resultObject.getString("name"); - run_id = (int) resultObject.get("id"); - String runId = ""+run_id; - String runState = resultObject.getString("state"); - String runStarted = resultObject.getString("start_time"); - String runEnded = resultObject.getString("finish_time"); - String runInputs = resultObject.getString("inputs"); - - runIdTextView.setText(runId); - runNameTextView.setText(runName); - - if(runState.contains("Pending")) - status.setImageResource(android.R.drawable.presence_busy); - else if (runState.contains("Running")) - status.setImageResource(android.R.drawable.presence_away); - else if (runState.contains("Finished")) - status.setImageResource(android.R.drawable.presence_online); - else if (runState.contains("Failed")) - status.setImageResource(android.R.drawable.presence_offline); - else - status.setImageResource(android.R.drawable.presence_invisible); - - runStateTextView.setText(runState); - runStartTime.setHint(runStarted); - runEndTime.setHint(runEnded); - runInputsText.setText(runInputs); - runInputsText.setMovementMethod(new ScrollingMovementMethod()); - - downloadOutput.setOnClickListener(this); - downloadLogs.setOnClickListener(this); - reloadRunResult(); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - if (id == R.id.action_refresh) { - reloadRunResult(); - return true; - } - if(id == android.R.id.home){ - //getActivity().finish(); - return true; - } - return super.onOptionsItemSelected(item); - } - - private void reloadRunResult(){ - Timer t = new Timer(); - // t.scheduleAtFixedRate(new RunTimerTask(getActivity(), run_id), 0, 5000); - t.schedule(new RunTimerTask(getActivity(),run_id),1); - } - - @Override - public void onClick(View view) { - switch(view.getId()){ - case R.id.buttonWorkflowDownloadOutput: - try { - System.out.println("output url: "+run_output_url); - if(run_output_url.isEmpty()){ - Toast.makeText(getActivity(), "No run logs available", Toast.LENGTH_LONG).show(); - }else { - new WorkflowDownloadManager(getActivity()).downloadWorkflow( - new File(PreferenceManager.getDefaultSharedPreferences(getActivity()).getString( - APP_DIRECTORY_NAME + "/Runoutput/outputs", "/TavernaMobile/Runouput/outputs/")), - new TavernaPlayerAPI(getActivity()).PLAYER_RUN_URL + run_output_url.substring(0, 5)); - } - } catch (Exception e) { - e.printStackTrace(); - Toast.makeText(getActivity(), "Error downloading run output",Toast.LENGTH_LONG).show(); - } - break; - case R.id.downloadRunLogs: - try { - System.out.println("run logs: "+run_logs_url); - if(run_logs_url.isEmpty()){ - Toast.makeText(getActivity(), "No run logs available", Toast.LENGTH_LONG).show(); - }else { - new WorkflowDownloadManager(getActivity()).downloadWorkflow( - new File(PreferenceManager.getDefaultSharedPreferences(getActivity()).getString( - APP_DIRECTORY_NAME + "/Runoutput/logs/", "/TavernaMobile/Runoutput/logs")), - new TavernaPlayerAPI(getActivity()).PLAYER_RUN_URL + run_logs_url.substring(0, 5)); - } - } catch (Exception e) { - e.printStackTrace(); - Toast.makeText(getActivity(), "Error downloading run logs",Toast.LENGTH_LONG).show(); - } - break; - } - } - - public void updateRun(Context context, final JSONObject runInfo){ - if(null != runInfo) - ((Activity)context).runOnUiThread(new Runnable() { - @Override - public void run() { - try { - runStartTime.setHint(runInfo.getString("start_time")); - runEndTime.setHint(runInfo.getString("finish_time")); - runStateTextView.setText(runInfo.getString("status_message")); - - if(runInfo.getString("status_message").contains("Pending")) - status.setImageResource(android.R.drawable.presence_busy); - else if (runInfo.getString("status_message").contains("Running")) - status.setImageResource(android.R.drawable.presence_away); - else if (runInfo.getString("status_message").contains("Finished")) - status.setImageResource(android.R.drawable.presence_online); - else if (runInfo.getString("status_message").contains("Failed")) - status.setImageResource(android.R.drawable.presence_offline); - else - status.setImageResource(android.R.drawable.presence_invisible); - - run_output_url = runInfo.has("outputs_zip")? runInfo.getString("outputs_zip"):""; - run_logs_url = runInfo.has("log")?runInfo.getString("log"):""; - } catch (JSONException e) { - e.printStackTrace(); - } - } - }); - } - - private class RunTimerTask extends TimerTask { - - private Context context; - private int runid; - - public RunTimerTask(Context context, int runID) { - this.context = context; - this.runid = runID; - } - - @Override - public void run() { - //QUERY player for the continuous status of the workflow run and update the ui with the results - StringBuffer sb = new StringBuffer(); - try { - - URL workflowurl = new URL(new TavernaPlayerAPI(this.context).PLAYER_RUN_URL+this.runid); - HttpURLConnection connection = (HttpURLConnection) workflowurl.openConnection(); - - connection.setRequestProperty("Accept", "application/json"); - connection.setRequestMethod("GET"); - connection.connect(); //send request - - InputStream dis = connection.getInputStream(); - BufferedReader br = new BufferedReader(new InputStreamReader(dis)); - - String jsonData = ""; - while ((jsonData = br.readLine()) != null) { - //json results of the full workflow details - sb.append(jsonData); - } - dis.close(); - br.close(); - connection.disconnect(); - - JSONObject runInfo = new JSONObject(sb.toString()); - updateRun(this.context, runInfo); - - }catch (IOException ex){ - ex.printStackTrace(); - } catch (JSONException e) { - e.printStackTrace(); - } - } - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowAboutFragment.java b/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowAboutFragment.java deleted file mode 100644 index c8f1e640..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowAboutFragment.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.apache.taverna.mobile.fragments.workflowdetails; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import org.apache.taverna.mobile.R; - -/** - * A simple {@link Fragment} subclass. - * Use the {@link WorkflowAboutFragment#newInstance} factory method to - * create an instance of this fragment. - */ -public class WorkflowAboutFragment extends Fragment { - // TODO: Rename parameter arguments, choose names that match - // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER - private static final String ARG_PARAM1 = "param1"; - private static final String ARG_PARAM2 = "param2"; - - // TODO: Rename and change types of parameters - private String mParam1; - private String mParam2; - - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment WorkflowAboutFragment. - */ - // TODO: Rename and change types and number of parameters - public static WorkflowAboutFragment newInstance(String param1, String param2) { - WorkflowAboutFragment fragment = new WorkflowAboutFragment(); - Bundle args = new Bundle(); - args.putString(ARG_PARAM1, param1); - args.putString(ARG_PARAM2, param2); - fragment.setArguments(args); - return fragment; - } - - public WorkflowAboutFragment() { - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (getArguments() != null) { - mParam1 = getArguments().getString(ARG_PARAM1); - mParam2 = getArguments().getString(ARG_PARAM2); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_workflow_about, container, false); - } - -} diff --git a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowLicenceFragment.java b/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowLicenceFragment.java deleted file mode 100644 index 8226dc39..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowLicenceFragment.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.apache.taverna.mobile.fragments.workflowdetails; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import org.apache.taverna.mobile.R; - -/** - * A simple {@link Fragment} subclass. - * Use the {@link WorkflowLicenceFragment#newInstance} factory method to - * create an instance of this fragment. - */ -public class WorkflowLicenceFragment extends Fragment { - // TODO: Rename parameter arguments, choose names that match - // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER - private static final String ARG_PARAM1 = "param1"; - private static final String ARG_PARAM2 = "param2"; - - // TODO: Rename and change types of parameters - private String mParam1; - private String mParam2; - - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment WorkflowLicenceFragment. - */ - // TODO: Rename and change types and number of parameters - public static WorkflowLicenceFragment newInstance(String param1, String param2) { - WorkflowLicenceFragment fragment = new WorkflowLicenceFragment(); - Bundle args = new Bundle(); - args.putString(ARG_PARAM1, param1); - args.putString(ARG_PARAM2, param2); - fragment.setArguments(args); - return fragment; - } - - public WorkflowLicenceFragment() { - // Required empty public constructor - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (getArguments() != null) { - mParam1 = getArguments().getString(ARG_PARAM1); - mParam2 = getArguments().getString(ARG_PARAM2); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_workflow_licence, container, false); - } - - @Override - public void onDetach() { - super.onDetach(); - } - -} diff --git a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowRunHistoryFragment.java b/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowRunHistoryFragment.java deleted file mode 100644 index 7d9ffda2..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowRunHistoryFragment.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.apache.taverna.mobile.fragments.workflowdetails; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.app.LoaderManager; -import android.app.ProgressDialog; -import android.content.Loader; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.adapters.RunAdapter; -import org.apache.taverna.mobile.tavernamobile.Runs; -import org.apache.taverna.mobile.tavernamobile.Workflow; -import org.apache.taverna.mobile.utils.DetailsLoader; - -import java.util.ArrayList; -import java.util.List; - -/** - * A simple {@link Fragment} subclass. - * Use the {@link WorkflowRunHistoryFragment#newInstance} factory method to - * create an instance of this fragment. - */ -public class WorkflowRunHistoryFragment extends Fragment implements LoaderManager.LoaderCallbacks{ - - // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER - private static final String ARG_PARAM2 = "param2"; - private ProgressDialog progressDialog; - private RecyclerView mRecyclerView; - private TextView emptyRunHistoryTextView; - private RunAdapter runAdapter; - List runsList; - - private static String workflowID; //represents a run name that matches the given workflow - - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param2 Parameter 2. - * @return A new instance of fragment WorkflowRunHistoryFragment. - */ - public static WorkflowRunHistoryFragment newInstance(String param2) { - WorkflowRunHistoryFragment fragment = new WorkflowRunHistoryFragment(); - Bundle args = new Bundle(); - workflowID = param2; - args.putString(ARG_PARAM2, param2); - fragment.setArguments(args); - return fragment; - } - - public WorkflowRunHistoryFragment() { - // Required empty public constructor - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - runsList = new ArrayList(); -/* runsList.add(new Runs("Test Run1 ", - SimpleDateFormat.getDateTimeInstance().format(new Date()).toString() - ,SimpleDateFormat.getDateTimeInstance().format(new Date()).toString(),"failed")); - runsList.add(new Runs("Test Run2 ", - SimpleDateFormat.getDateTimeInstance().format(new Date()).toString() - ,SimpleDateFormat.getDateTimeInstance().format(new Date()).toString(),"finished")); - */ - progressDialog = new ProgressDialog(getActivity()); - progressDialog.setMessage(getActivity().getResources().getString(R.string.loading)); - progressDialog.setCancelable(true); - - runAdapter = new RunAdapter(getActivity(),runsList ); - // System.out.println("WorkflowTitle->Run->"+workflowID); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView =inflater.inflate(R.layout.fragment_workflow_run_history, container, false); - emptyRunHistoryTextView = (TextView) rootView.findViewById(android.R.id.empty); - mRecyclerView = (RecyclerView) rootView.findViewById(android.R.id.list); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); - mRecyclerView.setAdapter(runAdapter); - getActivity().getLoaderManager().initLoader(0,savedInstanceState,this).forceLoad(); - return rootView; - } - - /** - * Called when the fragment is visible to the user and actively running. - * This is generally - * tied to {@link android.app.Activity#onResume() Activity.onResume} of the containing - * Activity's lifecycle. - */ - @Override - public void onResume() { - super.onResume(); - - // mRecyclerView.setScrollingTouchSlop(RecyclerView.TOUCH_SLOP_PAGING); - //getActivity().getLoaderManager().initLoader(1,null,this); - } - - @Override - public void onDetach() { - super.onDetach(); - } - - @Override - public Loader onCreateLoader(int i, Bundle bundle) { - //progressDialog.show(); - return new DetailsLoader(getActivity(), - DetailsLoader.LOAD_TYPE.TYPE_RUN_HISTORY, - workflowID); - } - - @Override - public void onLoadFinished(Loader workflowLoader, Workflow workflow) { - - try { - if (workflow.getWorkflow_runs() !=null | workflow.getWorkflow_runs().size() !=0) { - - runAdapter.setRunList(workflow.getWorkflow_runs()); - mRecyclerView.setAdapter(runAdapter); - mRecyclerView.setVisibility(View.VISIBLE); - emptyRunHistoryTextView.setVisibility(View.GONE); - - } else { - mRecyclerView.setVisibility(View.GONE); - emptyRunHistoryTextView.setVisibility(View.VISIBLE); - } - }catch(NullPointerException np){ - np.printStackTrace(); - } - - // progressDialog.dismiss(); - } - - @Override - public void onLoaderReset(Loader workflowLoader) { - workflowLoader.reset(); - } -} 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 deleted file mode 100644 index 0449dd7d..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/fragments/workflowdetails/WorkflowdetailFragment.java +++ /dev/null @@ -1,747 +0,0 @@ -package org.apache.taverna.mobile.fragments.workflowdetails; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.DownloadManager; -import android.app.LoaderManager; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.Loader; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.support.v4.app.Fragment; -import android.util.Base64; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ScrollView; -import android.widget.TextView; -import android.widget.Toast; -import android.widget.ZoomControls; - -import com.dropbox.client2.DropboxAPI; -import com.dropbox.client2.ProgressListener; -import com.dropbox.client2.android.AndroidAuthSession; -import com.dropbox.client2.exception.DropboxException; -import com.dropbox.client2.session.AppKeyPair; - -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.activities.DashboardMainActivity; -import org.apache.taverna.mobile.activities.RunResult; -import org.apache.taverna.mobile.adapters.WorkflowAdapter; -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.apache.taverna.mobile.utils.Workflow_DB; -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.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.charset.CharsetEncoder; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; - -/** - * Created by Larry Akah on 6/9/15. - */ -public class WorkflowdetailFragment extends Fragment implements View.OnClickListener,LoaderManager.LoaderCallbacks{ - /** - * The fragment argument representing the section number for this - * fragment. - */ - private static final String ARG_SECTION_NUMBER = "section_number"; - private DownloadManager downloadManager; - static View rootView; - private static ProgressDialog progressDialog; - public AlertDialog runDialog; - public AlertDialog.Builder alertDialogBuilder; - private static String download_url; - public static String WORKFLO_ID = ""; - public static Context cont; - SharedPreferences sharedPreferences; - private static boolean LOAD_STATE = false; - private static boolean DROPUPLOAD = false; - static Animation zoomin; - static Animation zoomout; - public boolean isZoomIn; - public static String workflow_uri ; - final static private String BOX_APP_KEY = "doicbvkfyzligh2"; - final static private String BOX_APP_SECRET = "3uuuw36mm7jkflc"; - static Workflow currentWorkflow = null; - private long wid; - - private DropboxAPI mDBApi; - - /** - * Returns a new instance of this fragment for the given section - * number. - */ - public static WorkflowdetailFragment newInstance(int sectionNumber) { - WorkflowdetailFragment fragment = new WorkflowdetailFragment(); - Bundle args = new Bundle(); - args.putInt(ARG_SECTION_NUMBER, sectionNumber); - fragment.setArguments(args); - return fragment; - } - - public static WorkflowdetailFragment getInstance(){ - return WorkflowdetailFragment.getInstance(); - } - - public WorkflowdetailFragment() { - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { - - AppKeyPair appKeys = new AppKeyPair(BOX_APP_KEY, BOX_APP_SECRET); - AndroidAuthSession session = new AndroidAuthSession(appKeys); - mDBApi = new DropboxAPI(session); - // long workflowid = getActivity().getIntent().getLongExtra("workflowid", 0); - rootView = inflater.inflate(R.layout.fragment_workflow_detail, container, false); - progressDialog = new ProgressDialog(getActivity()); - progressDialog.setMessage(getActivity().getResources().getString(R.string.loading)); - progressDialog.setCancelable(false); - // WORKFLO_ID = workflowid; - zoomin = AnimationUtils.loadAnimation(getActivity(), R.anim.zoomin); - zoomout = AnimationUtils.loadAnimation(getActivity(), R.anim.zoomout); - - isZoomIn = false; - sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); - wid = getActivity().getIntent().getLongExtra("wid", 0); - Button createRun = (Button) rootView.findViewById(R.id.run_wk); - createRun.setOnClickListener(this); - Button download = (Button) rootView.findViewById(R.id.download_wk); - download.setOnClickListener(this); - Button mark_workflow = (Button) rootView.findViewById(R.id.mark_wk); - mark_workflow.setOnClickListener(this); - final String favs = sharedPreferences.getString(WorkflowAdapter.FAVORITE_LIST_DB, ""); - String[] ids = favs.split(","); - if(ids.length > 0) { - for (String id : ids) - if (id.equalsIgnoreCase("" +wid )){ - mark_workflow.setBackgroundResource(R.drawable.abc_list_selector_disabled_holo_light); - break; - } - } - rootView.findViewById(R.id.saveToDropboxButton).setOnClickListener(this); - rootView.findViewById(R.id.saveToGoogleDriveButton).setOnClickListener(this); - (rootView.findViewById(R.id.wkf_image)).setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { - view.setAnimation(zoomin); - return true; - } - }); - downloadManager = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE); - return rootView; - } - - /** - * Called when a fragment is first attached to its activity. - * {@link #onCreate(android.os.Bundle)} will be called after this. - * - * @param activity - */ - //@Override - //public void onAttach(Activity activity) { - // super.onAttach(activity); - // cont = getActivity(); - //} - @Override - public void onAttach(Context context) { - super.onAttach(context); - cont = getActivity(); - } - - @Override - public void onClick(View view) { - switch(view.getId()){ - case R.id.run_wk: - if (((TextView)rootView.findViewById(R.id.wtype)).getText().toString().contains("Taverna 2")) - new WorkflowProcessTask(getActivity()).execute(download_url); - else - Toast.makeText(getActivity(), "Sorry! Only Taverna 2 workflows can be run.", Toast.LENGTH_LONG).show(); - break; - case R.id.download_wk: - // start the android Download manager to start downloading a remote workflow file - WorkflowDownloadManager dmgr = new WorkflowDownloadManager(getActivity(), downloadManager); - try { - dmgr.downloadWorkflow(new File(PreferenceManager.getDefaultSharedPreferences(getActivity()).getString( - DashboardMainActivity.APP_DIRECTORY_NAME, "/")), - download_url); - } catch (Exception e) { - e.printStackTrace(); - } - - break; - case R.id.mark_wk: - - ArrayList mfav = new ArrayList(); - String favs = sharedPreferences.getString(WorkflowAdapter.FAVORITE_LIST_DB, ""); - //save current workflow as favorite - mfav.add(currentWorkflow.getId()); - mfav.add(currentWorkflow.getWorkflow_author()); - mfav.add(currentWorkflow.getWorkflow_title()); - mfav.add(currentWorkflow.getWorkflow_description()); - mfav.add(SimpleDateFormat.getDateTimeInstance().format(new Date()).toString()); - mfav.add(currentWorkflow.getWorkflow_details_url()); - mfav.add(((TextView) rootView.findViewById(R.id.wkf_author)).getText()); - int result = new Workflow_DB(getActivity(), WorkflowAdapter.WORKFLOW_FAVORITE_KEY).insert(mfav); - if(result >0) { - sharedPreferences.edit().putString(WorkflowAdapter.FAVORITE_LIST_DB, favs+wid+",").apply(); - Toast.makeText(getActivity(), "Workflow marked as favorite", Toast.LENGTH_SHORT).show(); - view.setBackgroundResource(R.drawable.abc_list_selector_disabled_holo_light); - - }else if(result == -1){ - Toast.makeText(getActivity(),"Sorry! This workflow has already been marked as a favourite",Toast.LENGTH_SHORT).show(); - }else - Toast.makeText(getActivity(),"Error!, please try again",Toast.LENGTH_SHORT).show(); - break; - case R.id.saveToDropboxButton: - String authToken = PreferenceManager.getDefaultSharedPreferences(getActivity()).getString("dropboxauth", ""); - if (authToken.isEmpty()) - mDBApi.getSession().startOAuth2Authentication(getActivity()); - else { - mDBApi.getSession().setOAuth2AccessToken(authToken); - new WorkflowDriveUpload().execute(download_url); - } - break; - case R.id.saveToGoogleDriveButton: - break; - } - } - - /** - * Called when the fragment is visible to the user and actively running. - * This is generally - * tied to {@link android.app.Activity#onResume() Activity.onResume} of the containing - * Activity's lifecycle. - */ - @Override - public void onResume() { - super.onResume(); - if(!LOAD_STATE) - workflow_uri = getActivity().getIntent().getStringExtra("uri"); - - getActivity().getLoaderManager().initLoader(1, null, this).forceLoad(); - - if (mDBApi.getSession().authenticationSuccessful() && !DROPUPLOAD) { - try { - // Required to complete auth, sets the access token on the session - mDBApi.getSession().finishAuthentication(); - String accessToken = mDBApi.getSession().getOAuth2AccessToken(); - PreferenceManager.getDefaultSharedPreferences(getActivity()).edit().putString("dropboxauth", accessToken).commit(); - new WorkflowDriveUpload().execute(download_url); - } catch (IllegalStateException e) { - Log.i("DbAuthLog", "Error authenticating", e); - } - } - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - LOAD_STATE = true; - } - - @Override - public Loader onCreateLoader(int i, Bundle bundle) { - progressDialog.show(); - return new DetailsLoader(getActivity(), - DetailsLoader.LOAD_TYPE.TYPE_WORKFLOW_DETAIL, - workflow_uri); - } - - @Override - public void onLoadFinished(Loader workflowLoader, Workflow workflow) { - - } - - @Override - public void onLoaderReset(Loader workflowLoader) { - workflowLoader.reset(); - } - - public static void setWorkflowDetails(final Workflow wk){ - currentWorkflow = wk; - final TextView author = (TextView) rootView.findViewById(R.id.wkf_author_text); - //final TextView updated = (TextView) rootView.findViewById(R.id.wupdatedat); - final TextView type = (TextView) rootView.findViewById(R.id.wtype); - final TextView title = (TextView) rootView.findViewById(R.id.wtitle); - final TextView desc = (TextView) rootView.findViewById(R.id.wdescription); - final TextView createdat = (TextView) rootView.findViewById(R.id.wcreatedat); - final ImageView preview = (ImageView) rootView.findViewById(R.id.wkf_image); - WORKFLO_ID = wk.getWorkflow_title(); - ((Activity)cont).runOnUiThread(new Runnable() { - @Override - public void run() { - //load necessary widgets - - //set widget data - //Use android resources to insert text into placeholder - Resources resources = cont.getResources(); - User uploader = wk.getUploader(); - //String uploaderText = String.format(resources.getString(R.string.workflow_author), uploader != null ? uploader.getName():"Unknown"); - author.setText((uploader != null) ? uploader.getName() : "Unknown"); - title.setText(wk.getWorkflow_title()); - if (wk.getWorkflow_description() != null) { - desc.setText(wk.getWorkflow_description()); - } else { - //desc.setVisibility(View.INVISIBLE); //Not sure I trust this! Needs investigating. - } - String createdAtText = String.format(resources.getString(R.string.created), wk.getWorkflow_datecreated()); - createdat.setText(createdAtText); - //updated.setText("Workflow Description"); - String typeText = String.format(resources.getString(R.string.workflow_type_text), wk.getWorkflow_Type()); - type.setText(typeText); - - //preview.setImageURI(Uri.parse(wk.getWorkflow_preview())); - new LoadImageThread(preview, wk.getWorkflow_preview()).execute(); - download_url =wk.getWorkflow_remote_url(); - zoomin.setAnimationListener(new Animation.AnimationListener() { - - @Override - public void onAnimationStart(Animation arg0) { - // TODO Auto-generated method stub - preview.startAnimation(zoomout); - } - - @Override - public void onAnimationRepeat(Animation arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void onAnimationEnd(Animation arg0) { - preview.startAnimation(zoomout); - - } - }); - zoomout.setAnimationListener(new Animation.AnimationListener() { - - @Override - public void onAnimationStart(Animation arg0) { - // TODO Auto-generated method stub - preview.startAnimation(zoomin); - } - - @Override - public void onAnimationRepeat(Animation arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void onAnimationEnd(Animation arg0) { - preview.startAnimation(zoomin); - - } - }); - progressDialog.dismiss(); - } - }); - // preview.setOnClickListener(WorkflowdetailFragment.getInstance()); - } - - private static class LoadImageThread extends AsyncTask{ - ImageView imageView; - String src ; - public LoadImageThread(ImageView image, String source) { - imageView = image; - src = source; - } - - @Override - protected Bitmap doInBackground(String... strings) { - Bitmap myBitmap = null; - try { - URL url = new URL(src); - HttpURLConnection connection = null; - connection = (HttpURLConnection) url.openConnection(); - connection.setDoInput(true); - connection.connect(); - InputStream input = connection.getInputStream(); - myBitmap = BitmapFactory.decodeStream(input); -// imageView.setImageBitmap(myBitmap); - } catch (IOException e) { - e.printStackTrace(); - } - return myBitmap; - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - imageView.setImageBitmap(bitmap); - } - } - - //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; - } - //fetch and compute the framework on which the run inputs are to be built and entered - private class WorkflowRunTask extends AsyncTask{ - - private Context context; - TavernaPlayerAPI tavernaPlayerAPI = new TavernaPlayerAPI(); - - 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 = tavernaPlayerAPI.getPlayerUserName(this.context) + ":" + tavernaPlayerAPI.getPlayerUserPassword(this.context); - String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT); - - connection.setRequestProperty("Authorization", basicAuth); - connection.setRequestProperty("Accept", "application/json"); - connection.setRequestMethod("GET"); - // connection.setDoInput(true); - // connection.setDoOutput(true); - 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{ - - 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 - String playerurl = new TavernaPlayerAPI(this.context).PLAYER_BASE_URL+"workflows.json"; - TavernaPlayerAPI tavernaPlayerAPI = new TavernaPlayerAPI(); - - URL posturl = new URL(playerurl); - HttpURLConnection connection = (HttpURLConnection) posturl.openConnection(); - HttpURLConnection wconn = (HttpURLConnection) workflowurl.openConnection(); - wconn.setRequestMethod("GET"); - wconn.setDoOutput(true); - wconn.setRequestProperty("Accept", "application/xml"); - wconn.connect(); - - String user = tavernaPlayerAPI.getPlayerUserName(this.context) + ":" + tavernaPlayerAPI.getPlayerUserPassword(this.context); - 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 workflow( as .t2flow or .xml) workflow from remote resource. Now we need to post that to the player. - bufferedReader.close(); - wconn.disconnect(); - - 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); - 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(); - s = s.substring(1, s.length()); - try { - JSONObject workflowJson = new JSONObject(s); - new WorkflowRunTask(getActivity()).execute(workflowJson.getString("id")); - - } catch (JSONException e) { - e.printStackTrace(); - } - - } - } - - /** - * Upload workflow from myexperiment to DropBox - */ - private class WorkflowDriveUpload extends AsyncTask{ - @Override - protected void onPreExecute() { - Toast.makeText(getActivity(), "Saving workflow to dropBox", Toast.LENGTH_LONG).show(); - } - - @Override - protected String doInBackground(String... files) { - // File file = new File(files[0]); - HttpURLConnection mconn ; - // FileInputStream inputStream = null; - DropboxAPI.Entry response = null; - DropboxAPI.Entry metaDataEntry = null; - try { - mconn = (HttpURLConnection) new URL(files[0]).openConnection(); - mconn.setRequestMethod("GET"); - mconn.connect(); - - // inputStream = new FileInputStream(file); - - response = mDBApi.putFile("/"+ Uri.parse(files[0]).getLastPathSegment(), mconn.getInputStream(), - mconn.getContentLength(), null, new ProgressListener() { - @Override - public void onProgress(long l, long l2) { - if (l==l2){ - Toast.makeText(getActivity(), "Upload complete", Toast.LENGTH_LONG).show(); - } - } - }); - - Log.i("DbExampleLog", "The uploaded file's rev is: " + response.rev); - // metaDataEntry = mDBApi.metadata("/"+Uri.parse(files[0]).getLastPathSegment(), 1, null, false, null); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (DropboxException e) { - e.printStackTrace(); - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - return response.rev; - } - - @Override - protected void onPostExecute(String s) { - if(null != s) { - Toast.makeText(getActivity(), "File Saved to dropbox. Reference: " + s, Toast.LENGTH_LONG).show(); - DROPUPLOAD = true; - } - else{ - Toast.makeText(getActivity(), "Failed to save to dropbox "+s, Toast.LENGTH_LONG).show(); - } - } - } - -} diff --git a/app/src/main/java/org/apache/taverna/mobile/injection/ActivityContext.java b/app/src/main/java/org/apache/taverna/mobile/injection/ActivityContext.java new file mode 100644 index 00000000..d61259b5 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/injection/ActivityContext.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.injection; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +public @interface ActivityContext { +} diff --git a/app/src/main/java/org/apache/taverna/mobile/injection/ApplicationContext.java b/app/src/main/java/org/apache/taverna/mobile/injection/ApplicationContext.java new file mode 100644 index 00000000..8366eafb --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/injection/ApplicationContext.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.injection; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +public @interface ApplicationContext { +} diff --git a/app/src/main/java/org/apache/taverna/mobile/injection/PerActivity.java b/app/src/main/java/org/apache/taverna/mobile/injection/PerActivity.java new file mode 100755 index 00000000..e8ee51a3 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/injection/PerActivity.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.injection; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.inject.Scope; + +/** + * A scoping annotation to permit objects whose lifetime should + * conform to the life of the Activity to be memorised in the + * correct component. + */ + +@Scope +@Retention(RetentionPolicy.RUNTIME) +public @interface PerActivity { +} diff --git a/app/src/main/java/org/apache/taverna/mobile/injection/component/ActivityComponent.java b/app/src/main/java/org/apache/taverna/mobile/injection/component/ActivityComponent.java new file mode 100644 index 00000000..c3b09a22 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/injection/component/ActivityComponent.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.injection.component; + +import org.apache.taverna.mobile.injection.PerActivity; +import org.apache.taverna.mobile.injection.module.ActivityModule; +import org.apache.taverna.mobile.ui.DashboardActivity; +import org.apache.taverna.mobile.ui.FlashScreenActivity; +import org.apache.taverna.mobile.ui.anouncements.AnnouncementFragment; +import org.apache.taverna.mobile.ui.favouriteworkflow.FavouriteWorkflowsActivity; +import org.apache.taverna.mobile.ui.favouriteworkflow.FavouriteWorkflowsFragment; +import org.apache.taverna.mobile.ui.favouriteworkflowdetail.FavouriteWorkflowDetailActivity; +import org.apache.taverna.mobile.ui.favouriteworkflowdetail.FavouriteWorkflowDetailFragment; +import org.apache.taverna.mobile.ui.imagezoom.ImageZoomActivity; +import org.apache.taverna.mobile.ui.imagezoom.ImageZoomFragment; +import org.apache.taverna.mobile.ui.login.LoginActivity; +import org.apache.taverna.mobile.ui.login.LoginFragment; +import org.apache.taverna.mobile.ui.myworkflows.MyWorkflowActivity; +import org.apache.taverna.mobile.ui.myworkflows.MyWorkflowFragment; +import org.apache.taverna.mobile.ui.playerlogin.PlayerLoginFragment; +import org.apache.taverna.mobile.ui.tutorial.TutorialActivity; +import org.apache.taverna.mobile.ui.usage.UsageActivity; +import org.apache.taverna.mobile.ui.userprofile.UserProfileActivity; +import org.apache.taverna.mobile.ui.userprofile.UserProfileFragment; +import org.apache.taverna.mobile.ui.workflow.WorkflowFragment; +import org.apache.taverna.mobile.ui.workflowdetail.WorkflowDetailActivity; +import org.apache.taverna.mobile.ui.workflowdetail.WorkflowDetailFragment; +import org.apache.taverna.mobile.ui.workflowrun.WorkflowRunActivity; + +import dagger.Component; + +/** + * This component inject dependencies to all Activities across the application + */ + +@PerActivity +@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) +public interface ActivityComponent { + + void inject(DashboardActivity dashboardActivity); + + void inject(FavouriteWorkflowsActivity favouriteWorkflowsActivity); + + void inject(FavouriteWorkflowDetailActivity favouriteWorkflowDetailActivity); + + void inject(ImageZoomActivity imageZoomActivity); + + void inject(LoginActivity loginActivity); + + void inject(MyWorkflowActivity myWorkflowActivity); + + void inject(TutorialActivity tutorialActivity); + + void inject(UsageActivity usageActivity); + + void inject(UserProfileActivity userProfileActivity); + + void inject(WorkflowDetailActivity workflowDetailActivity); + + void inject(AnnouncementFragment announcementFragment); + + void inject(FavouriteWorkflowsFragment favouriteWorkflowsFragment); + + void inject(FavouriteWorkflowDetailFragment favouriteWorkflowDetailFragment); + + void inject(ImageZoomFragment imageZoomFragment); + + void inject(LoginFragment loginFragment); + + void inject(MyWorkflowFragment myWorkflowFragment); + + void inject(PlayerLoginFragment playerLoginFragment); + + void inject(UserProfileFragment userProfileFragment); + + void inject(WorkflowFragment workflowFragment); + + void inject(WorkflowDetailFragment workflowDetailFragment); + + void inject(WorkflowRunActivity workflowRunActivity); + + void inject(FlashScreenActivity flashScreenActivity); +} diff --git a/app/src/main/java/org/apache/taverna/mobile/injection/component/ApplicationComponent.java b/app/src/main/java/org/apache/taverna/mobile/injection/component/ApplicationComponent.java new file mode 100644 index 00000000..22fd38cd --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/injection/component/ApplicationComponent.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.injection.component; + +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.local.PreferencesHelper; +import org.apache.taverna.mobile.injection.ApplicationContext; +import org.apache.taverna.mobile.injection.module.ApplicationModule; + +import android.app.Application; +import android.content.Context; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = ApplicationModule.class) +public interface ApplicationComponent { + + @ApplicationContext + Context context(); + Application application(); + DataManager dataManager(); + PreferencesHelper preferencesHelper(); + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/injection/module/ActivityModule.java b/app/src/main/java/org/apache/taverna/mobile/injection/module/ActivityModule.java new file mode 100644 index 00000000..8a2738fa --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/injection/module/ActivityModule.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.injection.module; + +import android.app.Activity; +import android.content.Context; + +import org.apache.taverna.mobile.injection.ActivityContext; + +import dagger.Module; +import dagger.Provides; + +@Module +public class ActivityModule { + + private Activity mActivity; + + public ActivityModule(Activity activity) { + mActivity = activity; + } + + @Provides + Activity provideActivity() { + return mActivity; + } + + @Provides + @ActivityContext + Context providesContext() { + return mActivity; + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/injection/module/ApplicationModule.java b/app/src/main/java/org/apache/taverna/mobile/injection/module/ApplicationModule.java new file mode 100644 index 00000000..7ac727eb --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/injection/module/ApplicationModule.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.injection.module; + +import org.apache.taverna.mobile.injection.ApplicationContext; + +import android.app.Application; +import android.content.Context; + +import dagger.Module; +import dagger.Provides; + +/** + * Provide application-level dependencies. + */ + +@Module +public class ApplicationModule { + protected final Application mApplication; + + public ApplicationModule(Application application) { + mApplication = application; + } + + @Provides + Application provideApplication() { + return mApplication; + } + + @Provides + @ApplicationContext + Context provideContext() { + return mApplication; + } + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/Runs.java b/app/src/main/java/org/apache/taverna/mobile/tavernamobile/Runs.java deleted file mode 100644 index 8eeba064..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/Runs.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.apache.taverna.mobile.tavernamobile; - -/** - * Created by Larry Akah on 6/13/15. - * Workflow runs for a given workflow - */ -public class Runs { - private long run_id; - private long run_workflow_id; - private String run_name; - private String run_started_date; - private String run_ended_date; - private String state; - private String run_author; - public static enum RUN_STATE { FAILED,FINISHED,RUNNING}; - - - public Runs(String run_name, String run_started_date, String run_ended_date, String state) { - this.run_name = run_name; - this.run_started_date = run_started_date; - this.run_ended_date = run_ended_date; - this.state=state; - } - - public long getRun_id() { - return run_id; - } - - public void setRun_id(long run_id) { - this.run_id = run_id; - } - - public long getRun_workflow_id() { - return run_workflow_id; - } - - public void setRun_workflow_id(long run_workflow_id) { - this.run_workflow_id = run_workflow_id; - } - - public RUN_STATE getState() { - if(state.equalsIgnoreCase("finished")) - return RUN_STATE.FINISHED; - else if (state.equalsIgnoreCase("failed")) - return RUN_STATE.FAILED; - else - return RUN_STATE.RUNNING; - } - - public void setState(String state) { - this.state = state; - } - - public String getRun_name() { - return run_name; - } - - public void setRun_name(String run_name) { - this.run_name = run_name; - } - - public String getRun_started_date() { - return run_started_date; - } - - public void setRun_started_date(String run_started_date) { - this.run_started_date = run_started_date; - } - - public String getRun_author() { - return run_author; - } - - public void setRun_author(String run_author) { - this.run_author = run_author; - } - - public String getRun_ended_date() { - return run_ended_date; - } - - public void setRun_ended_date(String run_ended_date) { - this.run_ended_date = run_ended_date; - } -} 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 deleted file mode 100644 index 638094bd..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/TavernaPlayerAPI.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.apache.taverna.mobile.tavernamobile; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import android.content.Context; -import android.preference.PreferenceManager; - -import java.net.PasswordAuthentication; - -/** - * Created by Larry Akah on 6/13/15. - */ -public class TavernaPlayerAPI { - - public static String PLAYER_BASE_URL = "http://heater.cs.man.ac.uk:3000/"; - public static String SERVER_BASE_URL = "http://heater.cs.man.ac.uk:8090/taverna-2.5.4/"; - public static String PLAYER_WORKFLOW_URL = PLAYER_BASE_URL+"workflows/"; - public static String PLAYER_RUN_URL = PLAYER_BASE_URL+"runs/"; - public static String PLAYER_RUN_FRAMEWORK_URL = PLAYER_RUN_URL+"new?workflow_id="; //returns a json 'framework' used for creating runs for the given workflow - - public TavernaPlayerAPI(Context context) { - String server = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_server_url","/"); - String player = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_player_url","/"); - String user = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_player_url","/"); - String password = PreferenceManager.getDefaultSharedPreferences(context).getString("pref_player_url","/"); - PLAYER_BASE_URL = player; - SERVER_BASE_URL = server; - PLAYER_WORKFLOW_URL = PLAYER_BASE_URL+"workflows/"; - PLAYER_RUN_URL = PLAYER_BASE_URL+"runs/"; - PLAYER_RUN_FRAMEWORK_URL = PLAYER_RUN_URL+"new?workflow_id="; - } - - public TavernaPlayerAPI(){ - - } - - public static String getPLAYER_BASE_URL() { - return PLAYER_BASE_URL; - } - - public static String getSERVER_BASE_URL() { - return SERVER_BASE_URL; - } - - public static String getPLAYER_WORKFLOW_URL() { - return PLAYER_WORKFLOW_URL; - } - - public static String getPLAYER_RUN_URL(Context ctx) { - return PLAYER_RUN_URL; - } - - public static String getPLAYER_RUN_FRAMEWORK_URL(Context ctx) { - return PLAYER_RUN_FRAMEWORK_URL; - } - - public String getPlayerUserName(Context c){ - return PreferenceManager.getDefaultSharedPreferences(c).getString("pref_user","default"); - } - - public String getPlayerUserPassword(Context c){ - return PreferenceManager.getDefaultSharedPreferences(c).getString("pref_password","default"); - } - - public static class Authenticator extends java.net.Authenticator{ - private String username, password; - - public Authenticator(String username, String password) { - super(); - this.username = username; - this.password = password; - } - - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(this.username, this.password.toCharArray()); - } - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/User.java b/app/src/main/java/org/apache/taverna/mobile/tavernamobile/User.java deleted file mode 100644 index 09ca6e5d..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/User.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.apache.taverna.mobile.tavernamobile; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.graphics.Bitmap; - -import org.apache.taverna.mobile.adapters.WorkflowAdapter; -import org.simpleframework.xml.Element; - -import java.util.List; - -/** - * Created by root on 6/18/15. - */ -public class User { - - private static final long serialVersionUID = 3467195671046297377L; - @Element(required = false) - protected String id; - @Element(name = "created-at", required = false) - protected String created_at; - @Element(required = false) - protected String name; - @Element(required = false) - protected String description; - @Element(required = false) - protected String email; - @Element(required = false) - protected Bitmap avatar; - @Element(required = false) - protected String city; - @Element(required = false) - protected String country; - @Element(required = false) - protected String website; - protected String details_uri; - private String avatar_url; - private String row_id; //identifies the row to which this user is being loaded in, in the workflow listview - private WorkflowAdapter.ViewHolder userViewHolder; - - public User(String rid, WorkflowAdapter.ViewHolder vh){ - super(); - row_id = rid; - this.userViewHolder = vh; - } - - public WorkflowAdapter.ViewHolder getUserViewHolder() { - return userViewHolder; - } - - public void setUserViewHolder(WorkflowAdapter.ViewHolder userViewHolder) { - this.userViewHolder = userViewHolder; - } - - public String getRow_id() { - return this.row_id; - } - - protected List user_workflows; //a list of workflows owned by this user - - public void setId(String id) { - this.id = id; - } - - public String getCreated_at() { - return created_at; - } - - public void setCreated_at(String created_at) { - this.created_at = created_at; - } - - public String getDetails_uri() { - return this.details_uri; - } - - public void setDetails_uri(String details_uri) { - this.details_uri = details_uri; - } - - public String getAvatar_url() { - return this.avatar_url; - } - - public void setAvatar_url(String avatar_url) { - this.avatar_url = avatar_url; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public Bitmap getAvatar() { - return avatar; - } - - public void setAvatar(Bitmap avatar) { - this.avatar = avatar; - } - - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getCountry() { - return country; - } - - public void setCountry(String country) { - this.country = country; - } - - public String getWebsite() { - return website; - } - - public void setWebsite(String website) { - this.website = website; - } - - @Override - public String toString(){ - return "This is the user object"; - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/Workflow.java b/app/src/main/java/org/apache/taverna/mobile/tavernamobile/Workflow.java deleted file mode 100644 index b4547ae0..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/Workflow.java +++ /dev/null @@ -1,350 +0,0 @@ -package org.apache.taverna.mobile.tavernamobile; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; - -import org.apache.taverna.mobile.R; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by root on 6/8/15. - */ -public class Workflow { - private Context context; - private User uploader; - private String workflow_author; - private String workflow_title; - private String workflow_description, about, policy; - private String workflow_datecreated, workflow_datemodified; - private Bitmap workflow_author_bitmap; - private WorkflowComponent workflowComponent; - private String workflow_remote_url; //provides a link to download the workflow. Equivalent to content-uri in the xml form - private String workflow_web_url; //a string containing the workflow resource that can be loaded in browser - private String workflow_details_url;//used to refer to the details of the workflow - private List workflow_runs; - private int workflow_input; - private long id; - private String workflow_uploader;//indicate the user who uploaded the workflow - private String workflow_Type; //describes whether it is a type 1 or 2 workflow - private String workflow_preview; //a url to a preview image of the workflow - private String workflow_thumb_big; //a url to a full scale image of the workflow. I Will usually an SVG because the it is available for most of the workflows - private String workflow_licence_type; //describes a type of licensing for the workflow - private String workflow_content_type;//specifies a content type for the workflow; - private List workflow_tags;//provides a list of string tags that could be used to index the workflow for searches - private String workflow_versions;//a list of version for the workflow uploaded over time - private List workflow_credits;//key contributors to the workflow - - public static enum workflow_input_type{ TYPE_INT, TYPE_STRING, TYPE_OBJECT}; - - public Workflow() { - } - - public Workflow(Context context) { - this.context = context; - this.workflow_runs = new ArrayList(); - } - public Workflow(String author, String description, long id, String url){ - this.workflow_author = author; - this.workflow_author_bitmap = null;//BitmapFactory.decodeResource(getResources(), R.drawable.ic_userprofile); - this.workflow_description =description; - this.workflow_input=1; - this.id = id; - this.workflow_remote_url = url; - this.workflow_runs = new ArrayList(); - } - - public Workflow(Context ctx, String title, String author, String description, long id, String url){ - this.context = ctx; - this.workflow_author = author; - this.workflow_author_bitmap = BitmapFactory.decodeResource(this.context.getResources(), R.drawable.ic_userprofile); - this.workflow_description =description; - this.workflow_title =title; - this.workflow_input=1; - this.id = id; - this.workflow_remote_url = url; - this.workflow_runs = new ArrayList(); - } - - public long getId() { - return this.id; - } - - public void setId(long id) { - this.id = id; - } - - public String getWorkflow_datecreated() { - return this.workflow_datecreated; - } - - public String getWorkflow_remote_url() { - return this.workflow_remote_url; - } - - public void setWorkflow_remote_url(String workflow_remote_url) { - this.workflow_remote_url = workflow_remote_url; - } - - public String getWorkflow_details_url() { - return this.workflow_details_url; - } - - public User getUploader() { - return this.uploader; - } - - public void setUploader(User uploader) { - this.uploader = uploader; - } - - public void setWorkflow_details_url(String workflow_details_url) { - this.workflow_details_url = workflow_details_url; - } - - public String getPolicy() { - return this.policy; - } - - public void setPolicy(String policy) { - this.policy = policy; - } - - public String getAbout() { - return this.about; - } - - public void setAbout(String about) { - this.about = about; - } - - public void setWorkflow_datecreated(String workflow_datecreated) { - this.workflow_datecreated = workflow_datecreated; - } - - public String getWorkflow_datemodified() { - return this.workflow_datemodified; - } - - public void setWorkflow_datemodified(String workflow_datemodified) { - this.workflow_datemodified = workflow_datemodified; - } - - public List getWorkflow_runs() { - return this.workflow_runs; - } - - public void setWorkflow_runs(List workflow_runs) { - this.workflow_runs = workflow_runs; - } - - public void addWorkflowRun(Runs runs){ //adds a run to this workflow - this.workflow_runs.add(runs); - } - - public int getWorkflow_input() { - return this.workflow_input; - } - - public void setWorkflow_input(int workflow_input) { - this.workflow_input = workflow_input; - } - - public workflow_input_type getInputType(){ - return workflow_input_type.TYPE_INT; - } - - public String getWorkflow_author() { - return this.workflow_author; - } - - public String getWorkflow_description() { - return this.workflow_description; - } - - public String getWorkflow_title() { - return this.workflow_title; - } - - public Bitmap getWorkflow_author_bitmap() { - return this.workflow_author_bitmap; - } - - public WorkflowComponent getWorkflowComponent() { - return this.workflowComponent; - } - - public void setWorkflow_author(String workflow_author) { - this.workflow_author = workflow_author; - } - - public void setWorkflow_title(String workflow_title) { - this.workflow_title = workflow_title; - } - - public void setWorkflow_description(String workflow_description) { - this.workflow_description = workflow_description; - } - - public void setWorkflow_author_bitmap(Bitmap workflow_author_bitmap) { - this.workflow_author_bitmap = workflow_author_bitmap; - } - - public void setWorkflowComponent(WorkflowComponent workflowComponent) { - this.workflowComponent = workflowComponent; - } - - public String getWorkflow_web_url() { - return workflow_web_url; - } - - public void setWorkflow_web_url(String workflow_web_url) { - this.workflow_web_url = workflow_web_url; - } - - public String getWorkflow_uploader() { - return workflow_uploader; - } - - public void setWorkflow_uploader(String workflow_uploader) { - this.workflow_uploader = workflow_uploader; - } - - public String getWorkflow_Type() { - return workflow_Type; - } - - public void setWorkflow_Type(String workflow_Type) { - this.workflow_Type = workflow_Type; - } - - public String getWorkflow_preview() { - return workflow_preview; - } - - public void setWorkflow_preview(String workflow_preview) { - this.workflow_preview = workflow_preview; - } - - public String getWorkflow_thumb_big() { - return workflow_thumb_big; - } - - public void setWorkflow_thumb_big(String workflow_thumb_big) { - this.workflow_thumb_big = workflow_thumb_big; - } - - public String getWorkflow_licence_type() { - return workflow_licence_type; - } - - public void setWorkflow_licence_type(String workflow_licence_type) { - this.workflow_licence_type = workflow_licence_type; - } - - public String getWorkflow_content_type() { - return workflow_content_type; - } - - public void setWorkflow_content_type(String workflow_content_type) { - this.workflow_content_type = workflow_content_type; - } - - public List getWorkflow_tags() { - return workflow_tags; - } - - public void setWorkflow_tags(List workflow_tags) { - this.workflow_tags = workflow_tags; - } - - public String getWorkflow_versions() { - return workflow_versions; - } - - public void setWorkflow_versions(String workflow_versions) { - this.workflow_versions = workflow_versions; - } - - public List getWorkflow_credits() { - return workflow_credits; - } - - public void setWorkflow_credits(List workflow_credits) { - this.workflow_credits = workflow_credits; - } - - @Override - public String toString() { - return this.workflow_title; - } -} -/* Use the sample code if it becomes necessary to pass this objects amongst activities -/ simple class that just has one member property as an example -public class Workflow implements Parcelable { - private int mData; - - */ -/* everything below here is for implementing Parcelable *//* - - - // 99.9% of the time you can just ignore this - public int describeContents() { - return 0; - } - - // write your object's data to the passed-in Parcel - public void writeToParcel(Parcel out, int flags) { - out.writeInt(mData); - } - -// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods -public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Workflow createFromParcel(Parcel in) { - return new Workflow(in); - } - - public Workflow[] newArray(int size) { - return new Workflow[size]; - } -}; - - // example constructor that takes a Parcel and gives you an object populated with it's values - private Workflow(Parcel in) { - mData = in.readInt(); - } -} - -//application in intents. Sending object to another activity - Intent it = new Intent(); - it.putExtra("parsedWorkflow", myWorkflow); -//retrieve object - Workflow mWorkflow = (Workflow) getIntent().getParcelableExtra("parsedWorkflow"); - - */ diff --git a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/WorkflowComponent.java b/app/src/main/java/org/apache/taverna/mobile/tavernamobile/WorkflowComponent.java deleted file mode 100644 index dab4775d..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/tavernamobile/WorkflowComponent.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.apache.taverna.mobile.tavernamobile; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * Created by Larry Akah on 6/8/15. - * the component elements that make up a workflow's dataflow (e.g. Taverna has sources, sinks, processors, links and coordinations) - */ -public class WorkflowComponent { - - public WorkflowComponent() { - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/DashboardActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/DashboardActivity.java new file mode 100644 index 00000000..4acad97c --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/DashboardActivity.java @@ -0,0 +1,364 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.resource.drawable.GlideDrawable; +import com.bumptech.glide.request.animation.GlideAnimation; +import com.bumptech.glide.request.target.SimpleTarget; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.ui.anouncements.AnnouncementFragment; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.favouriteworkflow.FavouriteWorkflowsFragment; +import org.apache.taverna.mobile.ui.login.LoginActivity; +import org.apache.taverna.mobile.ui.myworkflows.MyWorkflowFragment; +import org.apache.taverna.mobile.ui.usage.UsageActivity; +import org.apache.taverna.mobile.ui.userprofile.UserProfileActivity; +import org.apache.taverna.mobile.ui.workflow.WorkflowFragment; +import org.apache.taverna.mobile.utils.ActivityUtils; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.NavigationView; +import android.support.v4.app.Fragment; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.webkit.WebView; +import android.widget.TableLayout; +import android.widget.TextView; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import de.hdodenhof.circleimageview.CircleImageView; + +import static com.raizlabs.android.dbflow.config.FlowManager.getContext; + +public class DashboardActivity extends BaseActivity { + + @Inject DataManager dataManager; + + @BindView(R.id.nav_view) + NavigationView navigationView; + + @BindView(R.id.drawer_layout) + DrawerLayout mDrawerLayout; + + @BindView(R.id.toolbar) + Toolbar toolbar; + + private Dialog dialog; + private Fragment fragment; + private MenuItem item; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_dashboard_main); + ButterKnife.bind(this); + getActivityComponent().inject(this); + setupDrawerContent(navigationView); + dialog = new Dialog(this); + + setSupportActionBar(toolbar); + final ActionBar ab = getSupportActionBar(); + if (ab != null) { + ab.setHomeAsUpIndicator(R.drawable.ic_menu); + ab.setDisplayHomeAsUpEnabled(true); + } + + /** + * Setting the Fragment in FrameLayout + */ + if (savedInstanceState == null) { + + fragment = new WorkflowFragment(); + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), fragment, + R.id.frame_container); + + navigationView.setCheckedItem(R.id.nav_workflows); + } + + setNavHeader(); + } + + /** + * @param navigationView Design Support NavigationView OnClick Listener Event + */ + private void setupDrawerContent(final NavigationView navigationView) { + + navigationView.setNavigationItemSelectedListener( + new NavigationView.OnNavigationItemSelectedListener() { + + @Override + public boolean onNavigationItemSelected(MenuItem menuItem) { + + switch (menuItem.getItemId()) { + case R.id.nav_workflows: + + fragment = new WorkflowFragment(); + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), + fragment, R.id.frame_container); + + menuItem.setChecked(true); + mDrawerLayout.closeDrawers(); + toolbar.setTitle(R.string.title_nav_all_workflows); + + return true; + + case R.id.nav_my_workflows: + + fragment = new MyWorkflowFragment(); + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), + fragment, R.id.frame_container); + + menuItem.setChecked(true); + mDrawerLayout.closeDrawers(); + toolbar.setTitle(R.string.title_nav_my_workflows); + return true; + + case R.id.nav_favourite_workflow: + + fragment = new FavouriteWorkflowsFragment(); + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), + fragment, R.id.frame_container); + + menuItem.setChecked(true); + mDrawerLayout.closeDrawers(); + toolbar.setTitle(R.string.title_nav_favourite_workflows); + return true; + + case R.id.nav_announcement: + + fragment = new AnnouncementFragment(); + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), + fragment, R.id.frame_container); + + menuItem.setChecked(true); + mDrawerLayout.closeDrawers(); + toolbar.setTitle(R.string.title_nav_announcement); + return true; + + + case R.id.nav_usage: + + Intent intent = new Intent(DashboardActivity.this, + UsageActivity.class); + startActivity(intent); + mDrawerLayout.closeDrawers(); + return true; + + case R.id.nav_about: + + TableLayout about = (TableLayout) getLayoutInflater().inflate(R + .layout.about, navigationView, false); + + dialog.setCanceledOnTouchOutside(true); + dialog.setTitle(getString(R.string.title_about)); + dialog.setContentView(about); + dialog.show(); + mDrawerLayout.closeDrawers(); + return true; + + case R.id.os_licences: + + WebView webView = (WebView) getLayoutInflater().inflate(R.layout + .fragment_licence, navigationView, false); + + webView.getSettings().setUseWideViewPort(true); + webView.loadUrl("file:///android_asset/licences.html"); + + AlertDialog alertDialog = new AlertDialog.Builder(DashboardActivity + .this, R.style.Theme_Taverna_Dialog) + .setTitle(getString(R.string.title_nav_os_licences)) + .setView(webView) + .setPositiveButton(android.R.string.ok, null) + .create(); + + alertDialog.show(); + mDrawerLayout.closeDrawers(); + return true; + + case R.id.apache_licences: + + WebView lWebView = (WebView) getLayoutInflater().inflate(R.layout + .fragment_licence, navigationView, false); + + lWebView.getSettings().setUseWideViewPort(true); + lWebView. + loadUrl("file:///android_asset/apache_licence_notice.html"); + + AlertDialog lAlertDialog = new AlertDialog.Builder(DashboardActivity + .this, R.style.Theme_Taverna_Dialog) + .setTitle(getString(R.string.title_nav_apache_licences)) + .setView(lWebView) + .setPositiveButton(android.R.string.ok, null) + .create(); + + lAlertDialog.show(); + mDrawerLayout.closeDrawers(); + return true; + + case R.id.nav_settings: + + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), + new SettingFragment(), R.id.frame_container); + + menuItem.setChecked(true); + mDrawerLayout.closeDrawers(); + toolbar.setTitle(R.string.title_nav_settings); + return true; + + case R.id.nav_logout: + + signOutConfirmation(); + return true; + + } + return true; + } + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.dashboard_main, menu); + return true; + } + + private void signOutConfirmation() { + new AlertDialog.Builder(this) + .setTitle(R.string.sign_out_conformation) + .setMessage(R.string.sign_out_message) + .setPositiveButton(R.string.sign_out, new DialogInterface.OnClickListener() { + + public void onClick(DialogInterface dialog, int whichButton) { + signOut(); + } + }) + .setNegativeButton(android.R.string.no, null).show(); + } + + private void signOut() { + mDrawerLayout.closeDrawers(); + dataManager.getPreferencesHelper().clear(); + dataManager.getDBHelper().clearFavouriteWorkflow(); + + startActivity(new Intent(getApplicationContext(), + LoginActivity.class)); + finish(); + } + + private void setNavHeader() { + + View headerView = navigationView.getHeaderView(0); + final CircleImageView navUserAvatar = headerView.findViewById(R.id.nav_user_avatar); + + if (dataManager.getPreferencesHelper().getUserAvatarUrl() != null) { + + String avatarUrl = dataManager.getPreferencesHelper().getUserAvatarUrl(); + + Glide.with(getContext()) + .load(avatarUrl) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .placeholder(R.drawable.ic_account_circle_black_24dp) + .error(R.drawable.ic_account_circle_black_24dp) + .into(new SimpleTarget() { + @Override + public void onResourceReady(GlideDrawable resource, GlideAnimation glideAnimation) { + navUserAvatar.setImageDrawable(resource); + } + }); + + navUserAvatar.setOnClickListener(new View.OnClickListener() { + @OnClick + public void onClick(View v) { + Intent intent = new Intent(DashboardActivity.this, UserProfileActivity.class); + startActivity(intent); + } + }); + } else { + + String avatarUrl = "http://www.myexperiment.org/images/avatar.png"; + + Glide.with(getContext()) + .load(avatarUrl) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .placeholder(R.drawable.ic_account_circle_black_24dp) + .error(R.drawable.ic_account_circle_black_24dp) + .into(new SimpleTarget() { + @Override + public void onResourceReady(GlideDrawable resource, GlideAnimation glideAnimation) { + navUserAvatar.setImageDrawable(resource); + } + }); + + navUserAvatar.setOnClickListener(new View.OnClickListener() { + @OnClick + public void onClick(View v) { + Intent intent = new Intent(DashboardActivity.this, UserProfileActivity.class); + startActivity(intent); + } + }); + } + + String userName = dataManager.getPreferencesHelper().getUserName(); + TextView navUserName = headerView.findViewById(R.id.nav_user_name); + navUserName.setText(userName); + + String userEmail = dataManager.getPreferencesHelper().getUserEmail(); + TextView navUserEmail = headerView.findViewById(R.id.nav_user_email); + navUserEmail.setText(userEmail); + + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + mDrawerLayout.openDrawer(GravityCompat.START); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onBackPressed() { + if (mDrawerLayout.isDrawerOpen(navigationView)) { + mDrawerLayout.closeDrawers(); + } else { + super.onBackPressed(); + } + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/DownloadingFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/DownloadingFragment.java new file mode 100644 index 00000000..4c3dc8bb --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/DownloadingFragment.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.utils.Constants; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class DownloadingFragment extends Fragment { + + @BindView(R.id.tvMessage) + TextView tv_Message; + + private String message; + + public static DownloadingFragment newInstance(String message) { + + Bundle args = new Bundle(); + args.putString(Constants.ARGS_MESSAGE, message); + DownloadingFragment fragment = new DownloadingFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + message = getArguments().getString(Constants.ARGS_MESSAGE); + } + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable + Bundle savedInstanceState) { + ViewGroup rootView = (ViewGroup) inflater.inflate( + R.layout.fragment_downloading, container, false); + + ButterKnife.bind(this, rootView); + return rootView; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + tv_Message.setText(message); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/FlashScreenActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/FlashScreenActivity.java new file mode 100644 index 00000000..2e24682a --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/FlashScreenActivity.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.login.LoginActivity; +import org.apache.taverna.mobile.ui.tutorial.TutorialActivity; +import android.content.Intent; +import android.os.Bundle; + +import android.support.annotation.Nullable; +import java.util.concurrent.TimeUnit; + +import javax.inject.Inject; + +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.functions.Consumer; +import io.reactivex.schedulers.Schedulers; + +public class FlashScreenActivity extends BaseActivity { + + @Inject + DataManager dataManager; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_flash_screen); + getActivityComponent().inject(this); + + Observable.timer(2, TimeUnit.SECONDS) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer() { + @Override + public void accept(Long aLong) throws Exception { + if (!dataManager.getPreferencesHelper().isLoggedInFlag()) { + dataManager.getPreferencesHelper().clear(); + if (dataManager.getPreferencesHelper().isFirstTimeLaunch()) { + startActivity(new Intent(FlashScreenActivity.this, + TutorialActivity.class)); + (FlashScreenActivity.this).finish(); + + } else { + startActivity(new Intent(FlashScreenActivity.this, + LoginActivity.class)); + (FlashScreenActivity.this).finish(); + } + } else { + startActivity(new Intent(FlashScreenActivity.this, + DashboardActivity.class)); + (FlashScreenActivity.this).finish(); + } + } + }); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/SettingFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/SettingFragment.java new file mode 100644 index 00000000..08715c7a --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/SettingFragment.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.local.PreferencesHelper; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v7.preference.PreferenceFragmentCompat; +import android.view.Menu; +import android.view.MenuItem; + + +public class SettingFragment extends PreferenceFragmentCompat implements SharedPreferences + .OnSharedPreferenceChangeListener { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + addPreferencesFromResource(R.xml.pref_general); + } + + @Override + public void onResume() { + super.onResume(); + getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener( + this); + } + + @Override + public void onPause() { + getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener( + this); + super.onPause(); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals(getString(R.string.pref_key_player_password)) || key.equals(getString(R + .string.pref_key_player_user))) { + getPreferenceManager().getSharedPreferences().edit().putBoolean(PreferencesHelper + .PREF_KEY_PLAYER_LOGGED_IN, false).apply(); + } + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + MenuItem item = menu.findItem(R.id.action_search); + item.setVisible(false); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/adapter/AnnouncementAdapter.java b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/AnnouncementAdapter.java index c25e50d9..679aaf20 100644 --- a/app/src/main/java/org/apache/taverna/mobile/ui/adapter/AnnouncementAdapter.java +++ b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/AnnouncementAdapter.java @@ -18,31 +18,29 @@ */ package org.apache.taverna.mobile.ui.adapter; +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.model.Announcement; + import android.support.v7.widget.RecyclerView; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.data.model.Announcement; - import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; - public class AnnouncementAdapter extends RecyclerView.Adapter { - private List mAnnouncementList; private final int VIEW_ITEM = 1; private final int VIEW_PROG = 0; + private List mAnnouncementList; - public AnnouncementAdapter( List announcementList) { + public AnnouncementAdapter(List announcementList) { mAnnouncementList = announcementList; } @@ -50,21 +48,12 @@ public void setAnnouncementList(List announcementList) { mAnnouncementList = announcementList; } - public static class ProgressViewHolder extends RecyclerView.ViewHolder { - public ProgressBar progressBar; - public ProgressViewHolder(View v) { - super(v); - progressBar = (ProgressBar)v.findViewById(R.id.progressBar1); - } - } - - @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { RecyclerView.ViewHolder vh; if (viewType == VIEW_ITEM) { View v = LayoutInflater.from(parent.getContext()).inflate( - R.layout.item_recyclerview, parent, false); + R.layout.item_announcement, parent, false); vh = new ViewHolder(v); } else { @@ -78,9 +67,9 @@ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - if(holder instanceof ViewHolder) { - ((ViewHolder) holder).tvAnnouncementTitle.setText(mAnnouncementList.get(position).getContent()); - Log.e("", "onBindViewHolder: "+mAnnouncementList.get(1).getContent()); + if (holder instanceof ViewHolder) { + ((ViewHolder) holder).tvAnnouncementTitle.setText(mAnnouncementList.get(position) + .getContent()); } } @@ -91,9 +80,17 @@ public int getItemCount() { @Override public int getItemViewType(int position) { - return mAnnouncementList.get(position)!=null? VIEW_ITEM: VIEW_PROG; + return mAnnouncementList.get(position) != null ? VIEW_ITEM : VIEW_PROG; } + public static class ProgressViewHolder extends RecyclerView.ViewHolder { + public ProgressBar progressBar; + + public ProgressViewHolder(View v) { + super(v); + progressBar = (ProgressBar) v.findViewById(R.id.progressBar1); + } + } class ViewHolder extends RecyclerView.ViewHolder { diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/adapter/EndlessRecyclerOnScrollListener.java b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/EndlessRecyclerOnScrollListener.java index f3fb3f57..7efd51bd 100644 --- a/app/src/main/java/org/apache/taverna/mobile/ui/adapter/EndlessRecyclerOnScrollListener.java +++ b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/EndlessRecyclerOnScrollListener.java @@ -23,15 +23,14 @@ public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener { - public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName(); - - private int previousTotal = 0; // The total number of items in the dataset after the last load - private boolean loading = true; // True if we are still waiting for the last set of data to load. - private int visibleThreshold = 1; // The minimum amount of items to have below your current scroll position before loading more. + public static final String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName(); int firstVisibleItem, visibleItemCount, totalItemCount; - + private int previousTotal = 0; // The total number of items in the dataset after the last load + private boolean loading = true; // True if we are still waiting for the last set of data to + // load. + private int visibleThreshold = 1; // The minimum amount of items to have below your current + // scroll position before loading more. private int current_page = 1; - private LinearLayoutManager mLinearLayoutManager; public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) { @@ -46,13 +45,19 @@ public void onScrolled(RecyclerView recyclerView, int dx, int dy) { totalItemCount = mLinearLayoutManager.getItemCount(); firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition(); - if (loading) { - if (totalItemCount > previousTotal+1) { - loading = false; - previousTotal = totalItemCount; - } + + if (totalItemCount < previousTotal) { + previousTotal = 0; + } + + if (loading && totalItemCount > previousTotal + 1) { + + loading = false; + previousTotal = totalItemCount; + } - if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) { + if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + + visibleThreshold)) { // End has been reached // Do something current_page++; diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/adapter/FavouriteWorkflowsAdapter.java b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/FavouriteWorkflowsAdapter.java new file mode 100644 index 00000000..b31eeccd --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/FavouriteWorkflowsAdapter.java @@ -0,0 +1,138 @@ +/* +* Apache Taverna Mobile +* Copyright 2016 The Apache Software Foundation + +* This product includes software developed at +* The Apache Software Foundation (http://www.apache.org/). + +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.apache.taverna.mobile.ui.adapter; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.model.Workflow; + +import android.content.Context; +import android.net.Uri; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class FavouriteWorkflowsAdapter extends RecyclerView.Adapter { + + private static final String TAG = FavouriteWorkflowsAdapter.class.getName(); + + private final List mWorkflowList; + private final Context context; + + + public FavouriteWorkflowsAdapter(List mWorkflowList, Context context) { + this.mWorkflowList = mWorkflowList; + this.context = context; + + } + + public void addWorkflow(Workflow workflow) { + this.mWorkflowList.add(workflow); + this.notifyDataSetChanged(); + + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + RecyclerView.ViewHolder vh; + + View v = LayoutInflater.from(parent.getContext()).inflate( + R.layout.item_recyclerview_favourite_workflow_list, parent, false); + vh = new ViewHolder(v); + + return vh; + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + if (holder instanceof ViewHolder) { + + Workflow workflow = mWorkflowList.get(position); + String date = workflow.getCreatedAt() + .substring(0, workflow.getCreatedAt().indexOf(' ')); + + + ((ViewHolder) holder).tvDate.setText(date); + ((ViewHolder) holder).tvTitle.setText(workflow.getTitle()); + ((ViewHolder) holder).tvType.setText(workflow.getType().getContent()); + ((ViewHolder) holder).tvUploader.setText(workflow.getUploader().getContent()); + + Uri uri = Uri.parse(workflow.getPreviewUri()); + + Glide.with(context) + .load(uri) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .placeholder(R.drawable.placeholder) + .error(R.drawable.placeholder) + .into(((ViewHolder) holder).ivWorkflowImage); + } + } + + @Override + public int getItemCount() { + //Log.d(TAG, "getItemCount: " + mWorkflowList.size()); + return mWorkflowList.size(); + } + + public Workflow getItem(int position) { + return mWorkflowList != null ? mWorkflowList.get(position) : null; + } + + class ViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.tvDate) + TextView tvDate; + + @BindView(R.id.tvTitle) + TextView tvTitle; + + @BindView(R.id.tvType) + TextView tvType; + + @BindView(R.id.tvUploader) + TextView tvUploader; + + @BindView(R.id.ivWorkflowImage) + ImageView ivWorkflowImage; + + public ViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + } + } + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/adapter/RecyclerItemClickListner.java b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/RecyclerItemClickListner.java index 5c0df16b..ac17eb46 100644 --- a/app/src/main/java/org/apache/taverna/mobile/ui/adapter/RecyclerItemClickListner.java +++ b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/RecyclerItemClickListner.java @@ -27,114 +27,114 @@ public class RecyclerItemClickListner implements RecyclerView.OnItemTouchListener { - + protected OnItemClickListener listener; - + private GestureDetector gestureDetector; - + @Nullable private View childView; - + private int childViewPosition; - + public RecyclerItemClickListner(Context context, OnItemClickListener listener) { this.gestureDetector = new GestureDetector(context, new GestureListener()); this.listener = listener; - } - - @Override + } + + @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent event) { childView = view.findChildViewUnder(event.getX(), event.getY()); childViewPosition = view.getChildAdapterPosition(childView); - + return childView != null && gestureDetector.onTouchEvent(event); - } - - @Override + } + + @Override public void onTouchEvent(RecyclerView view, MotionEvent event) { // Not needed. - } - - @Override + } + + @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { - - } - - /** - * A click listener for items. - */ - public interface OnItemClickListener { - - /** - * Called when an item is clicked. - * - * @param childView View of the item that was clicked. - * @param position Position of the item that was clicked. - */ + + } + + /** + * A click listener for items. + */ + public interface OnItemClickListener { + + /** + * Called when an item is clicked. + * + * @param childView View of the item that was clicked. + * @param position Position of the item that was clicked. + */ public void onItemClick(View childView, int position); - - /** - * Called when an item is long pressed. - * - * @param childView View of the item that was long pressed. - * @param position Position of the item that was long pressed. - */ + + /** + * Called when an item is long pressed. + * + * @param childView View of the item that was long pressed. + * @param position Position of the item that was long pressed. + */ public void onItemLongPress(View childView, int position); - - } - - /** - * A simple click listener whose methods can be overridden one by one. - */ - public static abstract class SimpleOnItemClickListener implements OnItemClickListener { - - /** - * Called when an item is clicked. The default implementation is a no-op. - * - * @param childView View of the item that was clicked. - * @param position Position of the item that was clicked. - */ + + } + + /** + * A simple click listener whose methods can be overridden one by one. + */ + public abstract static class SimpleOnItemClickListener implements OnItemClickListener { + + /** + * Called when an item is clicked. The default implementation is a no-op. + * + * @param childView View of the item that was clicked. + * @param position Position of the item that was clicked. + */ public void onItemClick(View childView, int position) { // Do nothing. - } - - /** - * Called when an item is long pressed. The default implementation is a no-op. - * - * @param childView View of the item that was long pressed. - * @param position Position of the item that was long pressed. - */ + } + + /** + * Called when an item is long pressed. The default implementation is a no-op. + * + * @param childView View of the item that was long pressed. + * @param position Position of the item that was long pressed. + */ public void onItemLongPress(View childView, int position) { // Do nothing. - } - - } - + } + + } + protected class GestureListener extends GestureDetector.SimpleOnGestureListener { - - @Override + + @Override public boolean onSingleTapUp(MotionEvent event) { if (childView != null) { listener.onItemClick(childView, childViewPosition); - } - - return true; - } - - @Override + } + + return true; + } + + @Override public void onLongPress(MotionEvent event) { if (childView != null) { listener.onItemLongPress(childView, childViewPosition); - } - } - - @Override + } + } + + @Override public boolean onDown(MotionEvent event) { // Best practice to always return true here. // http://developer.android.com/training/gestures/detector.html#detect - return true; - } - - } - + return true; + } + + } + } \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/adapter/TutorialSliderAdapter.java b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/TutorialSliderAdapter.java new file mode 100644 index 00000000..ebdc2773 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/TutorialSliderAdapter.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.adapter; + +import android.content.Context; +import android.support.v4.view.PagerAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.apache.taverna.mobile.data.model.TutorialSliderEnum; +import org.apache.taverna.mobile.injection.ApplicationContext; + +import javax.inject.Inject; + + +public class TutorialSliderAdapter extends PagerAdapter { + + private Context context; + + @Inject + public TutorialSliderAdapter(@ApplicationContext Context context) { + this.context = context; + } + + public Object instantiateItem(ViewGroup collection, int position) { + TutorialSliderEnum tutorialSliderEnum = TutorialSliderEnum.values()[position]; + LayoutInflater inflater = LayoutInflater.from(context); + ViewGroup layout = (ViewGroup) inflater + .inflate(tutorialSliderEnum.getLayoutId(), collection, false); + collection.addView(layout); + return layout; + } + + public void destroyItem(ViewGroup collection, int position, Object view) { + collection.removeView((View) view); + } + + public int getCount() { + return TutorialSliderEnum.values().length; + } + + public boolean isViewFromObject(View view, Object object) { + return view == object; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/adapter/WorkflowAdapter.java b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/WorkflowAdapter.java new file mode 100644 index 00000000..342dee48 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/adapter/WorkflowAdapter.java @@ -0,0 +1,168 @@ +/* +* Apache Taverna Mobile +* Copyright 2016 The Apache Software Foundation + +* This product includes software developed at +* The Apache Software Foundation (http://www.apache.org/). + +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.apache.taverna.mobile.ui.adapter; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.model.Workflow; + +import android.content.Context; +import android.net.Uri; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class WorkflowAdapter extends RecyclerView.Adapter { + + private final int VIEW_ITEM = 1; + private final int VIEW_PROG = 0; + + private static final String TAG = WorkflowAdapter.class.getName(); + + private final List mWorkflowList; + private final Context context; + + + public WorkflowAdapter(List mWorkflowList, Context context) { + this.mWorkflowList = mWorkflowList; + this.context = context; + + } + + public void addWorkflow(Workflow workflow) { + this.mWorkflowList.add(workflow); + this.notifyDataSetChanged(); + } + + public void removeLastNullWorkflow() { + if (mWorkflowList.get(mWorkflowList.size() - 1) == null) { + this.mWorkflowList.remove(mWorkflowList.size() - 1); + this.notifyDataSetChanged(); + } + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + RecyclerView.ViewHolder vh; + + if (viewType == VIEW_ITEM) { + View v = LayoutInflater.from(parent.getContext()).inflate( + R.layout.item_workflow_dashboard, parent, false); + vh = new ViewHolder(v); + } else { + View v = LayoutInflater.from(parent.getContext()).inflate( + R.layout.item_progressbar, parent, false); + vh = new ProgressViewHolder(v); + } + return vh; + } + + @Override + public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { + if (holder instanceof ViewHolder) { + + Workflow workflow = mWorkflowList.get(position); + String date = workflow.getCreatedAt() + .substring(0, workflow.getCreatedAt().indexOf(' ')); + + ((ViewHolder) holder).tvDate.setText(date); + ((ViewHolder) holder).tvTitle.setText(workflow.getTitle()); + ((ViewHolder) holder).tvType.setText(workflow.getType().getContent()); + ((ViewHolder) holder).tvUploader.setText(workflow.getUploader().getContent()); + + Uri uri = Uri.parse(workflow.getPreviewUri()); + + Glide.with(context) + .load(uri) + .diskCacheStrategy(DiskCacheStrategy.RESULT) + .placeholder(R.drawable.placeholder) + .error(R.drawable.placeholder) + .fitCenter() + .into(((ViewHolder) holder).ivWorkflowImage); + } + } + + @Override + public int getItemCount() { + return mWorkflowList.size(); + } + + @Override + public int getItemViewType(int position) { + return mWorkflowList.get(position) != null ? VIEW_ITEM : VIEW_PROG; + } + + public Workflow getItem(int position) { + return mWorkflowList != null ? mWorkflowList.get(position) : null; + } + + + class ViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.tvDate) + TextView tvDate; + + @BindView(R.id.tvTitle) + TextView tvTitle; + + @BindView(R.id.tvType) + TextView tvType; + + @BindView(R.id.tvUploader) + TextView tvUploader; + + @BindView(R.id.ivWorkflowImage) + ImageView ivWorkflowImage; + + public ViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + } + } + + public static class ProgressViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.progressBar1) + public ProgressBar progressBar; + + public ProgressViewHolder(View v) { + super(v); + ButterKnife.bind(this, v); + } + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementFragment.java index d10f8028..fc54d8da 100644 --- a/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementFragment.java +++ b/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementFragment.java @@ -18,20 +18,30 @@ */ package org.apache.taverna.mobile.ui.anouncements; +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.Announcements; +import org.apache.taverna.mobile.data.model.DetailAnnouncement; +import org.apache.taverna.mobile.ui.adapter.AnnouncementAdapter; +import org.apache.taverna.mobile.ui.adapter.EndlessRecyclerOnScrollListener; +import org.apache.taverna.mobile.ui.adapter.RecyclerItemClickListner; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.ConnectionInfo; +import org.apache.taverna.mobile.utils.ScrollChildSwipeRefreshLayout; + import android.app.ProgressDialog; import android.os.Bundle; import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.webkit.WebView; @@ -39,24 +49,26 @@ import android.widget.ProgressBar; import android.widget.TextView; -import org.apache.taverna.mobile.R; -import org.apache.taverna.mobile.data.DataManager; -import org.apache.taverna.mobile.data.model.Announcements; -import org.apache.taverna.mobile.data.model.DetailAnnouncement; -import org.apache.taverna.mobile.ui.adapter.AnnouncementAdapter; -import org.apache.taverna.mobile.ui.adapter.EndlessRecyclerOnScrollListener; -import org.apache.taverna.mobile.ui.adapter.RecyclerItemClickListner; -import org.apache.taverna.mobile.utils.ConnectionInfo; -import org.apache.taverna.mobile.utils.ScrollChildSwipeRefreshLayout; +import javax.inject.Inject; import butterknife.BindView; import butterknife.ButterKnife; +import static android.support.design.widget.Snackbar.make; -public class AnnouncementFragment extends Fragment implements RecyclerItemClickListner.OnItemClickListener, AnnouncementMvpView { +public class AnnouncementFragment extends Fragment implements RecyclerItemClickListner + .OnItemClickListener, AnnouncementMvpView { public final String LOG_TAG = getClass().getSimpleName(); + @Inject + DataManager dataManager; + + @Inject + AnnouncementPresenter mAnnouncementPresenter; + + AnnouncementAdapter mAnnouncementAdapter; + @BindView(R.id.rv_movies) RecyclerView mRecyclerView; @@ -66,28 +78,24 @@ public class AnnouncementFragment extends Fragment implements RecyclerItemClickL @BindView(R.id.progress_circular) ProgressBar mProgressBar; - private AlertDialog alertDialog; + private AlertDialog alertDialog; private ProgressDialog dialog; private Announcements mAnnouncements; - private DataManager dataManager; - - private AnnouncementPresenter mAnnouncementPresenter; - - private AnnouncementAdapter mAnnouncementAdapter; - private int mPageNumber = 1; private DetailAnnouncement mAnnouncementDetail; - private ConnectionInfo mConnectionInfo; @Override public void onItemClick(View childView, int position) { - showWaitProgress(true); - mAnnouncementPresenter.loadAnnouncementDetails(mAnnouncements.getAnnouncement().get(position).getId()); + if (mAnnouncements.getAnnouncement().get(position) != null && position != -1) { + showWaitProgress(true); + mAnnouncementPresenter.loadAnnouncementDetails(mAnnouncements.getAnnouncement() + .get(position).getId()); + } } @Override @@ -99,29 +107,18 @@ public void onItemLongPress(View childView, int position) { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - mAnnouncements = new Announcements(); - dataManager = new DataManager(); - mAnnouncementPresenter = new AnnouncementPresenter(dataManager); - mConnectionInfo =new ConnectionInfo(getContext()); + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + setHasOptionsMenu(true); } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_announcement, container, false); ButterKnife.bind(this, rootView); mAnnouncementPresenter.attachView(this); - Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar); - ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); - - final ActionBar ab = ((AppCompatActivity) getActivity()).getSupportActionBar(); - if (ab != null) { - ab.setHomeAsUpIndicator(R.drawable.ic_menu); - ab.setDisplayHomeAsUpEnabled(true); - } - final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); mRecyclerView.setLayoutManager(layoutManager); @@ -129,11 +126,12 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa mRecyclerView.setItemAnimator(new DefaultItemAnimator()); - mSwipeRefresh.setColorSchemeResources(R.color.colorAccent, R.color.colorAccent, R.color.colorPrimary); + mSwipeRefresh.setColorSchemeResources(R.color.colorAccent, R.color.colorAccent, R.color + .colorPrimary); mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { - if (mConnectionInfo.isConnectingToInternet()) { + if (ConnectionInfo.isConnectingToInternet(getContext())) { if (mSwipeRefresh.isRefreshing()) { mPageNumber = 1; mAnnouncementPresenter.loadAllAnnouncement(mPageNumber); @@ -141,7 +139,7 @@ public void onRefresh() { } } else { Log.i(LOG_TAG, "NO Internet Connection"); - showErrorSnackBar(); + showSnackBar(R.string.no_internet_connection); if (mSwipeRefresh.isRefreshing()) { mSwipeRefresh.setRefreshing(false); } @@ -153,19 +151,20 @@ public void onRefresh() { showProgressbar(true); mAnnouncementPresenter.loadAllAnnouncement(mPageNumber); - mRecyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(layoutManager) { + mRecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(layoutManager) { @Override public void onLoadMore(int current_page) { - if (mConnectionInfo.isConnectingToInternet()) { + if (ConnectionInfo.isConnectingToInternet(getContext())) { mAnnouncements.getAnnouncement().add(null); - mAnnouncementAdapter.notifyItemInserted(mAnnouncements.getAnnouncement().size()); + mAnnouncementAdapter.notifyItemInserted(mAnnouncements.getAnnouncement().size + ()); mPageNumber = ++mPageNumber; mAnnouncementPresenter.loadAllAnnouncement(mPageNumber); Log.i(LOG_TAG, "Loading more"); } else { Log.i(LOG_TAG, "Internet not available. Not loading more posts."); - showErrorSnackBar(); + showSnackBar(R.string.no_internet_connection); } } }); @@ -180,13 +179,13 @@ public void onDestroyView() { @Override - public void showAllAnouncement(Announcements announcements) { + public void showAllAnnouncement(Announcements announcements) { if (mPageNumber == 1) { mAnnouncements = announcements; mAnnouncementAdapter = new AnnouncementAdapter(mAnnouncements.getAnnouncement()); mRecyclerView.setAdapter(mAnnouncementAdapter); } else { - mAnnouncements.getAnnouncement().remove(mAnnouncements.getAnnouncement().size() - 1); + removeLoadMoreProgressBar(); mAnnouncements.getAnnouncement().addAll(announcements.getAnnouncement()); } @@ -197,26 +196,36 @@ public void showAllAnouncement(Announcements announcements) { } } + @Override + public void removeLoadMoreProgressBar() { + mAnnouncements.getAnnouncement().remove(mAnnouncements.getAnnouncement().size() - 1); + mAnnouncementAdapter.notifyDataSetChanged(); + } + @Override public void showProgressbar(boolean status) { if (status) { mProgressBar.setVisibility(View.VISIBLE); - } else + } else { mProgressBar.setVisibility(View.GONE); + } } @Override public void showAnnouncementDetail(DetailAnnouncement detailAnnouncement) { + if (alertDialog != null && alertDialog.isShowing()) { + alertDialog.dismiss(); + } mAnnouncementDetail = detailAnnouncement; AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext()); LayoutInflater inflater = getActivity().getLayoutInflater(); View dialogView = inflater.inflate(R.layout.detail_annoucement_dialog_layout, null); dialogBuilder.setView(dialogView); - TextView title = ButterKnife.findById(dialogView, R.id.tvDialogTitle); - TextView date = ButterKnife.findById(dialogView, R.id.tvDialogDate); - TextView author = ButterKnife.findById(dialogView, R.id.tvDialogAuthor); - WebView text = ButterKnife.findById(dialogView, R.id.wvDialogText); - Button buttonOk=ButterKnife.findById(dialogView, R.id.bDialogOK); + TextView title = dialogView.findViewById(R.id.tvDialogTitle); + TextView date = dialogView.findViewById(R.id.tvDialogDate); + TextView author = dialogView.findViewById(R.id.tvDialogAuthor); + WebView text = dialogView.findViewById(R.id.wvDialogText); + Button buttonOk = dialogView.findViewById(R.id.bDialogOK); buttonOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -236,9 +245,11 @@ public void onResume() { super.onResume(); } - public void showErrorSnackBar(){ - final Snackbar snackbar = Snackbar.make(mRecyclerView, "No Internet Connection", Snackbar.LENGTH_LONG); - snackbar.setAction("OK", new View.OnClickListener() { + @Override + public void showSnackBar(int message) { + final Snackbar snackbar = make(getActivity().findViewById(android.R.id.content), + message, Snackbar.LENGTH_LONG); + snackbar.setAction(getResources().getString(R.string.ok), new View.OnClickListener() { @Override public void onClick(View view) { snackbar.dismiss(); @@ -250,10 +261,20 @@ public void onClick(View view) { @Override public void showWaitProgress(boolean b) { - if(b){ - dialog = ProgressDialog.show(getContext(), "Loading", "Please wait...", true); - }else{ + if (b) { + if (dialog != null && dialog.isShowing()) { + dialog.dismiss(); + } + dialog = ProgressDialog.show(getContext(), "Loading", "Please wait...", true); + } else { dialog.dismiss(); } } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + MenuItem item = menu.findItem(R.id.action_search); + item.setVisible(false); + } } \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementMvpView.java index cfaaa57c..4a534bd2 100644 --- a/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementMvpView.java +++ b/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementMvpView.java @@ -18,16 +18,22 @@ */ package org.apache.taverna.mobile.ui.anouncements; -import org.apache.taverna.mobile.data.model.DetailAnnouncement; import org.apache.taverna.mobile.data.model.Announcements; +import org.apache.taverna.mobile.data.model.DetailAnnouncement; import org.apache.taverna.mobile.ui.base.MvpView; public interface AnnouncementMvpView extends MvpView { - void showAllAnouncement(Announcements announcements); + void showAllAnnouncement(Announcements announcements); + + void removeLoadMoreProgressBar(); + void showProgressbar(boolean b); - void showErrorSnackBar(); + + void showSnackBar(int message); + void showWaitProgress(boolean b); + void showAnnouncementDetail(DetailAnnouncement detailAnnouncement); } \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementPresenter.java index d4e5cfee..66791ede 100644 --- a/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementPresenter.java +++ b/app/src/main/java/org/apache/taverna/mobile/ui/anouncements/AnnouncementPresenter.java @@ -20,25 +20,33 @@ import android.util.Log; +import org.apache.taverna.mobile.R; import org.apache.taverna.mobile.data.DataManager; -import org.apache.taverna.mobile.data.model.DetailAnnouncement; import org.apache.taverna.mobile.data.model.Announcements; +import org.apache.taverna.mobile.data.model.DetailAnnouncement; import org.apache.taverna.mobile.ui.base.BasePresenter; -import rx.Observer; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; +import io.reactivex.disposables.CompositeDisposable; public class AnnouncementPresenter extends BasePresenter { public final String LOG_TAG = getClass().getSimpleName(); - private DataManager mDataManager; - private Subscription mSubscriptions; + private DataManager mDataManager; + private CompositeDisposable compositeDisposable; - public AnnouncementPresenter(DataManager dataManager){ + @Inject + public AnnouncementPresenter(DataManager dataManager) { mDataManager = dataManager; + compositeDisposable = new CompositeDisposable(); } @Override @@ -49,58 +57,72 @@ public void attachView(AnnouncementMvpView mvpView) { @Override public void detachView() { super.detachView(); - if (mSubscriptions != null) mSubscriptions.unsubscribe(); + compositeDisposable.clear(); } - public void loadAllAnnouncement(int pageNumber){ - - mSubscriptions = mDataManager.getAllAnnouncement(pageNumber) + public void loadAllAnnouncement(int pageNumber) { + checkViewAttached(); + compositeDisposable.add(mDataManager.getAllAnnouncement( + getAnnouncementQueryOptions(pageNumber)) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) - .subscribe(new Observer() { + .subscribeWith(new DisposableObserver() { + @Override - public void onCompleted() { - getMvpView().showProgressbar(false); + public void onNext(Announcements announcements) { + if (announcements.getAnnouncement() != null) { + getMvpView().showAllAnnouncement(announcements); + } else { + getMvpView().showSnackBar(R.string.no_more_announcement_available); + getMvpView().removeLoadMoreProgressBar(); + } } @Override public void onError(Throwable e) { -// Log.d(LOG_TAG,e.getMessage()); getMvpView().showProgressbar(false); - getMvpView().showErrorSnackBar(); + getMvpView().showSnackBar(R.string.failed_to_fetch_announcement); } @Override - public void onNext(Announcements announcement) { - getMvpView().showAllAnouncement(announcement); - Log.d(LOG_TAG,announcement.getAnnouncement().get(1).getResource()); + public void onComplete() { + getMvpView().showProgressbar(false); } - }); + })); } - public void loadAnnouncementDetails(String id){ - mSubscriptions = mDataManager.getAnnouncementDetail(id) + public void loadAnnouncementDetails(String id) { + checkViewAttached(); + compositeDisposable.add(mDataManager.getAnnouncementDetail(id) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) - .subscribe(new Observer() { + .subscribeWith(new DisposableObserver() { + @Override - public void onCompleted() { - getMvpView().showWaitProgress(false); + public void onNext(DetailAnnouncement detailAnnouncement) { + getMvpView().showAnnouncementDetail(detailAnnouncement); } @Override public void onError(Throwable e) { - Log.d(LOG_TAG,e.getMessage()); + Log.d(LOG_TAG, e.getMessage()); getMvpView().showWaitProgress(false); - getMvpView().showErrorSnackBar(); + getMvpView().showSnackBar(R.string.failed_to_fetch_announcement); } @Override - public void onNext(DetailAnnouncement detailAnnouncement) { - getMvpView().showAnnouncementDetail(detailAnnouncement); - + public void onComplete() { + getMvpView().showWaitProgress(false); } - }); + })); + } + + + private Map getAnnouncementQueryOptions(int PageNumber) { + Map option = new HashMap<>(); + option.put("order", "reverse"); + option.put("page", String.valueOf(PageNumber)); + return option; } } \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/base/BaseActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/base/BaseActivity.java new file mode 100644 index 00000000..25dee456 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/base/BaseActivity.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.base; + +import org.apache.taverna.mobile.TavernaApplication; +import org.apache.taverna.mobile.injection.component.ActivityComponent; +import org.apache.taverna.mobile.injection.component.DaggerActivityComponent; +import org.apache.taverna.mobile.injection.module.ActivityModule; + +import android.support.v7.app.AppCompatActivity; + +/** + * @author lusifer + */ +public class BaseActivity extends AppCompatActivity { + + private ActivityComponent activityComponent; + + + public ActivityComponent getActivityComponent() { + if (activityComponent == null) { + activityComponent = DaggerActivityComponent.builder() + .activityModule(new ActivityModule(this)) + .applicationComponent(TavernaApplication.get(this).getComponent()) + .build(); + } + return activityComponent; + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsActivity.java new file mode 100644 index 00000000..2c7d757b --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsActivity.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.favouriteworkflow; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.ActivityUtils; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.ActionBar; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class FavouriteWorkflowsActivity extends BaseActivity { + + @BindView(R.id.toolbar) + Toolbar mToolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_favourite_workflows); + + ButterKnife.bind(this); + + setSupportActionBar(mToolbar); + ActionBar actionbar = getSupportActionBar(); + + if (actionbar != null) { + actionbar.setHomeButtonEnabled(true); + actionbar.setDisplayHomeAsUpEnabled(true); + actionbar.setTitle(R.string.title_nav_favourite_workflows); + } + + if (savedInstanceState == null) { + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), + new FavouriteWorkflowsFragment(), R.id.frame_container); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.dashboard_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsFragment.java new file mode 100644 index 00000000..8f0c4ab4 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsFragment.java @@ -0,0 +1,225 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.favouriteworkflow; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.adapter.FavouriteWorkflowsAdapter; +import org.apache.taverna.mobile.ui.adapter.RecyclerItemClickListner; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.favouriteworkflowdetail.FavouriteWorkflowDetailActivity; +import org.apache.taverna.mobile.utils.Constants; + +import android.app.SearchManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.Snackbar; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SearchView; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class FavouriteWorkflowsFragment extends Fragment + implements FavouriteWorkflowsMvpView, RecyclerItemClickListner.OnItemClickListener { + + public final String LOG_TAG = getClass().getSimpleName(); + + @Inject DataManager dataManager; + @Inject FavouriteWorkflowsPresenter mFavouriteWorkflowsPresenter; + FavouriteWorkflowsAdapter mFavouriteWorkflowsAdapter; + FavouriteWorkflowsAdapter mSearchFavouriteWorkflowAdapter; + + @BindView(R.id.rv_fav_workflows) + RecyclerView mRecyclerView; + + @BindView(R.id.progress_circular) + ProgressBar mProgressBar; + + @BindView(R.id.layout_empty_fav_workflow) + RelativeLayout tvNoWorkflowError; + + List mWorkflowList; + private SearchView searchView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mWorkflowList = new ArrayList<>(); + setHasOptionsMenu(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_favourite_workflow_list, + container, false); + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + ButterKnife.bind(this, rootView); + + mFavouriteWorkflowsPresenter.attachView(this); + + mFavouriteWorkflowsAdapter = new FavouriteWorkflowsAdapter(mWorkflowList, getContext()); + + final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); + + mRecyclerView.setLayoutManager(layoutManager); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); + mRecyclerView.hasFixedSize(); + + mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListner(getActivity(), this)); + + mRecyclerView.setAdapter(mFavouriteWorkflowsAdapter); + + + mFavouriteWorkflowsPresenter.loadAllWorkflow(); + + return rootView; + } + + + @Override + public void showProgressbar(boolean b) { + if (b) { + + mProgressBar.setVisibility(View.VISIBLE); + } else { + + mProgressBar.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + } + } + + @Override + public void showErrorSnackBar() { + final Snackbar snackbar = Snackbar.make(mRecyclerView, + "Error occurred.Please try after some time", Snackbar + .LENGTH_INDEFINITE); + snackbar.setAction("OK", new View.OnClickListener() { + @Override + public void onClick(View view) { + snackbar.dismiss(); + } + }); + + snackbar.show(); + } + + @Override + public void showWorkflows(List workflowList) { + + mWorkflowList.addAll(workflowList); + mFavouriteWorkflowsAdapter.notifyDataSetChanged(); + } + + @Override + public void showEmptyWorkflow() { + tvNoWorkflowError.setVisibility(View.VISIBLE); + } + + @Override + public void onItemClick(View childView, int position) { + + if (searchView.isIconified() && TextUtils.isEmpty(searchView.getQuery())) { + if (mFavouriteWorkflowsAdapter.getItem(position) != null && position != -1) { + Intent intent = new Intent(getActivity(), FavouriteWorkflowDetailActivity.class); + intent.putExtra(Constants.WORKFLOW_ID, mFavouriteWorkflowsAdapter + .getItem(position).getId()); + intent.putExtra(Constants.WORKFLOW_TITLE, mFavouriteWorkflowsAdapter + .getItem(position).getTitle()); + startActivity(intent); + } + } else { + if (mSearchFavouriteWorkflowAdapter.getItem(position) != null && position != -1) { + Intent intent = new Intent(getActivity(), FavouriteWorkflowDetailActivity.class); + intent.putExtra(Constants.WORKFLOW_ID, mSearchFavouriteWorkflowAdapter + .getItem(position).getId()); + intent.putExtra(Constants.WORKFLOW_TITLE, mSearchFavouriteWorkflowAdapter + .getItem(position).getTitle()); + startActivity(intent); + } + } + } + + @Override + public void onItemLongPress(View childView, int position) { + + } + + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context + .SEARCH_SERVICE); + searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); + + searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity() + .getComponentName())); + searchView.setSubmitButtonEnabled(false); + mFavouriteWorkflowsPresenter.attachSearchHandler(searchView); + } + + @Override + public void performSearch(String search) { + mSearchFavouriteWorkflowAdapter = new FavouriteWorkflowsAdapter(new ArrayList(), + getContext()); + FavouriteWorkflowsAdapter wk = mFavouriteWorkflowsAdapter; + if (!TextUtils.isEmpty(search)) { + if (null != wk) + for (int i = 0; i < wk.getItemCount(); i++) { + Workflow workflow = wk.getItem(i); + if (workflow.getTitle().toLowerCase().contains(search.toLowerCase())) { + mSearchFavouriteWorkflowAdapter.addWorkflow(workflow); + } + } + + mRecyclerView.swapAdapter(mSearchFavouriteWorkflowAdapter, true); + if (mSearchFavouriteWorkflowAdapter.getItemCount() == 0) + + Toast.makeText(getActivity(), getString(R.string.msg_no_workflow_found), Toast + .LENGTH_SHORT).show(); + } else { + mRecyclerView.swapAdapter(mFavouriteWorkflowsAdapter, true); + } + } + + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsMvpView.java new file mode 100644 index 00000000..295b2d10 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsMvpView.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.favouriteworkflow; + + +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.base.MvpView; + +import java.util.List; + +public interface FavouriteWorkflowsMvpView extends MvpView { + + void showProgressbar(boolean b); + + void showErrorSnackBar(); + + void showWorkflows(List workflowList); + + void showEmptyWorkflow(); + + void performSearch(String search); + + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsPresenter.java new file mode 100644 index 00000000..093545e4 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflow/FavouriteWorkflowsPresenter.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.favouriteworkflow; + +import android.support.v7.widget.SearchView; + +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.base.BasePresenter; +import org.apache.taverna.mobile.utils.RxSearch; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.inject.Inject; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; + +public class FavouriteWorkflowsPresenter extends BasePresenter { + + public final String LOG_TAG = getClass().getSimpleName(); + + private DataManager mDataManager; + private CompositeDisposable compositeDisposable; + + @Inject + public FavouriteWorkflowsPresenter(DataManager dataManager) { + mDataManager = dataManager; + compositeDisposable = new CompositeDisposable(); + } + + @Override + public void attachView(FavouriteWorkflowsMvpView mvpView) { + super.attachView(mvpView); + } + + @Override + public void detachView() { + super.detachView(); + compositeDisposable.clear(); + } + + public void loadAllWorkflow() { + checkViewAttached(); + getMvpView().showProgressbar(true); + compositeDisposable.add(mDataManager.getFavoriteWorkflowList() + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver>() { + + @Override + public void onComplete() { + getMvpView().showProgressbar(false); + } + + @Override + public void onError(Throwable e) { + getMvpView().showProgressbar(false); + getMvpView().showErrorSnackBar(); + } + + @Override + public void onNext(List workflowList) { + if (workflowList.size() != 0) { + getMvpView().showWorkflows(workflowList); + } else { + getMvpView().showEmptyWorkflow(); + } + } + })); + } + + public void attachSearchHandler(SearchView searchView) { + checkViewAttached(); + RxSearch.fromSearchView(searchView) + .debounce(300, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(String searchQuery) { + getMvpView().performSearch(searchQuery); + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailActivity.java new file mode 100644 index 00000000..ed24d18d --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailActivity.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.favouriteworkflowdetail; + + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.Constants; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.ActionBar; +import android.support.v7.widget.Toolbar; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class FavouriteWorkflowDetailActivity extends BaseActivity { + + @BindView(R.id.toolbar) + Toolbar mToolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_detail_workflow); + + ButterKnife.bind(this); + + setSupportActionBar(mToolbar); + + ActionBar actionbar = getSupportActionBar(); + + if (actionbar != null) { + actionbar.setHomeButtonEnabled(true); + actionbar.setDisplayHomeAsUpEnabled(true); + actionbar.setTitle(getIntent().getStringExtra(Constants.WORKFLOW_TITLE)); + } + + + if (savedInstanceState == null) { + getSupportFragmentManager().beginTransaction() + .add(R.id.frame_container + , FavouriteWorkflowDetailFragment + .newInstance(getIntent() + .getStringExtra(Constants.WORKFLOW_ID))) + .commit(); + } + + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailFragment.java new file mode 100644 index 00000000..2da966ce --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailFragment.java @@ -0,0 +1,359 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.favouriteworkflowdetail; + + +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.v4.app.Fragment; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AlertDialog; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebView; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.License; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.imagezoom.ImageZoomActivity; +import org.apache.taverna.mobile.ui.imagezoom.ImageZoomFragment; +import org.apache.taverna.mobile.ui.workflowrun.WorkflowRunActivity; +import org.apache.taverna.mobile.utils.ConnectionInfo; +import org.apache.taverna.mobile.utils.Constants; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +public class FavouriteWorkflowDetailFragment extends Fragment + implements FavouriteWorkflowDetailMvpView { + + private static final String ID = "id"; + + public final String LOG_TAG = getClass().getSimpleName(); + + @Inject DataManager dataManager; + @Inject FavouriteWorkflowDetailPresenter mWorkflowDetailPresenter; + + @BindView(R.id.ivWorkflowImage) + ImageView workflowImage; + + @BindView(R.id.tvTitle) + TextView title; + + @BindView(R.id.ivUploader) + ImageView uploaderImage; + + @BindView(R.id.tvUploaderName) + TextView uploaderName; + + @BindView(R.id.tvDate) + TextView date; + + @BindView(R.id.tvType) + TextView type; + + @BindView(R.id.tvDescription) + WebView description; + + @BindView(R.id.ivFav) + ImageView ivFavourite; + + @BindView(R.id.progressBar) + ProgressBar mProgressBar; + + @BindView(R.id.scrollView) + ScrollView mScrollView; + + @BindView(R.id.rootLayout) + RelativeLayout rootLayout; + + @BindView(R.id.fabRun) + FloatingActionButton fabRun; + + private AlertDialog alertDialog; + + private String id; + + private String licenceId = null; + + private ProgressDialog dialog; + + private ActionBar actionBar; + + private Workflow mWorkflow; + + public static FavouriteWorkflowDetailFragment newInstance(String id) { + + Bundle args = new Bundle(); + + args.putString(ID, id); + + FavouriteWorkflowDetailFragment fragment = new FavouriteWorkflowDetailFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + id = getArguments().getString(ID); + + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_detail_workflow, container, false); + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + ButterKnife.bind(this, rootView); + + mWorkflowDetailPresenter.attachView(this); + + return rootView; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (ConnectionInfo.isConnectingToInternet(getContext())) { + + mWorkflowDetailPresenter.loadWorkflowDetail(id); + } else { + + mProgressBar.setVisibility(View.GONE); + showErrorSnackBar(getString(R.string.no_internet_connection)); + } + + setHasOptionsMenu(true); + + + } + + @OnClick(R.id.ivFav) + void favClick(View v) { + mWorkflowDetailPresenter.setFavourite(id); + } + + + @OnClick(R.id.fabRun) + void fabClickRunWorkflow(View v) { + Intent intent = new Intent(getActivity(), WorkflowRunActivity.class); + intent.putExtra(Constants.WORKFLOW_URL, mWorkflow.getContentUri()); + startActivity(intent); + } + + @OnClick(R.id.ivWorkflowImage) + void zoomImage(View v) { + + Intent intent = new Intent(getActivity(), ImageZoomActivity.class); + + intent.putExtra(ImageZoomFragment.JPG_URI, mWorkflow.getPreviewUri()); + intent.putExtra(ImageZoomFragment.SVG_URI, mWorkflow.getSvgUri()); + + startActivity(intent); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.menu_workflow_detail, menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.licence: + + if (licenceId == null) { + + showErrorSnackBar("Please wait"); + } else if (licenceId.isEmpty()) { + + showErrorSnackBar("No Licence Found"); + } else { + + mWorkflowDetailPresenter.loadLicenseDetail(licenceId); + } + + return true; + } + + return super.onOptionsItemSelected(item); + + } + + @Override + public void showProgressbar(boolean b) { + if (b) { + mProgressBar.setVisibility(View.VISIBLE); + } else { + mProgressBar.setVisibility(View.GONE); + mScrollView.setVisibility(View.VISIBLE); + } + } + + @Override + public void showWorkflowDetail(Workflow workflow) { + + this.mWorkflow = workflow; + + uploaderName.setText(workflow.getUploader().getContent()); + date.setText(workflow.getUpdatedAt() + .substring(0, workflow.getUpdatedAt().indexOf(' '))); + type.setText(workflow.getType().getContent()); + title.setText(workflow.getTitle()); + description.loadData(workflow.getDescription(), "text/html", "utf-8"); + + Glide.with(getContext()) + .load(workflow.getPreviewUri()) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .placeholder(R.drawable.placeholder) + .error(R.drawable.placeholder) + .into(workflowImage); + + if (workflow.getLicenseType().getId() == null) { + licenceId = ""; + } else { + licenceId = workflow.getLicenseType().getId(); + } + + if (mWorkflow.getType().getContent().equals(getString(R.string.t2_workflow_type))) { + fabRun.setVisibility(View.VISIBLE); + } else { + fabRun.setVisibility(View.GONE); + } + + } + + @Override + public void setImage(User user) { + + Glide.with(getContext()) + .load(user.getAvatar().getResource()) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .placeholder(R.drawable.placeholder) + .error(R.drawable.placeholder) + .into(uploaderImage); + + } + + @Override + public void showErrorSnackBar(String error) { + + final Snackbar snackbar = Snackbar.make(rootLayout, error, Snackbar + .LENGTH_INDEFINITE); + snackbar.setAction("OK", new View.OnClickListener() { + @Override + public void onClick(View view) { + snackbar.dismiss(); + } + }); + + snackbar.show(); + + } + + @Override + public void showLicense(License license) { + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext()); + + LayoutInflater inflater = getActivity().getLayoutInflater(); + + View dialogView = inflater.inflate(R.layout.dialog_licence_detail_workflow, null); + + dialogBuilder.setView(dialogView); + + TextView title = dialogView.findViewById(R.id.tvDialogTitle); + TextView date = dialogView.findViewById(R.id.tvDialogDate); + WebView text = dialogView.findViewById(R.id.wvDialogText); + Button buttonOk = dialogView.findViewById(R.id.bDialogOK); + + buttonOk.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + alertDialog.dismiss(); + } + }); + + text.loadDataWithBaseURL("", license.getDescription(), "text/html", "utf-8", ""); + date.setText(license.getCreatedAt().substring(0, license.getCreatedAt().indexOf(' '))); + title.setText(license.getTitle()); + + alertDialog = dialogBuilder.create(); + + alertDialog.show(); + } + + @Override + public void showLicenseProgress(boolean b) { + if (b) { + dialog = ProgressDialog.show(getContext(), "Loading", "Please wait...", true, true); + } else { + dialog.dismiss(); + } + } + + @Override + public void setFavouriteIcon() { + mWorkflowDetailPresenter.getFavourite(id); + } + + @Override + public void getFavouriteIcon(boolean b) { + if (b) { + ivFavourite.setImageResource(R.drawable.ic_star_black_24dp); + } else { + ivFavourite.setImageResource(R.drawable.ic_star_border_black_24dp); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + + mWorkflowDetailPresenter.detachView(); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailMvpView.java new file mode 100644 index 00000000..a3ec3b5c --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailMvpView.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.favouriteworkflowdetail; + + +import org.apache.taverna.mobile.data.model.License; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.base.MvpView; + +public interface FavouriteWorkflowDetailMvpView extends MvpView { + + void showProgressbar(boolean b); + + void showWorkflowDetail(Workflow workflow); + + void setImage(User user); + + void showErrorSnackBar(String error); + + void showLicense(License license); + + void showLicenseProgress(boolean b); + + void setFavouriteIcon(); + + void getFavouriteIcon(boolean b); +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailPresenter.java new file mode 100644 index 00000000..d02d058f --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/favouriteworkflowdetail/FavouriteWorkflowDetailPresenter.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.favouriteworkflowdetail; + +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.License; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.base.BasePresenter; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; +import io.reactivex.disposables.CompositeDisposable; + +public class FavouriteWorkflowDetailPresenter extends + BasePresenter { + + public final String LOG_TAG = getClass().getSimpleName(); + + private DataManager mDataManager; + private CompositeDisposable compositeDisposable; + + @Inject + public FavouriteWorkflowDetailPresenter(DataManager dataManager) { + mDataManager = dataManager; + compositeDisposable = new CompositeDisposable(); + } + + @Override + public void attachView(FavouriteWorkflowDetailMvpView mvpView) { + super.attachView(mvpView); + } + + @Override + public void detachView() { + super.detachView(); + compositeDisposable.clear(); + } + + public void loadWorkflowDetail(String id) { + checkViewAttached(); + getMvpView().showProgressbar(true); + compositeDisposable.add(mDataManager.getFavoriteDetailWorkflow(id) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Workflow workflow) { + getMvpView().showWorkflowDetail(workflow); + loadUserDetail(workflow.getUploader().getId()); + getFavourite(workflow.getId()); + } + + @Override + public void onError(Throwable e) { + getMvpView().showProgressbar(false); + } + + @Override + public void onComplete() { + getMvpView().showProgressbar(false); + } + })); + } + + private void loadUserDetail(String id) { + checkViewAttached(); + getMvpView().showProgressbar(true); + compositeDisposable.add(mDataManager.getUserDetail(id, getUserQueryOptions()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(User user) { + getMvpView().setImage(user); + } + + @Override + public void onError(Throwable e) { + getMvpView().showProgressbar(false); + getMvpView().showErrorSnackBar("Something went wrong please try after " + + "sometime"); + } + + @Override + public void onComplete() { + getMvpView().showProgressbar(false); + } + })); + } + + public void loadLicenseDetail(String id) { + checkViewAttached(); + getMvpView().showLicenseProgress(true); + compositeDisposable.add(mDataManager.getLicenseDetail(id, getLicenceQueryOptions()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(License license) { + getMvpView().showLicense(license); + } + + @Override + public void onError(Throwable e) { + getMvpView().showLicenseProgress(false); + getMvpView().showErrorSnackBar("Something went wrong please try after " + + "sometime"); + } + + @Override + public void onComplete() { + getMvpView().showLicenseProgress(false); + } + })); + } + + public void setFavourite(String id) { + checkViewAttached(); + compositeDisposable.add(mDataManager.setFavoriteWorkflow(id) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Boolean favoriteStatus) { + if (favoriteStatus) { + getMvpView().setFavouriteIcon(); + } else { + getMvpView().showErrorSnackBar("Something went wrong please try after" + + "sometime"); + } + } + + @Override + public void onError(Throwable e) { + getMvpView().showErrorSnackBar("Something went wrong please try after " + + "sometime"); + } + + @Override + public void onComplete() { + + } + })); + } + + public void getFavourite(String id) { + checkViewAttached(); + compositeDisposable.add(mDataManager.getFavoriteWorkflow(id) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Boolean b) { + getMvpView().getFavouriteIcon(b); + } + + @Override + public void onError(Throwable e) { + getMvpView().showErrorSnackBar("Something went wrong please try after " + + "sometime"); + } + + @Override + public void onComplete() { + + } + })); + } + + private Map getUserQueryOptions() { + Map option = new HashMap<>(); + option.put("elements", "avatar"); + return option; + } + + private Map getLicenceQueryOptions() { + Map option = new HashMap<>(); + option.put("elements", "title,description,url,created-at"); + return option; + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomActivity.java new file mode 100644 index 00000000..1bb25dbf --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomActivity.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.imagezoom; + + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.ActivityUtils; + +import android.os.Bundle; +import android.support.annotation.Nullable; + +import butterknife.ButterKnife; + +public class ImageZoomActivity extends BaseActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_image_zoom); + + ButterKnife.bind(this); + + + if (savedInstanceState == null) { + + ActivityUtils.addFragmentToActivity( + getSupportFragmentManager(), + ImageZoomFragment.newInstance( + getIntent().getStringExtra(ImageZoomFragment.JPG_URI), + getIntent().getStringExtra(ImageZoomFragment.SVG_URI)), + R.id.frame_container); + + } + + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomFragment.java new file mode 100644 index 00000000..fcb2b411 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomFragment.java @@ -0,0 +1,226 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.imagezoom; + + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.Nullable; +import android.support.design.widget.Snackbar; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.resource.drawable.GlideDrawable; +import com.bumptech.glide.request.Request; +import com.bumptech.glide.request.animation.GlideAnimation; +import com.bumptech.glide.request.target.SizeReadyCallback; +import com.bumptech.glide.request.target.Target; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.ConnectionInfo; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import uk.co.senab.photoview.PhotoViewAttacher; + +public class ImageZoomFragment extends Fragment implements ImageZoomMvpView { + + public static final String JPG_URI = "jpgURI"; + + public static final String SVG_URI = "svgURI"; + + private static final String SERVER_ERROR = "Sever Error. Please try after sometime"; + + @Inject ImageZoomPresenter mImageZoomPresenter; + + @BindView(R.id.ivWorkflowImage) + ImageView workflowImage; + + @BindView(R.id.ivClose) + ImageView close; + + PhotoViewAttacher mAttacher; + + private String svgURI; + + private String jpgURI; + + public static ImageZoomFragment newInstance(String jpgURI, String svgURI) { + Bundle args = new Bundle(); + args.putString(JPG_URI, jpgURI); + args.putString(SVG_URI, svgURI); + ImageZoomFragment fragment = new ImageZoomFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + svgURI = getArguments().getString(SVG_URI); + jpgURI = getArguments().getString(JPG_URI); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_image_zoom, container, false); + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + ButterKnife.bind(this, rootView); + + mImageZoomPresenter.attachView(this); + + return rootView; + } + + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (ConnectionInfo.isConnectingToInternet(getContext())) { + mImageZoomPresenter.loadImage(svgURI, workflowImage); + } else { + showErrorSnackBar(getString(R.string.no_internet_connection)); + } + } + + @OnClick(R.id.ivClose) + public void closeActivity(View v) { + getActivity().finish(); + } + + + @Override + public void showErrorSnackBar(String error) { + + final Snackbar snackbar = Snackbar.make(workflowImage, error, Snackbar.LENGTH_INDEFINITE); + snackbar.setAction("OK", new View.OnClickListener() { + @Override + public void onClick(View view) { + snackbar.dismiss(); + getActivity().finish(); + } + }); + snackbar.show(); + + Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + public void run() { + snackbar.dismiss(); + getActivity().finish(); + } + }, 2000); + } + + @Override + public Context getAppContext() { + return getContext(); + } + + + @Override + public void setJPGImage() { + + + Glide.with(getContext()) + .load(jpgURI) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .placeholder(R.drawable.placeholder) + .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) + .into(new Target() { + @Override + public void onLoadStarted(Drawable placeholder) { + workflowImage.setImageDrawable(placeholder); + } + + @Override + public void onLoadFailed(Exception e, Drawable errorDrawable) { + showErrorSnackBar(SERVER_ERROR); + } + + @Override + public void onResourceReady(GlideDrawable resource, + GlideAnimation + glideAnimation) { + workflowImage.setImageDrawable(resource.getCurrent()); + addImageAttacher(); + + } + + @Override + public void onLoadCleared(Drawable placeholder) { + workflowImage.setImageDrawable(placeholder); + } + + @Override + public void getSize(SizeReadyCallback cb) { + + } + + @Override + public Request getRequest() { + return null; + } + + @Override + public void setRequest(Request request) { + + } + + @Override + public void onStart() { + + } + + @Override + public void onStop() { + + } + + @Override + public void onDestroy() { + + } + }); + + } + + @Override + public void addImageAttacher() { + mAttacher = new PhotoViewAttacher(workflowImage); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mImageZoomPresenter.detachView(); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomMvpView.java new file mode 100644 index 00000000..a4b6d36e --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomMvpView.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.imagezoom; + + +import android.content.Context; + +import org.apache.taverna.mobile.ui.base.MvpView; + +public interface ImageZoomMvpView extends MvpView { + + void showErrorSnackBar(String error); + + Context getAppContext(); + + void setJPGImage(); + + void addImageAttacher(); +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomPresenter.java new file mode 100644 index 00000000..426405a5 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/imagezoom/ImageZoomPresenter.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.imagezoom; + + +import android.graphics.drawable.Drawable; +import android.graphics.drawable.PictureDrawable; +import android.net.Uri; +import android.os.Build; +import android.widget.ImageView; + +import com.bumptech.glide.GenericRequestBuilder; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.model.StreamEncoder; +import com.bumptech.glide.load.resource.file.FileToStreamDecoder; +import com.bumptech.glide.request.Request; +import com.bumptech.glide.request.animation.GlideAnimation; +import com.bumptech.glide.request.target.SizeReadyCallback; +import com.bumptech.glide.request.target.Target; +import com.caverock.androidsvg.SVG; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.base.BasePresenter; +import org.apache.taverna.mobile.utils.SvgDecoder; +import org.apache.taverna.mobile.utils.SvgDrawableTranscoder; + +import java.io.InputStream; + +import javax.inject.Inject; + +public class ImageZoomPresenter extends BasePresenter { + + private GenericRequestBuilder requestBuilder; + + @Inject + public ImageZoomPresenter() { + + } + + @Override + public void attachView(ImageZoomMvpView mvpView) { + + super.attachView(mvpView); + + requestBuilder = Glide.with(getMvpView().getAppContext()) + .using(Glide.buildStreamModelLoader(Uri.class, + getMvpView().getAppContext()), InputStream.class) + .from(Uri.class) + .as(SVG.class) + .transcode(new SvgDrawableTranscoder(), PictureDrawable.class) + .sourceEncoder(new StreamEncoder()) + .cacheDecoder(new FileToStreamDecoder(new SvgDecoder())) + .decoder(new SvgDecoder()) + .placeholder(R.drawable.placeholder) + .error(R.drawable.placeholder) + .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) + .animate(android.R.anim.fade_in); + + } + + @Override + public void detachView() { + super.detachView(); + + } + + public void loadImage(String svgURI, final ImageView imageView) { + + setSVG(svgURI, imageView); + } + + private void setSVG(String imageURI, final ImageView imageView) { + + requestBuilder + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .load(Uri.parse(imageURI)) + .into(new Target() { + @Override + public void onLoadStarted(Drawable placeholder) { + imageView.setImageDrawable(placeholder); + } + + @Override + public void onLoadFailed(Exception e, Drawable errorDrawable) { + imageView.setImageDrawable(errorDrawable); + + if (Build.VERSION_CODES.HONEYCOMB <= Build.VERSION.SDK_INT) { + imageView.setLayerType(ImageView.LAYER_TYPE_NONE, null); + } + + getMvpView().setJPGImage(); + } + + @Override + public void onResourceReady(PictureDrawable resource, + GlideAnimation + glideAnimation) { + if (Build.VERSION_CODES.HONEYCOMB <= Build.VERSION.SDK_INT) { + imageView.setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null); + } + imageView.setImageDrawable(resource); + getMvpView().addImageAttacher(); + } + + @Override + public void onLoadCleared(Drawable placeholder) { + + } + + @Override + public void getSize(SizeReadyCallback cb) { + + } + + @Override + public Request getRequest() { + return null; + } + + @Override + public void setRequest(Request request) { + + } + + @Override + public void onStart() { + + } + + @Override + public void onStop() { + + } + + @Override + public void onDestroy() { + + } + }); + + } + + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginActivity.java new file mode 100644 index 00000000..d928befe --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginActivity.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.login; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.ActivityUtils; + +import android.os.Bundle; + + +public class LoginActivity extends BaseActivity { + private static final String TAG = "LoginActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + + if (savedInstanceState == null) { + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), + LoginFragment.newInstance(), R.id.container); + } + } + + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginFragment.java new file mode 100644 index 00000000..3f544c5a --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginFragment.java @@ -0,0 +1,280 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.login; + + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.ui.DashboardActivity; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.ConnectionInfo; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; +import android.support.design.widget.Snackbar; +import android.support.design.widget.TextInputLayout; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.CheckBox; +import android.widget.EditText; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +public class LoginFragment extends Fragment implements LoginMvpView, View.OnFocusChangeListener { + + @Inject DataManager dataManager; + @Inject LoginPresenter mLoginPresenter; + + @BindView(R.id.etEmail) + EditText mEditTextEmail; + + @BindView(R.id.etPassword) + EditText mEditTextPassword; + + @BindView(R.id.input_layout_email) + TextInputLayout mTextInputEmail; + + @BindView(R.id.input_layout_password) + TextInputLayout mTextInputPassword; + + @BindView(R.id.cbRemember) + CheckBox mCheckBoxRemember; + + private ProgressDialog progressDialog; + + private final String myExperimentURL = "https://www.myexperiment.org/users/new"; + + public static LoginFragment newInstance() { + + LoginFragment fragment = new LoginFragment(); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_login, container, false); + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + ButterKnife.bind(this, rootView); + mLoginPresenter.attachView(this); + return rootView; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + + mEditTextEmail.addTextChangedListener(new CustomTextWatcher(mEditTextEmail)); + + + mEditTextPassword.addTextChangedListener(new CustomTextWatcher(mEditTextPassword)); + + mEditTextEmail.setOnFocusChangeListener(this); + + mEditTextPassword.setOnFocusChangeListener(this); + + progressDialog = new ProgressDialog(getContext()); + + progressDialog.setMessage("Please wait"); + + } + + + private void validateEmail() { + + if (mEditTextEmail.getText().toString().trim().length() == 0) { + + mTextInputEmail.setError(getString(R.string.err_login_email)); + } else { + + mTextInputEmail.setError(null); + } + + + } + + + private void validatePassword() { + if (mEditTextPassword.getText().toString().trim().length() == 0) { + + mTextInputPassword.setError(getString(R.string.err_login_password)); + } else { + + mTextInputPassword.setError(null); + } + + + } + + @OnClick(R.id.bLogin) + public void login(View v) { + if (ConnectionInfo.isConnectingToInternet(getContext())) { + if (mEditTextEmail.getText().toString().trim().length() > 0 && mEditTextPassword + .getText().toString().trim().length() > 0) { + + mLoginPresenter.login(mEditTextEmail.getText().toString().trim(), + mEditTextPassword.getText().toString().trim(), mCheckBoxRemember + .isChecked()); + + } else { + + showError("Please enter valid credential"); + } + } else { + + showError("NO Internet Connection"); + } + } + + @OnClick(R.id.bRegister) + public void register(View v) { + if (Build.VERSION.SDK_INT < 15) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setData(Uri.parse(myExperimentURL)); + startActivity(intent); + } else { + CustomTabsIntent.Builder customTabsIntentBuilder = new CustomTabsIntent.Builder(); + CustomTabsIntent customTabsIntent = customTabsIntentBuilder.build(); + customTabsIntent.launchUrl(getActivity(), Uri.parse(myExperimentURL)); + } + } + + @Override + public void showError(String string) { + final Snackbar snackbar = Snackbar.make(mEditTextPassword, string, Snackbar + .LENGTH_INDEFINITE); + snackbar.setAction("OK", new View.OnClickListener() { + @Override + public void onClick(View view) { + snackbar.dismiss(); + } + }); + + snackbar.show(); + } + + @Override + public void showProgressDialog(boolean flag) { + if (flag) { + progressDialog.show(); + } else { + progressDialog.cancel(); + } + } + + @Override + public void showDashboardActivity() { + Intent intent = new Intent(getActivity(), DashboardActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); + getActivity().finish(); + } + + @Override + public void showCredentialError() { + showError("Please enter valid credential"); + + mTextInputEmail.setError(getString(R.string.err_login_email)); + mTextInputPassword.setError(getString(R.string.err_login_password)); + requestFocus(mEditTextEmail); + } + + + private void requestFocus(View view) { + if (view.requestFocus()) { + getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams + .SOFT_INPUT_STATE_ALWAYS_VISIBLE); + } + } + + @Override + public void onFocusChange(View v, boolean hasFocus) { + switch (v.getId()) { + case R.id.etEmail: + if (!v.hasFocus()) { + validateEmail(); + } + break; + case R.id.etPassword: + if (!v.hasFocus()) { + validatePassword(); + } + break; + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + + mLoginPresenter.detachView(); + } + + private class CustomTextWatcher implements TextWatcher { + + private View view; + + private CustomTextWatcher(View view) { + this.view = view; + } + + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + public void afterTextChanged(Editable editable) { + switch (view.getId()) { + case R.id.etEmail: + validateEmail(); + break; + case R.id.etPassword: + validatePassword(); + break; + } + } + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginMvpView.java new file mode 100644 index 00000000..341520a0 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginMvpView.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.login; + + +import org.apache.taverna.mobile.ui.base.MvpView; + +public interface LoginMvpView extends MvpView { + + void showDashboardActivity(); + + void showCredentialError(); + + void showError(String string); + + void showProgressDialog(boolean flag); +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginPresenter.java new file mode 100644 index 00000000..e3fd901d --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/login/LoginPresenter.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.login; + + +import android.util.Base64; + +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.ui.base.BasePresenter; + +import javax.inject.Inject; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; + +public class LoginPresenter extends BasePresenter { + + public final String LOG_TAG = getClass().getSimpleName(); + + private DataManager mDataManager; + private CompositeDisposable compositeDisposable; + + @Inject + public LoginPresenter(DataManager dataManager) { + mDataManager = dataManager; + compositeDisposable = new CompositeDisposable(); + } + + @Override + public void attachView(LoginMvpView mvpView) { + super.attachView(mvpView); + } + + @Override + public void detachView() { + super.detachView(); + compositeDisposable.clear(); + } + + public void login(String username, String password, boolean flagLogin) { + checkViewAttached(); + getMvpView().showProgressDialog(true); + compositeDisposable.add(mDataManager + .getLoginUserDetail(getEncodedCredential(username, password), flagLogin) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(User value) { + getMvpView().showDashboardActivity(); + getMvpView().showProgressDialog(false); + } + + @Override + public void onError(Throwable e) { + getMvpView().showCredentialError(); + getMvpView().showProgressDialog(false); + } + + @Override + public void onComplete() { + + } + })); + } + + private String getEncodedCredential(String username, String password) { + return "Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64 + .NO_WRAP); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowActivity.java new file mode 100644 index 00000000..9caaf060 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowActivity.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.myworkflows; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.ActivityUtils; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.ActionBar; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class MyWorkflowActivity extends BaseActivity { + + @BindView(R.id.toolbar) + Toolbar mToolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_my_workflows); + + ButterKnife.bind(this); + + setSupportActionBar(mToolbar); + ActionBar actionbar = getSupportActionBar(); + + if (actionbar != null) { + actionbar.setHomeButtonEnabled(true); + actionbar.setDisplayHomeAsUpEnabled(true); + actionbar.setTitle(R.string.title_nav_my_workflows); + } + + if (savedInstanceState == null) { + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), + new MyWorkflowFragment(), R.id.frame_container); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.dashboard_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowFragment.java new file mode 100644 index 00000000..bc689523 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowFragment.java @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.myworkflows; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.adapter.RecyclerItemClickListner; +import org.apache.taverna.mobile.ui.adapter.WorkflowAdapter; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.workflowdetail.WorkflowDetailActivity; +import org.apache.taverna.mobile.utils.ConnectionInfo; +import org.apache.taverna.mobile.utils.Constants; +import org.apache.taverna.mobile.utils.ScrollChildSwipeRefreshLayout; + +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.Snackbar; +import android.support.v4.app.Fragment; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class MyWorkflowFragment extends Fragment implements MyWorkflowMvpView, + RecyclerItemClickListner.OnItemClickListener { + + public final String LOG_TAG = getClass().getSimpleName(); + + @Inject DataManager dataManager; + @Inject MyWorkflowPresenter mWorkflowPresenter; + WorkflowAdapter mWorkflowAdapter; + + @BindView(R.id.rv_workflows) + RecyclerView mRecyclerView; + + @BindView(R.id.progress_circular) + ProgressBar mProgressBar; + + @BindView(R.id.swipe_refresh) + ScrollChildSwipeRefreshLayout mSwipeRefresh; + + @BindView(R.id.layout_empty_workflows) + RelativeLayout mTextViewNoWorkflow; + + private List mWorkflowList; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mWorkflowList = new ArrayList<>(); + + + setHasOptionsMenu(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_dashboard, container, false); + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + ButterKnife.bind(this, rootView); + + mWorkflowPresenter.attachView(this); + + final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); + + mRecyclerView.setLayoutManager(layoutManager); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); + mRecyclerView.hasFixedSize(); + + mWorkflowAdapter = new WorkflowAdapter(mWorkflowList, getContext()); + + mRecyclerView.setAdapter(mWorkflowAdapter); + mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListner(getActivity(), this)); + + mWorkflowPresenter.loadMyWorkflows(); + + mSwipeRefresh.setColorSchemeResources(R.color.colorAccent, R.color.colorAccent, R.color + .colorPrimary); + + mSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + if (ConnectionInfo.isConnectingToInternet(getContext())) { + + mWorkflowPresenter.loadMyWorkflows(); + + mSwipeRefresh.setRefreshing(true); + } else { + + showErrorSnackBar("NO Internet Connection"); + if (mSwipeRefresh.isRefreshing()) { + mSwipeRefresh.setRefreshing(false); + } + } + } + }); + + return rootView; + } + + @Override + public void showProgressbar(boolean b) { + + if (b) { + mProgressBar.setVisibility(View.VISIBLE); + } else { + mProgressBar.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + } + + } + + @Override + public void showErrorSnackBar(String error) { + + final Snackbar snackbar = Snackbar.make(mRecyclerView, error, Snackbar + .LENGTH_INDEFINITE); + snackbar.setAction("OK", new View.OnClickListener() { + @Override + public void onClick(View view) { + snackbar.dismiss(); + } + }); + + snackbar.show(); + } + + @Override + public void showWorkflow(Workflow workflow) { + + if (mSwipeRefresh.isRefreshing()) { + mSwipeRefresh.setRefreshing(false); + mWorkflowList.clear(); + } + + mWorkflowList.add(workflow); + mWorkflowAdapter.notifyDataSetChanged(); + } + + @Override + public void checkWorkflowSize() { + + if (mWorkflowList.size() == 0) { + mTextViewNoWorkflow.setVisibility(View.VISIBLE); + } else { + mTextViewNoWorkflow.setVisibility(View.GONE); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mWorkflowPresenter.detachView(); + } + + @Override + public void onItemClick(View childView, int position) { + Intent intent = new Intent(getActivity(), WorkflowDetailActivity.class); + intent.putExtra(Constants.WORKFLOW_ID, mWorkflowList.get(position).getId()); + intent.putExtra(Constants.WORKFLOW_TITLE, mWorkflowList.get(position).getTitle()); + startActivity(intent); + } + + @Override + public void onItemLongPress(View childView, int position) { + + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + MenuItem item = menu.findItem(R.id.action_search); + item.setVisible(false); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowMvpView.java new file mode 100644 index 00000000..3f5cb985 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowMvpView.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.myworkflows; + +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.base.MvpView; + +public interface MyWorkflowMvpView extends MvpView { + + void showProgressbar(boolean b); + + void showErrorSnackBar(String error); + + void showWorkflow(Workflow workflow); + + + void checkWorkflowSize(); +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowPresenter.java new file mode 100644 index 00000000..01075015 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/myworkflows/MyWorkflowPresenter.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.myworkflows; + +import android.util.Log; + +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.base.BasePresenter; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.functions.Function; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; + +public class MyWorkflowPresenter extends BasePresenter { + + public final String LOG_TAG = getClass().getSimpleName(); + + private DataManager mDataManager; + private CompositeDisposable compositeDisposable; + + @Inject + public MyWorkflowPresenter(DataManager dataManager) { + mDataManager = dataManager; + compositeDisposable = new CompositeDisposable(); + } + + @Override + public void attachView(MyWorkflowMvpView mvpView) { + super.attachView(mvpView); + } + + @Override + public void detachView() { + super.detachView(); + compositeDisposable.clear(); + } + + public void loadMyWorkflows() { + checkViewAttached(); + getMvpView().showProgressbar(true); + compositeDisposable.clear(); + compositeDisposable.add(mDataManager.getMyWorkflows(mDataManager.getPreferencesHelper() + .getUserID(), getQueryOptions()) + .flatMap(new Function>() { + @Override + public ObservableSource apply(User user) throws Exception { + if (user.getWorkflows().getWorkflowList() != null && user.getWorkflows() + .getWorkflowList().size() != 0) { + return Observable.fromIterable(user.getWorkflows().getWorkflowList()) + .concatMap(new Function>() { + @Override + public ObservableSource apply(Workflow workflow) + throws Exception { + return mDataManager.getDetailWorkflow(workflow.getId(), + getWorkflowQueryOptions()); + } + }); + } else { + return Observable.empty(); + } + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Workflow workflow) { + getMvpView().showWorkflow(workflow); + } + + @Override + public void onError(Throwable e) { + getMvpView().showErrorSnackBar("Server Error! Try after sometime"); + Log.e(LOG_TAG, "onError: ", e); + } + + @Override + public void onComplete() { + getMvpView().showProgressbar(false); + getMvpView().checkWorkflowSize(); + } + })); + } + + private Map getQueryOptions() { + Map option = new HashMap<>(); + option.put("elements", "workflows"); + return option; + } + + private Map getWorkflowQueryOptions() { + Map option = new HashMap<>(); + option.put("elements", "title,type,uploader,preview,created-at"); + return option; + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/playerlogin/PlayerLoginFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/playerlogin/PlayerLoginFragment.java new file mode 100644 index 00000000..9ea3eda9 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/playerlogin/PlayerLoginFragment.java @@ -0,0 +1,255 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.playerlogin; + + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.ConnectionInfo; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.design.widget.Snackbar; +import android.support.design.widget.TextInputLayout; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.CheckBox; +import android.widget.EditText; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + + +public class PlayerLoginFragment extends Fragment implements PlayerLoginMvpView, View + .OnFocusChangeListener { + + @Inject DataManager dataManager; + @Inject PlayerLoginPresenter mPlayerLoginPresenter; + + @BindView(R.id.etEmail) + EditText mEditTextEmail; + + @BindView(R.id.etPassword) + EditText mEditTextPassword; + + @BindView(R.id.input_layout_email) + TextInputLayout mTextInputEmail; + + @BindView(R.id.input_layout_password) + TextInputLayout mTextInputPassword; + + @BindView(R.id.cbRemember) + CheckBox mCheckBoxRemember; + OnSuccessful mCallback; + + public static PlayerLoginFragment newInstance() { + + Bundle args = new Bundle(); + PlayerLoginFragment fragment = new PlayerLoginFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_player_login_layout, container, false); + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + ButterKnife.bind(this, rootView); + mPlayerLoginPresenter.attachView(this); + String email = dataManager.getPreferencesHelper().getPlayerUserEmail(); + String pw = dataManager.getPreferencesHelper().getPlayerUserPassword(); + mEditTextEmail.setText(email); + mEditTextPassword.setText(pw); + return rootView; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mEditTextEmail.addTextChangedListener(new CustomTextWatcher(mEditTextEmail)); + mEditTextEmail.setOnFocusChangeListener(this); + + mEditTextPassword.addTextChangedListener(new CustomTextWatcher(mEditTextPassword)); + mEditTextPassword.setOnFocusChangeListener(this); + } + + + @Override + public void onDestroyView() { + super.onDestroyView(); + mPlayerLoginPresenter.detachView(); + } + + + @OnClick(R.id.bLogin) + public void login(View v) { + if (ConnectionInfo.isConnectingToInternet(getContext())) { + if (mEditTextEmail.getText().toString().trim().length() > 0 && mEditTextPassword + .getText().toString().trim().length() > 0) { + + mPlayerLoginPresenter.playerLogin(mEditTextEmail.getText().toString().trim(), + mEditTextPassword.getText().toString().trim(), mCheckBoxRemember + .isChecked()); + + } else { + + showError(R.string.error_vaild_credential); + } + } else { + + showError(R.string.no_internet_connection); + } + } + + @Override + public void showError(int stringID) { + final Snackbar snackbar = Snackbar.make(mEditTextPassword, getString(stringID), Snackbar + .LENGTH_LONG); + snackbar.setAction("OK", new View.OnClickListener() { + @Override + public void onClick(View view) { + snackbar.dismiss(); + } + }); + + snackbar.show(); + } + + @Override + public void showCredentialError() { + mTextInputEmail.setError(getString(R.string.err_login_email)); + mTextInputPassword.setError(getString(R.string.err_login_password)); + requestFocus(mEditTextPassword); + } + + @Override + public void validCredential() { + mCallback.onSuccessfulLogin(); + } + + + private void validateEmail() { + + if (mEditTextEmail.getText().toString().trim().length() > 0) { + mTextInputEmail.setError(getString(R.string.err_login_email)); + } else { + mTextInputEmail.setError(null); + } + + + } + + private void requestFocus(View view) { + if (view.requestFocus()) { + getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams + .SOFT_INPUT_STATE_ALWAYS_VISIBLE); + } + } + + private void validatePassword() { + if (mEditTextPassword.getText().toString().trim().length() > 0) { + mTextInputPassword.setError(getString(R.string.err_login_password)); + } else { + mTextInputPassword.setError(null); + } + + + } + + @Override + public void onFocusChange(View v, boolean hasFocus) { + switch (v.getId()) { + case R.id.etEmail: + if (!v.hasFocus()) { + validateEmail(); + } + break; + case R.id.etPassword: + if (!v.hasFocus()) { + validatePassword(); + } + break; + } + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + + try { + mCallback = (OnSuccessful) getActivity(); + } catch (ClassCastException e) { + throw new ClassCastException(getActivity().toString() + + " must implement OnSuccessful"); + } + } + + + public interface OnSuccessful { + void onSuccessfulLogin(); + } + + private class CustomTextWatcher implements TextWatcher { + + private View view; + + private CustomTextWatcher(View view) { + this.view = view; + } + + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + public void afterTextChanged(Editable editable) { + switch (view.getId()) { + case R.id.etEmail: + validateEmail(); + break; + case R.id.etPassword: + validatePassword(); + break; + } + } + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/playerlogin/PlayerLoginMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/playerlogin/PlayerLoginMvpView.java new file mode 100644 index 00000000..4b4d84d7 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/playerlogin/PlayerLoginMvpView.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.playerlogin; + +import org.apache.taverna.mobile.ui.base.MvpView; + + +public interface PlayerLoginMvpView extends MvpView { + + void showError(int stringID); + + void showCredentialError(); + + void validCredential(); +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/playerlogin/PlayerLoginPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/playerlogin/PlayerLoginPresenter.java new file mode 100644 index 00000000..b75a9d07 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/playerlogin/PlayerLoginPresenter.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.playerlogin; + +import android.util.Base64; +import android.util.Log; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.ui.base.BasePresenter; + +import javax.inject.Inject; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; +import okhttp3.ResponseBody; +import retrofit2.HttpException; + +public class PlayerLoginPresenter extends BasePresenter { + + private static final String TAG = PlayerLoginPresenter.class.getSimpleName(); + + private DataManager mDataManager; + private CompositeDisposable compositeDisposable; + + @Inject + public PlayerLoginPresenter(DataManager dataManager) { + mDataManager = dataManager; + compositeDisposable = new CompositeDisposable(); + } + + @Override + public void attachView(PlayerLoginMvpView mvpView) { + super.attachView(mvpView); + } + + @Override + public void detachView() { + super.detachView(); + compositeDisposable.clear(); + } + + public void playerLogin(final String username, final String password, final boolean loginFlag) { + compositeDisposable.clear(); + compositeDisposable.add(mDataManager + .authPlayerUserLoginDetail(getEncodedCredential(username, password), loginFlag) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(ResponseBody responseBody) { + Log.d(TAG, "onCompleted: " + responseBody.byteStream()); + } + + @Override + public void onError(Throwable e) { + Log.e(TAG, "onError: ", e); + if (e instanceof HttpException) { + if (((HttpException) e).code() == 401) { + getMvpView().showCredentialError(); + } else if (((HttpException) e).code() == 406) { + getMvpView().validCredential(); + mDataManager.getPreferencesHelper() + .setUserPlayerLoggedInFlagAndCredential(loginFlag, + getEncodedCredential(username, password)); + + } else { + getMvpView().showError(R.string.servererr); + } + } + } + + @Override + public void onComplete() { + + } + })); + } + + private String getEncodedCredential(String username, String password) { + return "Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64 + .NO_WRAP); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/tutorial/TutorialActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/tutorial/TutorialActivity.java new file mode 100644 index 00000000..9b7cc66c --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/tutorial/TutorialActivity.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.tutorial; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.local.PreferencesHelper; +import org.apache.taverna.mobile.data.model.TutorialSliderEnum; +import org.apache.taverna.mobile.ui.adapter.TutorialSliderAdapter; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.login.LoginActivity; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.view.ViewPager; +import android.text.Html; +import android.view.View; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +public class TutorialActivity extends BaseActivity implements ViewPager.OnPageChangeListener { + + @BindView(R.id.slide_pager) + ViewPager slidePager; + + @BindView(R.id.layoutDots) + LinearLayout dotsLayout; + + @BindView(R.id.btn_skip) + Button bSkip; + + @BindView(R.id.btn_next) + Button bNext; + + @Inject + PreferencesHelper preferencesHelper; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActivityComponent().inject(this); + + setContentView(R.layout.activity_tutorial); + + ButterKnife.bind(this); + + if (Build.VERSION.SDK_INT >= 21) { + getWindow().getDecorView() + .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + } + + addBottomDots(0); + + TutorialSliderAdapter tutorialSliderAdapter = new TutorialSliderAdapter(this); + slidePager.setAdapter(tutorialSliderAdapter); + slidePager.addOnPageChangeListener(this); + + } + + @OnClick(R.id.btn_skip) + public void skipClick(View v) { + launchLoginScreen(); + } + + @OnClick(R.id.btn_next) + public void nextClick(View v) { + int current = getItem(+1); + if (current < TutorialSliderEnum.values().length) { + slidePager.setCurrentItem(current); + } else { + launchLoginScreen(); + } + } + + public void addBottomDots(int currentPage) { + TextView[] dots = new TextView[TutorialSliderEnum.values().length]; + + int[] colorsActive = getResources().getIntArray(R.array.array_dot_active); + int[] colorsInactive = getResources().getIntArray(R.array.array_dot_inactive); + + dotsLayout.removeAllViews(); + for (int i = 0; i < dots.length; i++) { + dots[i] = new TextView(this); + dots[i].setText(Html.fromHtml("•")); + dots[i].setTextSize(35); + dots[i].setTextColor(colorsInactive[currentPage]); + dotsLayout.addView(dots[i]); + } + + if (dots.length > 0) + dots[currentPage].setTextColor(colorsActive[currentPage]); + } + + public int getItem(int i) { + return slidePager.getCurrentItem() + i; + } + + public void launchLoginScreen() { + preferencesHelper.setFirstTimeLaunch(false); + startActivity(new Intent(TutorialActivity.this, LoginActivity.class)); + finish(); + } + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + addBottomDots(position); + + if (position == TutorialSliderEnum.values().length - 1) { + bNext.setText(getString(R.string.start)); + bSkip.setVisibility(View.GONE); + } else { + bNext.setText(getString(R.string.next)); + bSkip.setVisibility(View.VISIBLE); + } + + } + + @Override + public void onPageScrollStateChanged(int state) { + + } +} + diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/usage/UsageActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/usage/UsageActivity.java new file mode 100644 index 00000000..b9ccbd09 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/usage/UsageActivity.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.usage; + +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.Toolbar; +import android.view.MenuItem; + +import org.apache.taverna.mobile.R; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class UsageActivity extends AppCompatActivity { + + @BindView(R.id.toolbar) + Toolbar mToolbar; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_usage); + ButterKnife.bind(this); + + setSupportActionBar(mToolbar); + ActionBar actionbar = getSupportActionBar(); + + if (actionbar != null) { + actionbar.setHomeButtonEnabled(true); + actionbar.setDisplayHomeAsUpEnabled(true); + actionbar.setTitle(R.string.title_usage); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/userprofile/UserProfileActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/userprofile/UserProfileActivity.java new file mode 100644 index 00000000..409ccd38 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/userprofile/UserProfileActivity.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.userprofile; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.ActivityUtils; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.ActionBar; +import android.support.v7.widget.Toolbar; +import android.view.MenuItem; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class UserProfileActivity extends BaseActivity { + + @BindView(R.id.toolbar) + Toolbar mToolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_user_profile); + + ButterKnife.bind(this); + + setSupportActionBar(mToolbar); + ActionBar actionbar = getSupportActionBar(); + + if (actionbar != null) { + actionbar.setHomeButtonEnabled(true); + actionbar.setDisplayHomeAsUpEnabled(true); + actionbar.setTitle(R.string.title_user_profile); + } + + if (savedInstanceState == null) { + ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), + new UserProfileFragment(), R.id.frame_container); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/userprofile/UserProfileFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/userprofile/UserProfileFragment.java new file mode 100644 index 00000000..eff8e0b7 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/userprofile/UserProfileFragment.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.userprofile; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.resource.drawable.GlideDrawable; +import com.bumptech.glide.request.animation.GlideAnimation; +import com.bumptech.glide.request.target.SimpleTarget; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.favouriteworkflow.FavouriteWorkflowsActivity; +import org.apache.taverna.mobile.ui.myworkflows.MyWorkflowActivity; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import de.hdodenhof.circleimageview.CircleImageView; + +public class UserProfileFragment extends Fragment { + + @Inject DataManager dataManager; + + @BindView(R.id.user_name) + TextView mUserName; + + @BindView(R.id.user_avatar) + CircleImageView mUserAvatar; + + @BindView(R.id.user_email) + TextView mUserEmail; + + @BindView(R.id.user_website) + TextView mUserWebsite; + + @BindView(R.id.user_description) + TextView mUserDescription; + + @BindView(R.id.user_city) + TextView mUserCity; + + @BindView(R.id.user_country) + TextView mUserCountry; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_user_profile, parent, false); + + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + ButterKnife.bind(this, view); + + setUserDetail(); + + } + + @OnClick(R.id.my_workflow_layout) + void myWorkflows(View v) { + Intent intent = new Intent(getActivity(), MyWorkflowActivity.class); + getActivity().startActivity(intent); + } + + @OnClick(R.id.my_favorite_workflow_layout) + void myFavoriteWorkflow(View v) { + Intent intent = new Intent(getActivity(), FavouriteWorkflowsActivity.class); + getActivity().startActivity(intent); + } + + private void setUserDetail() { + + String userName = dataManager.getPreferencesHelper().getUserName(); + String userDescription = dataManager.getPreferencesHelper().getUserDescription(); + String userEmail = dataManager.getPreferencesHelper().getUserEmail(); + String userWebsite = dataManager.getPreferencesHelper().getUserWebsite(); + String userCity = dataManager.getPreferencesHelper().getUserCity(); + String userCountry = dataManager.getPreferencesHelper().getUserCountry(); + + String avatarUrl = dataManager.getPreferencesHelper().getUserAvatarUrl(); + Glide.with(getContext()) + .load(avatarUrl) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .placeholder(R.drawable.ic_account_circle_black_24dp) + .error(R.drawable.ic_account_circle_black_24dp) + .into(new SimpleTarget() { + @Override + public void onResourceReady(GlideDrawable resource, GlideAnimation glideAnimation) { + mUserAvatar.setImageDrawable(resource); + } + }); + + if (userName != null) { + mUserName.setText(userName); + } else { + mUserName.setText(R.string.empty_fields); + } + + if (userDescription != null) { + userDescription = android.text.Html.fromHtml(userDescription).toString(); + mUserDescription.setText(userDescription); + } else { + mUserDescription.setText(""); + } + + if (userEmail != null) { + mUserEmail.setText(userEmail); + } else { + mUserEmail.setText(R.string.empty_fields); + } + + if (userWebsite != null) { + mUserWebsite.setText(userWebsite); + } else { + mUserWebsite.setText(R.string.empty_fields); + } + + if (userCity != null) { + mUserCity.setText(userCity); + } else { + mUserCity.setText(R.string.empty_fields); + } + + if (userCountry != null) { + mUserCountry.setText(userCountry); + } else { + mUserCountry.setText(R.string.empty_fields); + } + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflow/WorkflowFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflow/WorkflowFragment.java new file mode 100644 index 00000000..750a7167 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflow/WorkflowFragment.java @@ -0,0 +1,308 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflow; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.data.model.Workflows; +import org.apache.taverna.mobile.ui.adapter.EndlessRecyclerOnScrollListener; +import org.apache.taverna.mobile.ui.adapter.RecyclerItemClickListner; +import org.apache.taverna.mobile.ui.adapter.WorkflowAdapter; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.workflowdetail.WorkflowDetailActivity; +import org.apache.taverna.mobile.utils.ConnectionInfo; +import org.apache.taverna.mobile.utils.Constants; +import org.apache.taverna.mobile.utils.ScrollChildSwipeRefreshLayout; + +import android.app.SearchManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.Snackbar; +import android.support.v4.app.Fragment; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SearchView; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class WorkflowFragment extends Fragment implements WorkflowMvpView, + RecyclerItemClickListner.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener { + + public final String LOG_TAG = getClass().getSimpleName(); + + @Inject + WorkflowPresenter mWorkflowPresenter; + WorkflowAdapter mWorkflowAdapter; + WorkflowAdapter mSearchWorkflowAdapter; + + @BindView(R.id.rv_workflows) + RecyclerView mRecyclerView; + + @BindView(R.id.progress_circular) + ProgressBar mProgressBar; + + @BindView(R.id.swipe_refresh) + ScrollChildSwipeRefreshLayout mSwipeRefresh; + + private int mPageNumber = 1; + + private int mSearchPageNumber = 1; + private List mWorkflowList; + private List mSearchWorkflowList; + + private SearchView searchView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mWorkflowList = new ArrayList<>(); + mSearchWorkflowList = new ArrayList<>(); + setHasOptionsMenu(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_dashboard, container, false); + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + ButterKnife.bind(this, rootView); + mWorkflowPresenter.attachView(this); + + final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); + mRecyclerView.setLayoutManager(layoutManager); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); + mRecyclerView.hasFixedSize(); + mWorkflowAdapter = new WorkflowAdapter(mWorkflowList, getActivity()); + mRecyclerView.setAdapter(mWorkflowAdapter); + mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListner(getActivity(), this)); + + mWorkflowPresenter.loadAllWorkflow(mPageNumber); + + mRecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(layoutManager) { + @Override + public void onLoadMore(int current_page) { + if (ConnectionInfo.isConnectingToInternet(getContext()) + && mRecyclerView.getAdapter().getItemCount() % 10 == 0) { + if (searchView.isIconified() || TextUtils.isEmpty(searchView.getQuery())) { + addLoadMoreProgressbar(); + ++mPageNumber; + mWorkflowPresenter.loadAllWorkflow(mPageNumber); + } else { + addLoadMoreProgressbar(); + ++mSearchPageNumber; + mWorkflowPresenter.searchWorkflow(mSearchPageNumber, searchView.getQuery() + .toString()); + } + } else if (!ConnectionInfo.isConnectingToInternet(getContext())) { + showSnackBar(R.string.no_internet_connection); + } + } + }); + + mSwipeRefresh.setColorSchemeColors(getActivity() + .getResources().getIntArray(R.array.swipeRefreshColors)); + mSwipeRefresh.setOnRefreshListener(this); + + return rootView; + } + + + @Override + public void onRefresh() { + if (searchView.isIconified()) { + if (ConnectionInfo.isConnectingToInternet(getContext())) { + mPageNumber = 1; + mSearchPageNumber = 1; + mWorkflowPresenter.loadAllWorkflow(mPageNumber); + mSwipeRefresh.setRefreshing(true); + } else { + showSnackBar(R.string.no_internet_connection); + if (mSwipeRefresh.isRefreshing()) { + mSwipeRefresh.setRefreshing(false); + } + } + } + } + + @Override + public void showProgressbar(boolean show) { + if (show && mWorkflowAdapter.getItemCount() == 0) { + mProgressBar.setVisibility(View.VISIBLE); + } else { + mProgressBar.setVisibility(View.GONE); + } + } + + @Override + public void showSnackBar(int message) { + final Snackbar snackbar = Snackbar.make(mRecyclerView, getActivity().getString(message), + Snackbar.LENGTH_SHORT); + snackbar.setAction(getActivity().getString(R.string.ok), new View.OnClickListener() { + @Override + public void onClick(View view) { + snackbar.dismiss(); + } + }); + snackbar.show(); + } + + @Override + public void showWorkflows(Workflows workflows) { + if (mPageNumber == 1) { + mSwipeRefresh.setRefreshing(false); + mWorkflowList.clear(); + } + mWorkflowList.addAll(workflows.getWorkflowList()); + mWorkflowAdapter.notifyDataSetChanged(); + } + + @Override + public void removeLoadMoreProgressbar() { + if (mPageNumber != 1 || mSearchPageNumber != 1) { + ((WorkflowAdapter) mRecyclerView.getAdapter()).removeLastNullWorkflow(); + } + } + + @Override + public void addLoadMoreProgressbar() { + ((WorkflowAdapter) mRecyclerView.getAdapter()).addWorkflow(null); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mWorkflowPresenter.detachView(); + } + + @Override + public void onItemClick(View childView, int position) { + if (searchView.isIconified() && TextUtils.isEmpty(searchView.getQuery())) { + if (mWorkflowAdapter.getItem(position) != null && position != -1) { + Intent intent = new Intent(getActivity(), WorkflowDetailActivity.class); + intent.putExtra(Constants.WORKFLOW_ID, mWorkflowAdapter.getItem(position).getId()); + intent.putExtra(Constants.WORKFLOW_TITLE, mWorkflowAdapter.getItem(position) + .getTitle()); + startActivity(intent); + } + } else { + if (mSearchWorkflowAdapter.getItem(position) != null && position != -1) { + Intent intent = new Intent(getActivity(), WorkflowDetailActivity.class); + intent.putExtra(Constants.WORKFLOW_ID, mSearchWorkflowAdapter.getItem(position) + .getId()); + intent.putExtra(Constants.WORKFLOW_TITLE, mSearchWorkflowAdapter.getItem(position) + .getTitle()); + startActivity(intent); + } + } + } + + @Override + public void onItemLongPress(View childView, int position) { + + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context + .SEARCH_SERVICE); + searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); + + searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity() + .getComponentName())); + searchView.setSubmitButtonEnabled(false); + searchView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { + @Override + public void onViewAttachedToWindow(View view) { + mWorkflowPresenter.attachSearchHandler(searchView); + mSearchWorkflowList.clear(); + } + + @Override + public void onViewDetachedFromWindow(View view) { + mRecyclerView.swapAdapter(mWorkflowAdapter, true); + mSwipeRefresh.setRefreshing(false); + mSearchWorkflowList.clear(); + mSearchPageNumber = 1; + } + }); + + } + + @Override + public void performSearch(String search) { + + mSearchWorkflowAdapter = new WorkflowAdapter(mSearchWorkflowList, getContext()); + WorkflowAdapter wk = mWorkflowAdapter; + if (!TextUtils.isEmpty(search)) { + if (wk != null) + for (int i = 0; i < wk.getItemCount(); i++) { + Workflow workflow = wk.getItem(i); + if (workflow.getTitle().toLowerCase().contains(search.toLowerCase())) { + mSearchWorkflowAdapter.addWorkflow(workflow); + } + } + mRecyclerView.swapAdapter(mSearchWorkflowAdapter, true); + } else { + mRecyclerView.swapAdapter(mWorkflowAdapter, true); + mSearchPageNumber = 1; + } + } + + @Override + public void showSearchResult(List workflowList) { + if (mSearchPageNumber == 1) { + mSearchWorkflowList.clear(); // to remove local search + mSearchWorkflowList.addAll(workflowList); + mSearchWorkflowAdapter.notifyDataSetChanged(); + } else { + mSearchWorkflowList.addAll(workflowList); + mSearchWorkflowAdapter.notifyDataSetChanged(); + } + } + + @Override + public void showSwipeRefreshLayout(boolean flag) { + if (flag) { + mSwipeRefresh.setRefreshing(flag); + } else { + if (mSwipeRefresh.isRefreshing()) { + mSwipeRefresh.setRefreshing(flag); + } + } + } + + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflow/WorkflowMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflow/WorkflowMvpView.java new file mode 100644 index 00000000..f45bb05e --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflow/WorkflowMvpView.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflow; + +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.data.model.Workflows; +import org.apache.taverna.mobile.ui.base.MvpView; + +import java.util.List; + + +public interface WorkflowMvpView extends MvpView { + + void showProgressbar(boolean b); + + void showSnackBar(int message); + + void showWorkflows(Workflows workflows); + + void removeLoadMoreProgressbar(); + + void addLoadMoreProgressbar(); + + void performSearch(String query); + + void showSearchResult(List workflowList); + + void showSwipeRefreshLayout(boolean flag); + +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflow/WorkflowPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflow/WorkflowPresenter.java new file mode 100644 index 00000000..eb2ca90d --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflow/WorkflowPresenter.java @@ -0,0 +1,185 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflow; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.Search; +import org.apache.taverna.mobile.data.model.Workflows; +import org.apache.taverna.mobile.ui.base.BasePresenter; +import org.apache.taverna.mobile.utils.RxSearch; + +import android.support.v7.widget.SearchView; +import android.text.TextUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.inject.Inject; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; + +public class WorkflowPresenter extends BasePresenter { + + public final String LOG_TAG = WorkflowPresenter.class.getSimpleName(); + + private DataManager mDataManager; + private CompositeDisposable compositeDisposable; + + @Inject + public WorkflowPresenter(DataManager dataManager) { + mDataManager = dataManager; + compositeDisposable = new CompositeDisposable(); + } + + @Override + public void attachView(WorkflowMvpView mvpView) { + super.attachView(mvpView); + } + + @Override + public void detachView() { + super.detachView(); + compositeDisposable.clear(); + } + + public void loadAllWorkflow(final int pageNumber) { + checkViewAttached(); + getMvpView().showProgressbar(true); + compositeDisposable.add(mDataManager.getAllWorkflow(getQueryOptions(pageNumber)) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Workflows workflows) { + if (workflows.getWorkflowList() != null) { + getMvpView().showProgressbar(false); + getMvpView().removeLoadMoreProgressbar(); + getMvpView().showWorkflows(workflows); + } else { + if (pageNumber == 1) { + getMvpView().showSnackBar(R.string.no_workflows_found); + } else { + getMvpView().showSnackBar(R.string.no_more_workflows_avialable); + } + getMvpView().removeLoadMoreProgressbar(); + } + } + + @Override + public void onError(Throwable e) { + getMvpView().showProgressbar(false); + getMvpView().showSnackBar(R.string.error_failed_to_fetch_workflow); + getMvpView().removeLoadMoreProgressbar(); + } + + @Override + public void onComplete() { + + } + })); + } + + public void attachSearchHandler(final SearchView searchView) { + checkViewAttached(); + compositeDisposable.add(RxSearch.fromSearchView(searchView) + .distinctUntilChanged() + .debounce(300, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(String searchText) { + getMvpView().performSearch(searchText); + if (!TextUtils.isEmpty(searchText)) { + searchWorkflow(1, searchText); + } + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + })); + } + + public void detachSearchHandler() { + compositeDisposable.clear(); + } + + public void searchWorkflow(int pageNumber, String query) { + checkViewAttached(); + if (!TextUtils.isEmpty(query)) { + if (pageNumber == 1) { + getMvpView().showSwipeRefreshLayout(true); + } + compositeDisposable.add(mDataManager.getSearchWorkflowResult(getSearchQueryOptions + (pageNumber, query)) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Search search) { + getMvpView().removeLoadMoreProgressbar(); + if (search.getWorkflowList() != null && + search.getWorkflowList().size() > 0) { + getMvpView().showSearchResult(search.getWorkflowList()); + } else { + getMvpView().showSnackBar(R.string.msg_no_workflow_found); + } + } + + @Override + public void onError(Throwable e) { + getMvpView().showSwipeRefreshLayout(false); + } + + @Override + public void onComplete() { + getMvpView().showSwipeRefreshLayout(false); + } + })); + } + } + + private Map getQueryOptions(int pageNumber) { + Map option = new HashMap<>(); + option.put("elements", "title,type,uploader,preview,created-at"); + option.put("page", String.valueOf(pageNumber)); + option.put("num", String.valueOf(10)); + option.put("order", "reverse"); + return option; + } + + private Map getSearchQueryOptions(int pageNumber, String query) { + Map option = getQueryOptions(pageNumber); + option.put("query", query); + option.put("type", "workflow"); + return option; + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailActivity.java new file mode 100644 index 00000000..221297ee --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailActivity.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflowdetail; + + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.utils.Constants; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.ActionBar; +import android.support.v7.widget.Toolbar; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class WorkflowDetailActivity extends BaseActivity { + + @BindView(R.id.toolbar) + Toolbar mToolbar; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_detail_workflow); + + ButterKnife.bind(this); + + setSupportActionBar(mToolbar); + ActionBar actionbar = getSupportActionBar(); + + String workflowTitle = getIntent().getStringExtra(Constants.WORKFLOW_TITLE); + String workflowId = getIntent().getStringExtra(Constants.WORKFLOW_ID); + + if (actionbar != null) { + actionbar.setHomeButtonEnabled(true); + actionbar.setDisplayHomeAsUpEnabled(true); + actionbar.setTitle(workflowTitle); + } + + + if (savedInstanceState == null) { + getSupportFragmentManager().beginTransaction() + .add(R.id.frame_container, WorkflowDetailFragment.newInstance(workflowId)) + .commit(); + } + + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailFragment.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailFragment.java new file mode 100644 index 00000000..c4478dd8 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailFragment.java @@ -0,0 +1,349 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflowdetail; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.v4.app.Fragment; +import android.support.v7.app.AlertDialog; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebView; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.resource.drawable.GlideDrawable; +import com.bumptech.glide.request.animation.GlideAnimation; +import com.bumptech.glide.request.target.SimpleTarget; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.License; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.imagezoom.ImageZoomActivity; +import org.apache.taverna.mobile.ui.imagezoom.ImageZoomFragment; +import org.apache.taverna.mobile.ui.workflowrun.WorkflowRunActivity; +import org.apache.taverna.mobile.utils.ConnectionInfo; +import org.apache.taverna.mobile.utils.Constants; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import de.hdodenhof.circleimageview.CircleImageView; + +public class WorkflowDetailFragment extends Fragment implements WorkflowDetailMvpView { + + private static final String ID = "id"; + + public final String LOG_TAG = getClass().getSimpleName(); + + @Inject DataManager dataManager; + @Inject WorkflowDetailPresenter mWorkflowDetailPresenter; + + @BindView(R.id.ivWorkflowImage) + ImageView workflowImage; + + @BindView(R.id.tvTitle) + TextView title; + + @BindView(R.id.ivUploader) + CircleImageView uploaderImage; + + @BindView(R.id.tvUploaderName) + TextView uploaderName; + + @BindView(R.id.tvDate) + TextView date; + + @BindView(R.id.tvType) + TextView type; + + @BindView(R.id.tvDescription) + WebView description; + + @BindView(R.id.ivFav) + ImageView ivFavourite; + + @BindView(R.id.progressBar) + ProgressBar mProgressBar; + + @BindView(R.id.scrollView) + ScrollView mScrollView; + + @BindView(R.id.rootLayout) + RelativeLayout rootLayout; + + @BindView(R.id.fabRun) + FloatingActionButton fabRun; + + private AlertDialog alertDialog; + + private String id; + + private String licenceId = null; + + private ProgressDialog dialog; + private Workflow mWorkflow; + + public static WorkflowDetailFragment newInstance(String id) { + + Bundle args = new Bundle(); + + args.putString(ID, id); + + WorkflowDetailFragment fragment = new WorkflowDetailFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + id = getArguments().getString(ID); + + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_detail_workflow, container, false); + ((BaseActivity) getActivity()).getActivityComponent().inject(this); + ButterKnife.bind(this, rootView); + + mWorkflowDetailPresenter.attachView(this); + + return rootView; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (ConnectionInfo.isConnectingToInternet(getContext())) { + + mWorkflowDetailPresenter.loadWorkflowDetail(id); + } else { + + mProgressBar.setVisibility(View.GONE); + showErrorSnackBar(getString(R.string.no_internet_connection)); + } + + setHasOptionsMenu(true); + + } + + @OnClick(R.id.ivFav) + void favClick(View v) { + mWorkflowDetailPresenter.setFavourite(id); + } + + + @OnClick(R.id.fabRun) + void fabClickRunWorkflow(View v) { + Intent intent = new Intent(getActivity(), WorkflowRunActivity.class); + intent.putExtra(Constants.WORKFLOW_URL, mWorkflow.getContentUri()); + startActivity(intent); + + } + + @OnClick(R.id.ivWorkflowImage) + void zoomImage(View v) { + Intent intent = new Intent(getActivity(), ImageZoomActivity.class); + intent.putExtra(ImageZoomFragment.JPG_URI, mWorkflow.getPreviewUri()); + intent.putExtra(ImageZoomFragment.SVG_URI, mWorkflow.getSvgUri()); + startActivity(intent); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.menu_workflow_detail, menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.licence: + + if (licenceId == null) { + showErrorSnackBar("Please wait"); + } else if (licenceId.isEmpty()) { + showErrorSnackBar("No Licence Found"); + } else { + mWorkflowDetailPresenter.loadLicenseDetail(licenceId); + } + + return true; + } + return super.onOptionsItemSelected(item); + + } + + @Override + public void showProgressbar(boolean b) { + if (b) { + mProgressBar.setVisibility(View.VISIBLE); + } else { + mProgressBar.setVisibility(View.GONE); + mScrollView.setVisibility(View.VISIBLE); + } + } + + @Override + public void showWorkflowDetail(Workflow workflow) { + + this.mWorkflow = workflow; + + uploaderName.setText(workflow.getUploader().getContent()); + date.setText(workflow.getUpdatedAt() + .substring(0, workflow.getUpdatedAt().indexOf(' '))); + type.setText(workflow.getType().getContent()); + title.setText(workflow.getTitle()); + description.loadData(workflow.getDescription(), "text/html", "utf-8"); + + Glide.with(getContext()) + .load(workflow.getPreviewUri()) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .placeholder(R.drawable.placeholder) + .error(R.drawable.placeholder) + .into(new SimpleTarget() { + @Override + public void onResourceReady(GlideDrawable resource, + GlideAnimation glideAnimation) { + workflowImage.setImageDrawable(resource); + } + }); + + if (workflow.getLicenseType().getId() == null) { + licenceId = ""; + } else { + licenceId = workflow.getLicenseType().getId(); + } + + if (mWorkflow.getType().getContent().equals(getString(R.string.t2_workflow_type))) { + fabRun.setVisibility(View.VISIBLE); + } else { + fabRun.setVisibility(View.GONE); + } + } + + @Override + public void setImage(User user) { + Glide.with(getContext()) + .load(user.getAvatar().getResource()) + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .placeholder(R.drawable.placeholder) + .error(R.drawable.placeholder) + .into(uploaderImage); + } + + @Override + public void showErrorSnackBar(String error) { + final Snackbar snackbar = Snackbar.make(rootLayout, error, Snackbar + .LENGTH_INDEFINITE); + snackbar.setAction("OK", new View.OnClickListener() { + @Override + public void onClick(View view) { + snackbar.dismiss(); + } + }); + snackbar.show(); + } + + @Override + public void showLicense(License license) { + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext()); + + LayoutInflater inflater = getActivity().getLayoutInflater(); + + View dialogView = inflater.inflate(R.layout.dialog_licence_detail_workflow, null); + + dialogBuilder.setView(dialogView); + + TextView title = dialogView.findViewById(R.id.tvDialogTitle); + TextView date = dialogView.findViewById(R.id.tvDialogDate); + WebView text = dialogView.findViewById(R.id.wvDialogText); + Button buttonOk = dialogView.findViewById(R.id.bDialogOK); + + buttonOk.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + alertDialog.dismiss(); + } + }); + + text.loadDataWithBaseURL("", license.getDescription(), "text/html", "utf-8", ""); + date.setText(license.getCreatedAt().substring(0, license.getCreatedAt().indexOf(' '))); + title.setText(license.getTitle()); + + alertDialog = dialogBuilder.create(); + + alertDialog.show(); + } + + @Override + public void showLicenseProgress(boolean b) { + if (b) { + dialog = ProgressDialog.show(getContext(), "Loading", "Please wait...", true, true); + } else { + dialog.dismiss(); + } + } + + @Override + public void setFavouriteIcon() { + mWorkflowDetailPresenter.getFavourite(id); + } + + @Override + public void getFavouriteIcon(boolean b) { + if (b) { + ivFavourite.setImageResource(R.drawable.ic_star_black_24dp); + } else { + ivFavourite.setImageResource(R.drawable.ic_star_border_black_24dp); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mWorkflowDetailPresenter.detachView(); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailMvpView.java new file mode 100644 index 00000000..def51109 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailMvpView.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflowdetail; + + +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.data.model.License; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.ui.base.MvpView; + +public interface WorkflowDetailMvpView extends MvpView { + + void showProgressbar(boolean b); + + void showWorkflowDetail(Workflow workflow); + + void setImage(User user); + + void showErrorSnackBar(String error); + + void showLicense(License license); + + void showLicenseProgress(boolean b); + + void setFavouriteIcon(); + + void getFavouriteIcon(boolean b); +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailPresenter.java new file mode 100644 index 00000000..ef2d85d4 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflowdetail/WorkflowDetailPresenter.java @@ -0,0 +1,216 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflowdetail; + +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.License; +import org.apache.taverna.mobile.data.model.User; +import org.apache.taverna.mobile.data.model.Workflow; +import org.apache.taverna.mobile.ui.base.BasePresenter; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; + +public class WorkflowDetailPresenter extends BasePresenter { + + public final String LOG_TAG = getClass().getSimpleName(); + private DataManager mDataManager; + private CompositeDisposable compositeDisposable; + + @Inject + public WorkflowDetailPresenter(DataManager dataManager) { + mDataManager = dataManager; + compositeDisposable = new CompositeDisposable(); + } + + @Override + public void attachView(WorkflowDetailMvpView mvpView) { + super.attachView(mvpView); + } + + @Override + public void detachView() { + super.detachView(); + compositeDisposable.clear(); + } + + public void loadWorkflowDetail(String id) { + checkViewAttached(); + getMvpView().showProgressbar(true); + compositeDisposable.add(mDataManager.getDetailWorkflow(id, getDetailQueryOptions()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Workflow workflow) { + getMvpView().showWorkflowDetail(workflow); + loadUserDetail(workflow.getUploader().getId()); + getFavourite(workflow.getId()); + } + + @Override + public void onError(Throwable e) { + getMvpView().showProgressbar(false); + } + + @Override + public void onComplete() { + getMvpView().showProgressbar(false); + } + })); + } + + private void loadUserDetail(String id) { + checkViewAttached(); + getMvpView().showProgressbar(true); + compositeDisposable.add(mDataManager.getUserDetail(id, getUserQueryOptions()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(User user) { + getMvpView().setImage(user); + } + + @Override + public void onError(Throwable e) { + getMvpView().showProgressbar(false); + getMvpView().showErrorSnackBar("Something went wrong please try after " + + "sometime"); + } + + @Override + public void onComplete() { + getMvpView().showProgressbar(false); + } + })); + } + + public void loadLicenseDetail(String id) { + checkViewAttached(); + getMvpView().showLicenseProgress(true); + compositeDisposable.add(mDataManager.getLicenseDetail(id, getLicenceQueryOptions()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(License license) { + getMvpView().showLicense(license); + } + + @Override + public void onError(Throwable e) { + getMvpView().showLicenseProgress(false); + getMvpView().showErrorSnackBar("Something went wrong please try after " + + "sometime"); + } + + @Override + public void onComplete() { + getMvpView().showLicenseProgress(false); + } + })); + } + + public void setFavourite(String id) { + checkViewAttached(); + compositeDisposable.add(mDataManager.setFavoriteWorkflow(id) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Boolean b) { + if (b) { + getMvpView().setFavouriteIcon(); + } else { + getMvpView().showErrorSnackBar("Something went wrong please try after" + + "sometime"); + } + } + + @Override + public void onError(Throwable e) { + getMvpView().showErrorSnackBar("Something went wrong please try after " + + "sometime"); + } + + @Override + public void onComplete() { + + } + })); + } + + public void getFavourite(String id) { + checkViewAttached(); + compositeDisposable.add(mDataManager.getFavoriteWorkflow(id) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Boolean favoriteStatus) { + getMvpView().getFavouriteIcon(favoriteStatus); + } + + @Override + public void onError(Throwable e) { + getMvpView().showErrorSnackBar("Something went wrong please try after " + + "sometime"); + } + + @Override + public void onComplete() { + + } + })); + } + + + private Map getDetailQueryOptions() { + Map option = new HashMap<>(); + option.put("elements", "id,title,type,uploader,preview,created-at,svg,updated-at," + + "description,license-type,tags,content-uri"); + return option; + } + + private Map getUserQueryOptions() { + Map option = new HashMap<>(); + option.put("elements", "avatar"); + return option; + } + + private Map getLicenceQueryOptions() { + Map option = new HashMap<>(); + option.put("elements", "title,description,url,created-at"); + return option; + } + + private Map getUserWorkflowsQueryOptions() { + Map option = new HashMap<>(); + option.put("elements", "workflow"); + return option; + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflowrun/WorkflowRunActivity.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflowrun/WorkflowRunActivity.java new file mode 100644 index 00000000..620c5de9 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflowrun/WorkflowRunActivity.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflowrun; + +import com.anton46.stepsview.StepsView; + +import org.apache.taverna.mobile.R; +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.ui.DownloadingFragment; +import org.apache.taverna.mobile.ui.base.BaseActivity; +import org.apache.taverna.mobile.ui.playerlogin.PlayerLoginFragment; +import org.apache.taverna.mobile.utils.Constants; +import org.apache.taverna.mobile.utils.NonSwipeableViewPager; +import org.apache.taverna.mobile.utils.WebViewGenerator; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.PagerAdapter; +import android.widget.Toast; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; + +import static com.raizlabs.android.dbflow.config.FlowManager.getContext; + +public class WorkflowRunActivity extends BaseActivity implements WorkflowRunMvpView, + PlayerLoginFragment.OnSuccessful { + + @Inject + DataManager dataManager; + @Inject + WorkflowRunPresenter mWorkflowRunPresenter; + PagerAdapter mPagerAdapter; + + @BindView(R.id.stepsView) + StepsView mStepsView; + + @BindView(R.id.viewpager) + NonSwipeableViewPager mPager; + + int position = 0; + + private String[] labels; + private String workflowRunURL; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActivityComponent().inject(this); + setContentView(R.layout.activity_workflow_run); + + ButterKnife.bind(this); + + + + mWorkflowRunPresenter.attachView(this); + + labels = getResources().getStringArray(R.array.player_run_slider_view_labels); + + mStepsView.setCompletedPosition(position % labels.length) + .setLabels(labels) + .setBarColorIndicator( + getContext().getResources().getColor(R.color.material_blue_grey_800)) + .setProgressColorIndicator(getContext().getResources().getColor(R.color + .colorPrimary)) + .setLabelColorIndicator(getContext().getResources().getColor(R.color.colorPrimary)) + .drawView(); + + + mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); + mPager.setAdapter(mPagerAdapter); + + if (dataManager.getPreferencesHelper().isUserPlayerLoggedInFlag()) { + mPager.setCurrentItem(++position); + mStepsView.setCompletedPosition(position % labels.length).drawView(); + + mWorkflowRunPresenter.runWorkflow(getIntent().getStringExtra(Constants.WORKFLOW_URL)); + } + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mWorkflowRunPresenter.detachView(); + } + + + @Override + public void onSuccessfulLogin() { + position = 1; + mPager.setCurrentItem(position); + mStepsView.setCompletedPosition(position % labels.length).drawView(); + mWorkflowRunPresenter.runWorkflow(getIntent().getStringExtra(Constants.WORKFLOW_URL)); + } + + @Override + public void movetoUploadWorkflow() { + position = 2; + mPager.setCurrentItem(position); + mStepsView.setCompletedPosition(position % labels.length).drawView(); + } + + @Override + public void movetoInputs() { + position = 3; + mStepsView.setCompletedPosition(position % labels.length).drawView(); + mPager.setCurrentItem(position); + + } + + @Override + public void setInputsAttribute(int id) { + String playerURL = dataManager.getPreferencesHelper().getPlayerURL(); + + if (playerURL.trim().endsWith("/")) { + playerURL = playerURL.substring(0, playerURL.length() - 1); + } + workflowRunURL = playerURL + "/workflows/" + id + + "/runs/new"; + mPager.getAdapter().notifyDataSetChanged(); + } + + @Override + public void showError() { + Toast.makeText(this, getString(R.string.servererr), Toast + .LENGTH_LONG).show(); + finish(); + } + + + private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { + public ScreenSlidePagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + switch (position) { + case 0: + return PlayerLoginFragment.newInstance(); + case 1: + return DownloadingFragment.newInstance(getString(R.string + .downloading_workflow_lable)); + case 2: + return DownloadingFragment.newInstance(getString(R.string + .uploading_workflow_lable)); + default: + return WebViewGenerator.newInstance(workflowRunURL); + + } + } + + @Override + public int getCount() { + return 4; + } + } + + +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflowrun/WorkflowRunMvpView.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflowrun/WorkflowRunMvpView.java new file mode 100644 index 00000000..c5dcff57 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflowrun/WorkflowRunMvpView.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflowrun; + + +import org.apache.taverna.mobile.ui.base.MvpView; + +public interface WorkflowRunMvpView extends MvpView { + + void movetoUploadWorkflow(); + + void movetoInputs(); + + void setInputsAttribute(int id); + + void showError(); +} diff --git a/app/src/main/java/org/apache/taverna/mobile/ui/workflowrun/WorkflowRunPresenter.java b/app/src/main/java/org/apache/taverna/mobile/ui/workflowrun/WorkflowRunPresenter.java new file mode 100644 index 00000000..a45ca762 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/ui/workflowrun/WorkflowRunPresenter.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.ui.workflowrun; + +import android.util.Base64; +import android.util.Log; + +import org.apache.taverna.mobile.data.DataManager; +import org.apache.taverna.mobile.data.model.PlayerWorkflow; +import org.apache.taverna.mobile.data.model.PlayerWorkflowDetail; +import org.apache.taverna.mobile.ui.base.BasePresenter; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import javax.inject.Inject; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.functions.Function; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okhttp3.ResponseBody; + +public class WorkflowRunPresenter extends BasePresenter { + + private static final String TAG = WorkflowRunPresenter.class.getSimpleName(); + + private final DataManager mDataManager; + private CompositeDisposable compositeDisposable; + + @Inject + public WorkflowRunPresenter(DataManager dataManager) { + mDataManager = dataManager; + compositeDisposable = new CompositeDisposable(); + } + + @Override + public void attachView(WorkflowRunMvpView mvpView) { + super.attachView(mvpView); + } + + @Override + public void detachView() { + super.detachView(); + compositeDisposable.clear(); + } + + public void runWorkflow(String contentURL) { + checkViewAttached(); + compositeDisposable.add(mDataManager.downloadWorkflowContent(contentURL) + .concatMap(new Function>() { + + @Override + public ObservableSource apply(ResponseBody responseBody) + throws Exception { + StringBuffer sb = new StringBuffer(); + String post = ""; + + String basicAuth = mDataManager.getPreferencesHelper() + .getUserPlayerCredential(); + boolean flag = false; + try { + + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(responseBody.byteStream())); + + String str = ""; + + while ((str = bufferedReader.readLine()) != null) { + sb.append(str); + } + + bufferedReader.close(); + + String data = "{\"document\":\"data:application/octet-stream;base64," + + Base64.encodeToString(sb.toString().getBytes("UTF-8"), Base64 + .URL_SAFE | Base64.NO_WRAP).replace('-', '+') + "\"}"; + + post = "{\"workflow\":" + data + "}"; + flag = true; + } catch (IOException e) { + Log.e(TAG, "call: ", e); + } + if (flag) { + RequestBody body = + RequestBody.create(MediaType.parse("application/json"), post); + + return mDataManager.uploadWorkflowContent(body, basicAuth.trim()); + } else { + return Observable.empty(); + } + } + }) + .concatMap(new Function>() { + + @Override + public ObservableSource apply( + PlayerWorkflow playerWorkflow) throws Exception { + return mDataManager.getWorkflowDetail(playerWorkflow.getId()); + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(PlayerWorkflowDetail playerWorkflowDetail) { + getMvpView().setInputsAttribute(playerWorkflowDetail.getRun() + .getWorkflowId()); + } + + @Override + public void onError(Throwable e) { + getMvpView().showError(); + } + + @Override + public void onComplete() { + + } + })); + } +} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/ActivityUtils.java b/app/src/main/java/org/apache/taverna/mobile/utils/ActivityUtils.java new file mode 100644 index 00000000..3d0c0dd9 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/ActivityUtils.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; + +public class ActivityUtils { + + + public static void addFragmentToActivity(FragmentManager fragmentManager, Fragment fragment, + int frameId) { + + for (int i = 0; i < fragmentManager.getBackStackEntryCount(); ++i) { + fragmentManager.popBackStack(); + } + FragmentTransaction transaction = fragmentManager.beginTransaction(); + transaction.replace(frameId, fragment); + transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); + transaction.commit(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/AvatarLoader.java b/app/src/main/java/org/apache/taverna/mobile/utils/AvatarLoader.java deleted file mode 100644 index cf989fa9..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/AvatarLoader.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.apache.taverna.mobile.utils; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import android.os.AsyncTask; - -import com.thebuzzmedia.sjxp.rule.IRule; - -import org.apache.taverna.mobile.adapters.WorkflowAdapter; -import org.apache.taverna.mobile.tavernamobile.User; -import org.apache.taverna.mobile.utils.xmlparsers.AvatarXMLParser; -import org.apache.taverna.mobile.utils.xmlparsers.MyExperimentXmlParserRules; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - -/** - * initiates a process to fetch and parse uploader information so as to retrieve the id, name and avatar link - * Created by Larry AKah on 6/29/15. - */ -public class AvatarLoader extends AsyncTask { - WorkflowAdapter.ViewHolder vh; - public AvatarLoader(WorkflowAdapter.ViewHolder userViewHolder) { - this.vh = userViewHolder; - } - - @Override - protected Void doInBackground(String... strings) { - URL url = null; - HttpURLConnection connection = null; - try { - - url = new URL(strings[0]); - connection = (HttpURLConnection) url.openConnection(); - connection.setDoInput(true); - connection.connect(); - InputStream input = connection.getInputStream(); - IRule avatarRule = new MyExperimentXmlParserRules.AuthorRule(IRule.Type.ATTRIBUTE,"/user/avatar", "resource","uri","id"); - IRule avatarName = new MyExperimentXmlParserRules.AuthorRule(IRule.Type.CHARACTER,"/user/name"); - AvatarXMLParser avatarXMLParser = new AvatarXMLParser(new IRule[]{avatarRule, avatarName}); - - avatarXMLParser.parse(input, new User(strings[1], this.vh)); - - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - return null; - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/ConnectionInfo.java b/app/src/main/java/org/apache/taverna/mobile/utils/ConnectionInfo.java index cd11e90c..e1b28471 100644 --- a/app/src/main/java/org/apache/taverna/mobile/utils/ConnectionInfo.java +++ b/app/src/main/java/org/apache/taverna/mobile/utils/ConnectionInfo.java @@ -25,26 +25,16 @@ public class ConnectionInfo { - private static String TAG; - private static Context context; - - public ConnectionInfo(Context context) { - TAG = this.getClass().getName(); - Log.i(TAG, "Utils: "); - ConnectionInfo.context = context; - } + private static final String TAG = "ConnectionInfo"; + public static boolean isConnectingToInternet(Context context) { - public boolean isConnectingToInternet() { - ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + Log.i(TAG, "isConnectingToInternet: Checking Internet Status"); + ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context + .CONNECTIVITY_SERVICE); if (connectivity != null) { - NetworkInfo[] info = connectivity.getAllNetworkInfo(); - if (info != null) - for (int i = 0; i < info.length; i++) - if (info[i].getState() == NetworkInfo.State.CONNECTED) { - return true; - } - + NetworkInfo info = connectivity.getActiveNetworkInfo(); + if (info != null) return true; } return false; } diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/Constants.java b/app/src/main/java/org/apache/taverna/mobile/utils/Constants.java new file mode 100644 index 00000000..b4a0832a --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/Constants.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + + +public class Constants { + + public static final String ARGS_MESSAGE = "args_message"; + + public static final String ARGS_URL = "url"; + + public static final String WORKFLOW_URL = "Workflow_url"; + + public static final String WORKFLOW_ID = "workflow_id"; + + public static final String WORKFLOW_TITLE = "workflow_title"; +} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/DB_Utility.java b/app/src/main/java/org/apache/taverna/mobile/utils/DB_Utility.java deleted file mode 100644 index 4ae919c8..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/DB_Utility.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.apache.taverna.mobile.utils; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import org.json.JSONArray; -import org.json.JSONException; - -import java.util.ArrayList; - -/** - * This class contains all utility functions used by our database for basic functionality not directly related to the core - * functionality of it but that aids a core functionality to carryout its function efficiently. - * This class is designed to be a singleton class - * @author Larry Akah - * - */ -public class DB_Utility { - - /** - * Returns a new JSONArray of new key values to be stored ommitting the identified entry to be removed - * @param keys - * @param removeid - * @return - * @throws org.json.JSONException - */ - public static JSONArray removeKey(JSONArray keys, String removeid) throws JSONException{ - ArrayList mkeys = new ArrayList(); - if(keys!=null){ - for(int i=0; i { - - public static enum LOAD_TYPE {TYPE_WORKFLOW_DETAIL, TYPE_RUN_HISTORY, TYPE_POLICY, TYPE_ABOUT_WORKFLOW}; - private LOAD_TYPE lt; - private String uri; - private Workflow workflow; - private Context context; - - public DetailsLoader(Context context, LOAD_TYPE load_type, String dataParam) { - super(context); - this.context = context; - this.lt = load_type; - uri = dataParam; - this.workflow = new Workflow(); - } - - @Override - public Workflow loadInBackground() { - HttpURLConnection connection = null; - InputStream dis = null; - //start a network request to fetch user's workflow details - try { - Log.i("LOADER STARTED", "loading data"); - //for password protected urls use the user's credentials - Authenticator.setDefault(new TavernaPlayerAPI.Authenticator("taverna", "taverna")); - TavernaPlayerAPI tavernaPlayerAPI = new TavernaPlayerAPI(); - URL workflowurl; - - switch (this.lt){ - case TYPE_WORKFLOW_DETAIL: - workflowurl = new URL(uri); - connection = (HttpURLConnection) workflowurl.openConnection(); - connection.setRequestProperty("Accept", "application/json"); - connection.setRequestMethod("GET"); - connection.connect(); //send request - - Log.i("Workflow Response Code", "" + connection.getResponseCode()); - Log.i("Workflow Response msg", ""+connection.getResponseMessage()); - dis = connection.getInputStream(); - break; - case TYPE_RUN_HISTORY: - workflowurl = new URL(new TavernaPlayerAPI(this.context).PLAYER_RUN_URL); - connection = (HttpURLConnection) workflowurl.openConnection(); - String userpass = tavernaPlayerAPI.getPlayerUserName(this.context) + ":" + tavernaPlayerAPI.getPlayerUserPassword(this.context); - 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. Run", ""+connection.getResponseMessage()); - dis = connection.getInputStream(); - break; - case TYPE_POLICY: - workflowurl = new URL(new TavernaPlayerAPI(this.context).SERVER_BASE_URL); - break; - default: - workflowurl = new URL(new TavernaPlayerAPI(this.context).PLAYER_WORKFLOW_URL); - break; - } - - switch(this.lt) { - case TYPE_WORKFLOW_DETAIL: { - //make rules and apply the parser - IRule workfl = new MyExperimentXmlParserRules.WorkflowDetailRule(IRule.Type.ATTRIBUTE, - "/workflow", "uri","resource", "id","version"); - IRule title = new MyExperimentXmlParserRules.TitleRule(IRule.Type.CHARACTER,"/workflow/title"); - IRule description = new MyExperimentXmlParserRules.DescriptionRule(IRule.Type.CHARACTER, "/workflow/description"); - IRule type = new MyExperimentXmlParserRules.TypeRule(IRule.Type.CHARACTER, "/workflow/type"); - IRule attrType = new MyExperimentXmlParserRules.TypeRule(IRule.Type.ATTRIBUTE, "/workflow/type", "resource", "uri","id"); - IRule uploader = new MyExperimentXmlParserRules.UploaderRule(IRule.Type.CHARACTER, "/workflow/uploader"); - IRule attrUploader = new MyExperimentXmlParserRules.UploaderRule(IRule.Type.ATTRIBUTE, "/workflow/uploader", "resource", "uri","id"); - IRule date = new MyExperimentXmlParserRules.DateRule(IRule.Type.CHARACTER, "/workflow/created-at"); - IRule preview = new MyExperimentXmlParserRules.PreviewRule(IRule.Type.CHARACTER, "/workflow/preview"); - IRule licetype = new MyExperimentXmlParserRules.LicenceTypeRule(IRule.Type.CHARACTER, "/workflow/licence-type"); - IRule attrlicetype = new MyExperimentXmlParserRules.LicenceTypeRule(IRule.Type.ATTRIBUTE,"/workflow/licence-type", "resource", "uri","id"); - IRule contenturi = new MyExperimentXmlParserRules.ContentUriRule(IRule.Type.CHARACTER, "/workflow/content-uri"); - IRule contentType = new MyExperimentXmlParserRules.ContentTypeRule(IRule.Type.CHARACTER, "/workflow/content-type"); - IRule tags = new MyExperimentXmlParserRules.TagsRule(IRule.Type.CHARACTER, "/workflow/tags/tag"); - IRule attrTags = new MyExperimentXmlParserRules.TagsRule(IRule.Type.ATTRIBUTE, "/workflow/tags/tag", "resource", "uri","id"); - - WorkflowDetailParser parser = new WorkflowDetailParser(new IRule[]{workfl,title,description,type, - attrlicetype,attrType, uploader,attrUploader,date,preview,licetype,contenturi,contentType,tags,attrTags}); - // System.out.println(sb.toString()); - parser.parse(dis, this.workflow); - } - dis.close(); - //br.close(); - return workflow; - case TYPE_RUN_HISTORY:{ - System.out.println("Downloading run history"); - BufferedReader br = new BufferedReader(new InputStreamReader(dis)); - StringBuffer sb = new StringBuffer(); - String jsonData = ""; - while((jsonData = br.readLine()) != null){ - sb.append(jsonData); - } - workflow = new Workflow(this.context); - JSONArray jsonArray = new JSONArray(sb.toString()); - Log.i("RUN JSON ", jsonArray.toString(2)); - for(int j=0; j< jsonArray.length();j++){ - JSONObject jsonObject = jsonArray.getJSONObject(j); - long id = jsonObject.getLong("id"); - long workflow_id = jsonObject.getLong("workflow_id"); - String name = jsonObject.getString("name"); - String started = jsonObject.getString("start_time"); - String ended = jsonObject.getString("finish_time"); - String state = jsonObject.getString("state"); - JSONObject userobj = jsonObject.getJSONObject("user"); - String username = userobj.getString("name"); - StringBuffer nm = new StringBuffer(), ur = new StringBuffer(); - for(String n: name.toLowerCase().split(" ")) - nm.append(n); - for (String p: uri.toLowerCase().split(" ")) - ur.append(p); - - if(nm.toString().equals(ur.toString())) { - Runs mrun = new Runs(name,started,ended,state); - mrun.setRun_id(id); - mrun.setRun_workflow_id(workflow_id); - mrun.setRun_author(username); - - workflow.addWorkflowRun(mrun); - } - } - } - return workflow; - case TYPE_POLICY:{ - - } - return workflow; - default: - BufferedReader br = new BufferedReader(new InputStreamReader(dis)); - StringBuffer sb = new StringBuffer(); - String jsonData = ""; - while((jsonData = br.readLine()) != null){ - sb.append(jsonData); - } - dis.close(); - br.close(); - return workflow; - } - - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (JSONException e) { - e.printStackTrace(); - } - return workflow; - } - - @Override - public boolean isStarted() { - return super.isStarted(); - } - - @Override - protected void onStartLoading() { - /* if(workflow != null){ - deliverResult(workflow); - }else{ - forceLoad(); - }*/ - forceLoad(); - Log.i("Loading State","loading started"); - } - - @Override - protected void onStopLoading() { - Log.i("Loading detailComponent","loading stopped"); - } - - @Override - public void deliverResult(Workflow data) { - if(isStarted()){ - super.deliverResult(data); - } - } -} -/** - * JSONObject js = new JSONObject(sb.toString()); - Log.i("JSON ", js.toString(2)); - String created_at = js.getString("created_at"); - String updated_at = js.getString("updated_at"); - JSONObject user = js.getJSONObject("user"); - workflow = new Workflow(this.context, js.getString("title"), - user.getString("name"), - js.getString("description"), - js.getInt("id"), - js.getString("url")); - workflow.setWorkflow_datecreated(created_at); - workflow.setWorkflow_datemodified(updated_at); - **/ \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/HttpUtil.java b/app/src/main/java/org/apache/taverna/mobile/utils/HttpUtil.java deleted file mode 100644 index 21d92af9..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/HttpUtil.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.apache.taverna.mobile.utils; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.auth.BasicScheme; -import org.apache.http.impl.client.AbstractHttpClient; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.util.EntityUtils; -import org.apache.taverna.mobile.tavernamobile.User; - -import java.io.DataInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.net.CookieStore; -import java.net.HttpURLConnection; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * Created by Larry Akah on 6/18/15. - */ -public class HttpUtil { - - public Object doPostAuthenticate(){ - User muser = new User("",null); - - return muser; - } - - public Object doGetRequestResponse(String uri, Class classType, String username, String password){ - Object dataObject = null; - - HttpClient httpClient = new DefaultHttpClient(); - HttpGet httpGet = new HttpGet(uri); - HttpResponse httpResponse = null; - try { - ((AbstractHttpClient) httpClient).setCookieStore((org.apache.http.client.CookieStore) CookieStore.class.newInstance()); - httpGet.addHeader(BasicScheme.authenticate(new UsernamePasswordCredentials(username,password), "UTF-8", false)); - httpResponse = httpClient.execute(httpGet); - - if(isSuccess(httpResponse, HttpURLConnection.HTTP_OK)){ - HttpEntity entity = httpResponse.getEntity(); - if(entity != null){ - String responseString = EntityUtils.toString(entity); - dataObject = this.deSerialize(classType, responseString); - } - } - } catch (InstantiationException e) { - e.printStackTrace(); - return e.getMessage(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - return e.getMessage(); - } catch (ClientProtocolException e) { - e.printStackTrace(); - return e.getMessage(); - } catch (IOException e) { - e.printStackTrace(); - return e.getMessage(); - } - - return dataObject; - - } - - //de-serializes xml data to target class - private Object deSerialize(Class classType, String responseString) { - //TODO deserialize data and return the appropriate object - // ObjectInputStream ori = new ObjectInputStream(new DataInputStream(responseString)) ; - - return null; - } - - private boolean isSuccess(HttpResponse httpResponse, int httpOk) { - - return httpResponse.getStatusLine().getStatusCode() == httpOk; - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/NonSwipeableViewPager.java b/app/src/main/java/org/apache/taverna/mobile/utils/NonSwipeableViewPager.java new file mode 100644 index 00000000..6883c245 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/NonSwipeableViewPager.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + +import android.content.Context; +import android.support.v4.view.ViewPager; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.animation.DecelerateInterpolator; +import android.widget.Scroller; + +import java.lang.reflect.Field; + +public class NonSwipeableViewPager extends ViewPager { + + private static final String TAG = NonSwipeableViewPager.class.getSimpleName(); + public NonSwipeableViewPager(Context context) { + super(context); + setMyScroller(); + } + + public NonSwipeableViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + setMyScroller(); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + // Never allow swiping to switch between pages + return false; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // Never allow swiping to switch between pages + return false; + } + + //down one is added for smooth scrolling + + private void setMyScroller() { + try { + Class viewpager = ViewPager.class; + Field scroller = viewpager.getDeclaredField("mScroller"); + scroller.setAccessible(true); + scroller.set(this, new MyScroller(getContext())); + } catch (Exception e) { + Log.e(TAG, "setMyScroller: ", e); + } + } + + public class MyScroller extends Scroller { + public MyScroller(Context context) { + super(context, new DecelerateInterpolator()); + } + + @Override + public void startScroll(int startX, int startY, int dx, int dy, int duration) { + super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/); + } + } +} \ No newline at end of file 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 deleted file mode 100644 index d0710a53..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/RunTask.java +++ /dev/null @@ -1,93 +0,0 @@ -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 { - - 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 { - TavernaPlayerAPI tavernaPlayerAPI = new TavernaPlayerAPI(); - URL workflowurl = new URL(new TavernaPlayerAPI(this.context).PLAYER_RUN_URL); - HttpURLConnection connection = (HttpURLConnection) workflowurl.openConnection(); - String userpass = tavernaPlayerAPI.getPlayerUserName(this.context) + ":" + tavernaPlayerAPI.getPlayerUserPassword(this.context); - 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); - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/RxSearch.java b/app/src/main/java/org/apache/taverna/mobile/utils/RxSearch.java new file mode 100644 index 00000000..46477add --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/RxSearch.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + +import android.support.annotation.NonNull; +import android.support.v7.widget.SearchView; + +import io.reactivex.Observable; +import io.reactivex.subjects.BehaviorSubject; + + +public class RxSearch { + + public static Observable fromSearchView(@NonNull final SearchView searchView) { + final BehaviorSubject subject = BehaviorSubject.create(); + + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + + @Override + public boolean onQueryTextSubmit(String query) { + subject.onNext(query); + subject.onComplete(); + searchView.clearFocus(); + return true; + } + + @Override + public boolean onQueryTextChange(String newText) { + subject.onNext(newText); + return true; + } + }); + + return subject; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/SvgDecoder.java b/app/src/main/java/org/apache/taverna/mobile/utils/SvgDecoder.java new file mode 100644 index 00000000..4642f581 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/SvgDecoder.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + +import com.bumptech.glide.load.ResourceDecoder; +import com.bumptech.glide.load.engine.Resource; +import com.bumptech.glide.load.resource.SimpleResource; +import com.caverock.androidsvg.SVG; +import com.caverock.androidsvg.SVGParseException; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Decodes an SVG internal representation from an {@link InputStream}. + */ +public class SvgDecoder implements ResourceDecoder { + public Resource decode(InputStream source, int width, int height) throws IOException { + try { + SVG svg = SVG.getFromInputStream(source); + return new SimpleResource(svg); + } catch (SVGParseException ex) { + throw new IOException("Cannot load SVG from stream", ex); + } + } + + @Override + public String getId() { + return ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/SvgDrawableTranscoder.java b/app/src/main/java/org/apache/taverna/mobile/utils/SvgDrawableTranscoder.java new file mode 100644 index 00000000..ac7d752f --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/SvgDrawableTranscoder.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + +import com.bumptech.glide.load.engine.Resource; +import com.bumptech.glide.load.resource.SimpleResource; +import com.bumptech.glide.load.resource.transcode.ResourceTranscoder; +import com.caverock.androidsvg.SVG; + +import android.graphics.Picture; +import android.graphics.drawable.PictureDrawable; + +/** + * Convert the {@link SVG}'s internal representation to an Android-compatible one ({@link Picture}). + */ +public class SvgDrawableTranscoder implements ResourceTranscoder { + @Override + public Resource transcode(Resource toTranscode) { + SVG svg = toTranscode.get(); + Picture picture = svg.renderToPicture(); + PictureDrawable drawable = new PictureDrawable(picture); + return new SimpleResource(drawable); + } + + @Override + public String getId() { + return ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/SvgSoftwareLayerSetter.java b/app/src/main/java/org/apache/taverna/mobile/utils/SvgSoftwareLayerSetter.java new file mode 100644 index 00000000..ea8de08e --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/SvgSoftwareLayerSetter.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.ImageViewTarget; +import com.bumptech.glide.request.target.Target; + +import android.annotation.TargetApi; +import android.graphics.drawable.PictureDrawable; +import android.os.Build; +import android.widget.ImageView; + +/** + * Listener which updates the {@link ImageView} to be software rendered, + * because {@link com.caverock.androidsvg.SVG SVG}/{@link android.graphics.Picture Picture} + * can't render on a hardware backed {@link android.graphics.Canvas Canvas}. + * + * @param not used, here to prevent unchecked warnings at usage + */ +@TargetApi(Build.VERSION_CODES.HONEYCOMB) +public class SvgSoftwareLayerSetter implements RequestListener { + + @Override + public boolean onException(Exception e, T model, Target target, + boolean isFirstResource) { + ImageView view = ((ImageViewTarget) target).getView(); + if (Build.VERSION_CODES.HONEYCOMB <= Build.VERSION.SDK_INT) { + view.setLayerType(ImageView.LAYER_TYPE_NONE, null); + } + return false; + } + + @Override + public boolean onResourceReady(PictureDrawable resource, T model + , Target target, boolean isFromMemoryCache, boolean isFirstResource) { + ImageView view = ((ImageViewTarget) target).getView(); + if (Build.VERSION_CODES.HONEYCOMB <= Build.VERSION.SDK_INT) { + view.setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null); + } + return false; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/WebViewGenerator.java b/app/src/main/java/org/apache/taverna/mobile/utils/WebViewGenerator.java new file mode 100644 index 00000000..79c4c0a3 --- /dev/null +++ b/app/src/main/java/org/apache/taverna/mobile/utils/WebViewGenerator.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.taverna.mobile.utils; + +import android.graphics.Bitmap; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.ProgressBar; + +import org.apache.taverna.mobile.R; + +public class WebViewGenerator extends Fragment { + + private ProgressBar progressBar; + + private WebView web; + + private String url; + + public static WebViewGenerator newInstance(String URL) { + + Bundle args = new Bundle(); + args.putString(Constants.ARGS_URL, URL); + WebViewGenerator fragment = new WebViewGenerator(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + url = getArguments().getString(Constants.ARGS_URL); + } + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle + savedInstanceState) { + View layout = inflater.inflate(R.layout.webviewgen, container, false); + + web = (WebView) layout.findViewById(R.id.webView); + + progressBar = (ProgressBar) layout.findViewById(R.id.progressBar); + + web.setWebViewClient(new WebClient()); + web.getSettings().setJavaScriptEnabled(true); + web.getSettings().setBuiltInZoomControls(true); + web.loadUrl(url); + web.canGoBack(); + return layout; + + } + + private void getServer() { + + } + + + public class WebClient extends WebViewClient { + + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + + super.onPageStarted(view, url, favicon); + + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + + progressBar.setVisibility(View.VISIBLE); + view.loadUrl(url); + return true; + + } + + @Override + public void onPageFinished(WebView view, String url) { + + super.onPageFinished(view, url); + + progressBar.setVisibility(View.GONE); + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowDataCallback.java b/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowDataCallback.java deleted file mode 100644 index a8fbbe56..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowDataCallback.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.apache.taverna.mobile.utils; - -import org.apache.taverna.mobile.tavernamobile.Workflow; - -import java.util.List; - -/** - * Callback for when data is ready to be put into the workflow adapter - * Created by root on 6/24/15. - */ -public interface WorkflowDataCallback { - - public void onWorkflowDataReady(List data); -} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowDownloadManager.java b/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowDownloadManager.java deleted file mode 100644 index 3c645ceb..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowDownloadManager.java +++ /dev/null @@ -1,110 +0,0 @@ -package org.apache.taverna.mobile.utils; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import android.app.DownloadManager; -import android.app.Notification; -import android.app.NotificationManager; -import android.content.Context; -import android.database.Cursor; -import android.media.RingtoneManager; -import android.net.Uri; -import android.support.v4.app.NotificationCompat; - -import org.apache.taverna.mobile.R; - -import java.io.File; - -/** - * Created by root on 6/11/15. - */ -public class WorkflowDownloadManager { - private DownloadManager downloadManager; - private Context context; - private boolean isDownloading; - - public WorkflowDownloadManager(Context ctx, DownloadManager downloadManager) { - this.context = ctx; - this.downloadManager = downloadManager; - this.isDownloading = false; - } - - public WorkflowDownloadManager(Context context) { - this.context = context; - this.downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); - this.isDownloading = false; - } - - /** - * Download the given workflow - * @param destination The destination file in which to save the downloaded file - */ - public void downloadWorkflow(File destination, String sourceurl) throws Exception{ - - DownloadManager.Query query = new DownloadManager.Query(); - query.setFilterByStatus(DownloadManager.STATUS_PAUSED| - DownloadManager.STATUS_PENDING| - DownloadManager.STATUS_RUNNING|DownloadManager.STATUS_FAILED| - DownloadManager.STATUS_SUCCESSFUL); - Cursor cur = this.downloadManager.query(query); - int col = cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME); - - for(cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) { - this.isDownloading = this.isDownloading || (destination.getName() == cur.getString(col)); - } - // cur.close(); - if (!this.isDownloading) { - Uri source = Uri.parse(sourceurl); - //extract the file name from the source url and append it to the workflow storage directory to be used to download the file into. - Uri destinationurl = Uri.withAppendedPath(Uri.fromFile(destination), Uri.parse(sourceurl).getLastPathSegment()); - - DownloadManager.Request request = new DownloadManager.Request(source); - request.setTitle("Workflow"); - request.setDescription("Downloading workflow"); - request.setDestinationUri(destinationurl); - request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED | - DownloadManager.Request.VISIBILITY_VISIBLE); - - long id = this.downloadManager.enqueue(request); - - if(id != 0) - sendNotification(this.context.getResources().getString(R.string.downloadprogress)); - cur.close(); - } - } - - public void sendNotification(String message){ - NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this.context); - notificationBuilder.setContentText(message) - .setContentTitle("Workflow Download") - .setSmallIcon(R.mipmap.ic_launcher) - .setAutoCancel(true) - .setVisibility(Notification.VISIBILITY_PUBLIC) - .setWhen(0) - .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); - Notification nf = notificationBuilder.build(); - NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.notify(1, nf); - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowLoader.java b/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowLoader.java deleted file mode 100644 index d4957de2..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowLoader.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.apache.taverna.mobile.utils; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import android.content.Context; -import android.os.AsyncTask; -import android.support.v4.widget.SwipeRefreshLayout; -import android.util.Log; - -import com.thebuzzmedia.sjxp.rule.IRule; - -import org.apache.taverna.mobile.tavernamobile.Workflow; -import org.apache.taverna.mobile.utils.xmlparsers.MyExperimentXmlParserRules; -import org.apache.taverna.mobile.utils.xmlparsers.WorkflowParser; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.ProtocolException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Larry Akah on 6/13/15. - */ -public class WorkflowLoader extends AsyncTask{ //WorkflowLoaderMain { - - private Context ctx; - private List userWorkflows; - private SwipeRefreshLayout refreshLayout; - - public WorkflowLoader(Context context, SwipeRefreshLayout sw) { - this.ctx = context; - this.refreshLayout = sw; - this.userWorkflows = new ArrayList(); - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - refreshLayout.setRefreshing(true); - } - - @Override - public List doInBackground(String[] pages) { - //start a network request to fetch user's workflows - - IRule wkflowRule = new MyExperimentXmlParserRules.WorkflowRule(IRule.Type.ATTRIBUTE, "/workflows/workflow", "resource", "uri","id", "version"); - IRule workflowNameRule = new MyExperimentXmlParserRules.WorkflowRule(IRule.Type.CHARACTER, "/workflows/workflow"); - WorkflowParser xmlParser = new WorkflowParser(new IRule[]{wkflowRule, workflowNameRule}); - try { - URL workflowurl = new URL("http://www.myexperiment.org/workflows.xml?page="+Integer.parseInt((pages[0]))); - HttpURLConnection connection = (HttpURLConnection) workflowurl.openConnection(); - connection.setRequestMethod("GET"); - connection.connect(); //send request - Log.i("WorkflowLoader","Loading workflows page = "+pages[0]); - - InputStream dis = connection.getInputStream(); - xmlParser.parse(dis, this.userWorkflows); - - }catch (MalformedURLException e) { - e.printStackTrace(); - } catch (ProtocolException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - }catch (Exception ex){ - ex.printStackTrace(); - } - return this.userWorkflows; - } - - @Override - protected void onPostExecute(Object o) { - refreshLayout.setRefreshing(false); - System.out.println("Workflow Count: "+this.userWorkflows.size()); - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowLoaderMain.java b/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowLoaderMain.java deleted file mode 100644 index 41c650d1..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowLoaderMain.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.apache.taverna.mobile.utils; -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import android.content.AsyncTaskLoader; -import android.content.Context; - -import org.apache.taverna.mobile.tavernamobile.Workflow; - -import java.util.List; - -/** - * Created by root on 6/23/15. - */ -public abstract class WorkflowLoaderMain extends AsyncTaskLoader> { - - public WorkflowLoaderMain(Context context) { - super(context); - } - - public abstract List loadInBackground(); - -} 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 deleted file mode 100644 index eae84791..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/WorkflowOpen.java +++ /dev/null @@ -1,291 +0,0 @@ -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 { - - private Context context; - private ProgressDialog progressDialog; - TavernaPlayerAPI tavernaPlayerAPI = new TavernaPlayerAPI(); - - 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 = tavernaPlayerAPI.getPlayerUserName(this.context) + ":" + tavernaPlayerAPI.getPlayerUserPassword(this.context); - 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{ - - 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 = tavernaPlayerAPI.getPlayerUserName(this.context) + ":" + tavernaPlayerAPI.getPlayerUserPassword(this.context); - 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 Message", "" + 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 ITEM_IDS; - private final String LIBTAG = getClass().getName(); - private JSONObject DBJSON; - private JSONObject dataobj; //hold all entries for a given ENTITY_KEY - - /** - * Constructor initializes a basic data store environment - * @param ctx a reference to the application's context or sand box - * @param entityKey The main data store key for each entity space/schema - */ - public Workflow_DB(Context ctx, String entityKey){ - context = ctx; - ENTITY_KEY = entityKey; - DBJSON = new JSONObject(); - ITEM_IDS = new ArrayList(); - dataobj = DBJSON; - } - - /** - * Inserts an entity set('row') into the data store - * @param items values for each 'column' in the entity - * @return the same instance for chaining multiple calls to this method. - * @throws org.json.JSONException - */ - public Workflow_DB put(ArrayList items) throws JSONException{ - - String item_id = this.generateRandomId(); - ITEM_IDS.add(item_id); - JSONArray jarray = new JSONArray(); - for(Object item: items){ - jarray.put(item); - } - dataobj.put(item_id, jarray); - return this; - } - - /** - * Returns all entity entries from the data store. Each item of an entity is accompanied with the key or unique id of the items. - * @author Larry Akah - * @throws org.json.JSONException for errors during construction of a JSON data string. - * @throws NullPointerException for any null accessed variable - */ - public List> get() throws JSONException , NullPointerException{ - msharedpreference = PreferenceManager.getDefaultSharedPreferences(context); - //read key and get existing data - List> results = new ArrayList>(); - JSONObject mainJson = new JSONObject(msharedpreference.getString(ENTITY_KEY, "{"+ENTITY_KEY+":{}}")); - - Log.i(ENTITY_KEY, mainJson.toString(2)); - - JSONArray keysJson = mainJson.getJSONArray("ids"); //retrieve a json array of ids for every entity entry - Log.i(ENTITY_KEY, keysJson.toString(2)); - - if(null != keysJson) - for(int i=0; i mlist = new ArrayList(); - if(null != resultArray) - for(int j=0; j newItem){ - boolean operationSucceeded = false; - - JSONArray jarray = new JSONArray(); - for(Object item: newItem){ - jarray.put(item); - } - try { - dataobj.put(itemId, jarray); //replace the current entry at the given ID. - Log.d(LIBTAG, ""+dataobj.toString(2)); - operationSucceeded = true; - } catch (JSONException e) { - e.printStackTrace(); - operationSucceeded = false; - }finally{ - return operationSucceeded; - } - } - - /** - * Updates all the items of a given entity - * @return the number of items successfully updated. - */ - public int updateAll(List> items){ - return 0; - } - - /** - * Gets an entry of an entity from the data store - * @author Larry Akah - * @param id The id of the item('row') in question to return - * @throws org.json.JSONException for errors during construction of a JSON data string. - * @throws NullPointerException for any null accessed variable - */ - public ArrayList get(String id) throws JSONException , NullPointerException{ - msharedpreference = PreferenceManager.getDefaultSharedPreferences(context); - //read key and get existing data - ArrayList results = new ArrayList(); - JSONObject mainJson = new JSONObject(msharedpreference.getString(ENTITY_KEY, ENTITY_KEY+":{}")); - - Log.i(ENTITY_KEY, mainJson.toString(2)); - - JSONArray keysJson = mainJson.getJSONArray("ids"); //retrieve a json array of ids for every entity entry - Log.i(ENTITY_KEY, keysJson.toString(2)); - - if(null != keysJson) - for(int i=0; i item){ - long start = System.currentTimeMillis(); - msharedpreference = PreferenceManager.getDefaultSharedPreferences(context); - try { - JSONObject jsonObject = new JSONObject(msharedpreference.getString(ENTITY_KEY, "{"+ENTITY_KEY+":{}}")); //main json db - System.out.println(jsonObject.toString(1)); - - JSONArray jsonArray; - if(jsonObject.has("ids")) - jsonArray = jsonObject.optJSONArray("ids"); - else - jsonArray = new JSONArray(); - - String newItemId = item.get(0).toString(); //use the workflow id as an entity key for the new entity - - //verify if this workflow item has already been marked as favorite - for(int k=0; k(){}); - ((Workflow)userObject).setWorkflow_tags(new ArrayList(){}); - - } - } - - /** - * parse workflows from myExperiment - */ - public final static class WorkflowRule extends DefaultRule{ - Workflow workflow; - List wlist; - static String uri,version,desc; - static String url=uri=version=desc=""; - static long id = 0; - - public WorkflowRule(Type type, String locationPath, String... attributeNames) throws IllegalArgumentException { - super(type, locationPath, attributeNames); - this.workflow = new Workflow(); - wlist = new ArrayList<>(); - } - //instantiated to parse xml data for a given workflow - public WorkflowRule(Type type, String path, int id, String attributenames){ - super(type,path,attributenames); - } - - @Override - public void handleParsedAttribute(XMLParser parser, int index, String value, Object userObject) { - - switch(index){ - case 0: - desc = "To view workflow on the web, click "+value; - break; - case 1: - uri = value; - break; - case 2: - id = Integer.parseInt(value); - break; - case 3: - version = value; - break; - } - } - - @Override - public void handleParsedCharacters(XMLParser parser, String text, Object workflowListObject) { - //add the workflow to the workflow list - this.workflow = new Workflow("", desc, id, url); - this.workflow.setWorkflow_details_url(uri); - this.workflow.setWorkflow_title(text); - this.workflow.setWorkflow_author(""); - wlist.add(this.workflow); - //WorkflowLoader.loadedWorkflows.add(this.workflow); - ((List)workflowListObject).add(this.workflow); - this.workflow = null; - } - } - -} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/xmlparsers/WorkflowDetailParser.java b/app/src/main/java/org/apache/taverna/mobile/utils/xmlparsers/WorkflowDetailParser.java deleted file mode 100644 index 906b99ed..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/xmlparsers/WorkflowDetailParser.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.apache.taverna.mobile.utils.xmlparsers; - -import com.thebuzzmedia.sjxp.XMLParser; -import com.thebuzzmedia.sjxp.XMLParserException; -import com.thebuzzmedia.sjxp.rule.IRule; - -import org.apache.taverna.mobile.fragments.WorkflowItemFragment; -import org.apache.taverna.mobile.fragments.workflowdetails.WorkflowdetailFragment; -import org.apache.taverna.mobile.tavernamobile.User; -import org.apache.taverna.mobile.tavernamobile.Workflow; - -/** - * Apache Taverna Mobile - * Copyright 2015 The Apache Software Foundation - - * This product includes software developed at - * The Apache Software Foundation (http://www.apache.org/). - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * Parse details from the xml output of myexperiment API - * Created by Larry Akah on 6/24/15. - */ -public class WorkflowDetailParser extends XMLParser { - - public WorkflowDetailParser(IRule[] rules) throws IllegalArgumentException, XMLParserException { - super(rules); - } - - //deliver results when parsing has completed and all the information required has been retrieved - @Override - protected void doEndDocument(Object userObject) { - if(userObject instanceof User){ - WorkflowItemFragment.startLoadingAvatar((User) userObject); - }else - WorkflowdetailFragment.setWorkflowDetails((Workflow) userObject); - } -} diff --git a/app/src/main/java/org/apache/taverna/mobile/utils/xmlparsers/WorkflowParser.java b/app/src/main/java/org/apache/taverna/mobile/utils/xmlparsers/WorkflowParser.java deleted file mode 100644 index f92837c0..00000000 --- a/app/src/main/java/org/apache/taverna/mobile/utils/xmlparsers/WorkflowParser.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.apache.taverna.mobile.utils.xmlparsers; - -import com.thebuzzmedia.sjxp.XMLParser; -import com.thebuzzmedia.sjxp.XMLParserException; -import com.thebuzzmedia.sjxp.rule.IRule; - -import org.apache.taverna.mobile.fragments.WorkflowItemFragment; -import org.apache.taverna.mobile.tavernamobile.Workflow; - -import java.util.List; - -/** - * Workflow end document class for detecting when the complete list of workflows have been read out - * Created by Larry Akah on 6/24/15. - */ - -public class WorkflowParser extends XMLParser { - - public WorkflowParser(IRule[] rules) throws IllegalArgumentException, XMLParserException { - super(rules); - } - - @Override - protected void doEndDocument(Object userObject) { - WorkflowItemFragment.updateWorkflowUI((List) userObject); - } -} diff --git a/app/src/main/res/anim/zoomin.xml b/app/src/main/res/anim/zoomin.xml index e36b7739..71d2e79d 100644 --- a/app/src/main/res/anim/zoomin.xml +++ b/app/src/main/res/anim/zoomin.xml @@ -1,4 +1,28 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/download.jpg b/app/src/main/res/drawable/download.jpg old mode 100755 new mode 100644 diff --git a/app/src/main/res/drawable/ic_account_circle_black_24dp.xml b/app/src/main/res/drawable/ic_account_circle_black_24dp.xml new file mode 100644 index 00000000..c1c8b395 --- /dev/null +++ b/app/src/main/res/drawable/ic_account_circle_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_email_black_24dp.xml b/app/src/main/res/drawable/ic_email_black_24dp.xml new file mode 100644 index 00000000..873cf780 --- /dev/null +++ b/app/src/main/res/drawable/ic_email_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_right_black_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_right_black_24dp.xml new file mode 100644 index 00000000..1b2b8917 --- /dev/null +++ b/app/src/main/res/drawable/ic_keyboard_arrow_right_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_language_black_24dp.xml b/app/src/main/res/drawable/ic_language_black_24dp.xml new file mode 100644 index 00000000..554ad735 --- /dev/null +++ b/app/src/main/res/drawable/ic_language_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_location_city_black_24dp.xml b/app/src/main/res/drawable/ic_location_city_black_24dp.xml new file mode 100644 index 00000000..20a40e5a --- /dev/null +++ b/app/src/main/res/drawable/ic_location_city_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_location_on_black_24dp.xml b/app/src/main/res/drawable/ic_location_on_black_24dp.xml new file mode 100644 index 00000000..2abc6ce4 --- /dev/null +++ b/app/src/main/res/drawable/ic_location_on_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_lock_black_24dp.xml b/app/src/main/res/drawable/ic_lock_black_24dp.xml new file mode 100644 index 00000000..50fbb6ee --- /dev/null +++ b/app/src/main/res/drawable/ic_lock_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_person_black_24dp.xml b/app/src/main/res/drawable/ic_person_black_24dp.xml new file mode 100644 index 00000000..8cb959c2 --- /dev/null +++ b/app/src/main/res/drawable/ic_person_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_search_black_24dp.xml b/app/src/main/res/drawable/ic_search_black_24dp.xml new file mode 100644 index 00000000..16cd84fb --- /dev/null +++ b/app/src/main/res/drawable/ic_search_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_star_black_24dp.xml b/app/src/main/res/drawable/ic_star_black_24dp.xml new file mode 100644 index 00000000..3876469b --- /dev/null +++ b/app/src/main/res/drawable/ic_star_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_star_border_black_24dp.xml b/app/src/main/res/drawable/ic_star_border_black_24dp.xml new file mode 100644 index 00000000..3111dff0 --- /dev/null +++ b/app/src/main/res/drawable/ic_star_border_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_stars_grey_24dp.xml b/app/src/main/res/drawable/ic_stars_grey_24dp.xml new file mode 100644 index 00000000..cb0e5f84 --- /dev/null +++ b/app/src/main/res/drawable/ic_stars_grey_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_storage_black_24dp.xml b/app/src/main/res/drawable/ic_storage_black_24dp.xml new file mode 100644 index 00000000..3d22780b --- /dev/null +++ b/app/src/main/res/drawable/ic_storage_black_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/ic_storage_grey_24dp.xml b/app/src/main/res/drawable/ic_storage_grey_24dp.xml new file mode 100644 index 00000000..24de6931 --- /dev/null +++ b/app/src/main/res/drawable/ic_storage_grey_24dp.xml @@ -0,0 +1,25 @@ + + + + diff --git a/app/src/main/res/drawable/login_button.xml b/app/src/main/res/drawable/login_button.xml new file mode 100644 index 00000000..1f1b9996 --- /dev/null +++ b/app/src/main/res/drawable/login_button.xml @@ -0,0 +1,24 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/myexlogo.png b/app/src/main/res/drawable/myexlogo.png new file mode 100644 index 00000000..a9d953eb Binary files /dev/null and b/app/src/main/res/drawable/myexlogo.png differ diff --git a/app/src/main/res/drawable/nav_header.png b/app/src/main/res/drawable/nav_header.png new file mode 100644 index 00000000..312c5b51 Binary files /dev/null and b/app/src/main/res/drawable/nav_header.png differ diff --git a/app/src/main/res/drawable/placeholder.png b/app/src/main/res/drawable/placeholder.png new file mode 100644 index 00000000..ebe206ff Binary files /dev/null and b/app/src/main/res/drawable/placeholder.png differ diff --git a/app/src/main/res/drawable/round_shape.xml b/app/src/main/res/drawable/round_shape.xml index 491b4386..bc0a756e 100755 --- a/app/src/main/res/drawable/round_shape.xml +++ b/app/src/main/res/drawable/round_shape.xml @@ -1,4 +1,28 @@ + diff --git a/app/src/main/res/layout-land/activity_dashboard_main.xml b/app/src/main/res/layout-land/activity_dashboard_main.xml index fec870c4..efcc201f 100644 --- a/app/src/main/res/layout-land/activity_dashboard_main.xml +++ b/app/src/main/res/layout-land/activity_dashboard_main.xml @@ -15,7 +15,6 @@ limitations under the License. + + diff --git a/app/src/main/res/layout-xlarge/fragment_login.xml b/app/src/main/res/layout-xlarge/fragment_login.xml deleted file mode 100644 index fb2d564a..00000000 --- a/app/src/main/res/layout-xlarge/fragment_login.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/about.xml b/app/src/main/res/layout/about.xml index 1d1e77c5..858ec0f7 100644 --- a/app/src/main/res/layout/about.xml +++ b/app/src/main/res/layout/about.xml @@ -15,6 +15,7 @@ limitations under the License. --> + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/drawer_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" +> - + + + - + - - - + diff --git a/app/src/main/res/layout/activity_detail_workflow.xml b/app/src/main/res/layout/activity_detail_workflow.xml new file mode 100644 index 00000000..2edac672 --- /dev/null +++ b/app/src/main/res/layout/activity_detail_workflow.xml @@ -0,0 +1,32 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_favourite_workflows.xml b/app/src/main/res/layout/activity_favourite_workflows.xml new file mode 100644 index 00000000..4dbe6b7f --- /dev/null +++ b/app/src/main/res/layout/activity_favourite_workflows.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_flash_screen.xml b/app/src/main/res/layout/activity_flash_screen.xml index 51594d10..b06ff27a 100644 --- a/app/src/main/res/layout/activity_flash_screen.xml +++ b/app/src/main/res/layout/activity_flash_screen.xml @@ -18,52 +18,44 @@ limitations under the License. android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" - tools:context="org.apache.taverna.mobile.activities.FlashScreenActivity"> + tools:context=".ui.FlashScreenActivity"> + android:textSize="@dimen/title_text_size" /> + android:layout_above="@+id/tvFooter" /> diff --git a/app/src/main/res/layout/activity_image_zoom.xml b/app/src/main/res/layout/activity_image_zoom.xml new file mode 100644 index 00000000..889e3963 --- /dev/null +++ b/app/src/main/res/layout/activity_image_zoom.xml @@ -0,0 +1,30 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index ae7a3339..fcc1eb32 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -1,18 +1,24 @@ + - + diff --git a/app/src/main/res/layout/activity_my_workflows.xml b/app/src/main/res/layout/activity_my_workflows.xml new file mode 100644 index 00000000..4dbe6b7f --- /dev/null +++ b/app/src/main/res/layout/activity_my_workflows.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_run_result.xml b/app/src/main/res/layout/activity_run_result.xml deleted file mode 100644 index 027aa673..00000000 --- a/app/src/main/res/layout/activity_run_result.xml +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/app/src/main/res/layout/activity_tutorial.xml b/app/src/main/res/layout/activity_tutorial.xml new file mode 100644 index 00000000..22d59ff0 --- /dev/null +++ b/app/src/main/res/layout/activity_tutorial.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_usage.xml b/app/src/main/res/layout/activity_usage.xml new file mode 100644 index 00000000..ad2800c7 --- /dev/null +++ b/app/src/main/res/layout/activity_usage.xml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_user_profile.xml b/app/src/main/res/layout/activity_user_profile.xml new file mode 100644 index 00000000..1c42c377 --- /dev/null +++ b/app/src/main/res/layout/activity_user_profile.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/activity_workflow_detail.xml b/app/src/main/res/layout/activity_workflow_detail.xml deleted file mode 100644 index 56edf112..00000000 --- a/app/src/main/res/layout/activity_workflow_detail.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - diff --git a/app/src/main/res/values-sw600dp/strings.xml b/app/src/main/res/layout/activity_workflow_run.xml similarity index 60% rename from app/src/main/res/values-sw600dp/strings.xml rename to app/src/main/res/layout/activity_workflow_run.xml index acbb78f1..cf4fea9b 100644 --- a/app/src/main/res/values-sw600dp/strings.xml +++ b/app/src/main/res/layout/activity_workflow_run.xml @@ -18,8 +18,22 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - - Powered By Apache Taverna - When the app is started you are initially prompted with an accounts page to login. Use Your myExperiment account to login. You will need to configure a Taverna player account in the settings when you have successfully logged-in to the app. you can also choose to remain logged-in or not from the login page. - Usage | Dashboard - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/appbar.xml b/app/src/main/res/layout/appbar.xml new file mode 100644 index 00000000..29776a14 --- /dev/null +++ b/app/src/main/res/layout/appbar.xml @@ -0,0 +1,28 @@ + + + + diff --git a/app/src/main/res/layout/dialog_licence_detail_workflow.xml b/app/src/main/res/layout/dialog_licence_detail_workflow.xml new file mode 100644 index 00000000..33de8f78 --- /dev/null +++ b/app/src/main/res/layout/dialog_licence_detail_workflow.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/favorite_item_layout.xml b/app/src/main/res/layout/favorite_item_layout.xml deleted file mode 100644 index 0c9cf3eb..00000000 --- a/app/src/main/res/layout/favorite_item_layout.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_announcement.xml b/app/src/main/res/layout/fragment_announcement.xml index 335a1b83..93fee6ed 100644 --- a/app/src/main/res/layout/fragment_announcement.xml +++ b/app/src/main/res/layout/fragment_announcement.xml @@ -17,18 +17,8 @@ --> - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_dashboard_main.xml b/app/src/main/res/layout/fragment_dashboard_main.xml deleted file mode 100644 index 32081e6a..00000000 --- a/app/src/main/res/layout/fragment_dashboard_main.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_detail_workflow.xml b/app/src/main/res/layout/fragment_detail_workflow.xml new file mode 100644 index 00000000..dd984ff2 --- /dev/null +++ b/app/src/main/res/layout/fragment_detail_workflow.xml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_workflow_run_history.xml b/app/src/main/res/layout/fragment_downloading.xml similarity index 53% rename from app/src/main/res/layout/fragment_workflow_run_history.xml rename to app/src/main/res/layout/fragment_downloading.xml index b1d075f4..55589460 100644 --- a/app/src/main/res/layout/fragment_workflow_run_history.xml +++ b/app/src/main/res/layout/fragment_downloading.xml @@ -1,3 +1,4 @@ + - + - - - + android:layout_centerInParent="true"/> - - + android:layout_centerHorizontal="true" + android:layout_marginTop="10dp" + android:textSize="20sp"/> + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_favourite_workflow_list.xml b/app/src/main/res/layout/fragment_favourite_workflow_list.xml new file mode 100644 index 00000000..6537c397 --- /dev/null +++ b/app/src/main/res/layout/fragment_favourite_workflow_list.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_image_zoom.xml b/app/src/main/res/layout/fragment_image_zoom.xml new file mode 100644 index 00000000..4f278357 --- /dev/null +++ b/app/src/main/res/layout/fragment_image_zoom.xml @@ -0,0 +1,37 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_item_grid.xml b/app/src/main/res/layout/fragment_item_grid.xml deleted file mode 100644 index 6ba0ef02..00000000 --- a/app/src/main/res/layout/fragment_item_grid.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_item_list.xml b/app/src/main/res/layout/fragment_item_list.xml deleted file mode 100644 index 0acec8ce..00000000 --- a/app/src/main/res/layout/fragment_item_list.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_licence.xml b/app/src/main/res/layout/fragment_licence.xml new file mode 100644 index 00000000..df783206 --- /dev/null +++ b/app/src/main/res/layout/fragment_licence.xml @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_licence_list.xml b/app/src/main/res/layout/fragment_licence_list.xml new file mode 100644 index 00000000..098f23ea --- /dev/null +++ b/app/src/main/res/layout/fragment_licence_list.xml @@ -0,0 +1,29 @@ + + + diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml index 37ebb53f..bb3b9b44 100644 --- a/app/src/main/res/layout/fragment_login.xml +++ b/app/src/main/res/layout/fragment_login.xml @@ -1,150 +1,169 @@ + - - - - - - + + - - + android:paddingBottom="@dimen/activity_vertical_margin" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin"> - + + android:layout_below="@+id/logo" + android:typeface="serif" + android:layout_centerHorizontal="true" + android:layout_marginTop="@dimen/app_name_text_margin" + android:text="@string/app_name" + android:textSize="@dimen/text_size" /> - + android:layout_below="@+id/tvAppName" + android:layout_centerInParent="true" + android:layout_marginTop="@dimen/login_layout_marginTop" + android:orientation="vertical" + android:padding="@dimen/login_layout_padding"> - + - + - + - - + + + + + + + + + + + + + + + + + + android:layout_height="wrap_content" + android:gravity="center" + android:layout_gravity="center" + android:textAlignment="center" + android:textSize="@dimen/disc_text_size" + android:text="@string/disclaimer_title" + android:layout_marginTop="@dimen/disc_margin_top"/> + + - - + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_player_login_layout.xml b/app/src/main/res/layout/fragment_player_login_layout.xml new file mode 100644 index 00000000..594fb6fb --- /dev/null +++ b/app/src/main/res/layout/fragment_player_login_layout.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_run_result.xml b/app/src/main/res/layout/fragment_run_result.xml deleted file mode 100644 index 78b3a0d4..00000000 --- a/app/src/main/res/layout/fragment_run_result.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_user_profile.xml b/app/src/main/res/layout/fragment_user_profile.xml new file mode 100644 index 00000000..af19b7d7 --- /dev/null +++ b/app/src/main/res/layout/fragment_user_profile.xml @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_workflow_about.xml b/app/src/main/res/layout/fragment_workflow_about.xml deleted file mode 100644 index fb78aed7..00000000 --- a/app/src/main/res/layout/fragment_workflow_about.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - diff --git a/app/src/main/res/layout/fragment_workflow_detail.xml b/app/src/main/res/layout/fragment_workflow_detail.xml deleted file mode 100644 index 8016f443..00000000 --- a/app/src/main/res/layout/fragment_workflow_detail.xml +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_workflow_licence.xml b/app/src/main/res/layout/fragment_workflow_licence.xml deleted file mode 100644 index 9b15538c..00000000 --- a/app/src/main/res/layout/fragment_workflow_licence.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/layout/item_recyclerview.xml b/app/src/main/res/layout/item_announcement.xml similarity index 52% rename from app/src/main/res/layout/item_recyclerview.xml rename to app/src/main/res/layout/item_announcement.xml index 23f33890..7e7b0cda 100644 --- a/app/src/main/res/layout/item_recyclerview.xml +++ b/app/src/main/res/layout/item_announcement.xml @@ -16,38 +16,44 @@ limitations under the License. --> + app:cardElevation="2pt"> + - - + android:orientation="horizontal"> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_progressbar.xml b/app/src/main/res/layout/item_progressbar.xml index 8498971f..66345107 100644 --- a/app/src/main/res/layout/item_progressbar.xml +++ b/app/src/main/res/layout/item_progressbar.xml @@ -17,7 +17,7 @@ --> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_workflow_dashboard.xml b/app/src/main/res/layout/item_workflow_dashboard.xml new file mode 100644 index 00000000..a9699d60 --- /dev/null +++ b/app/src/main/res/layout/item_workflow_dashboard.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/menu_item_layout.xml b/app/src/main/res/layout/menu_item_layout.xml deleted file mode 100644 index 08c28f8c..00000000 --- a/app/src/main/res/layout/menu_item_layout.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/nav_header.xml b/app/src/main/res/layout/nav_header.xml index e31a6870..ebefb1dd 100644 --- a/app/src/main/res/layout/nav_header.xml +++ b/app/src/main/res/layout/nav_header.xml @@ -1,35 +1,65 @@ + + + + android:layout_alignParentBottom="true" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" + android:layout_marginBottom="@dimen/layout_marginBottom"> - - + android:layout_marginLeft="@dimen/tv_layout_marginLeft" + android:textColor="@color/white" + android:text="@string/username" + android:textSize="@dimen/tv_textSize" + android:textStyle="bold"/> + + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_slide1.xml b/app/src/main/res/layout/tutorial_slide1.xml new file mode 100644 index 00000000..5e0518a8 --- /dev/null +++ b/app/src/main/res/layout/tutorial_slide1.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_slide2.xml b/app/src/main/res/layout/tutorial_slide2.xml new file mode 100644 index 00000000..83575f96 --- /dev/null +++ b/app/src/main/res/layout/tutorial_slide2.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_slide3.xml b/app/src/main/res/layout/tutorial_slide3.xml new file mode 100644 index 00000000..8ffe369e --- /dev/null +++ b/app/src/main/res/layout/tutorial_slide3.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/tutorial_slide4.xml b/app/src/main/res/layout/tutorial_slide4.xml new file mode 100644 index 00000000..b331d08c --- /dev/null +++ b/app/src/main/res/layout/tutorial_slide4.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/usage_layout.xml b/app/src/main/res/layout/usage_layout.xml deleted file mode 100644 index 0a960c10..00000000 --- a/app/src/main/res/layout/usage_layout.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/viewpager_workflow.xml b/app/src/main/res/layout/viewpager_workflow.xml deleted file mode 100644 index a8b72c0d..00000000 --- a/app/src/main/res/layout/viewpager_workflow.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/workflow_layout.xml b/app/src/main/res/layout/webviewgen.xml similarity index 72% rename from app/src/main/res/layout/workflow_layout.xml rename to app/src/main/res/layout/webviewgen.xml index 6bc31604..d7adfb3e 100644 --- a/app/src/main/res/layout/workflow_layout.xml +++ b/app/src/main/res/layout/webviewgen.xml @@ -18,19 +18,22 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - - - + android:id="@+id/webView" + /> + + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/workflow_item_layout.xml b/app/src/main/res/layout/workflow_item_layout.xml deleted file mode 100644 index 01fee20d..00000000 --- a/app/src/main/res/layout/workflow_item_layout.xml +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/workflow_run_item.xml b/app/src/main/res/layout/workflow_run_item.xml deleted file mode 100644 index ce05d85b..00000000 --- a/app/src/main/res/layout/workflow_run_item.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/dashboard_main.xml b/app/src/main/res/menu/dashboard_main.xml index d272ee76..256f6f49 100644 --- a/app/src/main/res/menu/dashboard_main.xml +++ b/app/src/main/res/menu/dashboard_main.xml @@ -20,11 +20,11 @@ limitations under the License. + tools:context="org.apache.taverna.mobile.ui.DashboardActivity"> diff --git a/app/src/main/res/menu/drawer_view.xml b/app/src/main/res/menu/drawer_view.xml index f56e06db..58e2eadb 100644 --- a/app/src/main/res/menu/drawer_view.xml +++ b/app/src/main/res/menu/drawer_view.xml @@ -1,50 +1,67 @@ + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/menu_workflow_detail.xml b/app/src/main/res/menu/menu_workflow_detail.xml index ac1714e7..2f537466 100644 --- a/app/src/main/res/menu/menu_workflow_detail.xml +++ b/app/src/main/res/menu/menu_workflow_detail.xml @@ -1,7 +1,26 @@ + + - + xmlns:app="http://schemas.android.com/apk/res-auto" + > + diff --git a/app/src/main/res/menu/run_result.xml b/app/src/main/res/menu/run_result.xml deleted file mode 100644 index e10c15a2..00000000 --- a/app/src/main/res/menu/run_result.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - diff --git a/app/src/main/res/mipmap-hdpi/icuserprofiles.png b/app/src/main/res/mipmap-hdpi/ic_user_profiles.png similarity index 100% rename from app/src/main/res/mipmap-hdpi/icuserprofiles.png rename to app/src/main/res/mipmap-hdpi/ic_user_profiles.png diff --git a/app/src/main/res/mipmap-mdpi/icuserprofiles.png b/app/src/main/res/mipmap-mdpi/ic_user_profiles.png similarity index 100% rename from app/src/main/res/mipmap-mdpi/icuserprofiles.png rename to app/src/main/res/mipmap-mdpi/ic_user_profiles.png diff --git a/app/src/main/res/mipmap-xhdpi/icuserprofiles.png b/app/src/main/res/mipmap-xhdpi/ic_user_profiles.png similarity index 100% rename from app/src/main/res/mipmap-xhdpi/icuserprofiles.png rename to app/src/main/res/mipmap-xhdpi/ic_user_profiles.png diff --git a/app/src/main/res/mipmap-xxhdpi/icuserprofiles.png b/app/src/main/res/mipmap-xxhdpi/ic_user_profiles.png similarity index 100% rename from app/src/main/res/mipmap-xxhdpi/icuserprofiles.png rename to app/src/main/res/mipmap-xxhdpi/ic_user_profiles.png diff --git a/app/src/main/res/mipmap-xxxhdpi/icuserprofiles.png b/app/src/main/res/mipmap-xxxhdpi/ic_user_profiles.png similarity index 100% rename from app/src/main/res/mipmap-xxxhdpi/icuserprofiles.png rename to app/src/main/res/mipmap-xxxhdpi/ic_user_profiles.png diff --git a/app/src/main/res/values-large/strings.xml b/app/src/main/res/values-large/strings.xml deleted file mode 100644 index 04157a78..00000000 --- a/app/src/main/res/values-large/strings.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - Powered By Apache Taverna - Run - When the app is started you are initially prompted with an accounts page to login. Use Your myExperiment account to login. You will need to configure a Taverna player account in the settings when you have successfully logged-in to the app. you can also choose to remain logged-in or not from the login page. - Usage | Dashboard - Once logged-in to the app, a stream of workflows appears as a stream from which you could view, mark workflows for offline viewing. There are two tabs on the dashboard, the second tab presents a list of marked workflows. there is a menu button the pulls out a navigation drawer menu from the left corner of the dashboard. You can also swipe finger from the extreme left of the screen to pull out the menu. Scrolling to the bottom of the workflow screen will load more workflows. You can pull down to refresh workflows for the initial workflow list. the search bar is used to fetch amongst currently loaded workflows. - Usage | Menus - - The navigation drawer brings up a menu. The workflow menu item allows one to quickly return to the workflow streams page from any screen. The \'Open Workflow\' item allows users to pick a valid workflow from external storage and run it against a Taverna Server through a Taverna Player. Settings allow user to configure player accounts and portal urls. Logout allows users to log-out of the app - Usage | Workfow Detail - The details screen allows users to run particular worklows and provides detailed information about the workflows. Workflows can also be downloaded from here. Workflows can also be marked from this screen which would save much more data for offline use than on the dashboard screen. This screen also provides a set of runs for the workflow from other users - - \ No newline at end of file diff --git a/app/src/main/res/values-v21/ids.xml b/app/src/main/res/values-v21/ids.xml new file mode 100644 index 00000000..2ea3fc54 --- /dev/null +++ b/app/src/main/res/values-v21/ids.xml @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml index f29eb74e..ac242bff 100644 --- a/app/src/main/res/values-v21/styles.xml +++ b/app/src/main/res/values-v21/styles.xml @@ -23,4 +23,8 @@ + + diff --git a/app/src/main/res/values-w820dp/strings.xml b/app/src/main/res/values-w820dp/strings.xml deleted file mode 100644 index 0abd9c2e..00000000 --- a/app/src/main/res/values-w820dp/strings.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - Powered By Apache Taverna - When the app is started you are initially prompted with an accounts page to login. Use Your myExperiment account to login. You will need to configure a Taverna player account in the settings when you have successfully logged-in to the app. you can also choose to remain logged-in or not from the login page. - Usage | Dashboard - The navigation drawer brings up a menu. The workflow menu item allows one to quickly return to the workflow streams page from any screen. The \'Open Workflow\' item allows users to pick a valid workflow from external storage and run it against a Taverna Server through a Taverna Player. Settings allow user to configure player accounts and portal urls. Logout allows users to log-out of the app - Usage | Workfow Detail - The details screen allows users to run particular worklows and provides detailed information about the workflows. Workflows can also be downloaded from here. Workflows can also be marked from this screen which would save much more data for offline use than on the dashboard screen. This screen also provides a set of runs for the workflow from other users - \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 1b5c1315..cf8f4726 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,8 +1,96 @@ + + #000000 #2196F3 #2196F3 #FF4081 #FFF5F5F5 #e0e0e0 + #EE2196F3 + #e0e0e0 + #ffff + + + #ff33b5e5 + + #33999999 + + #BB666666 + + #ff99cc00 + + #ffff4444 + + #ff0099cc + + #ff669900 + + #ffcc0000 + + #ffaa66cc + + #ffffbb33 + + #ffff8800 + + #ff00ddff + + #33CCCCCC + + + + @color/blue_light + @color/green_light + @color/red_light + @color/orange_light + + + + #f64c73 + #20d2bb + #3395ff + #3395ff + + + #d1395c + #14a895 + #2278d4 + #2278d4 + + + #f98da5 + #8cf9eb + #93c6fd + #93c6fd + + + @color/dot_light_screen1 + @color/dot_light_screen2 + @color/dot_light_screen3 + @color/dot_light_screen4 + + + + @color/dot_dark_screen1 + @color/dot_dark_screen2 + @color/dot_dark_screen3 + @color/dot_dark_screen4 + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 20dc8476..cc2063fe 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -16,12 +16,137 @@ limitations under the License. 16dp 16dp - 0dp - 10dp - 8dp + 0dp + 10dp + 8dp + + + 5dp + 200dp + 5dp + 1dp + 250dp + 16sp + 3dp + 16sp + 3dp + 14sp + 3dp + 14sp + 3dp + + + 5dp + 4dp + + + 25sp + 3sp + 45sp + 10sp + 10sp + 10sp + 13sp + 10sp + 10sp + 10sp + + + 300dp + 1sp + 55dp + 55dp + 16dp + -27dp + 0sp + 10sp + 20sp + 75dp + 5sp + 50sp + 50sp + 10sp + 0sp + 50sp + 10sp + 10sp + 18sp + 4dp + 10sp + 0sp + 10sp + 0sp + 15sp + 5sp + 10sp + 10sp + 10sp + 5sp + 2sp + 15sp - 240dp 3dp + 16dp + 16dp + 8dp + 25sp + 20dp + 15dp + 7dp + 50dp + 20sp + 20dp + 8dp + 10dp + 12dp + 40sp + 40dp + 5dp + 10dp + + 2dp + 50dp + 50dp + 30dp + 70dp + 70dp + 80dp + + + 25sp + 130sp + 15sp + + + 30dp + 20dp + 120dp + 30dp + 16dp + 40dp + 20dp + 1dp + + + 170dp + 90dp + 20dp + 5dp + 10dp + 15dp + 15dp + 10dp + 13dp + 20dp + + + 170dp + 10dp + 16dp + 14sp + 70dp + 10dp + 55dp + diff --git a/app/src/main/res/values/refs.xml b/app/src/main/res/values/refs.xml deleted file mode 100644 index 5315aa89..00000000 --- a/app/src/main/res/values/refs.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - @layout/fragment_item_list - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9633b0a5..02b958ce 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -13,47 +13,62 @@ See the License for the specific language governing permissions and limitations under the License. --> + Version: + Licence: + Apache Licence/Notice: + Taverna Mobile - Empty + Empty Settings Taverna Mobile Powered By MyExperiment - Usage + Usage Quit - Date Created + Date Created Date Modified Date Last Run - About Workflow - Login to your Account (MyExperiment) + About Workflow + Login Email or Username Password - Login + Login Dashboard + No More Announcement Available + Failed to fetch announcement + OK + - Favorites Workflows Usage - About + Profile + About Logout - Open Workflow Search Example action - Powered by Apache Taverna - Search workflows by name + Powered by + Apache Taverna + + Search workflows by name Download View Favorite - Workflow Author + Workflow Author Workflow component - No Favorites Added Yet - No Workflows Available. Pull down to refresh (or check your internet connection) - Workflows History empty. No runs have been created for this workflow + No Favorites Added Yet + No + Workflows + Available. Pull down to refresh (or check your internet connection) + + + Workflows History + empty. No runs have been created for this workflow + TITLE Marked On Type: %1$s @@ -64,50 +79,186 @@ limitations under the License. Workflow Detail - Workflow + Workflow Run History Licence | Policy - About + About Create Run - Unable to fetch latest workflows. Please check your network connection - + Unable to fetch latest workflows. Please check your network + connection + + Download Failed. Please try again Workflow download in progress - Unable to start Download. Please check your internet connection + Unable to start Download. Please check your internet connection + Already Downloading - download complete - More Info &raquo + download complete + More Info &raquo Loading details Loading Workflows - Fetching run components + Fetching run components Remain Logged-in - + Create a myExperiment account + Username must not be empty Password must not be empty v1.0 - Mobile Application for managing Taverna workflows.\n\nCopyright © 2015–2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. + Mobile Application for managing Taverna workflows.\n\nCopyright © 2015–2019 + The Apache Software Foundation, Licensed under the Apache License, Version 2.0. + View, run and download workflows on your Android mobile device. - Originally developed during Google Summer of Code 2015 for the Apache Taverna project. - Configure Player Account - Username used to login to Taverna player portal - Username/email - Password + Originally developed during Google Summer of Code 2015 for theApache Taverna project. + + Configure Player Account + Username used to login to Taverna player portal + Username/email + Password + Username/email Server error. Please try again later Invalid login credentials - Configure MyExperiment Account - Username used to login to MyExperiment + Configure MyExperiment Account + Username used to login to MyExperiment Workflow Run Result Run Started Run finish Time Usage | Login - When the app is started you are initially prompted with an accounts page to login. Use Your myExperiment account to login. You will need to configure a Taverna player account in the settings when you have successfully logged-in to the app. you can also choose to remain logged-in or not from the login page. + When the app is started you are initially prompted with an + accounts page to login. Use Your myExperiment account to login. You will need to configure a + Taverna player account in the settings when you have successfully logged-in to the app. you + can also choose to remain logged-in or not from the login page. + Usage | Dashboard - Once logged-in to the app, a stream of workflows appears as a stream from which you could view, mark workflows for offline viewing. There are two tabs on the dashboard, the second tab presents a list of marked workflows. there is a menu button the pulls out a navigation drawer menu from the left corner of the dashboard. You can also swipe finger from the extreme left of the screen to pull out the menu. Scrolling to the bottom of the workflow screen will load more workflows. You can pull down to refresh workflows for the initial workflow list. the search bar is used to fetch amongst currently loaded workflows. + Once logged-in to the app, a stream of workflows appears as + a stream from which you could view, mark workflows for offline viewing. There are two tabs + on the dashboard, the second tab presents a list of marked workflows. there is a menu button + the pulls out a navigation drawer menu from the left corner of the dashboard. You can also + swipe finger from the extreme left of the screen to pull out the menu. Scrolling to the + bottom of the workflow screen will load more workflows. You can pull down to refresh + workflows for the initial workflow list. the search bar is used to fetch amongst currently + loaded workflows. + Usage | Menus - The navigation drawer brings up a menu. The workflow menu item allows one to quickly return to the workflow streams page from any screen. The \'Open Workflow\' item allows users to pick a valid workflow from external storage and run it against a Taverna Server through a Taverna Player. Settings allow user to configure player accounts and portal urls. Logout allows users to log-out of the app + The navigation drawer brings up a menu. The workflow menu item + allows one to quickly return to the workflow streams page from any screen. The \'Open + Workflow\' item allows users to pick a valid workflow from external storage and run it + against a Taverna Server through a Taverna Player. Settings allow user to configure player + accounts and portal urls. Logout allows users to log-out of the app. + Usage | Workfow Detail - The details screen allows users to run particular worklows and provides detailed information about the workflows. Workflows can also be downloaded from here. Workflows can also be marked from this screen which would save much more data for offline use than on the dashboard screen. This screen also provides a set of runs for the workflow from other users + The details screen allows users to run particular worklows and + provides detailed information about the workflows. Workflows can also be downloaded from + here. Workflows can also be marked from this screen which would save much more data for + offline use than on the dashboard screen. This screen also provides a set of runs for the + workflow from other users. + Workflow Run ID: Announcementss + No Internet Connection + Licence + No Favourite Workflow Found ! + Image Zoom + Email or Username + Email + Password + Login Button + Enter valid email + Enter valid password + Failed to fetch Workflow + No more workflows avialable + No Workflows Found + + You have not created any workflow yet ! + Please enter valid credential + Taverna 2 + + + + Player \nLogin + Download + Upload + Inputs &\nRun + + + Downloading Workflow + Uploading Workflow + Please Wait ... + Taverna Player Portal Login + Login + Sign Out + Sign Out + Do you really want to sign out? + + Settings + + + + General + + + pref_logged_in + Remain Logged-in + Decide whether or not to be automatically logged-in when the app starts + + + http://heater.cs.man.ac.uk:3000/ + Configure Taverna player portal + Configure a different player URL for the app to use. End with the mount point(/) + + + http://heater.cs.man.ac.uk:8090/ + Configure Taverna Server + Configure a different Taverna Server for the app + + + All Workflows + Favourite Workflows + Announcement + Settings + Logout + Usage + About + My Workflows + Licence info + Apache Licence/Notice + + + No matching criteria workflow found + + pref_player_url + pref_key_player_user + pref_key_player_password + Taverna Player Password + pref_myexperimentuser + pref_myexperimentpass + Myexperiment password + + + Disclaimer: + myExperiment\'s Logo is nothing to do with Apache Taverna and is copyright to myExperiment + + NEXT + SKIP + GOT IT + + Login + Dashboard + Workflow + Menus + + + Username + Email + + + <NA> + Username + Email + Website + City + Country + My Workflow + Favorite Workflows + diff --git a/app/src/main/res/values/strings_activity_settings.xml b/app/src/main/res/values/strings_activity_settings.xml deleted file mode 100644 index 8779506f..00000000 --- a/app/src/main/res/values/strings_activity_settings.xml +++ /dev/null @@ -1,22 +0,0 @@ - - Settings - - - - - General - - - Remain Logged-in - Decide whether or not to be automatically logged-in when the app starts - - http://heater.cs.man.ac.uk:3000/ - Configure Taverna player portal - Configure a different player URL for the app to use. End with the mount point(/) - - - http://heater.cs.man.ac.uk:8090/ - Configure Taverna Server - Configure a different Taverna Server for the app - - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index cea7952f..61989a84 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -22,6 +22,7 @@ limitations under the License. @color/colorPrimaryDark @color/colorAccent @color/window_background + @style/PreferenceThemeOverlay.v14.Material +