diff --git a/README.md b/README.md index 12a71f5..2b847cf 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,19 @@ - + -# Learning RxJava 2 for Android by example +# RxJava 2 for Android +### How to +* Clone repo +* Clone https://github.com/businesstek/Fast-Android-Networking +* From RxJava2 Android Studio "File/New Module/Import Gradle Project" +* Only select modules "android-networking" and "rx2-android-networking" +* Add both modules to app module dependency +* Note: original fork had network bug in gradle.properties +* Note: ApiUser and UserDetail models are the same. Why? +* Note: added toast for feedback for networking +* Replace 6 calls in NetworkingActivity with your own node herokuapp to handle the REST calls. Sample index.js is included in assets folder -[![Mindorks](https://img.shields.io/badge/mindorks-opensource-blue.svg)](https://mindorks.com/open-source-projects) -[![Mindorks Community](https://img.shields.io/badge/join-community-blue.svg)](https://mindorks.com/join-community) -[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-RxJava2%20Android%20Samples-blue.svg?style=flat)](https://android-arsenal.com/details/3/4314) -[![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=102)](https://opensource.org/licenses/Apache-2.0) -[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/LICENSE) -## How to use RxJava 2 in Android Application -## How to migrate from RxJava 1.0 to RxJava 2.0 - -### This project is for : -* who is migrating to RxJava 2 -* or just started with RxJava. - -### Just Build the project and start learning RxJava by examples. +### Built to learn RxJava2 RxJava 2.0 has been completely rewritten from scratch on top of the Reactive-Streams specification. The specification itself has evolved out of RxJava 1.x and provides a common baseline for reactive systems and libraries. @@ -84,69 +82,23 @@ RxJava1 -> RxJava2 # Highlights of the examples : -* [DisposableExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/DisposableExampleActivity.java) - Using `CompositeDisposable` -* [FlowableExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/FlowableExampleActivity.java) - Using `Flowable` and `reduce` operator -* [SingleObserverExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/SingleObserverExampleActivity.java) - Using `SingleObserver` -* [CompletableObserverActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/CompletableObserverExampleActivity.java) - Using `CompletableObserver` -* [MapExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/MapExampleActivity.java) - Using `map` Operator -* [ZipExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/ZipExampleActivity.java) - Using `zip` Operator -* [BufferExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/BufferExampleActivity.java) - Using `buffer` Operator -* [TakeExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/TakeExampleActivity.java) - Using `take` Operator -* [ReduceExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReduceExampleActivity.java) - Using `reduce` Operator -* [FilterExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/FilterExampleActivity.java) - Using `filter` Operator -* [SkipExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/SkipExampleActivity.java) - Using `skip` Operator -* [ReplayExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplayExampleActivity.java) - Using `replay` Operator -* [ConcatExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/ConcatExampleActivity.java) - Using `concat` Operator -* [MergeExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/MergeExampleActivity.java) - Using `merge` Operator -* [DeferExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/DeferExampleActivity.java) - Using `defer` Observable -* [IntervalExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/IntervalExampleActivity.java) - Using `Interval` -* [RxBusActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBusActivity.java) - RxBus, RxJava2Bus, EventBus, RxEventBus -* [PaginationActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationActivity.java) - Pagination for loadMore in RecyclerView -* [ComposeOperatorExampleActivity](https://github.com/amitshekhariitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/compose/ComposeOperatorExampleActivity.java) - Compose operator for reusable - -### TODO - -* Many examples are to be added - -### Find this project useful ? :heart: -* Support it by clicking the :star: button on the upper right of this page. :v: - -### Check out an awesome MVP architecture based project which uses RxJava2, Dagger2. -* [Android-MVP-Architecture](https://github.com/MindorksOpenSource/android-mvp-architecture) - -### Check out an awesome library for fast and simple networking in Android. -* [Fast Android Networking Library](https://github.com/amitshekhariitbhu/Fast-Android-Networking) - -### Another awesome library for debugging databases and shared preferences. -* [Android Debug Database](https://github.com/amitshekhariitbhu/Android-Debug-Database) - -### [Check out Mindorks awesome open source projects here](https://mindorks.com/open-source-projects) - -### Contact - Let's become friend -- [Twitter](https://twitter.com/amitiitbhu) -- [Github](https://github.com/amitshekhariitbhu) -- [Medium](https://medium.com/@amitshekhar) -- [Facebook](https://www.facebook.com/amit.shekhar.iitbhu) - -### License -``` - Copyright (C) 2016 Amit Shekhar - Copyright (C) 2011 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. -``` - -### Contributing to RxJava 2 Android Samples -Just make pull request. You are in! +* [DisposableExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/DisposableExampleActivity.java) - Using `CompositeDisposable` +* [FlowableExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/FlowableExampleActivity.java) - Using `Flowable` and `reduce` operator +* [SingleObserverExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/SingleObserverExampleActivity.java) - Using `SingleObserver` +* [CompletableObserverActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/CompletableObserverExampleActivity.java) - Using `CompletableObserver` +* [MapExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/MapExampleActivity.java) - Using `map` Operator +* [ZipExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/ZipExampleActivity.java) - Using `zip` Operator +* [BufferExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/BufferExampleActivity.java) - Using `buffer` Operator +* [TakeExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/TakeExampleActivity.java) - Using `take` Operator +* [ReduceExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReduceExampleActivity.java) - Using `reduce` Operator +* [FilterExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/FilterExampleActivity.java) - Using `filter` Operator +* [SkipExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/SkipExampleActivity.java) - Using `skip` Operator +* [ReplayExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplayExampleActivity.java) - Using `replay` Operator +* [ConcatExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/ConcatExampleActivity.java) - Using `concat` Operator +* [MergeExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/MergeExampleActivity.java) - Using `merge` Operator +* [DeferExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/DeferExampleActivity.java) - Using `defer` Observable +* [IntervalExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/operators/IntervalExampleActivity.java) - Using `Interval` +* [RxBusActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBusActivity.java) - RxBus, RxJava2Bus, EventBus, RxEventBus +* [PaginationActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationActivity.java) - Pagination for loadMore in RecyclerView +* [ComposeOperatorExampleActivity](https://github.com/owneriitbhu/RxJava2-Android-Samples/blob/master/app/src/main/java/com/rxjava2/android/samples/ui/compose/ComposeOperatorExampleActivity.java) - Compose operator for reusable - diff --git a/android-networking/.gitignore b/android-networking/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/android-networking/.gitignore @@ -0,0 +1 @@ +/build diff --git a/android-networking/build.gradle b/android-networking/build.gradle new file mode 100644 index 0000000..3b327c1 --- /dev/null +++ b/android-networking/build.gradle @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 23 + buildToolsVersion '25.0.0' + + defaultConfig { + minSdkVersion 9 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + consumerProguardFiles 'proguard-rules.pro' + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + testCompile 'junit:junit:4.12' + androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.6.0' + compile 'com.squareup.okhttp3:okhttp:3.6.0' + compile 'com.google.code.gson:gson:2.8.0' +} +//apply from: 'upload.gradle' \ No newline at end of file diff --git a/android-networking/proguard-rules.pro b/android-networking/proguard-rules.pro new file mode 100644 index 0000000..c88a38b --- /dev/null +++ b/android-networking/proguard-rules.pro @@ -0,0 +1,20 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/owner/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# For OkHttp +-dontwarn okio.** diff --git a/android-networking/src/androidTest/AndroidManifest.xml b/android-networking/src/androidTest/AndroidManifest.xml new file mode 100755 index 0000000..944071c --- /dev/null +++ b/android-networking/src/androidTest/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/android-networking/src/androidTest/java/com/androidnetworking/GetJSONApiTest.java b/android-networking/src/androidTest/java/com/androidnetworking/GetJSONApiTest.java new file mode 100644 index 0000000..cab349d --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/GetJSONApiTest.java @@ -0,0 +1,469 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.JSONArrayRequestListener; +import com.androidnetworking.interfaces.JSONObjectRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndJSONArrayRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndJSONObjectRequestListener; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Rule; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import okhttp3.Response; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 03/04/17. + */ + +public class GetJSONApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public GetJSONApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testJSONObjectGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsJSONObject(new JSONObjectRequestListener() { + @Override + public void onResponse(JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONObjectGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsJSONObject(new JSONObjectRequestListener() { + @Override + public void onResponse(JSONObject response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testJSONArrayGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsJSONArray(new JSONArrayRequestListener() { + @Override + public void onResponse(JSONArray response) { + try { + JSONObject jsonObject = response.getJSONObject(0); + firstNameRef.set(jsonObject.getString("firstName")); + lastNameRef.set(jsonObject.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONArrayGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsJSONArray(new JSONArrayRequestListener() { + @Override + public void onResponse(JSONArray response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONObjectGetRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForJSONObject(); + + assertEquals("Amit", response.getResult().getString("firstName")); + + assertEquals("Shekhar", response.getResult().getString("lastName")); + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONObjectGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForJSONObject(); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONArrayGetRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForJSONArray(); + + JSONObject jsonObject = response.getResult().getJSONObject(0); + + assertEquals("Amit", jsonObject.getString("firstName")); + + assertEquals("Shekhar", jsonObject.getString("lastName")); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONArrayGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForJSONArray(); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + public void testResponseBodyAndJSONObjectGet() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndJSONObjectGet404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONObject response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testResponseBodyAndJSONArrayGet() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONArray(new OkHttpResponseAndJSONArrayRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONArray response) { + try { + JSONObject jsonObject = response.getJSONObject(0); + firstNameRef.set(jsonObject.getString("firstName")); + lastNameRef.set(jsonObject.getString("lastName")); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndJSONArrayGet404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONArray(new OkHttpResponseAndJSONArrayRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONArray response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testHeaderGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference headerRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .addHeaders("headerKey", "headerValue") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + headerRef.set(okHttpResponse.request().header("headerKey")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + assertEquals("headerValue", headerRef.get()); + } + +} \ No newline at end of file diff --git a/android-networking/src/androidTest/java/com/androidnetworking/GetObjectApiTest.java b/android-networking/src/androidTest/java/com/androidnetworking/GetObjectApiTest.java new file mode 100644 index 0000000..8409ab2 --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/GetObjectApiTest.java @@ -0,0 +1,450 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.OkHttpResponseAndParsedRequestListener; +import com.androidnetworking.interfaces.ParsedRequestListener; +import com.androidnetworking.model.User; + +import org.json.JSONException; +import org.junit.Rule; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import okhttp3.Response; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 10/04/17. + */ + +public class GetObjectApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public GetObjectApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testObjectGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsObject(User.class, new ParsedRequestListener() { + @Override + public void onResponse(User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsObject(User.class, new ParsedRequestListener() { + @Override + public void onResponse(User user) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testObjectListGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsObjectList(User.class, new ParsedRequestListener>() { + @Override + public void onResponse(List userList) { + firstNameRef.set(userList.get(0).firstName); + lastNameRef.set(userList.get(0).lastName); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectListGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsObjectList(User.class, new ParsedRequestListener>() { + @Override + public void onResponse(List userList) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectGetRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForObject(User.class); + + assertEquals("Amit", response.getResult().firstName); + + assertEquals("Shekhar", response.getResult().lastName); + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForObject(User.class); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectListGetRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse> response = request.executeForObjectList(User.class); + + User user = response.getResult().get(0); + + assertEquals("Amit", user.firstName); + + assertEquals("Shekhar", user.lastName); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectListGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse> response = request.executeForObjectList(User.class); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + public void testResponseBodyAndObjectGet() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObject(User.class, + new OkHttpResponseAndParsedRequestListener() { + @Override + public void onResponse(Response okHttpResponse, User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndObjectGet404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObject(User.class, + new OkHttpResponseAndParsedRequestListener() { + @Override + public void onResponse(Response okHttpResponse, User user) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testResponseBodyAndObjectListGet() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObjectList(User.class, + new OkHttpResponseAndParsedRequestListener>() { + @Override + public void onResponse(Response okHttpResponse, List userList) { + firstNameRef.set(userList.get(0).firstName); + lastNameRef.set(userList.get(0).lastName); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndObjectListGet404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObjectList(User.class, + new OkHttpResponseAndParsedRequestListener>() { + @Override + public void onResponse(Response okHttpResponse, List userList) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testHeaderGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference headerRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .addHeaders("headerKey", "headerValue") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObject(User.class, + new OkHttpResponseAndParsedRequestListener() { + @Override + public void onResponse(Response okHttpResponse, User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + headerRef.set(okHttpResponse.request().header("headerKey")); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + assertEquals("headerValue", headerRef.get()); + } + +} diff --git a/android-networking/src/androidTest/java/com/androidnetworking/GetStringApiTest.java b/android-networking/src/androidTest/java/com/androidnetworking/GetStringApiTest.java new file mode 100644 index 0000000..aaef6fe --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/GetStringApiTest.java @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.OkHttpResponseAndStringRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseListener; +import com.androidnetworking.interfaces.StringRequestListener; + +import org.junit.Rule; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import okhttp3.Response; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +public class GetStringApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public GetStringApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testStringGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsString(new StringRequestListener() { + @Override + public void onResponse(String response) { + responseRef.set(response); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("data", responseRef.get()); + } + + public void testStringGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .build() + .getAsString(new StringRequestListener() { + @Override + public void onResponse(String response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousStringGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForString(); + + assertEquals("data", response.getResult()); + } + + @SuppressWarnings("unchecked") + public void testSynchronousStringGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForString(); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + } + + public void testResponseBodyGet() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponse(new OkHttpResponseListener() { + @Override + public void onResponse(Response response) { + try { + responseRef.set(response.body().string()); + latch.countDown(); + } catch (IOException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("data", responseRef.get()); + } + + public void testResponseBodyGet404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponse(new OkHttpResponseListener() { + @Override + public void onResponse(Response response) { + try { + errorBodyRef.set(response.body().string()); + errorCodeRef.set(response.code()); + latch.countDown(); + } catch (IOException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + @SuppressWarnings("unchecked") + public void testSyncResponseBodyGet() throws InterruptedException, IOException { + + server.enqueue(new MockResponse().setBody("data")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForOkHttpResponse(); + + assertEquals("data", response.getResult().body().string()); + + } + + @SuppressWarnings("unchecked") + public void testSyncResponseBodyGet404() throws InterruptedException, IOException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.get(server.url("/").toString()).build(); + + ANResponse response = request.executeForOkHttpResponse(); + + assertEquals("data", response.getResult().body().string()); + + assertEquals(404, response.getResult().code()); + } + + public void testResponseBodyAndStringGet() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final AtomicReference responseStringRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndString(new OkHttpResponseAndStringRequestListener() { + @Override + public void onResponse(Response okHttpResponse, String response) { + responseBodySuccess.set(okHttpResponse.isSuccessful()); + responseStringRef.set(response); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("data", responseStringRef.get()); + } + + public void testResponseBodyAndStringGet404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndString(new OkHttpResponseAndStringRequestListener() { + @Override + public void onResponse(Response okHttpResponse, String response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testHeaderGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final AtomicReference headerRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.get(server.url("/").toString()) + .addHeaders("headerKey", "headerValue") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndString(new OkHttpResponseAndStringRequestListener() { + @Override + public void onResponse(Response okHttpResponse, String response) { + responseRef.set(response); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + headerRef.set(okHttpResponse.request().header("headerKey")); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("data", responseRef.get()); + assertEquals("headerValue", headerRef.get()); + } +} \ No newline at end of file diff --git a/android-networking/src/androidTest/java/com/androidnetworking/MultipartJSONApiTest.java b/android-networking/src/androidTest/java/com/androidnetworking/MultipartJSONApiTest.java new file mode 100644 index 0000000..de2cc93 --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/MultipartJSONApiTest.java @@ -0,0 +1,487 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.JSONArrayRequestListener; +import com.androidnetworking.interfaces.JSONObjectRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndJSONArrayRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndJSONObjectRequestListener; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Rule; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import okhttp3.Response; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 09/04/17. + */ + +public class MultipartJSONApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public MultipartJSONApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testJSONObjectMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsJSONObject(new JSONObjectRequestListener() { + @Override + public void onResponse(JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONObjectMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsJSONObject(new JSONObjectRequestListener() { + @Override + public void onResponse(JSONObject response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testJSONArrayMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsJSONArray(new JSONArrayRequestListener() { + @Override + public void onResponse(JSONArray response) { + try { + JSONObject jsonObject = response.getJSONObject(0); + firstNameRef.set(jsonObject.getString("firstName")); + lastNameRef.set(jsonObject.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONArrayMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsJSONArray(new JSONArrayRequestListener() { + @Override + public void onResponse(JSONArray response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONObjectMultipartRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForJSONObject(); + + assertEquals("Amit", response.getResult().getString("firstName")); + + assertEquals("Shekhar", response.getResult().getString("lastName")); + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONObjectMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForJSONObject(); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONArrayMultipartRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForJSONArray(); + + JSONObject jsonObject = response.getResult().getJSONObject(0); + + assertEquals("Amit", jsonObject.getString("firstName")); + + assertEquals("Shekhar", jsonObject.getString("lastName")); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONArrayMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForJSONArray(); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + public void testResponseBodyAndJSONObjectMultipart() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndJSONObjectMultipart404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONObject response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testResponseBodyAndJSONArrayMultipart() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONArray(new OkHttpResponseAndJSONArrayRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONArray response) { + try { + JSONObject jsonObject = response.getJSONObject(0); + firstNameRef.set(jsonObject.getString("firstName")); + lastNameRef.set(jsonObject.getString("lastName")); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndJSONArrayMultipart404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONArray(new OkHttpResponseAndJSONArrayRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONArray response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testHeaderMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference headerRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addHeaders("headerKey", "headerValue") + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + headerRef.set(okHttpResponse.request().header("headerKey")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + assertEquals("headerValue", headerRef.get()); + } + + +} diff --git a/android-networking/src/androidTest/java/com/androidnetworking/MultipartObjectApiTest.java b/android-networking/src/androidTest/java/com/androidnetworking/MultipartObjectApiTest.java new file mode 100644 index 0000000..021c244 --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/MultipartObjectApiTest.java @@ -0,0 +1,467 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.OkHttpResponseAndParsedRequestListener; +import com.androidnetworking.interfaces.ParsedRequestListener; +import com.androidnetworking.model.User; + +import org.json.JSONException; +import org.junit.Rule; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import okhttp3.Response; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 12/04/17. + */ + +public class MultipartObjectApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public MultipartObjectApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testObjectMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsObject(User.class, new ParsedRequestListener() { + @Override + public void onResponse(User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsObject(User.class, new ParsedRequestListener() { + @Override + public void onResponse(User user) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testObjectListMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsObjectList(User.class, new ParsedRequestListener>() { + @Override + public void onResponse(List userList) { + firstNameRef.set(userList.get(0).firstName); + lastNameRef.set(userList.get(0).lastName); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectListMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsObjectList(User.class, new ParsedRequestListener>() { + @Override + public void onResponse(List userList) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectMultipartRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForObject(User.class); + + assertEquals("Amit", response.getResult().firstName); + + assertEquals("Shekhar", response.getResult().lastName); + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForObject(User.class); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectListMultipartRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse> response = request.executeForObjectList(User.class); + + User user = response.getResult().get(0); + + assertEquals("Amit", user.firstName); + + assertEquals("Shekhar", user.lastName); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectListMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse> response = request.executeForObjectList(User.class); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + public void testResponseBodyAndObjectMultipart() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObject(User.class, + new OkHttpResponseAndParsedRequestListener() { + @Override + public void onResponse(Response okHttpResponse, User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndObjectMultipart404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObject(User.class, + new OkHttpResponseAndParsedRequestListener() { + @Override + public void onResponse(Response okHttpResponse, User user) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testResponseBodyAndObjectListMultipart() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObjectList(User.class, + new OkHttpResponseAndParsedRequestListener>() { + @Override + public void onResponse(Response okHttpResponse, List userList) { + firstNameRef.set(userList.get(0).firstName); + lastNameRef.set(userList.get(0).lastName); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndObjectListMultipart404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObjectList(User.class, + new OkHttpResponseAndParsedRequestListener>() { + @Override + public void onResponse(Response okHttpResponse, List userList) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testHeaderMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference headerRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addHeaders("headerKey", "headerValue") + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObject(User.class, + new OkHttpResponseAndParsedRequestListener() { + @Override + public void onResponse(Response okHttpResponse, User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + headerRef.set(okHttpResponse.request().header("headerKey")); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + assertEquals("headerValue", headerRef.get()); + } + +} diff --git a/android-networking/src/androidTest/java/com/androidnetworking/MultipartStringApiTest.java b/android-networking/src/androidTest/java/com/androidnetworking/MultipartStringApiTest.java new file mode 100644 index 0000000..30402bf --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/MultipartStringApiTest.java @@ -0,0 +1,371 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.OkHttpResponseAndParsedRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndStringRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseListener; +import com.androidnetworking.interfaces.StringRequestListener; +import com.androidnetworking.model.User; + +import org.junit.Rule; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import okhttp3.Response; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 27/03/17. + */ + +public class MultipartStringApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public MultipartStringApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testStringMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsString(new StringRequestListener() { + @Override + public void onResponse(String response) { + responseRef.set(response); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("data", responseRef.get()); + } + + public void testStringMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getAsString(new StringRequestListener() { + @Override + public void onResponse(String response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + @SuppressWarnings("unchecked") + public void testSynchronousStringMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForString(); + + assertEquals("data", response.getResult()); + } + + @SuppressWarnings("unchecked") + public void testSynchronousMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForString(); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + } + + public void testResponseBodyMultipart() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponse(new OkHttpResponseListener() { + @Override + public void onResponse(Response response) { + try { + responseRef.set(response.body().string()); + latch.countDown(); + } catch (IOException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("data", responseRef.get()); + } + + public void testResponseBodyMultipart404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponse(new OkHttpResponseListener() { + @Override + public void onResponse(Response response) { + try { + errorBodyRef.set(response.body().string()); + errorCodeRef.set(response.code()); + latch.countDown(); + } catch (IOException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + @SuppressWarnings("unchecked") + public void testSyncResponseBodyMultipart() throws InterruptedException, IOException { + + server.enqueue(new MockResponse().setBody("data")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForOkHttpResponse(); + + assertEquals("data", response.getResult().body().string()); + + } + + @SuppressWarnings("unchecked") + public void testSyncResponseBodyMultipart404() throws InterruptedException, IOException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build(); + + ANResponse response = request.executeForOkHttpResponse(); + + assertEquals("data", response.getResult().body().string()); + + assertEquals(404, response.getResult().code()); + } + + public void testResponseBodyAndStringMultipart() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final AtomicReference responseStringRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndString(new OkHttpResponseAndStringRequestListener() { + @Override + public void onResponse(Response okHttpResponse, String response) { + responseBodySuccess.set(okHttpResponse.isSuccessful()); + responseStringRef.set(response); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("data", responseStringRef.get()); + } + + public void testResponseBodyAndStringMultipart404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndString(new OkHttpResponseAndStringRequestListener() { + @Override + public void onResponse(Response okHttpResponse, String response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testHeaderMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final AtomicReference headerRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.upload(server.url("/").toString()) + .addHeaders("headerKey", "headerValue") + .addMultipartParameter("key", "value") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndString(new OkHttpResponseAndStringRequestListener() { + @Override + public void onResponse(Response okHttpResponse, String response) { + responseRef.set(response); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + headerRef.set(okHttpResponse.request().header("headerKey")); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("data", responseRef.get()); + assertEquals("headerValue", headerRef.get()); + } + +} \ No newline at end of file diff --git a/android-networking/src/androidTest/java/com/androidnetworking/PostJSONApiTest.java b/android-networking/src/androidTest/java/com/androidnetworking/PostJSONApiTest.java new file mode 100644 index 0000000..c546b6a --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/PostJSONApiTest.java @@ -0,0 +1,499 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.JSONArrayRequestListener; +import com.androidnetworking.interfaces.JSONObjectRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndJSONArrayRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndJSONObjectRequestListener; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Rule; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import okhttp3.Response; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 06/04/17. + */ + +public class PostJSONApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public PostJSONApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testJSONObjectPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsJSONObject(new JSONObjectRequestListener() { + @Override + public void onResponse(JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONObjectPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsJSONObject(new JSONObjectRequestListener() { + @Override + public void onResponse(JSONObject response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testJSONArrayPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsJSONArray(new JSONArrayRequestListener() { + @Override + public void onResponse(JSONArray response) { + try { + JSONObject jsonObject = response.getJSONObject(0); + firstNameRef.set(jsonObject.getString("firstName")); + lastNameRef.set(jsonObject.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONArrayPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsJSONArray(new JSONArrayRequestListener() { + @Override + public void onResponse(JSONArray response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONObjectPostRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForJSONObject(); + + assertEquals("Amit", response.getResult().getString("firstName")); + + assertEquals("Shekhar", response.getResult().getString("lastName")); + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONObjectPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForJSONObject(); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONArrayPostRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForJSONArray(); + + JSONObject jsonObject = response.getResult().getJSONObject(0); + + assertEquals("Amit", jsonObject.getString("firstName")); + + assertEquals("Shekhar", jsonObject.getString("lastName")); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousJSONArrayPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForJSONArray(); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + public void testResponseBodyAndJSONObjectPost() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndJSONObjectPost404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONObject response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testResponseBodyAndJSONArrayPost() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONArray(new OkHttpResponseAndJSONArrayRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONArray response) { + try { + JSONObject jsonObject = response.getJSONObject(0); + firstNameRef.set(jsonObject.getString("firstName")); + lastNameRef.set(jsonObject.getString("lastName")); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndJSONArrayPost404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONArray(new OkHttpResponseAndJSONArrayRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONArray response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testHeaderPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference headerRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addHeaders("headerKey", "headerValue") + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndJSONObject(new OkHttpResponseAndJSONObjectRequestListener() { + @Override + public void onResponse(Response okHttpResponse, JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + headerRef.set(okHttpResponse.request().header("headerKey")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + assertEquals("headerValue", headerRef.get()); + } + +} diff --git a/android-networking/src/androidTest/java/com/androidnetworking/PostObjectApiTest.java b/android-networking/src/androidTest/java/com/androidnetworking/PostObjectApiTest.java new file mode 100644 index 0000000..49a07b2 --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/PostObjectApiTest.java @@ -0,0 +1,480 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.OkHttpResponseAndParsedRequestListener; +import com.androidnetworking.interfaces.ParsedRequestListener; +import com.androidnetworking.model.User; + +import org.json.JSONException; +import org.junit.Rule; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import okhttp3.Response; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 11/04/17. + */ + +public class PostObjectApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public PostObjectApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testObjectPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsObject(User.class, new ParsedRequestListener() { + @Override + public void onResponse(User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsObject(User.class, new ParsedRequestListener() { + @Override + public void onResponse(User user) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testObjectListPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsObjectList(User.class, new ParsedRequestListener>() { + @Override + public void onResponse(List userList) { + firstNameRef.set(userList.get(0).firstName); + lastNameRef.set(userList.get(0).lastName); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectListPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsObjectList(User.class, new ParsedRequestListener>() { + @Override + public void onResponse(List userList) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectPostRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForObject(User.class); + + assertEquals("Amit", response.getResult().firstName); + + assertEquals("Shekhar", response.getResult().lastName); + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForObject(User.class); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectListPostRequest() throws InterruptedException, JSONException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse> response = request.executeForObjectList(User.class); + + User user = response.getResult().get(0); + + assertEquals("Amit", user.firstName); + + assertEquals("Shekhar", user.lastName); + + } + + @SuppressWarnings("unchecked") + public void testSynchronousObjectListPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse> response = request.executeForObjectList(User.class); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + + } + + public void testResponseBodyAndObjectPost() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObject(User.class, + new OkHttpResponseAndParsedRequestListener() { + @Override + public void onResponse(Response okHttpResponse, User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndObjectPost404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObject(User.class, + new OkHttpResponseAndParsedRequestListener() { + @Override + public void onResponse(Response okHttpResponse, User user) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testResponseBodyAndObjectListPost() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObjectList(User.class, + new OkHttpResponseAndParsedRequestListener>() { + @Override + public void onResponse(Response okHttpResponse, List userList) { + firstNameRef.set(userList.get(0).firstName); + lastNameRef.set(userList.get(0).lastName); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testResponseBodyAndObjectListPost404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObjectList(User.class, + new OkHttpResponseAndParsedRequestListener>() { + @Override + public void onResponse(Response okHttpResponse, List userList) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testHeaderPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference headerRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addHeaders("headerKey", "headerValue") + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndObject(User.class, + new OkHttpResponseAndParsedRequestListener() { + @Override + public void onResponse(Response okHttpResponse, User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + headerRef.set(okHttpResponse.request().header("headerKey")); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + assertEquals("headerValue", headerRef.get()); + } + +} diff --git a/android-networking/src/androidTest/java/com/androidnetworking/PostStringApiTest.java b/android-networking/src/androidTest/java/com/androidnetworking/PostStringApiTest.java new file mode 100644 index 0000000..c931be6 --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/PostStringApiTest.java @@ -0,0 +1,381 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.OkHttpResponseAndStringRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseListener; +import com.androidnetworking.interfaces.StringRequestListener; + +import org.junit.Rule; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicReference; + +import okhttp3.Response; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 25/03/17. + */ + +public class PostStringApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public PostStringApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testStringPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsString(new StringRequestListener() { + @Override + public void onResponse(String response) { + responseRef.set(response); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("data", responseRef.get()); + } + + + public void testStringPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getAsString(new StringRequestListener() { + @Override + public void onResponse(String response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + @SuppressWarnings("unchecked") + public void testSynchronousStringPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForString(); + + assertEquals("data", response.getResult()); + } + + @SuppressWarnings("unchecked") + public void testSynchronousStringPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForString(); + + ANError error = response.getError(); + + assertEquals("data", error.getErrorBody()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, error.getErrorDetail()); + + assertEquals(404, error.getErrorCode()); + } + + public void testResponseBodyPost() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponse(new OkHttpResponseListener() { + @Override + public void onResponse(Response response) { + try { + responseRef.set(response.body().string()); + latch.countDown(); + } catch (IOException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("data", responseRef.get()); + } + + public void testResponseBodyPost404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponse(new OkHttpResponseListener() { + @Override + public void onResponse(Response response) { + try { + errorBodyRef.set(response.body().string()); + errorCodeRef.set(response.code()); + latch.countDown(); + } catch (IOException e) { + assertTrue(false); + } + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + @SuppressWarnings("unchecked") + public void testSyncResponseBodyPost() throws InterruptedException, IOException { + + server.enqueue(new MockResponse().setBody("data")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForOkHttpResponse(); + + assertEquals("data", response.getResult().body().string()); + + } + + @SuppressWarnings("unchecked") + public void testSyncResponseBodyPost404() throws InterruptedException, IOException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + ANRequest request = AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build(); + + ANResponse response = request.executeForOkHttpResponse(); + + assertEquals("data", response.getResult().body().string()); + + assertEquals(404, response.getResult().code()); + } + + public void testResponseBodyAndStringPost() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final AtomicReference responseStringRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndString(new OkHttpResponseAndStringRequestListener() { + @Override + public void onResponse(Response okHttpResponse, String response) { + responseBodySuccess.set(okHttpResponse.isSuccessful()); + responseStringRef.set(response); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("data", responseStringRef.get()); + } + + public void testResponseBodyAndStringPost404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference errorDetailRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndString(new OkHttpResponseAndStringRequestListener() { + @Override + public void onResponse(Response okHttpResponse, String response) { + assertTrue(false); + } + + @Override + public void onError(ANError anError) { + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + } + + public void testHeaderPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final AtomicReference headerRef = new AtomicReference<>(); + final AtomicReference responseBodySuccess = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + AndroidNetworking.post(server.url("/").toString()) + .addHeaders("headerKey", "headerValue") + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .setExecutor(Executors.newSingleThreadExecutor()) + .build() + .getAsOkHttpResponseAndString(new OkHttpResponseAndStringRequestListener() { + @Override + public void onResponse(Response okHttpResponse, String response) { + responseRef.set(response); + responseBodySuccess.set(okHttpResponse.isSuccessful()); + headerRef.set(okHttpResponse.request().header("headerKey")); + latch.countDown(); + } + + @Override + public void onError(ANError anError) { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(responseBodySuccess.get()); + assertEquals("data", responseRef.get()); + assertEquals("headerValue", headerRef.get()); + } + +} diff --git a/android-networking/src/androidTest/java/com/androidnetworking/model/User.java b/android-networking/src/androidTest/java/com/androidnetworking/model/User.java new file mode 100644 index 0000000..a078877 --- /dev/null +++ b/android-networking/src/androidTest/java/com/androidnetworking/model/User.java @@ -0,0 +1,31 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.model; + +/** + * Created by owner on 10/04/17. + */ + +public class User { + + public String firstName; + public String lastName; + +} diff --git a/android-networking/src/main/AndroidManifest.xml b/android-networking/src/main/AndroidManifest.xml new file mode 100644 index 0000000..3986b22 --- /dev/null +++ b/android-networking/src/main/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + diff --git a/android-networking/src/main/java/com/androidnetworking/AndroidNetworking.java b/android-networking/src/main/java/com/androidnetworking/AndroidNetworking.java new file mode 100644 index 0000000..e532cc9 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/AndroidNetworking.java @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking; + +import android.content.Context; +import android.graphics.BitmapFactory; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ConnectionClassManager; +import com.androidnetworking.common.ConnectionQuality; +import com.androidnetworking.interceptors.HttpLoggingInterceptor.Level; +import com.androidnetworking.core.Core; +import com.androidnetworking.interfaces.ConnectionQualityChangeListener; +import com.androidnetworking.interfaces.Parser; +import com.androidnetworking.internal.ANImageLoader; +import com.androidnetworking.internal.ANRequestQueue; +import com.androidnetworking.internal.InternalNetworking; +import com.androidnetworking.utils.ParseUtil; +import com.androidnetworking.utils.Utils; + +import okhttp3.OkHttpClient; + +/** + * Created by owner on 24/03/16. + */ + +/** + * AndroidNetworking entry point. + * You must initialize this class before use. The simplest way is to just do + * {#code AndroidNetworking.initialize(context)}. + */ +@SuppressWarnings("unused") +public class AndroidNetworking { + + /** + * private constructor to prevent instantiation of this class + */ + private AndroidNetworking() { + } + + /** + * Initializes AndroidNetworking with the default config. + * + * @param context The context + */ + public static void initialize(Context context) { + InternalNetworking.setClientWithCache(context.getApplicationContext()); + ANRequestQueue.initialize(); + ANImageLoader.initialize(); + } + + /** + * Initializes AndroidNetworking with the specified config. + * + * @param context The context + * @param okHttpClient The okHttpClient + */ + public static void initialize(Context context, OkHttpClient okHttpClient) { + if (okHttpClient != null && okHttpClient.cache() == null) { + okHttpClient = okHttpClient + .newBuilder() + .cache(Utils.getCache(context.getApplicationContext(), + ANConstants.MAX_CACHE_SIZE, ANConstants.CACHE_DIR_NAME)) + .build(); + } + InternalNetworking.setClient(okHttpClient); + ANRequestQueue.initialize(); + ANImageLoader.initialize(); + } + + /** + * Method to set decodeOptions + * + * @param decodeOptions The decode config for Bitmaps + */ + public static void setBitmapDecodeOptions(BitmapFactory.Options decodeOptions) { + if (decodeOptions != null) { + ANImageLoader.getInstance().setBitmapDecodeOptions(decodeOptions); + } + } + + /** + * Method to set connectionQualityChangeListener + * + * @param connectionChangeListener The connectionQualityChangeListener + */ + public static void setConnectionQualityChangeListener(ConnectionQualityChangeListener connectionChangeListener) { + ConnectionClassManager.getInstance().setListener(connectionChangeListener); + } + + /** + * Method to set connectionQualityChangeListener + */ + public static void removeConnectionQualityChangeListener() { + ConnectionClassManager.getInstance().removeListener(); + } + + /** + * Method to make GET request + * + * @param url The url on which request is to be made + * @return The GetRequestBuilder + */ + public static ANRequest.GetRequestBuilder get(String url) { + return new ANRequest.GetRequestBuilder(url); + } + + /** + * Method to make HEAD request + * + * @param url The url on which request is to be made + * @return The HeadRequestBuilder + */ + public static ANRequest.HeadRequestBuilder head(String url) { + return new ANRequest.HeadRequestBuilder(url); + } + + /** + * Method to make POST request + * + * @param url The url on which request is to be made + * @return The PostRequestBuilder + */ + public static ANRequest.PostRequestBuilder post(String url) { + return new ANRequest.PostRequestBuilder(url); + } + + /** + * Method to make PUT request + * + * @param url The url on which request is to be made + * @return The PutRequestBuilder + */ + public static ANRequest.PutRequestBuilder put(String url) { + return new ANRequest.PutRequestBuilder(url); + } + + /** + * Method to make DELETE request + * + * @param url The url on which request is to be made + * @return The DeleteRequestBuilder + */ + public static ANRequest.DeleteRequestBuilder delete(String url) { + return new ANRequest.DeleteRequestBuilder(url); + } + + /** + * Method to make PATCH request + * + * @param url The url on which request is to be made + * @return The PatchRequestBuilder + */ + public static ANRequest.PatchRequestBuilder patch(String url) { + return new ANRequest.PatchRequestBuilder(url); + } + + /** + * Method to make download request + * + * @param url The url on which request is to be made + * @param dirPath The directory path on which file is to be saved + * @param fileName The file name with which file is to be saved + * @return The DownloadBuilder + */ + public static ANRequest.DownloadBuilder download(String url, String dirPath, String fileName) { + return new ANRequest.DownloadBuilder(url, dirPath, fileName); + } + + /** + * Method to make upload request + * + * @param url The url on which request is to be made + * @return The MultiPartBuilder + */ + public static ANRequest.MultiPartBuilder upload(String url) { + return new ANRequest.MultiPartBuilder(url); + } + + /** + * Method to cancel requests with the given tag + * + * @param tag The tag with which requests are to be cancelled + */ + public static void cancel(Object tag) { + ANRequestQueue.getInstance().cancelRequestWithGivenTag(tag, false); + } + + /** + * Method to force cancel requests with the given tag + * + * @param tag The tag with which requests are to be cancelled + */ + public static void forceCancel(Object tag) { + ANRequestQueue.getInstance().cancelRequestWithGivenTag(tag, true); + } + + /** + * Method to cancel all given request + */ + public static void cancelAll() { + ANRequestQueue.getInstance().cancelAll(false); + } + + /** + * Method to force cancel all given request + */ + public static void forceCancelAll() { + ANRequestQueue.getInstance().cancelAll(true); + } + + /** + * Method to enable logging + */ + public static void enableLogging() { + enableLogging(Level.BASIC); + } + + /** + * Method to enable logging with tag + * + * @param level The level for logging + */ + public static void enableLogging(Level level) { + InternalNetworking.enableLogging(level); + } + + /** + * Method to evict a bitmap with given key from LruCache + * + * @param key The key of the bitmap + */ + public static void evictBitmap(String key) { + final ANImageLoader.ImageCache imageCache = ANImageLoader.getInstance().getImageCache(); + if (imageCache != null && key != null) { + imageCache.evictBitmap(key); + } + } + + /** + * Method to clear LruCache + */ + public static void evictAllBitmap() { + final ANImageLoader.ImageCache imageCache = ANImageLoader.getInstance().getImageCache(); + if (imageCache != null) { + imageCache.evictAllBitmap(); + } + } + + /** + * Method to set userAgent globally + * + * @param userAgent The userAgent + */ + public static void setUserAgent(String userAgent) { + InternalNetworking.setUserAgent(userAgent); + } + + /** + * Method to get currentBandwidth + * + * @return currentBandwidth + */ + public static int getCurrentBandwidth() { + return ConnectionClassManager.getInstance().getCurrentBandwidth(); + } + + /** + * Method to get currentConnectionQuality + * + * @return currentConnectionQuality + */ + public static ConnectionQuality getCurrentConnectionQuality() { + return ConnectionClassManager.getInstance().getCurrentConnectionQuality(); + } + + /** + * Method to set ParserFactory + * + * @param parserFactory The ParserFactory + */ + public static void setParserFactory(Parser.Factory parserFactory) { + ParseUtil.setParserFactory(parserFactory); + } + + /** + * Shuts AndroidNetworking down + */ + public static void shutDown() { + Core.shutDown(); + evictAllBitmap(); + ConnectionClassManager.getInstance().removeListener(); + ConnectionClassManager.shutDown(); + ParseUtil.shutDown(); + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/cache/LruBitmapCache.java b/android-networking/src/main/java/com/androidnetworking/cache/LruBitmapCache.java new file mode 100644 index 0000000..9786eee --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/cache/LruBitmapCache.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.cache; + +import android.graphics.Bitmap; + +import com.androidnetworking.internal.ANImageLoader; + +/** + * Created by owner on 24/03/16. + */ +public class LruBitmapCache extends LruCache + implements ANImageLoader.ImageCache { + + public LruBitmapCache(int maxSize) { + super(maxSize); + } + + @Override + protected int sizeOf(String key, Bitmap value) { + return value.getRowBytes() * value.getHeight(); + } + + @Override + public Bitmap getBitmap(String key) { + return get(key); + } + + @Override + public void evictBitmap(String key) { + remove(key); + } + + @Override + public void evictAllBitmap() { + evictAll(); + } + + @Override + public void putBitmap(String url, Bitmap bitmap) { + put(url, bitmap); + } + +} diff --git a/android-networking/src/main/java/com/androidnetworking/cache/LruCache.java b/android-networking/src/main/java/com/androidnetworking/cache/LruCache.java new file mode 100644 index 0000000..2cf3d6b --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/cache/LruCache.java @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.cache; + +import android.annotation.SuppressLint; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Created by owner on 28/05/16. + */ +public class LruCache { + private final LinkedHashMap map; + + private int size; + private int maxSize; + + private int putCount; + private int createCount; + private int evictionCount; + private int hitCount; + private int missCount; + + public LruCache(int maxSize) { + if (maxSize <= 0) { + throw new IllegalArgumentException("maxSize <= 0"); + } + this.maxSize = maxSize; + this.map = new LinkedHashMap(0, 0.75f, true); + } + + public void resize(int maxSize) { + if (maxSize <= 0) { + throw new IllegalArgumentException("maxSize <= 0"); + } + + synchronized (this) { + this.maxSize = maxSize; + } + trimToSize(maxSize); + } + + public final V get(K key) { + if (key == null) { + throw new NullPointerException("key == null"); + } + + V mapValue; + synchronized (this) { + mapValue = map.get(key); + if (mapValue != null) { + hitCount++; + return mapValue; + } + missCount++; + } + + V createdValue = create(key); + if (createdValue == null) { + return null; + } + + synchronized (this) { + createCount++; + mapValue = map.put(key, createdValue); + + if (mapValue != null) { + // There was a conflict so undo that last put + map.put(key, mapValue); + } else { + size += safeSizeOf(key, createdValue); + } + } + + if (mapValue != null) { + entryRemoved(false, key, createdValue, mapValue); + return mapValue; + } else { + trimToSize(maxSize); + return createdValue; + } + } + + public final V put(K key, V value) { + if (key == null || value == null) { + throw new NullPointerException("key == null || value == null"); + } + + V previous; + synchronized (this) { + putCount++; + size += safeSizeOf(key, value); + previous = map.put(key, value); + if (previous != null) { + size -= safeSizeOf(key, previous); + } + } + + if (previous != null) { + entryRemoved(false, key, previous, value); + } + + trimToSize(maxSize); + return previous; + } + + public void trimToSize(int maxSize) { + while (true) { + K key; + V value; + synchronized (this) { + if (size < 0 || (map.isEmpty() && size != 0)) { + throw new IllegalStateException(getClass().getName() + + ".sizeOf() is reporting inconsistent results!"); + } + + if (size <= maxSize || map.isEmpty()) { + break; + } + + Map.Entry toEvict = map.entrySet().iterator().next(); + key = toEvict.getKey(); + value = toEvict.getValue(); + map.remove(key); + size -= safeSizeOf(key, value); + evictionCount++; + } + + entryRemoved(true, key, value, null); + } + } + + public final V remove(K key) { + if (key == null) { + throw new NullPointerException("key == null"); + } + + V previous; + synchronized (this) { + previous = map.remove(key); + if (previous != null) { + size -= safeSizeOf(key, previous); + } + } + + if (previous != null) { + entryRemoved(false, key, previous, null); + } + + return previous; + } + + protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) { + } + + protected V create(K key) { + return null; + } + + private int safeSizeOf(K key, V value) { + int result = sizeOf(key, value); + if (result < 0) { + throw new IllegalStateException("Negative size: " + key + "=" + value); + } + return result; + } + + protected int sizeOf(K key, V value) { + return 1; + } + + public final void evictAll() { + trimToSize(-1); + } + + public synchronized final int size() { + return size; + } + + public synchronized final int maxSize() { + return maxSize; + } + + public synchronized final int hitCount() { + return hitCount; + } + + public synchronized final int missCount() { + return missCount; + } + + public synchronized final int createCount() { + return createCount; + } + + public synchronized final int putCount() { + return putCount; + } + + public synchronized final int evictionCount() { + return evictionCount; + } + + public synchronized final Map snapshot() { + return new LinkedHashMap(map); + } + + @SuppressLint("DefaultLocale") + @Override + public synchronized final String toString() { + int accesses = hitCount + missCount; + int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0; + return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]", + maxSize, hitCount, missCount, hitPercent); + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/ANConstants.java b/android-networking/src/main/java/com/androidnetworking/common/ANConstants.java new file mode 100644 index 0000000..f633b47 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/ANConstants.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +/** + * Created by owner on 29/03/16. + */ +public final class ANConstants { + public static final int MAX_CACHE_SIZE = 10 * 1024 * 1024; + public static final int UPDATE = 0x01; + public static final String CACHE_DIR_NAME = "cache_an"; + public static final String CONNECTION_ERROR = "connectionError"; + public static final String RESPONSE_FROM_SERVER_ERROR = "responseFromServerError"; + public static final String REQUEST_CANCELLED_ERROR = "requestCancelledError"; + public static final String PARSE_ERROR = "parseError"; + public static final String NETWORK_ON_MAIN_THREAD_ERROR = "networkOnMainThreadError"; + public static final String PREFETCH = "prefetch"; + public static final String FAST_ANDROID_NETWORKING = "FastAndroidNetworking"; + public static final String USER_AGENT = "User-Agent"; + public static final String SUCCESS = "success"; +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/ANRequest.java b/android-networking/src/main/java/com/androidnetworking/common/ANRequest.java new file mode 100644 index 0000000..2edd98c --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/ANRequest.java @@ -0,0 +1,1712 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.widget.ImageView; + +import com.androidnetworking.core.Core; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.AnalyticsListener; +import com.androidnetworking.interfaces.BitmapRequestListener; +import com.androidnetworking.interfaces.DownloadListener; +import com.androidnetworking.interfaces.DownloadProgressListener; +import com.androidnetworking.interfaces.JSONArrayRequestListener; +import com.androidnetworking.interfaces.JSONObjectRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndBitmapRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndJSONArrayRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndJSONObjectRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndParsedRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseAndStringRequestListener; +import com.androidnetworking.interfaces.OkHttpResponseListener; +import com.androidnetworking.interfaces.ParsedRequestListener; +import com.androidnetworking.interfaces.StringRequestListener; +import com.androidnetworking.interfaces.UploadProgressListener; +import com.androidnetworking.internal.ANRequestQueue; +import com.androidnetworking.internal.SynchronousCall; +import com.androidnetworking.utils.ParseUtil; +import com.androidnetworking.utils.Utils; +import com.google.gson.internal.$Gson$Types; +import com.google.gson.reflect.TypeToken; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.File; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import okhttp3.CacheControl; +import okhttp3.Call; +import okhttp3.FormBody; +import okhttp3.Headers; +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.RequestBody; +import okhttp3.Response; +import okio.Okio; + +/** + * Created by owner on 26/03/16. + */ +@SuppressWarnings({"unchecked", "unused"}) +public class ANRequest { + + private final static String TAG = ANRequest.class.getSimpleName(); + + private int mMethod; + private Priority mPriority; + private int mRequestType; + private String mUrl; + private int sequenceNumber; + private Object mTag; + private ResponseType mResponseType; + private HashMap mHeadersMap = new HashMap<>(); + private HashMap mBodyParameterMap = new HashMap<>(); + private HashMap mUrlEncodedFormBodyParameterMap = new HashMap<>(); + private HashMap mMultiPartParameterMap = new HashMap<>(); + private HashMap mQueryParameterMap = new HashMap<>(); + private HashMap mPathParameterMap = new HashMap<>(); + private HashMap mMultiPartFileMap = new HashMap<>(); + private String mDirPath; + private String mFileName; + private String mApplicationJsonString = null; + private String mStringBody = null; + private byte[] mByte = null; + private File mFile = null; + private static final MediaType JSON_MEDIA_TYPE = + MediaType.parse("application/json; charset=utf-8"); + private static final MediaType MEDIA_TYPE_MARKDOWN = + MediaType.parse("text/x-markdown; charset=utf-8"); + private MediaType customMediaType = null; + private static final Object sDecodeLock = new Object(); + + private Future future; + private Call call; + private int mProgress; + private boolean isCancelled; + private boolean isDelivered; + private int mPercentageThresholdForCancelling = 0; + private JSONArrayRequestListener mJSONArrayRequestListener; + private JSONObjectRequestListener mJSONObjectRequestListener; + private StringRequestListener mStringRequestListener; + private OkHttpResponseListener mOkHttpResponseListener; + private BitmapRequestListener mBitmapRequestListener; + private ParsedRequestListener mParsedRequestListener; + private OkHttpResponseAndJSONObjectRequestListener mOkHttpResponseAndJSONObjectRequestListener; + private OkHttpResponseAndJSONArrayRequestListener mOkHttpResponseAndJSONArrayRequestListener; + private OkHttpResponseAndStringRequestListener mOkHttpResponseAndStringRequestListener; + private OkHttpResponseAndBitmapRequestListener mOkHttpResponseAndBitmapRequestListener; + private OkHttpResponseAndParsedRequestListener mOkHttpResponseAndParsedRequestListener; + private DownloadProgressListener mDownloadProgressListener; + private UploadProgressListener mUploadProgressListener; + private DownloadListener mDownloadListener; + private AnalyticsListener mAnalyticsListener; + + private Bitmap.Config mDecodeConfig; + private int mMaxWidth; + private int mMaxHeight; + private ImageView.ScaleType mScaleType; + private CacheControl mCacheControl = null; + private Executor mExecutor = null; + private OkHttpClient mOkHttpClient = null; + private String mUserAgent = null; + private Type mType = null; + + public ANRequest(GetRequestBuilder builder) { + this.mRequestType = RequestType.SIMPLE; + this.mMethod = builder.mMethod; + this.mPriority = builder.mPriority; + this.mUrl = builder.mUrl; + this.mTag = builder.mTag; + this.mHeadersMap = builder.mHeadersMap; + this.mDecodeConfig = builder.mDecodeConfig; + this.mMaxHeight = builder.mMaxHeight; + this.mMaxWidth = builder.mMaxWidth; + this.mScaleType = builder.mScaleType; + this.mQueryParameterMap = builder.mQueryParameterMap; + this.mPathParameterMap = builder.mPathParameterMap; + this.mCacheControl = builder.mCacheControl; + this.mExecutor = builder.mExecutor; + this.mOkHttpClient = builder.mOkHttpClient; + this.mUserAgent = builder.mUserAgent; + } + + public ANRequest(PostRequestBuilder builder) { + this.mRequestType = RequestType.SIMPLE; + this.mMethod = builder.mMethod; + this.mPriority = builder.mPriority; + this.mUrl = builder.mUrl; + this.mTag = builder.mTag; + this.mHeadersMap = builder.mHeadersMap; + this.mBodyParameterMap = builder.mBodyParameterMap; + this.mUrlEncodedFormBodyParameterMap = builder.mUrlEncodedFormBodyParameterMap; + this.mQueryParameterMap = builder.mQueryParameterMap; + this.mPathParameterMap = builder.mPathParameterMap; + this.mApplicationJsonString = builder.mApplicationJsonString; + this.mStringBody = builder.mStringBody; + this.mFile = builder.mFile; + this.mByte = builder.mByte; + this.mCacheControl = builder.mCacheControl; + this.mExecutor = builder.mExecutor; + this.mOkHttpClient = builder.mOkHttpClient; + this.mUserAgent = builder.mUserAgent; + if (builder.mCustomContentType != null) { + this.customMediaType = MediaType.parse(builder.mCustomContentType); + } + } + + public ANRequest(DownloadBuilder builder) { + this.mRequestType = RequestType.DOWNLOAD; + this.mMethod = Method.GET; + this.mPriority = builder.mPriority; + this.mUrl = builder.mUrl; + this.mTag = builder.mTag; + this.mDirPath = builder.mDirPath; + this.mFileName = builder.mFileName; + this.mHeadersMap = builder.mHeadersMap; + this.mQueryParameterMap = builder.mQueryParameterMap; + this.mPathParameterMap = builder.mPathParameterMap; + this.mCacheControl = builder.mCacheControl; + this.mPercentageThresholdForCancelling = builder.mPercentageThresholdForCancelling; + this.mExecutor = builder.mExecutor; + this.mOkHttpClient = builder.mOkHttpClient; + this.mUserAgent = builder.mUserAgent; + } + + public ANRequest(MultiPartBuilder builder) { + this.mRequestType = RequestType.MULTIPART; + this.mMethod = Method.POST; + this.mPriority = builder.mPriority; + this.mUrl = builder.mUrl; + this.mTag = builder.mTag; + this.mHeadersMap = builder.mHeadersMap; + this.mQueryParameterMap = builder.mQueryParameterMap; + this.mPathParameterMap = builder.mPathParameterMap; + this.mMultiPartParameterMap = builder.mMultiPartParameterMap; + this.mMultiPartFileMap = builder.mMultiPartFileMap; + this.mCacheControl = builder.mCacheControl; + this.mPercentageThresholdForCancelling = builder.mPercentageThresholdForCancelling; + this.mExecutor = builder.mExecutor; + this.mOkHttpClient = builder.mOkHttpClient; + this.mUserAgent = builder.mUserAgent; + if (builder.mCustomContentType != null) { + this.customMediaType = MediaType.parse(builder.mCustomContentType); + } + } + + public void getAsJSONObject(JSONObjectRequestListener requestListener) { + this.mResponseType = ResponseType.JSON_OBJECT; + this.mJSONObjectRequestListener = requestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsJSONArray(JSONArrayRequestListener requestListener) { + this.mResponseType = ResponseType.JSON_ARRAY; + this.mJSONArrayRequestListener = requestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsString(StringRequestListener requestListener) { + this.mResponseType = ResponseType.STRING; + this.mStringRequestListener = requestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsOkHttpResponse(OkHttpResponseListener requestListener) { + this.mResponseType = ResponseType.OK_HTTP_RESPONSE; + this.mOkHttpResponseListener = requestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsBitmap(BitmapRequestListener requestListener) { + this.mResponseType = ResponseType.BITMAP; + this.mBitmapRequestListener = requestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsParsed(TypeToken typeToken, ParsedRequestListener parsedRequestListener) { + this.mType = typeToken.getType(); + this.mResponseType = ResponseType.PARSED; + this.mParsedRequestListener = parsedRequestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsObject(Class objectClass, ParsedRequestListener parsedRequestListener) { + this.mType = objectClass; + this.mResponseType = ResponseType.PARSED; + this.mParsedRequestListener = parsedRequestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsObjectList(Class objectClass, ParsedRequestListener parsedRequestListener) { + this.mType = $Gson$Types.newParameterizedTypeWithOwner(null, List.class, objectClass); + this.mResponseType = ResponseType.PARSED; + this.mParsedRequestListener = parsedRequestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsOkHttpResponseAndJSONObject(OkHttpResponseAndJSONObjectRequestListener requestListener) { + this.mResponseType = ResponseType.JSON_OBJECT; + this.mOkHttpResponseAndJSONObjectRequestListener = requestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsOkHttpResponseAndJSONArray(OkHttpResponseAndJSONArrayRequestListener requestListener) { + this.mResponseType = ResponseType.JSON_ARRAY; + this.mOkHttpResponseAndJSONArrayRequestListener = requestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsOkHttpResponseAndString(OkHttpResponseAndStringRequestListener requestListener) { + this.mResponseType = ResponseType.STRING; + this.mOkHttpResponseAndStringRequestListener = requestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + + public void getAsOkHttpResponseAndBitmap(OkHttpResponseAndBitmapRequestListener requestListener) { + this.mResponseType = ResponseType.BITMAP; + this.mOkHttpResponseAndBitmapRequestListener = requestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsOkHttpResponseAndParsed(TypeToken typeToken, OkHttpResponseAndParsedRequestListener parsedRequestListener) { + this.mType = typeToken.getType(); + this.mResponseType = ResponseType.PARSED; + this.mOkHttpResponseAndParsedRequestListener = parsedRequestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsOkHttpResponseAndObject(Class objectClass, OkHttpResponseAndParsedRequestListener parsedRequestListener) { + this.mType = objectClass; + this.mResponseType = ResponseType.PARSED; + this.mOkHttpResponseAndParsedRequestListener = parsedRequestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void getAsOkHttpResponseAndObjectList(Class objectClass, OkHttpResponseAndParsedRequestListener parsedRequestListener) { + this.mType = $Gson$Types.newParameterizedTypeWithOwner(null, List.class, objectClass); + this.mResponseType = ResponseType.PARSED; + this.mOkHttpResponseAndParsedRequestListener = parsedRequestListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void startDownload(DownloadListener downloadListener) { + this.mDownloadListener = downloadListener; + ANRequestQueue.getInstance().addRequest(this); + } + + public void prefetch() { + this.mResponseType = ResponseType.PREFETCH; + ANRequestQueue.getInstance().addRequest(this); + } + + public ANResponse executeForJSONObject() { + this.mResponseType = ResponseType.JSON_OBJECT; + return SynchronousCall.execute(this); + } + + public ANResponse executeForJSONArray() { + this.mResponseType = ResponseType.JSON_ARRAY; + return SynchronousCall.execute(this); + } + + public ANResponse executeForString() { + this.mResponseType = ResponseType.STRING; + return SynchronousCall.execute(this); + } + + public ANResponse executeForOkHttpResponse() { + this.mResponseType = ResponseType.OK_HTTP_RESPONSE; + return SynchronousCall.execute(this); + } + + public ANResponse executeForBitmap() { + this.mResponseType = ResponseType.BITMAP; + return SynchronousCall.execute(this); + } + + public ANResponse executeForParsed(TypeToken typeToken) { + this.mType = typeToken.getType(); + this.mResponseType = ResponseType.PARSED; + return SynchronousCall.execute(this); + } + + public ANResponse executeForObject(Class objectClass) { + this.mType = objectClass; + this.mResponseType = ResponseType.PARSED; + return SynchronousCall.execute(this); + } + + public ANResponse executeForObjectList(Class objectClass) { + this.mType = $Gson$Types.newParameterizedTypeWithOwner(null, List.class, objectClass); + this.mResponseType = ResponseType.PARSED; + return SynchronousCall.execute(this); + } + + public ANResponse executeForDownload() { + return SynchronousCall.execute(this); + } + + public T setDownloadProgressListener(DownloadProgressListener downloadProgressListener) { + this.mDownloadProgressListener = downloadProgressListener; + return (T) this; + } + + public T setUploadProgressListener(UploadProgressListener uploadProgressListener) { + this.mUploadProgressListener = uploadProgressListener; + return (T) this; + } + + public T setAnalyticsListener(AnalyticsListener analyticsListener) { + this.mAnalyticsListener = analyticsListener; + return (T) this; + } + + public AnalyticsListener getAnalyticsListener() { + return mAnalyticsListener; + } + + public int getMethod() { + return mMethod; + } + + public Priority getPriority() { + return mPriority; + } + + public String getUrl() { + String tempUrl = mUrl; + for (HashMap.Entry entry : mPathParameterMap.entrySet()) { + tempUrl = tempUrl.replace("{" + entry.getKey() + "}", String.valueOf(entry.getValue())); + } + HttpUrl.Builder urlBuilder = HttpUrl.parse(tempUrl).newBuilder(); + for (HashMap.Entry entry : mQueryParameterMap.entrySet()) { + urlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); + } + return urlBuilder.build().toString(); + } + + public int getSequenceNumber() { + return sequenceNumber; + } + + public void setSequenceNumber(int sequenceNumber) { + this.sequenceNumber = sequenceNumber; + } + + public void setProgress(int progress) { + this.mProgress = progress; + } + + public void setResponseAs(ResponseType responseType) { + this.mResponseType = responseType; + } + + public ResponseType getResponseAs() { + return mResponseType; + } + + public Object getTag() { + return mTag; + } + + public int getRequestType() { + return mRequestType; + } + + public OkHttpClient getOkHttpClient() { + return mOkHttpClient; + } + + public void setUserAgent(String userAgent) { + this.mUserAgent = userAgent; + } + + public String getUserAgent() { + return mUserAgent; + } + + public Type getType() { + return mType; + } + + public void setType(Type type) { + this.mType = type; + } + + public DownloadProgressListener getDownloadProgressListener() { + return new DownloadProgressListener() { + @Override + public void onProgress(final long bytesDownloaded, final long totalBytes) { + if (mDownloadProgressListener != null && !isCancelled) { + mDownloadProgressListener.onProgress(bytesDownloaded, totalBytes); + } + } + }; + } + + public void updateDownloadCompletion() { + isDelivered = true; + if (mDownloadListener != null) { + if (!isCancelled) { + if (mExecutor != null) { + mExecutor.execute(new Runnable() { + @Override + public void run() { + if (mDownloadListener != null) { + mDownloadListener.onDownloadComplete(); + } + finish(); + } + }); + } else { + Core.getInstance().getExecutorSupplier().forMainThreadTasks().execute(new Runnable() { + @Override + public void run() { + if (mDownloadListener != null) { + mDownloadListener.onDownloadComplete(); + } + finish(); + } + }); + } + } else { + deliverError(new ANError()); + finish(); + } + } else { + finish(); + } + } + + public UploadProgressListener getUploadProgressListener() { + return new UploadProgressListener() { + @Override + public void onProgress(final long bytesUploaded, final long totalBytes) { + mProgress = (int) ((bytesUploaded * 100) / totalBytes); + if (mUploadProgressListener != null && !isCancelled) { + mUploadProgressListener.onProgress(bytesUploaded, totalBytes); + } + } + }; + } + + public String getDirPath() { + return mDirPath; + } + + public String getFileName() { + return mFileName; + } + + public CacheControl getCacheControl() { + return mCacheControl; + } + + public ImageView.ScaleType getScaleType() { + return mScaleType; + } + + public void cancel(boolean forceCancel) { + try { + if (forceCancel || mPercentageThresholdForCancelling == 0 + || mProgress < mPercentageThresholdForCancelling) { + isCancelled = true; + if (call != null) { + call.cancel(); + } + if (future != null) { + future.cancel(true); + } + if (!isDelivered) { + deliverError(new ANError()); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public boolean isCanceled() { + return isCancelled; + } + + public Call getCall() { + return call; + } + + public void setCall(Call call) { + this.call = call; + } + + public Future getFuture() { + return future; + } + + public void setFuture(Future future) { + this.future = future; + } + + public void destroy() { + mJSONArrayRequestListener = null; + mJSONArrayRequestListener = null; + mStringRequestListener = null; + mBitmapRequestListener = null; + mParsedRequestListener = null; + mDownloadProgressListener = null; + mUploadProgressListener = null; + mDownloadListener = null; + mAnalyticsListener = null; + } + + public void finish() { + destroy(); + ANRequestQueue.getInstance().finish(this); + } + + public ANResponse parseResponse(Response response) { + switch (mResponseType) { + case JSON_ARRAY: + try { + JSONArray json = new JSONArray(Okio.buffer(response.body().source()).readUtf8()); + return ANResponse.success(json); + } catch (Exception e) { + return ANResponse.failed(Utils.getErrorForParse(new ANError(e))); + } + case JSON_OBJECT: + try { + JSONObject json = new JSONObject(Okio.buffer(response.body() + .source()).readUtf8()); + return ANResponse.success(json); + } catch (Exception e) { + return ANResponse.failed(Utils.getErrorForParse(new ANError(e))); + } + case STRING: + try { + return ANResponse.success(Okio.buffer(response + .body().source()).readUtf8()); + } catch (Exception e) { + return ANResponse.failed(Utils.getErrorForParse(new ANError(e))); + } + case BITMAP: + synchronized (sDecodeLock) { + try { + return Utils.decodeBitmap(response, mMaxWidth, mMaxHeight, + mDecodeConfig, mScaleType); + } catch (Exception e) { + return ANResponse.failed(Utils.getErrorForParse(new ANError(e))); + } + } + case PARSED: + try { + return ANResponse.success(ParseUtil.getParserFactory() + .responseBodyParser(mType).convert(response.body())); + } catch (Exception e) { + return ANResponse.failed(Utils.getErrorForParse(new ANError(e))); + } + case PREFETCH: + try { + Okio.buffer(response.body().source()).skip(Long.MAX_VALUE); + return ANResponse.success(ANConstants.PREFETCH); + } catch (Exception e) { + return ANResponse.failed(Utils.getErrorForParse(new ANError(e))); + } + } + return null; + } + + public ANError parseNetworkError(ANError anError) { + try { + if (anError.getResponse() != null && anError.getResponse().body() != null + && anError.getResponse().body().source() != null) { + anError.setErrorBody(Okio.buffer(anError + .getResponse().body().source()).readUtf8()); + } + } catch (Exception e) { + e.printStackTrace(); + } + return anError; + } + + public synchronized void deliverError(ANError anError) { + try { + if (!isDelivered) { + if (isCancelled) { + anError.setCancellationMessageInError(); + anError.setErrorCode(0); + } + deliverErrorResponse(anError); + } + isDelivered = true; + } catch (Exception e) { + e.printStackTrace(); + } + } + + + public void deliverResponse(final ANResponse response) { + try { + isDelivered = true; + if (!isCancelled) { + if (mExecutor != null) { + mExecutor.execute(new Runnable() { + @Override + public void run() { + deliverSuccessResponse(response); + } + }); + } else { + Core.getInstance().getExecutorSupplier().forMainThreadTasks().execute(new Runnable() { + public void run() { + deliverSuccessResponse(response); + } + }); + } + } else { + ANError anError = new ANError(); + anError.setCancellationMessageInError(); + anError.setErrorCode(0); + deliverErrorResponse(anError); + finish(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void deliverSuccessResponse(ANResponse response) { + if (mJSONObjectRequestListener != null) { + mJSONObjectRequestListener.onResponse((JSONObject) response.getResult()); + } else if (mJSONArrayRequestListener != null) { + mJSONArrayRequestListener.onResponse((JSONArray) response.getResult()); + } else if (mStringRequestListener != null) { + mStringRequestListener.onResponse((String) response.getResult()); + } else if (mBitmapRequestListener != null) { + mBitmapRequestListener.onResponse((Bitmap) response.getResult()); + } else if (mParsedRequestListener != null) { + mParsedRequestListener.onResponse(response.getResult()); + } else if (mOkHttpResponseAndJSONObjectRequestListener != null) { + mOkHttpResponseAndJSONObjectRequestListener.onResponse(response.getOkHttpResponse(), (JSONObject) response.getResult()); + } else if (mOkHttpResponseAndJSONArrayRequestListener != null) { + mOkHttpResponseAndJSONArrayRequestListener.onResponse(response.getOkHttpResponse(), (JSONArray) response.getResult()); + } else if (mOkHttpResponseAndStringRequestListener != null) { + mOkHttpResponseAndStringRequestListener.onResponse(response.getOkHttpResponse(), (String) response.getResult()); + } else if (mOkHttpResponseAndBitmapRequestListener != null) { + mOkHttpResponseAndBitmapRequestListener.onResponse(response.getOkHttpResponse(), (Bitmap) response.getResult()); + } else if (mOkHttpResponseAndParsedRequestListener != null) { + mOkHttpResponseAndParsedRequestListener.onResponse(response.getOkHttpResponse(), response.getResult()); + } + finish(); + } + + private void deliverErrorResponse(ANError anError) { + if (mJSONObjectRequestListener != null) { + mJSONObjectRequestListener.onError(anError); + } else if (mJSONArrayRequestListener != null) { + mJSONArrayRequestListener.onError(anError); + } else if (mStringRequestListener != null) { + mStringRequestListener.onError(anError); + } else if (mBitmapRequestListener != null) { + mBitmapRequestListener.onError(anError); + } else if (mParsedRequestListener != null) { + mParsedRequestListener.onError(anError); + } else if (mOkHttpResponseListener != null) { + mOkHttpResponseListener.onError(anError); + } else if (mOkHttpResponseAndJSONObjectRequestListener != null) { + mOkHttpResponseAndJSONObjectRequestListener.onError(anError); + } else if (mOkHttpResponseAndJSONArrayRequestListener != null) { + mOkHttpResponseAndJSONArrayRequestListener.onError(anError); + } else if (mOkHttpResponseAndStringRequestListener != null) { + mOkHttpResponseAndStringRequestListener.onError(anError); + } else if (mOkHttpResponseAndBitmapRequestListener != null) { + mOkHttpResponseAndBitmapRequestListener.onError(anError); + } else if (mOkHttpResponseAndParsedRequestListener != null) { + mOkHttpResponseAndParsedRequestListener.onError(anError); + } else if (mDownloadListener != null) { + mDownloadListener.onError(anError); + } + } + + public void deliverOkHttpResponse(final Response response) { + try { + isDelivered = true; + if (!isCancelled) { + if (mExecutor != null) { + mExecutor.execute(new Runnable() { + @Override + public void run() { + if (mOkHttpResponseListener != null) { + mOkHttpResponseListener.onResponse(response); + } + finish(); + } + }); + } else { + Core.getInstance().getExecutorSupplier().forMainThreadTasks().execute(new Runnable() { + public void run() { + if (mOkHttpResponseListener != null) { + mOkHttpResponseListener.onResponse(response); + } + finish(); + } + }); + } + } else { + ANError anError = new ANError(); + anError.setCancellationMessageInError(); + anError.setErrorCode(0); + if (mOkHttpResponseListener != null) { + mOkHttpResponseListener.onError(anError); + } + finish(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public RequestBody getRequestBody() { + if (mApplicationJsonString != null) { + if (customMediaType != null) { + return RequestBody.create(customMediaType, mApplicationJsonString); + } + return RequestBody.create(JSON_MEDIA_TYPE, mApplicationJsonString); + } else if (mStringBody != null) { + if (customMediaType != null) { + return RequestBody.create(customMediaType, mStringBody); + } + return RequestBody.create(MEDIA_TYPE_MARKDOWN, mStringBody); + } else if (mFile != null) { + if (customMediaType != null) { + return RequestBody.create(customMediaType, mFile); + } + return RequestBody.create(MEDIA_TYPE_MARKDOWN, mFile); + } else if (mByte != null) { + if (customMediaType != null) { + return RequestBody.create(customMediaType, mByte); + } + return RequestBody.create(MEDIA_TYPE_MARKDOWN, mByte); + } else { + FormBody.Builder builder = new FormBody.Builder(); + try { + for (HashMap.Entry entry : mBodyParameterMap.entrySet()) { + builder.add(entry.getKey(), entry.getValue()); + } + for (HashMap.Entry entry : mUrlEncodedFormBodyParameterMap.entrySet()) { + builder.addEncoded(entry.getKey(), entry.getValue()); + } + } catch (Exception e) { + e.printStackTrace(); + } + return builder.build(); + } + } + + public RequestBody getMultiPartRequestBody() { + MultipartBody.Builder builder = new MultipartBody + .Builder() + .setType((customMediaType == null) ? MultipartBody.FORM : customMediaType); + try { + for (HashMap.Entry entry : mMultiPartParameterMap.entrySet()) { + builder.addPart(Headers.of("Content-Disposition", + "form-data; name=\"" + entry.getKey() + "\""), + RequestBody.create(null, entry.getValue())); + } + for (HashMap.Entry entry : mMultiPartFileMap.entrySet()) { + String fileName = entry.getValue().getName(); + RequestBody fileBody = RequestBody.create(MediaType.parse(Utils.getMimeType(fileName)), + entry.getValue()); + builder.addPart(Headers.of("Content-Disposition", + "form-data; name=\"" + entry.getKey() + "\"; filename=\"" + fileName + "\""), + fileBody); + } + } catch (Exception e) { + e.printStackTrace(); + } + return builder.build(); + } + + public Headers getHeaders() { + Headers.Builder builder = new Headers.Builder(); + try { + for (HashMap.Entry entry : mHeadersMap.entrySet()) { + builder.add(entry.getKey(), entry.getValue()); + } + } catch (Exception e) { + e.printStackTrace(); + } + return builder.build(); + } + + public static class HeadRequestBuilder extends GetRequestBuilder { + + public HeadRequestBuilder(String url) { + super(url, Method.HEAD); + } + } + + public static class GetRequestBuilder implements RequestBuilder { + private Priority mPriority = Priority.MEDIUM; + private int mMethod = Method.GET; + private String mUrl; + private Object mTag; + private Bitmap.Config mDecodeConfig; + private BitmapFactory.Options mBitmapOptions; + private int mMaxWidth; + private int mMaxHeight; + private ImageView.ScaleType mScaleType; + private HashMap mHeadersMap = new HashMap<>(); + private HashMap mQueryParameterMap = new HashMap<>(); + private HashMap mPathParameterMap = new HashMap<>(); + private CacheControl mCacheControl; + private Executor mExecutor; + private OkHttpClient mOkHttpClient; + private String mUserAgent; + + public GetRequestBuilder(String url) { + this.mUrl = url; + this.mMethod = Method.GET; + } + + public GetRequestBuilder(String url, int method) { + this.mUrl = url; + this.mMethod = method; + } + + @Override + public T setPriority(Priority priority) { + mPriority = priority; + return (T) this; + } + + @Override + public T setTag(Object tag) { + mTag = tag; + return (T) this; + } + + @Override + public T addQueryParameter(String key, String value) { + mQueryParameterMap.put(key, value); + return (T) this; + } + + @Override + public T addQueryParameter(Map queryParameterMap) { + if (queryParameterMap != null) { + mQueryParameterMap.putAll(queryParameterMap); + } + return (T) this; + } + + @Override + public T addQueryParameter(Object object) { + if (object != null) { + mQueryParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T addPathParameter(String key, String value) { + mPathParameterMap.put(key, value); + return (T) this; + } + + @Override + public T addPathParameter(Map pathParameterMap) { + if (pathParameterMap != null) { + mPathParameterMap.putAll(pathParameterMap); + } + return (T) this; + } + + @Override + public T addPathParameter(Object object) { + if (object != null) { + mPathParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T addHeaders(String key, String value) { + mHeadersMap.put(key, value); + return (T) this; + } + + @Override + public T addHeaders(Map headerMap) { + if (headerMap != null) { + mHeadersMap.putAll(headerMap); + } + return (T) this; + } + + @Override + public T addHeaders(Object object) { + if (object != null) { + mHeadersMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T doNotCacheResponse() { + mCacheControl = new CacheControl.Builder().noStore().build(); + return (T) this; + } + + @Override + public T getResponseOnlyIfCached() { + mCacheControl = CacheControl.FORCE_CACHE; + return (T) this; + } + + @Override + public T getResponseOnlyFromNetwork() { + mCacheControl = CacheControl.FORCE_NETWORK; + return (T) this; + } + + @Override + public T setMaxAgeCacheControl(int maxAge, TimeUnit timeUnit) { + mCacheControl = new CacheControl.Builder().maxAge(maxAge, timeUnit).build(); + return (T) this; + } + + @Override + public T setMaxStaleCacheControl(int maxStale, TimeUnit timeUnit) { + mCacheControl = new CacheControl.Builder().maxStale(maxStale, timeUnit).build(); + return (T) this; + } + + @Override + public T setExecutor(Executor executor) { + mExecutor = executor; + return (T) this; + } + + @Override + public T setOkHttpClient(OkHttpClient okHttpClient) { + mOkHttpClient = okHttpClient; + return (T) this; + } + + @Override + public T setUserAgent(String userAgent) { + mUserAgent = userAgent; + return (T) this; + } + + public T setBitmapConfig(Bitmap.Config bitmapConfig) { + mDecodeConfig = bitmapConfig; + return (T) this; + } + + public T setBitmapOptions(BitmapFactory.Options bitmapOptions) { + mBitmapOptions = bitmapOptions; + return (T) this; + } + + public T setBitmapMaxHeight(int maxHeight) { + mMaxHeight = maxHeight; + return (T) this; + } + + public T setBitmapMaxWidth(int maxWidth) { + mMaxWidth = maxWidth; + return (T) this; + } + + public T setImageScaleType(ImageView.ScaleType imageScaleType) { + mScaleType = imageScaleType; + return (T) this; + } + + public ANRequest build() { + return new ANRequest(this); + } + } + + public static class PutRequestBuilder extends PostRequestBuilder { + + public PutRequestBuilder(String url) { + super(url, Method.PUT); + } + } + + public static class DeleteRequestBuilder extends PostRequestBuilder { + + public DeleteRequestBuilder(String url) { + super(url, Method.DELETE); + } + } + + public static class PatchRequestBuilder extends PostRequestBuilder { + + public PatchRequestBuilder(String url) { + super(url, Method.PATCH); + } + } + + public static class PostRequestBuilder implements RequestBuilder { + + private Priority mPriority = Priority.MEDIUM; + private int mMethod = Method.POST; + private String mUrl; + private Object mTag; + private String mApplicationJsonString = null; + private String mStringBody = null; + private byte[] mByte = null; + private File mFile = null; + private HashMap mHeadersMap = new HashMap<>(); + private HashMap mBodyParameterMap = new HashMap<>(); + private HashMap mUrlEncodedFormBodyParameterMap = new HashMap<>(); + private HashMap mQueryParameterMap = new HashMap<>(); + private HashMap mPathParameterMap = new HashMap<>(); + private CacheControl mCacheControl; + private Executor mExecutor; + private OkHttpClient mOkHttpClient; + private String mUserAgent; + private String mCustomContentType; + + public PostRequestBuilder(String url) { + this.mUrl = url; + this.mMethod = Method.POST; + } + + public PostRequestBuilder(String url, int method) { + this.mUrl = url; + this.mMethod = method; + } + + @Override + public T setPriority(Priority priority) { + mPriority = priority; + return (T) this; + } + + @Override + public T setTag(Object tag) { + mTag = tag; + return (T) this; + } + + @Override + public T addQueryParameter(String key, String value) { + mQueryParameterMap.put(key, value); + return (T) this; + } + + @Override + public T addQueryParameter(Map queryParameterMap) { + if (queryParameterMap != null) { + mQueryParameterMap.putAll(queryParameterMap); + } + return (T) this; + } + + @Override + public T addQueryParameter(Object object) { + if (object != null) { + mQueryParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T addPathParameter(String key, String value) { + mPathParameterMap.put(key, value); + return (T) this; + } + + @Override + public T addPathParameter(Map pathParameterMap) { + if (pathParameterMap != null) { + mPathParameterMap.putAll(pathParameterMap); + } + return (T) this; + } + + @Override + public T addPathParameter(Object object) { + if (object != null) { + mPathParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T addHeaders(String key, String value) { + mHeadersMap.put(key, value); + return (T) this; + } + + @Override + public T addHeaders(Map headerMap) { + if (headerMap != null) { + mHeadersMap.putAll(headerMap); + } + return (T) this; + } + + @Override + public T addHeaders(Object object) { + if (object != null) { + mHeadersMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T doNotCacheResponse() { + mCacheControl = new CacheControl.Builder().noStore().build(); + return (T) this; + } + + @Override + public T getResponseOnlyIfCached() { + mCacheControl = CacheControl.FORCE_CACHE; + return (T) this; + } + + @Override + public T getResponseOnlyFromNetwork() { + mCacheControl = CacheControl.FORCE_NETWORK; + return (T) this; + } + + @Override + public T setMaxAgeCacheControl(int maxAge, TimeUnit timeUnit) { + mCacheControl = new CacheControl.Builder().maxAge(maxAge, timeUnit).build(); + return (T) this; + } + + @Override + public T setMaxStaleCacheControl(int maxStale, TimeUnit timeUnit) { + mCacheControl = new CacheControl.Builder().maxStale(maxStale, timeUnit).build(); + return (T) this; + } + + @Override + public T setExecutor(Executor executor) { + mExecutor = executor; + return (T) this; + } + + @Override + public T setOkHttpClient(OkHttpClient okHttpClient) { + mOkHttpClient = okHttpClient; + return (T) this; + } + + @Override + public T setUserAgent(String userAgent) { + mUserAgent = userAgent; + return (T) this; + } + + public T addBodyParameter(String key, String value) { + mBodyParameterMap.put(key, value); + return (T) this; + } + + public T addBodyParameter(Map bodyParameterMap) { + if (bodyParameterMap != null) { + mBodyParameterMap.putAll(bodyParameterMap); + } + return (T) this; + } + + public T addBodyParameter(Object object) { + if (object != null) { + mBodyParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + public T addUrlEncodeFormBodyParameter(String key, String value) { + mUrlEncodedFormBodyParameterMap.put(key, value); + return (T) this; + } + + public T addUrlEncodeFormBodyParameter(Map bodyParameterMap) { + if (bodyParameterMap != null) { + mUrlEncodedFormBodyParameterMap.putAll(bodyParameterMap); + } + return (T) this; + } + + public T addUrlEncodeFormBodyParameter(Object object) { + if (object != null) { + mUrlEncodedFormBodyParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + public T addApplicationJsonBody(Object object) { + if (object != null) { + mApplicationJsonString = ParseUtil + .getParserFactory() + .getString(object); + } + return (T) this; + } + + public T addJSONObjectBody(JSONObject jsonObject) { + if (jsonObject != null) { + mApplicationJsonString = jsonObject.toString(); + } + return (T) this; + } + + public T addJSONArrayBody(JSONArray jsonArray) { + if (jsonArray != null) { + mApplicationJsonString = jsonArray.toString(); + } + return (T) this; + } + + public T addStringBody(String stringBody) { + mStringBody = stringBody; + return (T) this; + } + + public T addFileBody(File file) { + mFile = file; + return (T) this; + } + + public T addByteBody(byte[] bytes) { + mByte = bytes; + return (T) this; + } + + public T setContentType(String contentType) { + mCustomContentType = contentType; + return (T) this; + } + + public ANRequest build() { + return new ANRequest(this); + } + } + + public static class DownloadBuilder implements RequestBuilder { + + private Priority mPriority = Priority.MEDIUM; + private String mUrl; + private Object mTag; + private HashMap mHeadersMap = new HashMap<>(); + private HashMap mQueryParameterMap = new HashMap<>(); + private HashMap mPathParameterMap = new HashMap<>(); + private String mDirPath; + private String mFileName; + private CacheControl mCacheControl; + private int mPercentageThresholdForCancelling = 0; + private Executor mExecutor; + private OkHttpClient mOkHttpClient; + private String mUserAgent; + + public DownloadBuilder(String url, String dirPath, String fileName) { + this.mUrl = url; + this.mDirPath = dirPath; + this.mFileName = fileName; + } + + @Override + public T setPriority(Priority priority) { + mPriority = priority; + return (T) this; + } + + @Override + public T setTag(Object tag) { + mTag = tag; + return (T) this; + } + + @Override + public T addHeaders(String key, String value) { + mHeadersMap.put(key, value); + return (T) this; + } + + @Override + public T addHeaders(Map headerMap) { + if (headerMap != null) { + mHeadersMap.putAll(headerMap); + } + return (T) this; + } + + @Override + public T addHeaders(Object object) { + if (object != null) { + mHeadersMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T addQueryParameter(String key, String value) { + mQueryParameterMap.put(key, value); + return (T) this; + } + + @Override + public T addQueryParameter(Map queryParameterMap) { + if (queryParameterMap != null) { + mQueryParameterMap.putAll(queryParameterMap); + } + return (T) this; + } + + @Override + public T addQueryParameter(Object object) { + if (object != null) { + mQueryParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T addPathParameter(String key, String value) { + mPathParameterMap.put(key, value); + return (T) this; + } + + @Override + public T addPathParameter(Map pathParameterMap) { + if (pathParameterMap != null) { + mPathParameterMap.putAll(pathParameterMap); + } + return (T) this; + } + + @Override + public T addPathParameter(Object object) { + if (object != null) { + mPathParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T doNotCacheResponse() { + mCacheControl = new CacheControl.Builder().noStore().build(); + return (T) this; + } + + @Override + public T getResponseOnlyIfCached() { + mCacheControl = CacheControl.FORCE_CACHE; + return (T) this; + } + + @Override + public T getResponseOnlyFromNetwork() { + mCacheControl = CacheControl.FORCE_NETWORK; + return (T) this; + } + + @Override + public T setMaxAgeCacheControl(int maxAge, TimeUnit timeUnit) { + mCacheControl = new CacheControl.Builder().maxAge(maxAge, timeUnit).build(); + return (T) this; + } + + @Override + public T setMaxStaleCacheControl(int maxStale, TimeUnit timeUnit) { + mCacheControl = new CacheControl.Builder().maxStale(maxStale, timeUnit).build(); + return (T) this; + } + + @Override + public T setExecutor(Executor executor) { + mExecutor = executor; + return (T) this; + } + + @Override + public T setOkHttpClient(OkHttpClient okHttpClient) { + mOkHttpClient = okHttpClient; + return (T) this; + } + + @Override + public T setUserAgent(String userAgent) { + mUserAgent = userAgent; + return (T) this; + } + + public T setPercentageThresholdForCancelling(int percentageThresholdForCancelling) { + mPercentageThresholdForCancelling = percentageThresholdForCancelling; + return (T) this; + } + + public ANRequest build() { + return new ANRequest(this); + } + } + + public static class MultiPartBuilder implements RequestBuilder { + + private Priority mPriority = Priority.MEDIUM; + private String mUrl; + private Object mTag; + private HashMap mHeadersMap = new HashMap<>(); + private HashMap mMultiPartParameterMap = new HashMap<>(); + private HashMap mQueryParameterMap = new HashMap<>(); + private HashMap mPathParameterMap = new HashMap<>(); + private HashMap mMultiPartFileMap = new HashMap<>(); + private CacheControl mCacheControl; + private int mPercentageThresholdForCancelling = 0; + private Executor mExecutor; + private OkHttpClient mOkHttpClient; + private String mUserAgent; + private String mCustomContentType; + + public MultiPartBuilder(String url) { + this.mUrl = url; + } + + @Override + public T setPriority(Priority priority) { + mPriority = priority; + return (T) this; + } + + @Override + public T setTag(Object tag) { + mTag = tag; + return (T) this; + } + + @Override + public T addQueryParameter(String key, String value) { + mQueryParameterMap.put(key, value); + return (T) this; + } + + @Override + public T addQueryParameter(Map queryParameterMap) { + if (queryParameterMap != null) { + mQueryParameterMap.putAll(queryParameterMap); + } + return (T) this; + } + + @Override + public T addQueryParameter(Object object) { + if (object != null) { + mQueryParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T addPathParameter(String key, String value) { + mPathParameterMap.put(key, value); + return (T) this; + } + + @Override + public T addPathParameter(Map pathParameterMap) { + if (pathParameterMap != null) { + mPathParameterMap.putAll(pathParameterMap); + } + return (T) this; + } + + @Override + public T addPathParameter(Object object) { + if (object != null) { + mPathParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T addHeaders(String key, String value) { + mHeadersMap.put(key, value); + return (T) this; + } + + @Override + public T addHeaders(Map headerMap) { + if (headerMap != null) { + mHeadersMap.putAll(headerMap); + } + return (T) this; + } + + @Override + public T addHeaders(Object object) { + if (object != null) { + mHeadersMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + @Override + public T doNotCacheResponse() { + mCacheControl = new CacheControl.Builder().noStore().build(); + return (T) this; + } + + @Override + public T getResponseOnlyIfCached() { + mCacheControl = CacheControl.FORCE_CACHE; + return (T) this; + } + + @Override + public T getResponseOnlyFromNetwork() { + mCacheControl = CacheControl.FORCE_NETWORK; + return (T) this; + } + + @Override + public T setMaxAgeCacheControl(int maxAge, TimeUnit timeUnit) { + mCacheControl = new CacheControl.Builder().maxAge(maxAge, timeUnit).build(); + return (T) this; + } + + @Override + public T setMaxStaleCacheControl(int maxStale, TimeUnit timeUnit) { + mCacheControl = new CacheControl.Builder().maxStale(maxStale, timeUnit).build(); + return (T) this; + } + + @Override + public T setExecutor(Executor executor) { + mExecutor = executor; + return (T) this; + } + + @Override + public T setOkHttpClient(OkHttpClient okHttpClient) { + mOkHttpClient = okHttpClient; + return (T) this; + } + + @Override + public T setUserAgent(String userAgent) { + mUserAgent = userAgent; + return (T) this; + } + + public T addMultipartParameter(String key, String value) { + mMultiPartParameterMap.put(key, value); + return (T) this; + } + + public T addMultipartParameter(Map multiPartParameterMap) { + if (multiPartParameterMap != null) { + mMultiPartParameterMap.putAll(multiPartParameterMap); + } + return (T) this; + } + + public T addMultipartParameter(Object object) { + if (object != null) { + mMultiPartParameterMap.putAll(ParseUtil + .getParserFactory() + .getStringMap(object)); + } + return (T) this; + } + + public T addMultipartFile(String key, File file) { + mMultiPartFileMap.put(key, file); + return (T) this; + } + + public T addMultipartFile(Map multiPartFileMap) { + if (multiPartFileMap != null) { + mMultiPartFileMap.putAll(multiPartFileMap); + } + return (T) this; + } + + public T setPercentageThresholdForCancelling(int percentageThresholdForCancelling) { + this.mPercentageThresholdForCancelling = percentageThresholdForCancelling; + return (T) this; + } + + public T setContentType(String contentType) { + mCustomContentType = contentType; + return (T) this; + } + + public ANRequest build() { + return new ANRequest(this); + } + } + + @Override + public String toString() { + return "ANRequest{" + + "sequenceNumber='" + sequenceNumber + + ", mMethod=" + mMethod + + ", mPriority=" + mPriority + + ", mRequestType=" + mRequestType + + ", mUrl=" + mUrl + + '}'; + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/ANResponse.java b/android-networking/src/main/java/com/androidnetworking/common/ANResponse.java new file mode 100644 index 0000000..2b4e8d2 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/ANResponse.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +import com.androidnetworking.error.ANError; + +import okhttp3.Response; + +/** + * Created by owner on 22/03/16. + */ +public class ANResponse { + + private final T mResult; + + private final ANError mANError; + + private Response response; + + public static ANResponse success(T result) { + return new ANResponse<>(result); + } + + public static ANResponse failed(ANError anError) { + return new ANResponse<>(anError); + } + + public ANResponse(T result) { + this.mResult = result; + this.mANError = null; + } + + public ANResponse(ANError anError) { + this.mResult = null; + this.mANError = anError; + } + + public T getResult() { + return mResult; + } + + public boolean isSuccess() { + return mANError == null; + } + + public ANError getError() { + return mANError; + } + + public void setOkHttpResponse(Response response) { + this.response = response; + } + + public Response getOkHttpResponse() { + return response; + } + +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/ConnectionClassManager.java b/android-networking/src/main/java/com/androidnetworking/common/ConnectionClassManager.java new file mode 100644 index 0000000..b903d38 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/ConnectionClassManager.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +import com.androidnetworking.core.Core; +import com.androidnetworking.interfaces.ConnectionQualityChangeListener; + +/** + * Created by owner on 29/05/16. + */ +public class ConnectionClassManager { + + private static final int BYTES_TO_BITS = 8; + private static final int DEFAULT_SAMPLES_TO_QUALITY_CHANGE = 5; + private static final int MINIMUM_SAMPLES_TO_DECIDE_QUALITY = 2; + private static final int DEFAULT_POOR_BANDWIDTH = 150; + private static final int DEFAULT_MODERATE_BANDWIDTH = 550; + private static final int DEFAULT_GOOD_BANDWIDTH = 2000; + private static final long BANDWIDTH_LOWER_BOUND = 10; + + private static ConnectionClassManager sInstance; + private ConnectionQuality mCurrentConnectionQuality = ConnectionQuality.UNKNOWN; + private int mCurrentBandwidthForSampling = 0; + private int mCurrentNumberOfSample = 0; + private int mCurrentBandwidth = 0; + private ConnectionQualityChangeListener mConnectionQualityChangeListener; + + public static ConnectionClassManager getInstance() { + if (sInstance == null) { + synchronized (ConnectionClassManager.class) { + if (sInstance == null) { + sInstance = new ConnectionClassManager(); + } + } + } + return sInstance; + } + + public synchronized void updateBandwidth(long bytes, long timeInMs) { + if (timeInMs == 0 || bytes < 20000 || (bytes) * 1.0 / (timeInMs) * + BYTES_TO_BITS < BANDWIDTH_LOWER_BOUND) { + return; + } + double bandwidth = (bytes) * 1.0 / (timeInMs) * BYTES_TO_BITS; + mCurrentBandwidthForSampling = (int) ((mCurrentBandwidthForSampling * + mCurrentNumberOfSample + bandwidth) / (mCurrentNumberOfSample + 1)); + mCurrentNumberOfSample++; + if (mCurrentNumberOfSample == DEFAULT_SAMPLES_TO_QUALITY_CHANGE || + (mCurrentConnectionQuality == ConnectionQuality.UNKNOWN && + mCurrentNumberOfSample == MINIMUM_SAMPLES_TO_DECIDE_QUALITY)) { + final ConnectionQuality lastConnectionQuality = mCurrentConnectionQuality; + mCurrentBandwidth = mCurrentBandwidthForSampling; + if (mCurrentBandwidthForSampling <= 0) { + mCurrentConnectionQuality = ConnectionQuality.UNKNOWN; + } else if (mCurrentBandwidthForSampling < DEFAULT_POOR_BANDWIDTH) { + mCurrentConnectionQuality = ConnectionQuality.POOR; + } else if (mCurrentBandwidthForSampling < DEFAULT_MODERATE_BANDWIDTH) { + mCurrentConnectionQuality = ConnectionQuality.MODERATE; + } else if (mCurrentBandwidthForSampling < DEFAULT_GOOD_BANDWIDTH) { + mCurrentConnectionQuality = ConnectionQuality.GOOD; + } else if (mCurrentBandwidthForSampling > DEFAULT_GOOD_BANDWIDTH) { + mCurrentConnectionQuality = ConnectionQuality.EXCELLENT; + } + if (mCurrentNumberOfSample == DEFAULT_SAMPLES_TO_QUALITY_CHANGE) { + mCurrentBandwidthForSampling = 0; + mCurrentNumberOfSample = 0; + } + if (mCurrentConnectionQuality != lastConnectionQuality && + mConnectionQualityChangeListener != null) { + Core.getInstance().getExecutorSupplier().forMainThreadTasks() + .execute(new Runnable() { + @Override + public void run() { + mConnectionQualityChangeListener + .onChange(mCurrentConnectionQuality, mCurrentBandwidth); + } + }); + } + } + + } + + public int getCurrentBandwidth() { + return mCurrentBandwidth; + } + + public ConnectionQuality getCurrentConnectionQuality() { + return mCurrentConnectionQuality; + } + + public void setListener(ConnectionQualityChangeListener connectionQualityChangeListener) { + mConnectionQualityChangeListener = connectionQualityChangeListener; + } + + public void removeListener() { + mConnectionQualityChangeListener = null; + } + + public static void shutDown() { + if (sInstance != null) { + sInstance = null; + } + } + +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/ConnectionQuality.java b/android-networking/src/main/java/com/androidnetworking/common/ConnectionQuality.java new file mode 100644 index 0000000..4eb0787 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/ConnectionQuality.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +/** + * Created by owner on 29/05/16. + */ +public enum ConnectionQuality { + /** + * Bandwidth under 150 kbps. + */ + POOR, + /** + * Bandwidth between 150 and 550 kbps. + */ + MODERATE, + /** + * Bandwidth between 550 and 2000 kbps. + */ + GOOD, + /** + * EXCELLENT - Bandwidth over 2000 kbps. + */ + EXCELLENT, + /** + * Placeholder for unknown bandwidth. This is the initial value and will stay at this value + * if a bandwidth cannot be accurately found. + */ + UNKNOWN +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/Method.java b/android-networking/src/main/java/com/androidnetworking/common/Method.java new file mode 100644 index 0000000..1735743 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/Method.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +/** + * Created by owner on 26/03/16. + */ +public interface Method { + int GET = 0; + int POST = 1; + int PUT = 2; + int DELETE = 3; + int HEAD = 4; + int PATCH = 5; +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/Priority.java b/android-networking/src/main/java/com/androidnetworking/common/Priority.java new file mode 100644 index 0000000..d763e71 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/Priority.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +/** + * Created by owner on 22/03/16. + */ + + +/** + * Priority levels recognized by the request server. + */ +public enum Priority { + /** + * NOTE: DO NOT CHANGE ORDERING OF THOSE CONSTANTS UNDER ANY CIRCUMSTANCES. + * Doing so will make ordering incorrect. + */ + + /** + * Lowest priority level. Used for prefetches of data. + */ + LOW, + + /** + * Medium priority level. Used for warming of data that might soon get visible. + */ + MEDIUM, + + /** + * Highest priority level. Used for data that are currently visible on screen. + */ + HIGH, + + /** + * Highest priority level. Used for data that are required instantly(mainly for emergency). + */ + IMMEDIATE + +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/RequestBuilder.java b/android-networking/src/main/java/com/androidnetworking/common/RequestBuilder.java new file mode 100644 index 0000000..a72cda3 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/RequestBuilder.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; + +/** + * Created by owner on 26/03/16. + */ +public interface RequestBuilder { + + RequestBuilder setPriority(Priority priority); + + RequestBuilder setTag(Object tag); + + RequestBuilder addHeaders(String key, String value); + + RequestBuilder addHeaders(Map headerMap); + + RequestBuilder addHeaders(Object object); + + RequestBuilder addQueryParameter(String key, String value); + + RequestBuilder addQueryParameter(Map queryParameterMap); + + RequestBuilder addQueryParameter(Object object); + + RequestBuilder addPathParameter(String key, String value); + + RequestBuilder addPathParameter(Map pathParameterMap); + + RequestBuilder addPathParameter(Object object); + + RequestBuilder doNotCacheResponse(); + + RequestBuilder getResponseOnlyIfCached(); + + RequestBuilder getResponseOnlyFromNetwork(); + + RequestBuilder setMaxAgeCacheControl(int maxAge, TimeUnit timeUnit); + + RequestBuilder setMaxStaleCacheControl(int maxStale, TimeUnit timeUnit); + + RequestBuilder setExecutor(Executor executor); + + RequestBuilder setOkHttpClient(OkHttpClient okHttpClient); + + RequestBuilder setUserAgent(String userAgent); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/RequestType.java b/android-networking/src/main/java/com/androidnetworking/common/RequestType.java new file mode 100644 index 0000000..88d70b2 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/RequestType.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +/** + * Created by owner on 04/04/16. + */ +public interface RequestType { + int SIMPLE = 0; + int DOWNLOAD = 1; + int MULTIPART = 2; +} diff --git a/android-networking/src/main/java/com/androidnetworking/common/ResponseType.java b/android-networking/src/main/java/com/androidnetworking/common/ResponseType.java new file mode 100644 index 0000000..5a70c31 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/common/ResponseType.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.common; + +/** + * Created by owner on 26/03/16. + */ +public enum ResponseType { + STRING, + JSON_OBJECT, + JSON_ARRAY, + OK_HTTP_RESPONSE, + BITMAP, + PREFETCH, + PARSED +} diff --git a/android-networking/src/main/java/com/androidnetworking/core/ANExecutor.java b/android-networking/src/main/java/com/androidnetworking/core/ANExecutor.java new file mode 100644 index 0000000..948d41a --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/core/ANExecutor.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.core; + +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.telephony.TelephonyManager; + +import com.androidnetworking.common.Priority; +import com.androidnetworking.internal.InternalRunnable; + +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by owner on 22/03/16. + */ +public class ANExecutor extends ThreadPoolExecutor { + + private static final int DEFAULT_THREAD_COUNT = 3; + + ANExecutor(int maxNumThreads, ThreadFactory threadFactory) { + super(maxNumThreads, maxNumThreads, 0, TimeUnit.MILLISECONDS, + new PriorityBlockingQueue(), threadFactory); + } + + + void adjustThreadCount(NetworkInfo info) { + if (info == null || !info.isConnectedOrConnecting()) { + setThreadCount(DEFAULT_THREAD_COUNT); + return; + } + switch (info.getType()) { + case ConnectivityManager.TYPE_WIFI: + case ConnectivityManager.TYPE_WIMAX: + case ConnectivityManager.TYPE_ETHERNET: + setThreadCount(4); + break; + case ConnectivityManager.TYPE_MOBILE: + switch (info.getSubtype()) { + case TelephonyManager.NETWORK_TYPE_LTE: // 4G + case TelephonyManager.NETWORK_TYPE_HSPAP: + case TelephonyManager.NETWORK_TYPE_EHRPD: + setThreadCount(3); + break; + case TelephonyManager.NETWORK_TYPE_UMTS: // 3G + case TelephonyManager.NETWORK_TYPE_CDMA: + case TelephonyManager.NETWORK_TYPE_EVDO_0: + case TelephonyManager.NETWORK_TYPE_EVDO_A: + case TelephonyManager.NETWORK_TYPE_EVDO_B: + setThreadCount(2); + break; + case TelephonyManager.NETWORK_TYPE_GPRS: // 2G + case TelephonyManager.NETWORK_TYPE_EDGE: + setThreadCount(1); + break; + default: + setThreadCount(DEFAULT_THREAD_COUNT); + } + break; + default: + setThreadCount(DEFAULT_THREAD_COUNT); + } + } + + private void setThreadCount(int threadCount) { + setCorePoolSize(threadCount); + setMaximumPoolSize(threadCount); + } + + @Override + public Future submit(Runnable task) { + AndroidNetworkingFutureTask futureTask = new AndroidNetworkingFutureTask((InternalRunnable) task); + execute(futureTask); + return futureTask; + } + + private static final class AndroidNetworkingFutureTask extends FutureTask + implements Comparable { + private final InternalRunnable hunter; + + public AndroidNetworkingFutureTask(InternalRunnable hunter) { + super(hunter, null); + this.hunter = hunter; + } + + @Override + public int compareTo(AndroidNetworkingFutureTask other) { + Priority p1 = hunter.getPriority(); + Priority p2 = other.hunter.getPriority(); + return (p1 == p2 ? hunter.sequence - other.hunter.sequence : p2.ordinal() - p1.ordinal()); + } + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/core/Core.java b/android-networking/src/main/java/com/androidnetworking/core/Core.java new file mode 100644 index 0000000..95563f4 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/core/Core.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.core; + +/** + * Created by owner on 22/03/16. + */ +public class Core { + + private static Core sInstance = null; + private final ExecutorSupplier mExecutorSupplier; + + private Core() { + this.mExecutorSupplier = new DefaultExecutorSupplier(); + } + + public static Core getInstance() { + if (sInstance == null) { + synchronized (Core.class) { + if (sInstance == null) { + sInstance = new Core(); + } + } + } + return sInstance; + } + + public ExecutorSupplier getExecutorSupplier() { + return mExecutorSupplier; + } + + public static void shutDown() { + if (sInstance != null) { + sInstance = null; + } + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/core/DefaultExecutorSupplier.java b/android-networking/src/main/java/com/androidnetworking/core/DefaultExecutorSupplier.java new file mode 100644 index 0000000..aac0017 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/core/DefaultExecutorSupplier.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.core; + +import android.os.Process; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadFactory; + +/** + * Created by owner on 22/03/16. + */ +public class DefaultExecutorSupplier implements ExecutorSupplier { + + public static final int DEFAULT_MAX_NUM_THREADS = 2 * Runtime.getRuntime().availableProcessors() + 1; + private final ANExecutor mNetworkExecutor; + private final ANExecutor mImmediateNetworkExecutor; + private final Executor mMainThreadExecutor; + + public DefaultExecutorSupplier() { + ThreadFactory backgroundPriorityThreadFactory = new PriorityThreadFactory(Process.THREAD_PRIORITY_BACKGROUND); + mNetworkExecutor = new ANExecutor(DEFAULT_MAX_NUM_THREADS, backgroundPriorityThreadFactory); + mImmediateNetworkExecutor = new ANExecutor(2, backgroundPriorityThreadFactory); + mMainThreadExecutor = new MainThreadExecutor(); + } + + @Override + public ANExecutor forNetworkTasks() { + return mNetworkExecutor; + } + + @Override + public ANExecutor forImmediateNetworkTasks() { + return mImmediateNetworkExecutor; + } + + @Override + public Executor forMainThreadTasks() { + return mMainThreadExecutor; + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/core/ExecutorSupplier.java b/android-networking/src/main/java/com/androidnetworking/core/ExecutorSupplier.java new file mode 100644 index 0000000..16e9699 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/core/ExecutorSupplier.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.core; + +import java.util.concurrent.Executor; + +/** + * Created by owner on 22/03/16. + */ +public interface ExecutorSupplier { + + ANExecutor forNetworkTasks(); + + ANExecutor forImmediateNetworkTasks(); + + Executor forMainThreadTasks(); +} diff --git a/android-networking/src/main/java/com/androidnetworking/core/MainThreadExecutor.java b/android-networking/src/main/java/com/androidnetworking/core/MainThreadExecutor.java new file mode 100644 index 0000000..67e2c6f --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/core/MainThreadExecutor.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.core; + +import android.os.Handler; +import android.os.Looper; + +import java.util.concurrent.Executor; + +/** + * Created by owner on 22/03/16. + */ +public class MainThreadExecutor implements Executor { + + private final Handler handler = new Handler(Looper.getMainLooper()); + + @Override + public void execute(Runnable runnable) { + handler.post(runnable); + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/core/PriorityThreadFactory.java b/android-networking/src/main/java/com/androidnetworking/core/PriorityThreadFactory.java new file mode 100644 index 0000000..63dbe32 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/core/PriorityThreadFactory.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.core; + +/** + * Created by owner on 22/03/16. + */ + + +import android.os.Process; + +import java.util.concurrent.ThreadFactory; + +public class PriorityThreadFactory implements ThreadFactory { + + private final int mThreadPriority; + + public PriorityThreadFactory(int threadPriority) { + mThreadPriority = threadPriority; + } + + @Override + public Thread newThread(final Runnable runnable) { + Runnable wrapperRunnable = new Runnable() { + @Override + public void run() { + try { + Process.setThreadPriority(mThreadPriority); + } catch (Throwable t) { + + } + runnable.run(); + } + }; + return new Thread(wrapperRunnable); + } + +} diff --git a/android-networking/src/main/java/com/androidnetworking/error/ANError.java b/android-networking/src/main/java/com/androidnetworking/error/ANError.java new file mode 100644 index 0000000..cc8a32f --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/error/ANError.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.error; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.utils.ParseUtil; + +import okhttp3.Response; + +/** + * Created by owner on 22/03/16. + */ +@SuppressWarnings({"unchecked", "unused"}) +public class ANError extends Exception { + + private String errorBody; + + private int errorCode = 0; + + private String errorDetail; + + private Response response; + + public ANError() { + } + + public ANError(Response response) { + this.response = response; + } + + public ANError(String message) { + super(message); + } + + public ANError(String message, Response response) { + super(message); + this.response = response; + } + + public ANError(String message, Throwable throwable) { + super(message, throwable); + } + + public ANError(String message, Response response, Throwable throwable) { + super(message, throwable); + this.response = response; + } + + public ANError(Response response, Throwable throwable) { + super(throwable); + this.response = response; + } + + public ANError(Throwable throwable) { + super(throwable); + } + + public Response getResponse() { + return response; + } + + public void setErrorDetail(String errorDetail) { + this.errorDetail = errorDetail; + } + + public String getErrorDetail() { + return this.errorDetail; + } + + public void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } + + public int getErrorCode() { + return this.errorCode; + } + + public void setCancellationMessageInError() { + this.errorDetail = ANConstants.REQUEST_CANCELLED_ERROR; + } + + public String getErrorBody() { + return errorBody; + } + + public void setErrorBody(String errorBody) { + this.errorBody = errorBody; + } + + public T getErrorAsObject(Class objectClass) { + try { + return (T) (ParseUtil + .getParserFactory() + .getObject(errorBody, objectClass)); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/gsonparserfactory/GsonParserFactory.java b/android-networking/src/main/java/com/androidnetworking/gsonparserfactory/GsonParserFactory.java new file mode 100644 index 0000000..222b0e3 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/gsonparserfactory/GsonParserFactory.java @@ -0,0 +1,91 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.gsonparserfactory; + +import com.androidnetworking.interfaces.Parser; +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.HashMap; + +import okhttp3.RequestBody; +import okhttp3.ResponseBody; + +/** + * Created by owner on 31/07/16. + */ +public final class GsonParserFactory extends Parser.Factory { + + private final Gson gson; + + public GsonParserFactory() { + this.gson = new Gson(); + } + + public GsonParserFactory(Gson gson) { + this.gson = gson; + } + + @Override + public Parser responseBodyParser(Type type) { + TypeAdapter adapter = gson.getAdapter(TypeToken.get(type)); + return new GsonResponseBodyParser<>(gson, adapter); + } + + @Override + public Parser requestBodyParser(Type type) { + TypeAdapter adapter = gson.getAdapter(TypeToken.get(type)); + return new GsonRequestBodyParser<>(gson, adapter); + } + + @Override + public Object getObject(String string, Type type) { + try { + return gson.fromJson(string, type); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + public String getString(Object object) { + try { + return gson.toJson(object); + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + + @Override + public HashMap getStringMap(Object object) { + try { + Type type = new TypeToken>() { + }.getType(); + return gson.fromJson(gson.toJson(object), type); + } catch (Exception e) { + e.printStackTrace(); + } + return new HashMap<>(); + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/gsonparserfactory/GsonRequestBodyParser.java b/android-networking/src/main/java/com/androidnetworking/gsonparserfactory/GsonRequestBodyParser.java new file mode 100644 index 0000000..b83adc2 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/gsonparserfactory/GsonRequestBodyParser.java @@ -0,0 +1,60 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.gsonparserfactory; + +import com.androidnetworking.interfaces.Parser; +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.Charset; + +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okio.Buffer; + +/** + * Created by owner on 31/07/16. + */ +final class GsonRequestBodyParser implements Parser { + private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8"); + private static final Charset UTF_8 = Charset.forName("UTF-8"); + + private final Gson gson; + private final TypeAdapter adapter; + + GsonRequestBodyParser(Gson gson, TypeAdapter adapter) { + this.gson = gson; + this.adapter = adapter; + } + + @Override + public RequestBody convert(T value) throws IOException { + Buffer buffer = new Buffer(); + Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8); + JsonWriter jsonWriter = gson.newJsonWriter(writer); + adapter.write(jsonWriter, value); + jsonWriter.close(); + return RequestBody.create(MEDIA_TYPE, buffer.readByteString()); + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/gsonparserfactory/GsonResponseBodyParser.java b/android-networking/src/main/java/com/androidnetworking/gsonparserfactory/GsonResponseBodyParser.java new file mode 100644 index 0000000..973de31 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/gsonparserfactory/GsonResponseBodyParser.java @@ -0,0 +1,52 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.gsonparserfactory; + +import com.androidnetworking.interfaces.Parser; +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; + +import java.io.IOException; + +import okhttp3.ResponseBody; + +/** + * Created by owner on 31/07/16. + */ +final class GsonResponseBodyParser implements Parser { + private final Gson gson; + private final TypeAdapter adapter; + + GsonResponseBodyParser(Gson gson, TypeAdapter adapter) { + this.gson = gson; + this.adapter = adapter; + } + + @Override + public T convert(ResponseBody value) throws IOException { + JsonReader jsonReader = gson.newJsonReader(value.charStream()); + try { + return adapter.read(jsonReader); + } finally { + value.close(); + } + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/interceptors/GzipRequestInterceptor.java b/android-networking/src/main/java/com/androidnetworking/interceptors/GzipRequestInterceptor.java new file mode 100644 index 0000000..1795d01 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interceptors/GzipRequestInterceptor.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interceptors; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okio.Buffer; +import okio.BufferedSink; +import okio.GzipSink; +import okio.Okio; + +/** + * Created by owner on 02/05/16. + */ +public class GzipRequestInterceptor implements Interceptor { + @Override + public Response intercept(Chain chain) throws IOException { + Request originalRequest = chain.request(); + if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) { + return chain.proceed(originalRequest); + } + + Request compressedRequest = originalRequest.newBuilder() + .header("Content-Encoding", "gzip") + .method(originalRequest.method(), forceContentLength(gzip(originalRequest.body()))) + .build(); + return chain.proceed(compressedRequest); + } + + private RequestBody forceContentLength(final RequestBody requestBody) throws IOException { + final Buffer buffer = new Buffer(); + requestBody.writeTo(buffer); + return new RequestBody() { + @Override + public MediaType contentType() { + return requestBody.contentType(); + } + + @Override + public long contentLength() { + return buffer.size(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + sink.write(buffer.snapshot()); + } + }; + } + + + private RequestBody gzip(final RequestBody body) { + return new RequestBody() { + @Override + public MediaType contentType() { + return body.contentType(); + } + + @Override + public long contentLength() { + return -1; // We don't know the compressed length in advance! + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + BufferedSink gzipSink = Okio.buffer(new GzipSink(sink)); + body.writeTo(gzipSink); + gzipSink.close(); + } + }; + } +} \ No newline at end of file diff --git a/android-networking/src/main/java/com/androidnetworking/interceptors/HttpLoggingInterceptor.java b/android-networking/src/main/java/com/androidnetworking/interceptors/HttpLoggingInterceptor.java new file mode 100644 index 0000000..de7867b --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interceptors/HttpLoggingInterceptor.java @@ -0,0 +1,302 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.interceptors; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.concurrent.TimeUnit; + +import okhttp3.Connection; +import okhttp3.Headers; +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.internal.http.HttpHeaders; +import okhttp3.internal.platform.Platform; +import okio.Buffer; +import okio.BufferedSource; + +import static okhttp3.internal.platform.Platform.INFO; + +/** + * Created by owner on 31/01/17. + */ + +public class HttpLoggingInterceptor implements Interceptor { + + private static final Charset UTF8 = Charset.forName("UTF-8"); + + public enum Level { + /** + * No logs. + */ + NONE, + /** + * Logs request and response lines. + *

+ *

Example: + *

{@code
+         * --> POST /greeting http/1.1 (3-byte body)
+         *
+         * <-- 200 OK (22ms, 6-byte body)
+         * }
+ */ + BASIC, + /** + * Logs request and response lines and their respective headers. + *

+ *

Example: + *

{@code
+         * --> POST /greeting http/1.1
+         * Host: example.com
+         * Content-Type: plain/text
+         * Content-Length: 3
+         * --> END POST
+         *
+         * <-- 200 OK (22ms)
+         * Content-Type: plain/text
+         * Content-Length: 6
+         * <-- END HTTP
+         * }
+ */ + HEADERS, + /** + * Logs request and response lines and their respective headers and bodies (if present). + *

+ *

Example: + *

{@code
+         * --> POST /greeting http/1.1
+         * Host: example.com
+         * Content-Type: plain/text
+         * Content-Length: 3
+         *
+         * Hi?
+         * --> END POST
+         *
+         * <-- 200 OK (22ms)
+         * Content-Type: plain/text
+         * Content-Length: 6
+         *
+         * Hello!
+         * <-- END HTTP
+         * }
+ */ + BODY + } + + public interface Logger { + void log(String message); + + /** + * A {@link Logger} defaults output appropriate for the current platform. + */ + Logger DEFAULT = new Logger() { + @Override + public void log(String message) { + Platform.get().log(INFO, message, null); + } + }; + } + + public HttpLoggingInterceptor() { + this(Logger.DEFAULT); + } + + public HttpLoggingInterceptor(Logger logger) { + this.logger = logger; + } + + private final Logger logger; + + private volatile Level level = Level.NONE; + + /** + * Change the level at which this interceptor logs. + */ + public HttpLoggingInterceptor setLevel(Level level) { + if (level == null) throw new NullPointerException("level == null. Use Level.NONE instead."); + this.level = level; + return this; + } + + public Level getLevel() { + return level; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Level level = this.level; + + Request request = chain.request(); + if (level == Level.NONE) { + return chain.proceed(request); + } + + boolean logBody = level == Level.BODY; + boolean logHeaders = logBody || level == Level.HEADERS; + + RequestBody requestBody = request.body(); + boolean hasRequestBody = requestBody != null; + + Connection connection = chain.connection(); + Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1; + String requestStartMessage = "--> " + request.method() + ' ' + request.url() + ' ' + protocol; + if (!logHeaders && hasRequestBody) { + requestStartMessage += " (" + requestBody.contentLength() + "-byte body)"; + } + logger.log(requestStartMessage); + + if (logHeaders) { + if (hasRequestBody) { + // Request body headers are only present when installed as a network interceptor. Force + // them to be included (when available) so there values are known. + if (requestBody.contentType() != null) { + logger.log("Content-Type: " + requestBody.contentType()); + } + if (requestBody.contentLength() != -1) { + logger.log("Content-Length: " + requestBody.contentLength()); + } + } + + Headers headers = request.headers(); + for (int i = 0, count = headers.size(); i < count; i++) { + String name = headers.name(i); + // Skip headers from the request body as they are explicitly logged above. + if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) { + logger.log(name + ": " + headers.value(i)); + } + } + + if (!logBody || !hasRequestBody) { + logger.log("--> END " + request.method()); + } else if (bodyEncoded(request.headers())) { + logger.log("--> END " + request.method() + " (encoded body omitted)"); + } else { + Buffer buffer = new Buffer(); + requestBody.writeTo(buffer); + + Charset charset = UTF8; + MediaType contentType = requestBody.contentType(); + if (contentType != null) { + charset = contentType.charset(UTF8); + } + + logger.log(""); + if (isPlaintext(buffer)) { + logger.log(buffer.readString(charset)); + logger.log("--> END " + request.method() + + " (" + requestBody.contentLength() + "-byte body)"); + } else { + logger.log("--> END " + request.method() + " (binary " + + requestBody.contentLength() + "-byte body omitted)"); + } + } + } + + long startNs = System.nanoTime(); + Response response; + try { + response = chain.proceed(request); + } catch (Exception e) { + logger.log("<-- HTTP FAILED: " + e); + throw e; + } + long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs); + + ResponseBody responseBody = response.body(); + long contentLength = responseBody.contentLength(); + String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length"; + logger.log("<-- " + response.code() + ' ' + response.message() + ' ' + + response.request().url() + " (" + tookMs + "ms" + (!logHeaders ? ", " + + bodySize + " body" : "") + ')'); + + if (logHeaders) { + Headers headers = response.headers(); + for (int i = 0, count = headers.size(); i < count; i++) { + logger.log(headers.name(i) + ": " + headers.value(i)); + } + + if (!logBody || !HttpHeaders.hasBody(response)) { + logger.log("<-- END HTTP"); + } else if (bodyEncoded(response.headers())) { + logger.log("<-- END HTTP (encoded body omitted)"); + } else { + BufferedSource source = responseBody.source(); + source.request(Long.MAX_VALUE); // Buffer the entire body. + Buffer buffer = source.buffer(); + + Charset charset = UTF8; + MediaType contentType = responseBody.contentType(); + if (contentType != null) { + charset = contentType.charset(UTF8); + } + + if (!isPlaintext(buffer)) { + logger.log(""); + logger.log("<-- END HTTP (binary " + buffer.size() + "-byte body omitted)"); + return response; + } + + if (contentLength != 0) { + logger.log(""); + logger.log(buffer.clone().readString(charset)); + } + + logger.log("<-- END HTTP (" + buffer.size() + "-byte body)"); + } + } + + return response; + } + + /** + * Returns true if the body in question probably contains human readable text. Uses a small sample + * of code points to detect unicode control characters commonly used in binary file signatures. + */ + static boolean isPlaintext(Buffer buffer) { + try { + Buffer prefix = new Buffer(); + long byteCount = buffer.size() < 64 ? buffer.size() : 64; + buffer.copyTo(prefix, 0, byteCount); + for (int i = 0; i < 16; i++) { + if (prefix.exhausted()) { + break; + } + int codePoint = prefix.readUtf8CodePoint(); + if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) { + return false; + } + } + return true; + } catch (EOFException e) { + return false; // Truncated UTF-8 sequence. + } + } + + private boolean bodyEncoded(Headers headers) { + String contentEncoding = headers.get("Content-Encoding"); + return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity"); + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/AnalyticsListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/AnalyticsListener.java new file mode 100644 index 0000000..8ca0e45 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/AnalyticsListener.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interfaces; + +/** + * Created by owner on 31/05/16. + */ +public interface AnalyticsListener { + + void onReceived(long timeTakenInMillis, long bytesSent, long bytesReceived, boolean isFromCache); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/BitmapRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/BitmapRequestListener.java new file mode 100644 index 0000000..5aa537a --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/BitmapRequestListener.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interfaces; + +import android.graphics.Bitmap; + +import com.androidnetworking.error.ANError; + +/** + * Created by owner on 23/05/16. + */ +public interface BitmapRequestListener { + + void onResponse(Bitmap response); + + void onError(ANError anError); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/ConnectionQualityChangeListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/ConnectionQualityChangeListener.java new file mode 100644 index 0000000..b654a76 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/ConnectionQualityChangeListener.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.common.ConnectionQuality; + +/** + * Created by owner on 29/05/16. + */ +public interface ConnectionQualityChangeListener { + + void onChange(ConnectionQuality currentConnectionQuality, int currentBandwidth); +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/DownloadListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/DownloadListener.java new file mode 100644 index 0000000..b4225bc --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/DownloadListener.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +/** + * Created by owner on 29/04/16. + */ +public interface DownloadListener { + + void onDownloadComplete(); + + void onError(ANError anError); +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/DownloadProgressListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/DownloadProgressListener.java new file mode 100644 index 0000000..d63c7ef --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/DownloadProgressListener.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interfaces; + +/** + * Created by owner on 30/03/16. + */ +public interface DownloadProgressListener { + void onProgress(long bytesDownloaded, long totalBytes); +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/JSONArrayRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/JSONArrayRequestListener.java new file mode 100644 index 0000000..51f394b --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/JSONArrayRequestListener.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +import org.json.JSONArray; + +/** + * Created by owner on 23/05/16. + */ +public interface JSONArrayRequestListener { + + void onResponse(JSONArray response); + + void onError(ANError anError); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/JSONObjectRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/JSONObjectRequestListener.java new file mode 100644 index 0000000..82eb47c --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/JSONObjectRequestListener.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +import org.json.JSONObject; + +/** + * Created by owner on 23/05/16. + */ +public interface JSONObjectRequestListener { + + void onResponse(JSONObject response); + + void onError(ANError anError); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndBitmapRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndBitmapRequestListener.java new file mode 100644 index 0000000..4994554 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndBitmapRequestListener.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.interfaces; + +import android.graphics.Bitmap; + +import com.androidnetworking.error.ANError; + +import okhttp3.Response; + +/** + * Created by owner on 23/05/16. + */ +public interface OkHttpResponseAndBitmapRequestListener { + + void onResponse(Response okHttpResponse, Bitmap response); + + void onError(ANError anError); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndJSONArrayRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndJSONArrayRequestListener.java new file mode 100644 index 0000000..7c95e42 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndJSONArrayRequestListener.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +import org.json.JSONArray; + +import okhttp3.Response; + +/** + * Created by owner on 23/05/16. + */ +public interface OkHttpResponseAndJSONArrayRequestListener { + + void onResponse(Response okHttpResponse, JSONArray response); + + void onError(ANError anError); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndJSONObjectRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndJSONObjectRequestListener.java new file mode 100644 index 0000000..292a64a --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndJSONObjectRequestListener.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +import org.json.JSONObject; + +import okhttp3.Response; + +/** + * Created by owner on 23/05/16. + */ +public interface OkHttpResponseAndJSONObjectRequestListener { + + void onResponse(Response okHttpResponse, JSONObject response); + + void onError(ANError anError); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndParsedRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndParsedRequestListener.java new file mode 100644 index 0000000..e487e7e --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndParsedRequestListener.java @@ -0,0 +1,35 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +import okhttp3.Response; + +/** + * Created by owner on 31/07/16. + */ +public interface OkHttpResponseAndParsedRequestListener { + + void onResponse(Response okHttpResponse, T response); + + void onError(ANError anError); + +} \ No newline at end of file diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndStringRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndStringRequestListener.java new file mode 100644 index 0000000..bc7973e --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseAndStringRequestListener.java @@ -0,0 +1,35 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +import okhttp3.Response; + +/** + * Created by owner on 23/05/16. + */ +public interface OkHttpResponseAndStringRequestListener { + + void onResponse(Response okHttpResponse, String response); + + void onError(ANError anError); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseListener.java new file mode 100644 index 0000000..0c6a26a --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/OkHttpResponseListener.java @@ -0,0 +1,35 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +import okhttp3.Response; + +/** + * Created by owner on 22/08/16. + */ +public interface OkHttpResponseListener { + + void onResponse(Response response); + + void onError(ANError anError); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/ParsedRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/ParsedRequestListener.java new file mode 100644 index 0000000..197f447 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/ParsedRequestListener.java @@ -0,0 +1,33 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +/** + * Created by owner on 31/07/16. + */ +public interface ParsedRequestListener { + + void onResponse(T response); + + void onError(ANError anError); + +} \ No newline at end of file diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/Parser.java b/android-networking/src/main/java/com/androidnetworking/interfaces/Parser.java new file mode 100644 index 0000000..c980779 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/Parser.java @@ -0,0 +1,60 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.interfaces; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.HashMap; + +import okhttp3.RequestBody; +import okhttp3.ResponseBody; + +/** + * Created by owner on 31/07/16. + */ +public interface Parser { + + T convert(F value) throws IOException; + + abstract class Factory { + + public Parser responseBodyParser(Type type) { + return null; + } + + public Parser requestBodyParser(Type type) { + return null; + } + + public Object getObject(String string, Type type) { + return null; + } + + public String getString(Object object) { + return null; + } + + public HashMap getStringMap(Object object) { + return null; + } + + } + +} \ No newline at end of file diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/StringRequestListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/StringRequestListener.java new file mode 100644 index 0000000..9432d5d --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/StringRequestListener.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interfaces; + +import com.androidnetworking.error.ANError; + +/** + * Created by owner on 23/05/16. + */ +public interface StringRequestListener { + + void onResponse(String response); + + void onError(ANError anError); + +} diff --git a/android-networking/src/main/java/com/androidnetworking/interfaces/UploadProgressListener.java b/android-networking/src/main/java/com/androidnetworking/interfaces/UploadProgressListener.java new file mode 100644 index 0000000..e6aa12c --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/interfaces/UploadProgressListener.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.interfaces; + +/** + * Created by owner on 21/04/16. + */ +public interface UploadProgressListener { + void onProgress(long bytesUploaded, long totalBytes); +} diff --git a/android-networking/src/main/java/com/androidnetworking/internal/ANImageLoader.java b/android-networking/src/main/java/com/androidnetworking/internal/ANImageLoader.java new file mode 100644 index 0000000..b1c0a01 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/internal/ANImageLoader.java @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.internal; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Handler; +import android.os.Looper; +import android.widget.ImageView; + +import com.androidnetworking.AndroidNetworking; +import com.androidnetworking.cache.LruBitmapCache; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.BitmapRequestListener; + +import java.util.HashMap; +import java.util.LinkedList; + +/** + * Created by owner on 23/03/16. + */ +public class ANImageLoader { + + // Get max available VM memory, exceeding this amount will throw an + // OutOfMemory exception. Stored in kilobytes as LruCache takes an + // int in its constructor. + private static final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); + + // Use 1/8th of the available memory for this memory cache. + private static final int cacheSize = maxMemory / 8; + + private int mBatchResponseDelayMs = 100; + + private final ImageCache mCache; + + private final HashMap mInFlightRequests = + new HashMap(); + + private final HashMap mBatchedResponses = + new HashMap(); + + private final Handler mHandler = new Handler(Looper.getMainLooper()); + + private Runnable mRunnable; + + private BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); + + private static ANImageLoader sInstance; + + public static void initialize() { + getInstance(); + } + + public static ANImageLoader getInstance() { + if (sInstance == null) { + synchronized (ANImageLoader.class) { + if (sInstance == null) { + sInstance = new ANImageLoader(new LruBitmapCache(cacheSize)); + } + } + } + return sInstance; + } + + public interface ImageCache { + Bitmap getBitmap(String key); + + void putBitmap(String key, Bitmap bitmap); + + void evictBitmap(String key); + + void evictAllBitmap(); + } + + public ANImageLoader(ImageCache imageCache) { + mCache = imageCache; + } + + public ImageCache getImageCache() { + return mCache; + } + + public static ImageListener getImageListener(final ImageView view, + final int defaultImageResId, + final int errorImageResId) { + return new ImageListener() { + @Override + public void onResponse(ImageContainer response, boolean isImmediate) { + if (response.getBitmap() != null) { + view.setImageBitmap(response.getBitmap()); + } else if (defaultImageResId != 0) { + view.setImageResource(defaultImageResId); + } + } + + @Override + public void onError(ANError anError) { + if (errorImageResId != 0) { + view.setImageResource(errorImageResId); + } + } + }; + } + + public interface ImageListener { + + void onResponse(ImageContainer response, boolean isImmediate); + + void onError(ANError anError); + } + + public boolean isCached(String requestUrl, int maxWidth, int maxHeight) { + return isCached(requestUrl, maxWidth, maxHeight, ImageView.ScaleType.CENTER_INSIDE); + } + + public boolean isCached(String requestUrl, int maxWidth, int maxHeight, + ImageView.ScaleType scaleType) { + throwIfNotOnMainThread(); + + String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight, scaleType); + return mCache.getBitmap(cacheKey) != null; + } + + public ImageContainer get(String requestUrl, final ImageListener listener) { + return get(requestUrl, listener, 0, 0); + } + + + public ImageContainer get(String requestUrl, ImageListener imageListener, + int maxWidth, int maxHeight) { + return get(requestUrl, imageListener, maxWidth, maxHeight, + ImageView.ScaleType.CENTER_INSIDE); + } + + public ImageContainer get(String requestUrl, ImageListener imageListener, + int maxWidth, int maxHeight, ImageView.ScaleType scaleType) { + + throwIfNotOnMainThread(); + + final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight, scaleType); + + Bitmap cachedBitmap = mCache.getBitmap(cacheKey); + if (cachedBitmap != null) { + ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null); + imageListener.onResponse(container, true); + return container; + } + + ImageContainer imageContainer = + new ImageContainer(null, requestUrl, cacheKey, imageListener); + + imageListener.onResponse(imageContainer, true); + + BatchedImageRequest request = mInFlightRequests.get(cacheKey); + if (request != null) { + request.addContainer(imageContainer); + return imageContainer; + } + + ANRequest newRequest = makeImageRequest(requestUrl, maxWidth, maxHeight, scaleType, + cacheKey); + + mInFlightRequests.put(cacheKey, + new BatchedImageRequest(newRequest, imageContainer)); + return imageContainer; + } + + protected ANRequest makeImageRequest(String requestUrl, int maxWidth, int maxHeight, + ImageView.ScaleType scaleType, final String cacheKey) { + ANRequest ANRequest = AndroidNetworking.get(requestUrl) + .setTag("ImageRequestTag") + .setBitmapMaxHeight(maxHeight) + .setBitmapMaxWidth(maxWidth) + .setImageScaleType(scaleType) + .setBitmapConfig(Bitmap.Config.RGB_565) + .setBitmapOptions(mBitmapOptions) + .build(); + + ANRequest.getAsBitmap(new BitmapRequestListener() { + @Override + public void onResponse(Bitmap response) { + onGetImageSuccess(cacheKey, response); + } + + @Override + public void onError(ANError anError) { + onGetImageError(cacheKey, anError); + } + }); + + return ANRequest; + } + + public void setBitmapDecodeOptions(BitmapFactory.Options bitmapOptions) { + mBitmapOptions = bitmapOptions; + } + + public void setBatchedResponseDelay(int newBatchedResponseDelayMs) { + mBatchResponseDelayMs = newBatchedResponseDelayMs; + } + + + protected void onGetImageSuccess(String cacheKey, Bitmap response) { + mCache.putBitmap(cacheKey, response); + + BatchedImageRequest request = mInFlightRequests.remove(cacheKey); + + if (request != null) { + request.mResponseBitmap = response; + + batchResponse(cacheKey, request); + } + } + + protected void onGetImageError(String cacheKey, ANError anError) { + BatchedImageRequest request = mInFlightRequests.remove(cacheKey); + + if (request != null) { + request.setError(anError); + batchResponse(cacheKey, request); + } + } + + public class ImageContainer { + + private Bitmap mBitmap; + + private final ImageListener mListener; + + private final String mCacheKey; + + private final String mRequestUrl; + + public ImageContainer(Bitmap bitmap, String requestUrl, + String cacheKey, ImageListener listener) { + mBitmap = bitmap; + mRequestUrl = requestUrl; + mCacheKey = cacheKey; + mListener = listener; + } + + public void cancelRequest() { + if (mListener == null) { + return; + } + + BatchedImageRequest request = mInFlightRequests.get(mCacheKey); + if (request != null) { + boolean canceled = request.removeContainerAndCancelIfNecessary(this); + if (canceled) { + mInFlightRequests.remove(mCacheKey); + } + } else { + request = mBatchedResponses.get(mCacheKey); + if (request != null) { + request.removeContainerAndCancelIfNecessary(this); + if (request.mContainers.size() == 0) { + mBatchedResponses.remove(mCacheKey); + } + } + } + } + + public Bitmap getBitmap() { + return mBitmap; + } + + + public String getRequestUrl() { + return mRequestUrl; + } + } + + private class BatchedImageRequest { + + private final ANRequest mRequest; + + private Bitmap mResponseBitmap; + + private ANError mANError; + + private final LinkedList mContainers = new LinkedList(); + + public BatchedImageRequest(ANRequest request, ImageContainer container) { + mRequest = request; + mContainers.add(container); + } + + public void setError(ANError anError) { + mANError = anError; + } + + public ANError getError() { + return mANError; + } + + public void addContainer(ImageContainer container) { + mContainers.add(container); + } + + public boolean removeContainerAndCancelIfNecessary(ImageContainer container) { + mContainers.remove(container); + if (mContainers.size() == 0) { + mRequest.cancel(true); + if (mRequest.isCanceled()) { + mRequest.destroy(); + ANRequestQueue.getInstance().finish(mRequest); + } + return true; + } + return false; + } + } + + private void batchResponse(String cacheKey, BatchedImageRequest request) { + mBatchedResponses.put(cacheKey, request); + if (mRunnable == null) { + mRunnable = new Runnable() { + @Override + public void run() { + for (BatchedImageRequest bir : mBatchedResponses.values()) { + for (ImageContainer container : bir.mContainers) { + if (container.mListener == null) { + continue; + } + if (bir.getError() == null) { + container.mBitmap = bir.mResponseBitmap; + container.mListener.onResponse(container, false); + } else { + container.mListener.onError(bir.getError()); + } + } + } + mBatchedResponses.clear(); + mRunnable = null; + } + + }; + mHandler.postDelayed(mRunnable, mBatchResponseDelayMs); + } + } + + private void throwIfNotOnMainThread() { + if (Looper.myLooper() != Looper.getMainLooper()) { + throw new IllegalStateException("ImageLoader must be invoked from the main thread."); + } + } + + private static String getCacheKey(String url, int maxWidth, int maxHeight, + ImageView.ScaleType scaleType) { + return new StringBuilder(url.length() + 12).append("#W").append(maxWidth) + .append("#H").append(maxHeight).append("#S").append(scaleType.ordinal()).append(url) + .toString(); + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/internal/ANRequestQueue.java b/android-networking/src/main/java/com/androidnetworking/internal/ANRequestQueue.java new file mode 100644 index 0000000..b7e9a62 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/internal/ANRequestQueue.java @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.internal; + +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.Priority; +import com.androidnetworking.core.Core; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Created by owner on 22/03/16. + */ +public class ANRequestQueue { + + private final static String TAG = ANRequestQueue.class.getSimpleName(); + private final Set mCurrentRequests = new HashSet<>(); + private AtomicInteger mSequenceGenerator = new AtomicInteger(); + private static ANRequestQueue sInstance = null; + + public static void initialize() { + getInstance(); + } + + public static ANRequestQueue getInstance() { + if (sInstance == null) { + synchronized (ANRequestQueue.class) { + if (sInstance == null) { + sInstance = new ANRequestQueue(); + } + } + } + return sInstance; + } + + public interface RequestFilter { + boolean apply(ANRequest request); + } + + + private void cancel(RequestFilter filter, boolean forceCancel) { + synchronized (mCurrentRequests) { + try { + for (Iterator iterator = mCurrentRequests.iterator(); iterator.hasNext(); ) { + ANRequest request = iterator.next(); + if (filter.apply(request)) { + request.cancel(forceCancel); + if (request.isCanceled()) { + request.destroy(); + iterator.remove(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public void cancelAll(boolean forceCancel) { + synchronized (mCurrentRequests) { + try { + for (Iterator iterator = mCurrentRequests.iterator(); iterator.hasNext(); ) { + ANRequest request = iterator.next(); + request.cancel(forceCancel); + if (request.isCanceled()) { + request.destroy(); + iterator.remove(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public void cancelRequestWithGivenTag(final Object tag, final boolean forceCancel) { + try { + if (tag == null) { + return; + } + cancel(new RequestFilter() { + @Override + public boolean apply(ANRequest request) { + if (request.getTag() instanceof String && tag instanceof String) { + final String tempRequestTag = (String) request.getTag(); + final String tempTag = (String) tag; + return tempRequestTag.equals(tempTag); + } + return request.getTag().equals(tag); + } + }, forceCancel); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public int getSequenceNumber() { + return mSequenceGenerator.incrementAndGet(); + } + + public ANRequest addRequest(ANRequest request) { + synchronized (mCurrentRequests) { + try { + mCurrentRequests.add(request); + } catch (Exception e) { + e.printStackTrace(); + } + } + try { + request.setSequenceNumber(getSequenceNumber()); + if (request.getPriority() == Priority.IMMEDIATE) { + request.setFuture(Core.getInstance() + .getExecutorSupplier() + .forImmediateNetworkTasks() + .submit(new InternalRunnable(request))); + } else { + request.setFuture(Core.getInstance() + .getExecutorSupplier() + .forNetworkTasks() + .submit(new InternalRunnable(request))); + } + } catch (Exception e) { + e.printStackTrace(); + } + return request; + } + + public void finish(ANRequest request) { + synchronized (mCurrentRequests) { + try { + mCurrentRequests.remove(request); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/internal/DownloadProgressHandler.java b/android-networking/src/main/java/com/androidnetworking/internal/DownloadProgressHandler.java new file mode 100644 index 0000000..4646635 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/internal/DownloadProgressHandler.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.internal; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.interfaces.DownloadProgressListener; +import com.androidnetworking.model.Progress; + +/** + * Created by owner on 24/05/16. + */ +public class DownloadProgressHandler extends Handler { + + private final DownloadProgressListener mDownloadProgressListenerWeakRef; + + public DownloadProgressHandler(DownloadProgressListener downloadProgressListener) { + super(Looper.getMainLooper()); + mDownloadProgressListenerWeakRef = downloadProgressListener; + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case ANConstants.UPDATE: + if (mDownloadProgressListenerWeakRef != null) { + final Progress progress = (Progress) msg.obj; + mDownloadProgressListenerWeakRef.onProgress(progress.currentBytes, progress.totalBytes); + } + break; + default: + super.handleMessage(msg); + break; + } + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/internal/InternalNetworking.java b/android-networking/src/main/java/com/androidnetworking/internal/InternalNetworking.java new file mode 100644 index 0000000..6726570 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/internal/InternalNetworking.java @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.internal; + +/** + * Created by owner on 22/03/16. + */ + +import android.content.Context; +import android.net.TrafficStats; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ConnectionClassManager; +import com.androidnetworking.interceptors.HttpLoggingInterceptor; +import com.androidnetworking.interceptors.HttpLoggingInterceptor.Level; +import com.androidnetworking.error.ANError; +import com.androidnetworking.utils.Utils; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import okhttp3.Headers; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import static com.androidnetworking.common.Method.DELETE; +import static com.androidnetworking.common.Method.GET; +import static com.androidnetworking.common.Method.HEAD; +import static com.androidnetworking.common.Method.PATCH; +import static com.androidnetworking.common.Method.POST; +import static com.androidnetworking.common.Method.PUT; + +public final class InternalNetworking { + + private InternalNetworking() { + + } + + public static OkHttpClient sHttpClient = getClient(); + + public static String sUserAgent = null; + + public static Response performSimpleRequest(ANRequest request) throws ANError { + Request okHttpRequest; + Response okHttpResponse; + try { + Request.Builder builder = new Request.Builder().url(request.getUrl()); + addHeadersToRequestBuilder(builder, request); + RequestBody requestBody = null; + switch (request.getMethod()) { + case GET: { + builder = builder.get(); + break; + } + case POST: { + requestBody = request.getRequestBody(); + builder = builder.post(requestBody); + break; + } + case PUT: { + requestBody = request.getRequestBody(); + builder = builder.put(requestBody); + break; + } + case DELETE: { + requestBody = request.getRequestBody(); + builder = builder.delete(requestBody); + break; + } + case HEAD: { + builder = builder.head(); + break; + } + case PATCH: { + requestBody = request.getRequestBody(); + builder = builder.patch(requestBody); + break; + } + } + if (request.getCacheControl() != null) { + builder.cacheControl(request.getCacheControl()); + } + okHttpRequest = builder.build(); + + if (request.getOkHttpClient() != null) { + request.setCall(request.getOkHttpClient().newBuilder().cache(sHttpClient.cache()).build().newCall(okHttpRequest)); + } else { + request.setCall(sHttpClient.newCall(okHttpRequest)); + } + final long startTime = System.currentTimeMillis(); + final long startBytes = TrafficStats.getTotalRxBytes(); + okHttpResponse = request.getCall().execute(); + final long timeTaken = System.currentTimeMillis() - startTime; + if (okHttpResponse.cacheResponse() == null) { + final long finalBytes = TrafficStats.getTotalRxBytes(); + final long diffBytes; + if (startBytes == TrafficStats.UNSUPPORTED || finalBytes == TrafficStats.UNSUPPORTED) { + diffBytes = okHttpResponse.body().contentLength(); + } else { + diffBytes = finalBytes - startBytes; + } + ConnectionClassManager.getInstance().updateBandwidth(diffBytes, timeTaken); + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, + (requestBody != null && + requestBody.contentLength() != 0) ? requestBody.contentLength() : -1, + okHttpResponse.body().contentLength(), false); + } else if (request.getAnalyticsListener() != null) { + if (okHttpResponse.networkResponse() == null) { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, 0, 0, true); + } else { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, + (requestBody != null && requestBody.contentLength() != 0) ? requestBody.contentLength() : -1, + 0, true); + } + } + } catch (IOException ioe) { + throw new ANError(ioe); + } + return okHttpResponse; + } + + public static Response performDownloadRequest(final ANRequest request) throws ANError { + Request okHttpRequest; + Response okHttpResponse; + try { + Request.Builder builder = new Request.Builder().url(request.getUrl()); + addHeadersToRequestBuilder(builder, request); + builder = builder.get(); + if (request.getCacheControl() != null) { + builder.cacheControl(request.getCacheControl()); + } + okHttpRequest = builder.build(); + + OkHttpClient okHttpClient; + + if (request.getOkHttpClient() != null) { + okHttpClient = request.getOkHttpClient().newBuilder().cache(sHttpClient.cache()) + .addNetworkInterceptor(new Interceptor() { + @Override + public Response intercept(Chain chain) throws IOException { + Response originalResponse = chain.proceed(chain.request()); + return originalResponse.newBuilder() + .body(new ResponseProgressBody(originalResponse.body(), + request.getDownloadProgressListener())) + .build(); + } + }).build(); + } else { + okHttpClient = sHttpClient.newBuilder() + .addNetworkInterceptor(new Interceptor() { + @Override + public Response intercept(Chain chain) throws IOException { + Response originalResponse = chain.proceed(chain.request()); + return originalResponse.newBuilder() + .body(new ResponseProgressBody(originalResponse.body(), + request.getDownloadProgressListener())) + .build(); + } + }).build(); + } + request.setCall(okHttpClient.newCall(okHttpRequest)); + final long startTime = System.currentTimeMillis(); + final long startBytes = TrafficStats.getTotalRxBytes(); + okHttpResponse = request.getCall().execute(); + Utils.saveFile(okHttpResponse, request.getDirPath(), request.getFileName()); + final long timeTaken = System.currentTimeMillis() - startTime; + if (okHttpResponse.cacheResponse() == null) { + final long finalBytes = TrafficStats.getTotalRxBytes(); + final long diffBytes; + if (startBytes == TrafficStats.UNSUPPORTED || finalBytes == TrafficStats.UNSUPPORTED) { + diffBytes = okHttpResponse.body().contentLength(); + } else { + diffBytes = finalBytes - startBytes; + } + ConnectionClassManager.getInstance().updateBandwidth(diffBytes, timeTaken); + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, -1, + okHttpResponse.body().contentLength(), false); + } else if (request.getAnalyticsListener() != null) { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, -1, 0, true); + } + } catch (IOException ioe) { + try { + File destinationFile = new File(request.getDirPath() + File.separator + request.getFileName()); + if (destinationFile.exists()) { + destinationFile.delete(); + } + } catch (Exception e) { + e.printStackTrace(); + } + throw new ANError(ioe); + } + return okHttpResponse; + } + + + public static Response performUploadRequest(ANRequest request) throws ANError { + Request okHttpRequest; + Response okHttpResponse; + try { + Request.Builder builder = new Request.Builder().url(request.getUrl()); + addHeadersToRequestBuilder(builder, request); + final RequestBody requestBody = request.getMultiPartRequestBody(); + final long requestBodyLength = requestBody.contentLength(); + builder = builder.post(new RequestProgressBody(requestBody, request.getUploadProgressListener())); + if (request.getCacheControl() != null) { + builder.cacheControl(request.getCacheControl()); + } + okHttpRequest = builder.build(); + if (request.getOkHttpClient() != null) { + request.setCall(request.getOkHttpClient() + .newBuilder() + .cache(sHttpClient.cache()) + .build() + .newCall(okHttpRequest)); + } else { + request.setCall(sHttpClient.newCall(okHttpRequest)); + } + final long startTime = System.currentTimeMillis(); + okHttpResponse = request.getCall().execute(); + final long timeTaken = System.currentTimeMillis() - startTime; + if (request.getAnalyticsListener() != null) { + if (okHttpResponse.cacheResponse() == null) { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, + requestBodyLength, okHttpResponse.body().contentLength(), false); + } else { + if (okHttpResponse.networkResponse() == null) { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, 0, 0, true); + } else { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, + requestBodyLength != 0 ? requestBodyLength : -1, 0, true); + } + } + } + } catch (IOException ioe) { + throw new ANError(ioe); + } + return okHttpResponse; + } + + public static OkHttpClient getClient() { + if (sHttpClient == null) { + return getDefaultClient(); + } + return sHttpClient; + } + + public static void addHeadersToRequestBuilder(Request.Builder builder, ANRequest request) { + if (request.getUserAgent() != null) { + builder.addHeader(ANConstants.USER_AGENT, request.getUserAgent()); + } else if (sUserAgent != null) { + request.setUserAgent(sUserAgent); + builder.addHeader(ANConstants.USER_AGENT, sUserAgent); + } + Headers requestHeaders = request.getHeaders(); + if (requestHeaders != null) { + builder.headers(requestHeaders); + if (request.getUserAgent() != null && !requestHeaders.names().contains(ANConstants.USER_AGENT)) { + builder.addHeader(ANConstants.USER_AGENT, request.getUserAgent()); + } + } + } + + public static OkHttpClient getDefaultClient() { + return new OkHttpClient().newBuilder() + .connectTimeout(60, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .writeTimeout(60, TimeUnit.SECONDS) + .build(); + } + + public static void setClientWithCache(Context context) { + sHttpClient = new OkHttpClient().newBuilder() + .cache(Utils.getCache(context, ANConstants.MAX_CACHE_SIZE, ANConstants.CACHE_DIR_NAME)) + .connectTimeout(60, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .writeTimeout(60, TimeUnit.SECONDS) + .build(); + } + + public static void setUserAgent(String userAgent) { + sUserAgent = userAgent; + } + + public static void setClient(OkHttpClient okHttpClient) { + sHttpClient = okHttpClient; + } + + public static void enableLogging(Level level) { + HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); + logging.setLevel(level); + sHttpClient = getClient() + .newBuilder() + .addInterceptor(logging) + .build(); + } + +} diff --git a/android-networking/src/main/java/com/androidnetworking/internal/InternalRunnable.java b/android-networking/src/main/java/com/androidnetworking/internal/InternalRunnable.java new file mode 100644 index 0000000..33a03fe --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/internal/InternalRunnable.java @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.internal; + +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.common.Priority; +import com.androidnetworking.common.ResponseType; +import com.androidnetworking.core.Core; +import com.androidnetworking.error.ANError; +import com.androidnetworking.utils.SourceCloseUtil; +import com.androidnetworking.utils.Utils; + +import okhttp3.Response; + +import static com.androidnetworking.common.RequestType.DOWNLOAD; +import static com.androidnetworking.common.RequestType.MULTIPART; +import static com.androidnetworking.common.RequestType.SIMPLE; + +/** + * Created by owner on 22/03/16. + */ +public class InternalRunnable implements Runnable { + + private final Priority priority; + public final int sequence; + public final ANRequest request; + + public InternalRunnable(ANRequest request) { + this.request = request; + this.sequence = request.getSequenceNumber(); + this.priority = request.getPriority(); + } + + @Override + public void run() { + switch (request.getRequestType()) { + case SIMPLE: + executeSimpleRequest(); + break; + case DOWNLOAD: + executeDownloadRequest(); + break; + case MULTIPART: + executeUploadRequest(); + break; + } + } + + private void executeSimpleRequest() { + Response okHttpResponse = null; + try { + okHttpResponse = InternalNetworking.performSimpleRequest(request); + + if (okHttpResponse == null) { + deliverError(request, Utils.getErrorForConnection(new ANError())); + return; + } + + if (request.getResponseAs() == ResponseType.OK_HTTP_RESPONSE) { + request.deliverOkHttpResponse(okHttpResponse); + return; + } + if (okHttpResponse.code() >= 400) { + deliverError(request, Utils.getErrorForServerResponse(new ANError(okHttpResponse), + request, okHttpResponse.code())); + return; + } + + ANResponse response = request.parseResponse(okHttpResponse); + if (!response.isSuccess()) { + deliverError(request, response.getError()); + return; + } + response.setOkHttpResponse(okHttpResponse); + request.deliverResponse(response); + } catch (Exception e) { + deliverError(request, Utils.getErrorForConnection(new ANError(e))); + } finally { + SourceCloseUtil.close(okHttpResponse, request); + } + } + + private void executeDownloadRequest() { + Response okHttpResponse; + try { + okHttpResponse = InternalNetworking.performDownloadRequest(request); + if (okHttpResponse == null) { + deliverError(request, Utils.getErrorForConnection(new ANError())); + return; + } + if (okHttpResponse.code() >= 400) { + deliverError(request, Utils.getErrorForServerResponse(new ANError(okHttpResponse), + request, okHttpResponse.code())); + return; + } + request.updateDownloadCompletion(); + } catch (Exception e) { + deliverError(request, Utils.getErrorForConnection(new ANError(e))); + } + } + + private void executeUploadRequest() { + Response okHttpResponse = null; + try { + okHttpResponse = InternalNetworking.performUploadRequest(request); + + if (okHttpResponse == null) { + deliverError(request, Utils.getErrorForConnection(new ANError())); + return; + } + + if (request.getResponseAs() == ResponseType.OK_HTTP_RESPONSE) { + request.deliverOkHttpResponse(okHttpResponse); + return; + } + + if (okHttpResponse.code() >= 400) { + deliverError(request, Utils.getErrorForServerResponse(new ANError(okHttpResponse), + request, okHttpResponse.code())); + return; + } + ANResponse response = request.parseResponse(okHttpResponse); + if (!response.isSuccess()) { + deliverError(request, response.getError()); + return; + } + response.setOkHttpResponse(okHttpResponse); + request.deliverResponse(response); + } catch (Exception e) { + deliverError(request, Utils.getErrorForConnection(new ANError(e))); + } finally { + SourceCloseUtil.close(okHttpResponse, request); + } + } + + public Priority getPriority() { + return priority; + } + + private void deliverError(final ANRequest request, final ANError anError) { + Core.getInstance().getExecutorSupplier().forMainThreadTasks().execute(new Runnable() { + public void run() { + request.deliverError(anError); + request.finish(); + } + }); + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/internal/RequestProgressBody.java b/android-networking/src/main/java/com/androidnetworking/internal/RequestProgressBody.java new file mode 100644 index 0000000..213c61d --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/internal/RequestProgressBody.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.internal; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.interfaces.UploadProgressListener; +import com.androidnetworking.model.Progress; + +import java.io.IOException; + +import okhttp3.MediaType; +import okhttp3.RequestBody; +import okio.Buffer; +import okio.BufferedSink; +import okio.ForwardingSink; +import okio.Okio; +import okio.Sink; + +/** + * Created by owner on 21/04/16. + */ +public class RequestProgressBody extends RequestBody { + private final RequestBody requestBody; + private BufferedSink bufferedSink; + private UploadProgressHandler uploadProgressHandler; + + public RequestProgressBody(RequestBody requestBody, UploadProgressListener uploadProgressListener) { + this.requestBody = requestBody; + if (uploadProgressListener != null) { + this.uploadProgressHandler = new UploadProgressHandler(uploadProgressListener); + } + } + + public MediaType contentType() { + return requestBody.contentType(); + } + + @Override + public long contentLength() throws IOException { + return requestBody.contentLength(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + if (bufferedSink == null) { + bufferedSink = Okio.buffer(sink(sink)); + } + requestBody.writeTo(bufferedSink); + bufferedSink.flush(); + } + + private Sink sink(Sink sink) { + return new ForwardingSink(sink) { + long bytesWritten = 0L; + long contentLength = 0L; + + @Override + public void write(Buffer source, long byteCount) throws IOException { + super.write(source, byteCount); + if (contentLength == 0) { + contentLength = contentLength(); + } + bytesWritten += byteCount; + if (uploadProgressHandler != null) { + uploadProgressHandler.obtainMessage(ANConstants.UPDATE, + new Progress(bytesWritten, contentLength)).sendToTarget(); + } + } + }; + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/internal/ResponseProgressBody.java b/android-networking/src/main/java/com/androidnetworking/internal/ResponseProgressBody.java new file mode 100644 index 0000000..5f0d260 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/internal/ResponseProgressBody.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.internal; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.interfaces.DownloadProgressListener; +import com.androidnetworking.model.Progress; + +import java.io.IOException; + +import okhttp3.MediaType; +import okhttp3.ResponseBody; +import okio.Buffer; +import okio.BufferedSource; +import okio.ForwardingSource; +import okio.Okio; +import okio.Source; + +/** + * Created by owner on 24/05/16. + */ +public class ResponseProgressBody extends ResponseBody { + + private final ResponseBody mResponseBody; + private BufferedSource bufferedSource; + private DownloadProgressHandler downloadProgressHandler; + + public ResponseProgressBody(ResponseBody responseBody, DownloadProgressListener downloadProgressListener) { + this.mResponseBody = responseBody; + if (downloadProgressListener != null) { + this.downloadProgressHandler = new DownloadProgressHandler(downloadProgressListener); + } + } + + @Override + public MediaType contentType() { + return mResponseBody.contentType(); + } + + @Override + public long contentLength() { + return mResponseBody.contentLength(); + } + + @Override + public BufferedSource source() { + if (bufferedSource == null) { + bufferedSource = Okio.buffer(source(mResponseBody.source())); + } + return bufferedSource; + } + + private Source source(Source source) { + + return new ForwardingSource(source) { + + long totalBytesRead; + + @Override + public long read(Buffer sink, long byteCount) throws IOException { + long bytesRead = super.read(sink, byteCount); + totalBytesRead += ((bytesRead != -1) ? bytesRead : 0); + if (downloadProgressHandler != null) { + downloadProgressHandler + .obtainMessage(ANConstants.UPDATE, + new Progress(totalBytesRead, mResponseBody.contentLength())) + .sendToTarget(); + } + return bytesRead; + } + }; + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/internal/SynchronousCall.java b/android-networking/src/main/java/com/androidnetworking/internal/SynchronousCall.java new file mode 100644 index 0000000..b85e1f6 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/internal/SynchronousCall.java @@ -0,0 +1,143 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.internal; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.common.ResponseType; +import com.androidnetworking.error.ANError; +import com.androidnetworking.utils.SourceCloseUtil; +import com.androidnetworking.utils.Utils; + +import okhttp3.Response; + +import static com.androidnetworking.common.RequestType.DOWNLOAD; +import static com.androidnetworking.common.RequestType.MULTIPART; +import static com.androidnetworking.common.RequestType.SIMPLE; + +/** + * Created by owner on 14/09/16. + */ +@SuppressWarnings("unchecked") +public final class SynchronousCall { + + private SynchronousCall() { + + } + + public static ANResponse execute(ANRequest request) { + switch (request.getRequestType()) { + case SIMPLE: + return executeSimpleRequest(request); + case DOWNLOAD: + return executeDownloadRequest(request); + case MULTIPART: + return executeUploadRequest(request); + } + return new ANResponse<>(new ANError()); + } + + private static ANResponse executeSimpleRequest(ANRequest request) { + Response okHttpResponse = null; + try { + okHttpResponse = InternalNetworking.performSimpleRequest(request); + if (okHttpResponse == null) { + return new ANResponse<>(Utils.getErrorForConnection(new ANError())); + } + + if (request.getResponseAs() == ResponseType.OK_HTTP_RESPONSE) { + ANResponse response = new ANResponse(okHttpResponse); + response.setOkHttpResponse(okHttpResponse); + return response; + } + if (okHttpResponse.code() >= 400) { + ANResponse response = new ANResponse<>(Utils.getErrorForServerResponse(new ANError(okHttpResponse), + request, okHttpResponse.code())); + response.setOkHttpResponse(okHttpResponse); + return response; + } + ANResponse response = request.parseResponse(okHttpResponse); + response.setOkHttpResponse(okHttpResponse); + return response; + } catch (ANError se) { + return new ANResponse<>(Utils.getErrorForConnection(new ANError(se))); + } catch (Exception e) { + return new ANResponse<>(Utils.getErrorForNetworkOnMainThreadOrConnection(e)); + } finally { + SourceCloseUtil.close(okHttpResponse, request); + } + } + + private static ANResponse executeDownloadRequest(ANRequest request) { + Response okHttpResponse; + try { + okHttpResponse = InternalNetworking.performDownloadRequest(request); + if (okHttpResponse == null) { + return new ANResponse<>(Utils.getErrorForConnection(new ANError())); + } + if (okHttpResponse.code() >= 400) { + ANResponse response = new ANResponse<>(Utils.getErrorForServerResponse(new ANError(okHttpResponse), + request, okHttpResponse.code())); + response.setOkHttpResponse(okHttpResponse); + return response; + } + ANResponse response = new ANResponse(ANConstants.SUCCESS); + response.setOkHttpResponse(okHttpResponse); + return response; + } catch (ANError se) { + return new ANResponse<>(Utils.getErrorForConnection(new ANError(se))); + } catch (Exception e) { + return new ANResponse<>(Utils.getErrorForNetworkOnMainThreadOrConnection(e)); + } + } + + private static ANResponse executeUploadRequest(ANRequest request) { + Response okHttpResponse = null; + try { + okHttpResponse = InternalNetworking.performUploadRequest(request); + + if (okHttpResponse == null) { + return new ANResponse<>(Utils.getErrorForConnection(new ANError())); + } + + if (request.getResponseAs() == ResponseType.OK_HTTP_RESPONSE) { + ANResponse response = new ANResponse(okHttpResponse); + response.setOkHttpResponse(okHttpResponse); + return response; + } + if (okHttpResponse.code() >= 400) { + ANResponse response = new ANResponse<>(Utils.getErrorForServerResponse(new ANError(okHttpResponse), + request, okHttpResponse.code())); + response.setOkHttpResponse(okHttpResponse); + return response; + } + ANResponse response = request.parseResponse(okHttpResponse); + response.setOkHttpResponse(okHttpResponse); + return response; + } catch (ANError se) { + return new ANResponse<>(Utils.getErrorForConnection(se)); + } catch (Exception e) { + return new ANResponse<>(Utils.getErrorForNetworkOnMainThreadOrConnection(e)); + } finally { + SourceCloseUtil.close(okHttpResponse, request); + } + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/internal/UploadProgressHandler.java b/android-networking/src/main/java/com/androidnetworking/internal/UploadProgressHandler.java new file mode 100644 index 0000000..03924fc --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/internal/UploadProgressHandler.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.internal; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.interfaces.UploadProgressListener; +import com.androidnetworking.model.Progress; + +/** + * Created by owner on 24/05/16. + */ +public class UploadProgressHandler extends Handler { + + private final UploadProgressListener mUploadProgressListenerWeakRef; + + public UploadProgressHandler(UploadProgressListener uploadProgressListener) { + super(Looper.getMainLooper()); + mUploadProgressListenerWeakRef = uploadProgressListener; + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case ANConstants.UPDATE: + if (mUploadProgressListenerWeakRef != null) { + final Progress progress = (Progress) msg.obj; + mUploadProgressListenerWeakRef.onProgress(progress.currentBytes, progress.totalBytes); + } + break; + default: + super.handleMessage(msg); + break; + } + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/model/Progress.java b/android-networking/src/main/java/com/androidnetworking/model/Progress.java new file mode 100644 index 0000000..3384c95 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/model/Progress.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.model; + +import java.io.Serializable; + +/** + * Created by owner on 24/05/16. + */ + +public class Progress implements Serializable { + + public long currentBytes; + public long totalBytes; + + public Progress(long currentBytes, long totalBytes) { + this.currentBytes = currentBytes; + this.totalBytes = totalBytes; + } + +} \ No newline at end of file diff --git a/android-networking/src/main/java/com/androidnetworking/utils/ParseUtil.java b/android-networking/src/main/java/com/androidnetworking/utils/ParseUtil.java new file mode 100644 index 0000000..61b385f --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/utils/ParseUtil.java @@ -0,0 +1,48 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.utils; + +import com.androidnetworking.gsonparserfactory.GsonParserFactory; +import com.androidnetworking.interfaces.Parser; +import com.google.gson.Gson; + +/** + * Created by owner on 15/09/16. + */ +public class ParseUtil { + + private static Parser.Factory mParserFactory; + + public static void setParserFactory(Parser.Factory parserFactory) { + mParserFactory = parserFactory; + } + + public static Parser.Factory getParserFactory() { + if (mParserFactory == null) { + mParserFactory = new GsonParserFactory(new Gson()); + } + return mParserFactory; + } + + public static void shutDown() { + mParserFactory = null; + } + +} diff --git a/android-networking/src/main/java/com/androidnetworking/utils/SourceCloseUtil.java b/android-networking/src/main/java/com/androidnetworking/utils/SourceCloseUtil.java new file mode 100644 index 0000000..7643942 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/utils/SourceCloseUtil.java @@ -0,0 +1,46 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.androidnetworking.utils; + +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ResponseType; + +import okhttp3.Response; + +/** + * Created by owner on 15/09/16. + */ +public final class SourceCloseUtil { + + private SourceCloseUtil() { + } + + public static void close(Response response, ANRequest request) { + if (request.getResponseAs() != ResponseType.OK_HTTP_RESPONSE && + response != null && response.body() != null && + response.body().source() != null) { + try { + response.body().source().close(); + } catch (Exception ignore) { + + } + } + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/utils/Utils.java b/android-networking/src/main/java/com/androidnetworking/utils/Utils.java new file mode 100644 index 0000000..79c171c --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/utils/Utils.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Build; +import android.os.NetworkOnMainThreadException; +import android.widget.ImageView; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.core.Core; +import com.androidnetworking.error.ANError; +import com.androidnetworking.interfaces.AnalyticsListener; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.FileNameMap; +import java.net.URLConnection; + +import okhttp3.Cache; +import okhttp3.Response; +import okio.Okio; + +/** + * Created by owner on 25/03/16. + */ +public class Utils { + + public static File getDiskCacheDir(Context context, String uniqueName) { + return new File(context.getCacheDir(), uniqueName); + } + + public static Cache getCache(Context context, int maxCacheSize, String uniqueName) { + return new Cache(getDiskCacheDir(context, uniqueName), maxCacheSize); + } + + public static String getMimeType(String path) { + FileNameMap fileNameMap = URLConnection.getFileNameMap(); + String contentTypeFor = fileNameMap.getContentTypeFor(path); + if (contentTypeFor == null) { + contentTypeFor = "application/octet-stream"; + } + return contentTypeFor; + } + + public static ANResponse decodeBitmap(Response response, int maxWidth, + int maxHeight, Bitmap.Config decodeConfig, + ImageView.ScaleType scaleType) { + return decodeBitmap(response, maxWidth, maxHeight, decodeConfig, + new BitmapFactory.Options(), scaleType); + } + + public static ANResponse decodeBitmap(Response response, int maxWidth, + int maxHeight, Bitmap.Config decodeConfig, + BitmapFactory.Options decodeOptions, + ImageView.ScaleType scaleType) { + byte[] data = new byte[0]; + try { + data = Okio.buffer(response.body().source()).readByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } + Bitmap bitmap = null; + if (maxWidth == 0 && maxHeight == 0) { + decodeOptions.inPreferredConfig = decodeConfig; + bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions); + } else { + decodeOptions.inJustDecodeBounds = true; + BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions); + int actualWidth = decodeOptions.outWidth; + int actualHeight = decodeOptions.outHeight; + + int desiredWidth = getResizedDimension(maxWidth, maxHeight, + actualWidth, actualHeight, scaleType); + int desiredHeight = getResizedDimension(maxHeight, maxWidth, + actualHeight, actualWidth, scaleType); + + decodeOptions.inJustDecodeBounds = false; + decodeOptions.inSampleSize = + findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight); + Bitmap tempBitmap = + BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions); + + if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth || + tempBitmap.getHeight() > desiredHeight)) { + bitmap = Bitmap.createScaledBitmap(tempBitmap, + desiredWidth, desiredHeight, true); + tempBitmap.recycle(); + } else { + bitmap = tempBitmap; + } + } + + if (bitmap == null) { + return ANResponse.failed(Utils.getErrorForParse(new ANError(response))); + } else { + return ANResponse.success(bitmap); + } + } + + private static int getResizedDimension(int maxPrimary, int maxSecondary, + int actualPrimary, int actualSecondary, + ImageView.ScaleType scaleType) { + + if ((maxPrimary == 0) && (maxSecondary == 0)) { + return actualPrimary; + } + + if (scaleType == ImageView.ScaleType.FIT_XY) { + if (maxPrimary == 0) { + return actualPrimary; + } + return maxPrimary; + } + + if (maxPrimary == 0) { + double ratio = (double) maxSecondary / (double) actualSecondary; + return (int) (actualPrimary * ratio); + } + + if (maxSecondary == 0) { + return maxPrimary; + } + + double ratio = (double) actualSecondary / (double) actualPrimary; + int resized = maxPrimary; + + if (scaleType == ImageView.ScaleType.CENTER_CROP) { + if ((resized * ratio) < maxSecondary) { + resized = (int) (maxSecondary / ratio); + } + return resized; + } + + if ((resized * ratio) > maxSecondary) { + resized = (int) (maxSecondary / ratio); + } + return resized; + } + + public static int findBestSampleSize(int actualWidth, int actualHeight, + int desiredWidth, int desiredHeight) { + double wr = (double) actualWidth / desiredWidth; + double hr = (double) actualHeight / desiredHeight; + double ratio = Math.min(wr, hr); + float n = 1.0f; + while ((n * 2) <= ratio) { + n *= 2; + } + return (int) n; + } + + public static void saveFile(Response response, String dirPath, + String fileName) throws IOException { + InputStream is = null; + byte[] buf = new byte[2048]; + int len; + FileOutputStream fos = null; + try { + is = response.body().byteStream(); + File dir = new File(dirPath); + if (!dir.exists()) { + dir.mkdirs(); + } + File file = new File(dir, fileName); + fos = new FileOutputStream(file); + while ((len = is.read(buf)) != -1) { + fos.write(buf, 0, len); + } + fos.flush(); + } finally { + try { + if (is != null) is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + if (fos != null) fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static void sendAnalytics(final AnalyticsListener analyticsListener, + final long timeTakenInMillis, final long bytesSent, + final long bytesReceived, final boolean isFromCache) { + Core.getInstance().getExecutorSupplier().forMainThreadTasks().execute(new Runnable() { + @Override + public void run() { + if (analyticsListener != null) { + analyticsListener.onReceived(timeTakenInMillis, bytesSent, bytesReceived, + isFromCache); + } + } + }); + } + + public static ANError getErrorForConnection(ANError error) { + error.setErrorDetail(ANConstants.CONNECTION_ERROR); + error.setErrorCode(0); + return error; + } + + + public static ANError getErrorForServerResponse(ANError error, ANRequest request, int code) { + error = request.parseNetworkError(error); + error.setErrorCode(code); + error.setErrorDetail(ANConstants.RESPONSE_FROM_SERVER_ERROR); + return error; + } + + public static ANError getErrorForParse(ANError error) { + error.setErrorCode(0); + error.setErrorDetail(ANConstants.PARSE_ERROR); + return error; + } + + public static ANError getErrorForNetworkOnMainThreadOrConnection(Exception e) { + ANError error = new ANError(e); + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB + && e instanceof NetworkOnMainThreadException) { + error.setErrorDetail(ANConstants.NETWORK_ON_MAIN_THREAD_ERROR); + } else { + error.setErrorDetail(ANConstants.CONNECTION_ERROR); + } + error.setErrorCode(0); + return error; + } +} diff --git a/android-networking/src/main/java/com/androidnetworking/widget/ANImageView.java b/android-networking/src/main/java/com/androidnetworking/widget/ANImageView.java new file mode 100644 index 0000000..70f8470 --- /dev/null +++ b/android-networking/src/main/java/com/androidnetworking/widget/ANImageView.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking.widget; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.androidnetworking.error.ANError; +import com.androidnetworking.internal.ANImageLoader; + +/** + * Created by owner on 23/03/16. + */ +public class ANImageView extends ImageView { + + private String mUrl; + + private int mDefaultImageId; + + private int mErrorImageId; + + private ANImageLoader.ImageContainer mImageContainer; + + public ANImageView(Context context) { + this(context, null); + } + + public ANImageView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ANImageView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public void setImageUrl(String url) { + mUrl = url; + loadImageIfNecessary(false); + } + + public void setDefaultImageResId(int defaultImage) { + mDefaultImageId = defaultImage; + } + + public void setErrorImageResId(int errorImage) { + mErrorImageId = errorImage; + } + + void loadImageIfNecessary(final boolean isInLayoutPass) { + int width = getWidth(); + int height = getHeight(); + ScaleType scaleType = getScaleType(); + + boolean wrapWidth = false, wrapHeight = false; + if (getLayoutParams() != null) { + wrapWidth = getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT; + wrapHeight = getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT; + } + + boolean isFullyWrapContent = wrapWidth && wrapHeight; + if (width == 0 && height == 0 && !isFullyWrapContent) { + return; + } + + if (TextUtils.isEmpty(mUrl)) { + if (mImageContainer != null) { + mImageContainer.cancelRequest(); + mImageContainer = null; + } + setDefaultImageOrNull(); + return; + } + + if (mImageContainer != null && mImageContainer.getRequestUrl() != null) { + if (mImageContainer.getRequestUrl().equals(mUrl)) { + return; + } else { + mImageContainer.cancelRequest(); + setDefaultImageOrNull(); + } + } + + int maxWidth = wrapWidth ? 0 : width; + int maxHeight = wrapHeight ? 0 : height; + + ANImageLoader.ImageContainer newContainer = ANImageLoader.getInstance().get(mUrl, + new ANImageLoader.ImageListener() { + @Override + public void onResponse(final ANImageLoader.ImageContainer response, + boolean isImmediate) { + if (isImmediate && isInLayoutPass) { + post(new Runnable() { + @Override + public void run() { + onResponse(response, false); + } + }); + return; + } + + if (response.getBitmap() != null) { + setImageBitmap(response.getBitmap()); + } else if (mDefaultImageId != 0) { + setImageResource(mDefaultImageId); + } + } + + @Override + public void onError(ANError error) { + if (mErrorImageId != 0) { + setImageResource(mErrorImageId); + } + } + }, maxWidth, maxHeight, scaleType); + + mImageContainer = newContainer; + } + + private void setDefaultImageOrNull() { + if (mDefaultImageId != 0) { + setImageResource(mDefaultImageId); + } else { + setImageBitmap(null); + } + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + loadImageIfNecessary(true); + } + + @Override + protected void onDetachedFromWindow() { + if (mImageContainer != null) { + mImageContainer.cancelRequest(); + setImageBitmap(null); + mImageContainer = null; + } + super.onDetachedFromWindow(); + } + + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); + invalidate(); + } + +} diff --git a/android-networking/src/main/res/values/strings.xml b/android-networking/src/main/res/values/strings.xml new file mode 100644 index 0000000..66ca996 --- /dev/null +++ b/android-networking/src/main/res/values/strings.xml @@ -0,0 +1,20 @@ + + + + Android Networking + diff --git a/android-networking/src/test/java/com/androidnetworking/ExampleUnitTest.java b/android-networking/src/test/java/com/androidnetworking/ExampleUnitTest.java new file mode 100644 index 0000000..bbc8754 --- /dev/null +++ b/android-networking/src/test/java/com/androidnetworking/ExampleUnitTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 Amit Shekhar + * Copyright (C) 2011 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. + */ + +package com.androidnetworking; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * To work on unit tests, switch the Test Artifact in the Build Variants view. + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 62fe87b..af233ac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,11 +20,12 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) + compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:25.1.0' compile 'com.android.support:recyclerview-v7:25.1.0' compile 'io.reactivex.rxjava2:rxjava:2.1.1' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' - compile 'com.amitshekhar.android:rx2-android-networking:1.0.0' -} + compile project(':android-networking') + compile project(':rx2-android-networking') +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 6b7a2bf..ab6c072 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,6 +1,6 @@ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified -# in /Users/amitshekhar/Library/Android/sdk/tools/proguard/proguard-android.txt +# in /Users/owner/Library/Android/sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9b4c4f7..2a8cb2d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,7 +14,6 @@ - diff --git a/app/src/main/java/com/rxjava2/android/samples/model/ApiUser.java b/app/src/main/java/com/rxjava2/android/samples/model/ApiUser.java index 09039ef..70cbd48 100644 --- a/app/src/main/java/com/rxjava2/android/samples/model/ApiUser.java +++ b/app/src/main/java/com/rxjava2/android/samples/model/ApiUser.java @@ -1,7 +1,7 @@ package com.rxjava2.android.samples.model; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class ApiUser { public long id; diff --git a/app/src/main/java/com/rxjava2/android/samples/model/Car.java b/app/src/main/java/com/rxjava2/android/samples/model/Car.java index e223650..a328a28 100644 --- a/app/src/main/java/com/rxjava2/android/samples/model/Car.java +++ b/app/src/main/java/com/rxjava2/android/samples/model/Car.java @@ -6,7 +6,7 @@ import io.reactivex.ObservableSource; /** - * Created by amitshekhar on 30/08/16. + * Created by owner on 30/08/16. */ public class Car { diff --git a/app/src/main/java/com/rxjava2/android/samples/model/Events.java b/app/src/main/java/com/rxjava2/android/samples/model/Events.java index d4541b4..a60da5d 100644 --- a/app/src/main/java/com/rxjava2/android/samples/model/Events.java +++ b/app/src/main/java/com/rxjava2/android/samples/model/Events.java @@ -1,7 +1,7 @@ package com.rxjava2.android.samples.model; /** - * Created by amitshekhar on 06/02/17. + * Created by owner on 06/02/17. */ public class Events { diff --git a/app/src/main/java/com/rxjava2/android/samples/model/User.java b/app/src/main/java/com/rxjava2/android/samples/model/User.java index bb11397..18c0ba7 100644 --- a/app/src/main/java/com/rxjava2/android/samples/model/User.java +++ b/app/src/main/java/com/rxjava2/android/samples/model/User.java @@ -1,7 +1,7 @@ package com.rxjava2.android.samples.model; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class User { public long id; diff --git a/app/src/main/java/com/rxjava2/android/samples/model/UserDetail.java b/app/src/main/java/com/rxjava2/android/samples/model/UserDetail.java index 1be734b..c9d9343 100644 --- a/app/src/main/java/com/rxjava2/android/samples/model/UserDetail.java +++ b/app/src/main/java/com/rxjava2/android/samples/model/UserDetail.java @@ -1,7 +1,7 @@ package com.rxjava2.android.samples.model; /** - * Created by amitshekhar on 04/02/17. + * Created by owner on 04/02/17. */ public class UserDetail { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/networking/NetworkingActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/networking/NetworkingActivity.java index f651870..353d8a4 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/networking/NetworkingActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/networking/NetworkingActivity.java @@ -5,6 +5,7 @@ import android.util.Log; import android.util.Pair; import android.view.View; +import android.widget.Toast; import com.rx2androidnetworking.Rx2AndroidNetworking; import com.rxjava2.android.samples.R; @@ -27,13 +28,14 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 04/02/17. + * Created by owner on 04/02/17. */ public class NetworkingActivity extends AppCompatActivity { public static final String TAG = NetworkingActivity.class.getSimpleName(); + String str = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -44,8 +46,8 @@ protected void onCreate(Bundle savedInstanceState) { * Map Operator Example */ public void map(View view) { - Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAnUser/{userId}") - .addPathParameter("userId", "1") + Rx2AndroidNetworking.get("https://secret-ridge-27839.herokuapp.com/getAnUser/{userId}") + .addPathParameter("userId", "12") .build() .getObjectObservable(ApiUser.class) .subscribeOn(Schedulers.io()) @@ -67,6 +69,7 @@ public void onSubscribe(Disposable d) { @Override public void onNext(User user) { + str = user.toString(); Log.d(TAG, "user : " + user.toString()); } @@ -77,6 +80,8 @@ public void onError(Throwable e) { @Override public void onComplete() { + Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show(); + Log.d(TAG, "onComplete"); } }); @@ -88,10 +93,10 @@ public void onComplete() { */ /** - * This observable return the list of User who loves cricket + * This observable return the list of User who loves baseball */ - private Observable> getCricketFansObservable() { - return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllCricketFans") + private Observable> getBaseballFansObservable() { + return Rx2AndroidNetworking.get("https://secret-ridge-27839.herokuapp.com/getAllBaseballFans") .build() .getObjectListObservable(User.class); } @@ -100,7 +105,7 @@ private Observable> getCricketFansObservable() { * This observable return the list of User who loves Football */ private Observable> getFootballFansObservable() { - return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllFootballFans") + return Rx2AndroidNetworking.get("https://secret-ridge-27839.herokuapp.com/getAllFootballFans") .build() .getObjectListObservable(User.class); } @@ -112,12 +117,12 @@ private Observable> getFootballFansObservable() { */ private void findUsersWhoLovesBoth() { // here we are using zip operator to combine both request - Observable.zip(getCricketFansObservable(), getFootballFansObservable(), + Observable.zip(getBaseballFansObservable(), getFootballFansObservable(), new BiFunction, List, List>() { @Override - public List apply(List cricketFans, List footballFans) throws Exception { + public List apply(List baseballFans, List footballFans) throws Exception { List userWhoLovesBoth = - filterUserWhoLovesBoth(cricketFans, footballFans); + filterUserWhoLovesBoth(baseballFans, footballFans); return userWhoLovesBoth; } }) @@ -150,12 +155,12 @@ public void onComplete() { }); } - private List filterUserWhoLovesBoth(List cricketFans, List footballFans) { + private List filterUserWhoLovesBoth(List baseballFans, List footballFans) { List userWhoLovesBoth = new ArrayList<>(); - for (User cricketFan : cricketFans) { + for (User baseballFan : baseballFans) { for (User footballFan : footballFans) { - if (cricketFan.id == footballFan.id) { - userWhoLovesBoth.add(cricketFan); + if (baseballFan.id == footballFan.id) { + userWhoLovesBoth.add(baseballFan); } } } @@ -173,7 +178,7 @@ public void zip(View view) { */ private Observable> getAllMyFriendsObservable() { - return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllFriends/{userId}") + return Rx2AndroidNetworking.get("https://secret-ridge-27839.herokuapp.com/getAllFriends/{userId}") .addPathParameter("userId", "1") .build() .getObjectListObservable(User.class); @@ -313,7 +318,7 @@ public void onComplete() { */ private Observable> getUserListObservable() { - return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllUsers/{pageNumber}") + return Rx2AndroidNetworking.get("https://secret-ridge-27839.herokuapp.com/getAllUsers/{pageNumber}") .addPathParameter("pageNumber", "0") .addQueryParameter("limit", "10") .build() @@ -321,7 +326,7 @@ private Observable> getUserListObservable() { } private Observable getUserDetailObservable(long id) { - return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAnUserDetail/{userId}") + return Rx2AndroidNetworking.get("https://secret-ridge-27839.herokuapp.com/getAnUserDetail/{userId}") .addPathParameter("userId", String.valueOf(id)) .build() .getObjectObservable(UserDetail.class); diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/AsyncSubjectExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/AsyncSubjectExampleActivity.java index 501bc63..2bebfab 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/AsyncSubjectExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/AsyncSubjectExampleActivity.java @@ -15,7 +15,7 @@ import io.reactivex.subjects.AsyncSubject; /** - * Created by amitshekhar on 17/12/16. + * Created by owner on 17/12/16. */ public class AsyncSubjectExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/BehaviorSubjectExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/BehaviorSubjectExampleActivity.java index e398fd8..eca9617 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/BehaviorSubjectExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/BehaviorSubjectExampleActivity.java @@ -15,7 +15,7 @@ import io.reactivex.subjects.BehaviorSubject; /** - * Created by amitshekhar on 17/12/16. + * Created by owner on 17/12/16. */ public class BehaviorSubjectExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/BufferExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/BufferExampleActivity.java index ead4b70..be79a43 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/BufferExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/BufferExampleActivity.java @@ -17,7 +17,7 @@ import io.reactivex.disposables.Disposable; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class BufferExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/CompletableObserverExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/CompletableObserverExampleActivity.java index 1f7451a..d05b6bd 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/CompletableObserverExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/CompletableObserverExampleActivity.java @@ -19,7 +19,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class CompletableObserverExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ConcatExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ConcatExampleActivity.java index ce4a3f5..5853c61 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ConcatExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ConcatExampleActivity.java @@ -15,7 +15,7 @@ import io.reactivex.disposables.Disposable; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class ConcatExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/DebounceExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/DebounceExampleActivity.java index d0f9802..a9fb625 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/DebounceExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/DebounceExampleActivity.java @@ -21,7 +21,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 22/12/16. + * Created by owner on 22/12/16. */ public class DebounceExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/DeferExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/DeferExampleActivity.java index 4aed8c6..8597bbe 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/DeferExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/DeferExampleActivity.java @@ -16,7 +16,7 @@ import io.reactivex.disposables.Disposable; /** - * Created by amitshekhar on 30/08/16. + * Created by owner on 30/08/16. */ public class DeferExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/DelayExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/DelayExampleActivity.java index 2979e75..3e025ee 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/DelayExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/DelayExampleActivity.java @@ -19,7 +19,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 05/03/17. + * Created by owner on 05/03/17. */ public class DelayExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/DisposableExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/DisposableExampleActivity.java index 2dd124b..f7ac88c 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/DisposableExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/DisposableExampleActivity.java @@ -21,7 +21,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class DisposableExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/FilterExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/FilterExampleActivity.java index e470182..3061256 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/FilterExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/FilterExampleActivity.java @@ -17,7 +17,7 @@ /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class FilterExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/FlowableExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/FlowableExampleActivity.java index 7303cc2..1f9600e 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/FlowableExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/FlowableExampleActivity.java @@ -16,7 +16,7 @@ import io.reactivex.functions.BiFunction; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class FlowableExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/IntervalExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/IntervalExampleActivity.java index 22469be..46e1523 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/IntervalExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/IntervalExampleActivity.java @@ -19,7 +19,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class IntervalExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/MapExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/MapExampleActivity.java index ccc6ace..fec5474 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/MapExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/MapExampleActivity.java @@ -25,7 +25,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class MapExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/MergeExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/MergeExampleActivity.java index 0cd7487..99640c9 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/MergeExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/MergeExampleActivity.java @@ -15,7 +15,7 @@ import io.reactivex.disposables.Disposable; /** - * Created by amitshekhar on 28/08/16. + * Created by owner on 28/08/16. */ public class MergeExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/PublishSubjectExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/PublishSubjectExampleActivity.java index af8822c..194d717 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/PublishSubjectExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/PublishSubjectExampleActivity.java @@ -15,7 +15,7 @@ import io.reactivex.subjects.PublishSubject; /** - * Created by amitshekhar on 17/12/16. + * Created by owner on 17/12/16. */ public class PublishSubjectExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReduceExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReduceExampleActivity.java index 1ab9930..b2dd6de 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReduceExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReduceExampleActivity.java @@ -16,7 +16,7 @@ import io.reactivex.functions.BiFunction; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class ReduceExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplayExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplayExampleActivity.java index 8880ea9..1b4257c 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplayExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplayExampleActivity.java @@ -16,7 +16,7 @@ import io.reactivex.subjects.PublishSubject; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class ReplayExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplaySubjectExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplaySubjectExampleActivity.java index 7f09563..94f178b 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplaySubjectExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ReplaySubjectExampleActivity.java @@ -15,7 +15,7 @@ import io.reactivex.subjects.ReplaySubject; /** - * Created by amitshekhar on 17/12/16. + * Created by owner on 17/12/16. */ public class ReplaySubjectExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/SimpleExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/SimpleExampleActivity.java index 423047d..30f6715 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/SimpleExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/SimpleExampleActivity.java @@ -17,7 +17,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class SimpleExampleActivity extends AppCompatActivity { @@ -53,7 +53,7 @@ private void doSomeWork() { } private Observable getObservable() { - return Observable.just("Cricket", "Football"); + return Observable.just("Baseball", "Football"); } private Observer getObserver() { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/SingleObserverExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/SingleObserverExampleActivity.java index 6c9ce7c..3e0673f 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/SingleObserverExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/SingleObserverExampleActivity.java @@ -15,7 +15,7 @@ import io.reactivex.disposables.Disposable; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class SingleObserverExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/SkipExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/SkipExampleActivity.java index 26706ea..6ffbc83 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/SkipExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/SkipExampleActivity.java @@ -17,7 +17,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class SkipExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/TakeExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/TakeExampleActivity.java index ae71924..19c872f 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/TakeExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/TakeExampleActivity.java @@ -17,7 +17,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class TakeExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ThrottleLastExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ThrottleLastExampleActivity.java index 95b6a45..f79a154 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ThrottleLastExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ThrottleLastExampleActivity.java @@ -21,7 +21,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 22/12/16. + * Created by owner on 22/12/16. */ public class ThrottleLastExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/TimerExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/TimerExampleActivity.java index 17f6369..c6c0dad 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/TimerExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/TimerExampleActivity.java @@ -19,7 +19,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class TimerExampleActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ZipExampleActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ZipExampleActivity.java index af446f3..8d32533 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/operators/ZipExampleActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/operators/ZipExampleActivity.java @@ -24,7 +24,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class ZipExampleActivity extends AppCompatActivity { @@ -49,16 +49,16 @@ public void onClick(View view) { /* * Here we are getting two user list - * One, the list of cricket fans + * One, the list of baseball fans * Another one, the list of football fans * Then we are finding the list of users who loves both */ private void doSomeWork() { - Observable.zip(getCricketFansObservable(), getFootballFansObservable(), + Observable.zip(getBaseballFansObservable(), getFootballFansObservable(), new BiFunction, List, List>() { @Override - public List apply(List cricketFans, List footballFans) throws Exception { - return Utils.filterUserWhoLovesBoth(cricketFans, footballFans); + public List apply(List baseballFans, List footballFans) throws Exception { + return Utils.filterUserWhoLovesBoth(baseballFans, footballFans); } }) // Run on a background thread @@ -68,12 +68,12 @@ public List apply(List cricketFans, List footballFans) throws .subscribe(getObserver()); } - private Observable> getCricketFansObservable() { + private Observable> getBaseballFansObservable() { return Observable.create(new ObservableOnSubscribe>() { @Override public void subscribe(ObservableEmitter> e) throws Exception { if (!e.isDisposed()) { - e.onNext(Utils.getUserListWhoLovesCricket()); + e.onNext(Utils.getUserListWhoLovesBaseball()); e.onComplete(); } } diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationActivity.java index b68b312..f248f79 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationActivity.java @@ -25,7 +25,7 @@ import io.reactivex.processors.PublishProcessor; /** - * Created by amitshekhar on 15/03/17. + * Created by owner on 15/03/17. */ public class PaginationActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationAdapter.java b/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationAdapter.java index 9c9d162..e711081 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationAdapter.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/pagination/PaginationAdapter.java @@ -12,7 +12,7 @@ import java.util.List; /** - * Created by amitshekhar on 15/03/17. + * Created by owner on 15/03/17. */ public class PaginationAdapter extends RecyclerView.Adapter { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBus.java b/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBus.java index cdc81b0..effb090 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBus.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBus.java @@ -4,7 +4,7 @@ import io.reactivex.subjects.PublishSubject; /** - * Created by amitshekhar on 06/02/17. + * Created by owner on 06/02/17. */ public class RxBus { diff --git a/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBusActivity.java b/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBusActivity.java index 2911b42..06e6d3e 100644 --- a/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBusActivity.java +++ b/app/src/main/java/com/rxjava2/android/samples/ui/rxbus/RxBusActivity.java @@ -16,7 +16,7 @@ import io.reactivex.schedulers.Schedulers; /** - * Created by amitshekhar on 06/02/17. + * Created by owner on 06/02/17. */ public class RxBusActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/rxjava2/android/samples/utils/AppConstant.java b/app/src/main/java/com/rxjava2/android/samples/utils/AppConstant.java index 4a8b40f..d1d9f2f 100644 --- a/app/src/main/java/com/rxjava2/android/samples/utils/AppConstant.java +++ b/app/src/main/java/com/rxjava2/android/samples/utils/AppConstant.java @@ -1,7 +1,7 @@ package com.rxjava2.android.samples.utils; /** - * Created by amitshekhar on 30/08/16. + * Created by owner on 30/08/16. */ public final class AppConstant { diff --git a/app/src/main/java/com/rxjava2/android/samples/utils/Utils.java b/app/src/main/java/com/rxjava2/android/samples/utils/Utils.java index 04695b2..35b94f9 100644 --- a/app/src/main/java/com/rxjava2/android/samples/utils/Utils.java +++ b/app/src/main/java/com/rxjava2/android/samples/utils/Utils.java @@ -10,7 +10,7 @@ import java.util.List; /** - * Created by amitshekhar on 27/08/16. + * Created by owner on 27/08/16. */ public class Utils { @@ -23,18 +23,18 @@ public static List getUserList() { List userList = new ArrayList<>(); User userOne = new User(); - userOne.firstname = "Amit"; - userOne.lastname = "Shekhar"; + userOne.firstname = "Able"; + userOne.lastname = "Black"; userList.add(userOne); User userTwo = new User(); - userTwo.firstname = "Manish"; - userTwo.lastname = "Kumar"; + userTwo.firstname = "Bly"; + userTwo.lastname = "Cane"; userList.add(userTwo); User userThree = new User(); - userThree.firstname = "Sumit"; - userThree.lastname = "Kumar"; + userThree.firstname = "Candy"; + userThree.lastname = "Donut"; userList.add(userThree); return userList; @@ -45,18 +45,18 @@ public static List getApiUserList() { List apiUserList = new ArrayList<>(); ApiUser apiUserOne = new ApiUser(); - apiUserOne.firstname = "Amit"; - apiUserOne.lastname = "Shekhar"; + apiUserOne.firstname = "Able"; + apiUserOne.lastname = "Black"; apiUserList.add(apiUserOne); ApiUser apiUserTwo = new ApiUser(); - apiUserTwo.firstname = "Manish"; - apiUserTwo.lastname = "Kumar"; + apiUserTwo.firstname = "Bly"; + apiUserTwo.lastname = "Cane"; apiUserList.add(apiUserTwo); ApiUser apiUserThree = new ApiUser(); - apiUserThree.firstname = "Sumit"; - apiUserThree.lastname = "Kumar"; + apiUserThree.firstname = "Candy"; + apiUserThree.lastname = "Donut"; apiUserList.add(apiUserThree); return apiUserList; @@ -76,20 +76,20 @@ public static List convertApiUserListToUserList(List apiUserList) return userList; } - public static List getUserListWhoLovesCricket() { + public static List getUserListWhoLovesBaseball() { List userList = new ArrayList<>(); User userOne = new User(); userOne.id = 1; - userOne.firstname = "Amit"; - userOne.lastname = "Shekhar"; + userOne.firstname = "Able"; + userOne.lastname = "Black"; userList.add(userOne); User userTwo = new User(); userTwo.id = 2; - userTwo.firstname = "Manish"; - userTwo.lastname = "Kumar"; + userTwo.firstname = "Bly"; + userTwo.lastname = "Cane"; userList.add(userTwo); return userList; @@ -102,26 +102,26 @@ public static List getUserListWhoLovesFootball() { User userOne = new User(); userOne.id = 1; - userOne.firstname = "Amit"; - userOne.lastname = "Shekhar"; + userOne.firstname = "Able"; + userOne.lastname = "Black"; userList.add(userOne); User userTwo = new User(); userTwo.id = 3; - userTwo.firstname = "Sumit"; - userTwo.lastname = "Kumar"; + userTwo.firstname = "Bly"; + userTwo.lastname = "Cane"; userList.add(userTwo); return userList; } - public static List filterUserWhoLovesBoth(List cricketFans, List footballFans) { + public static List filterUserWhoLovesBoth(List baseballFans, List footballFans) { List userWhoLovesBoth = new ArrayList(); - for (User cricketFan : cricketFans) { + for (User baseballFan : baseballFans) { for (User footballFan : footballFans) { - if (cricketFan.id == footballFan.id) { - userWhoLovesBoth.add(cricketFan); + if (baseballFan.id == footballFan.id) { + userWhoLovesBoth.add(baseballFan); } } } diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png old mode 100644 new mode 100755 index cde69bc..a3753ae Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png old mode 100644 new mode 100755 index c133a0c..2189a0c Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png old mode 100644 new mode 100755 index bfa42f0..b82cd0f Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png old mode 100644 new mode 100755 index 324e72c..692e2fd Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png old mode 100644 new mode 100755 index aee44e1..34cb12d Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cdd27c4..9ec3cc0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,7 +5,7 @@ Networking Pagination Simple - Map + Observe ApiUser Map to User Zip Disposable Take diff --git a/assets/Rx_Logo_S.png b/assets/Rx_Logo_S.png new file mode 100644 index 0000000..b4066e8 Binary files /dev/null and b/assets/Rx_Logo_S.png differ diff --git a/assets/index.js b/assets/index.js new file mode 100644 index 0000000..6cf1e91 --- /dev/null +++ b/assets/index.js @@ -0,0 +1,108 @@ +// +// go to path of heroku +// git add * +// git commit -m "fix" +// git push heroku master +// https://secret-ridge-27839.herokuapp.com/getAnUser/12 + +var express = require('express'); +var app = express(); + +var user = [{ + id: 12, + firstname: 'able', + lastname: 'black', + isfollowing: ['baseball'] + }, + { + id: 13, + firstname: 'bly', + lastname: 'cane', + isfollowing: ['football'] + }, + { + id: 14, + firstname: 'candy', + lastname: 'donut', + isfollowing: ['baseball', 'football'] + }]; + +var userdetail =[ + { + id: 12, + firstname: 'able', + lastname: 'black' + }, + { + id: 13, + firstname: 'bly', + lastname: 'cane' + }, + { + id: 14, + firstname: 'candy', + lastname: 'donut' + } +]; + +app.set('port', (process.env.PORT || 5000)); + +//for android app +app.get('/getAnUser/:userId', function(request, response) { + var id = request.params.userId; + var item = userdetail.filter(function(el) { + return (el.id == id); + }); +var str = JSON.stringify(item[0]); +response.send(str); +}); + +app.get('/getAllBaseballFans', function(request, response) { + var item = user.filter(function(el) { + return (el.isfollowing.indexOf("baseball") >= 0); + }); + var jObject={}; + for(i in item) + { + jObject[i] = item[i]; + } + response.send(jObject); +}); + +app.get('/getAllFootballFans', function(request, response) { + var item = user.filter(function(el) { + return (el.isfollowing.indexOf("football") >= 0); + }); + var jObject={}; + for(i in item) + { + jObject[i] = item[i]; + } + response.send(jObject); + +}); + +app.get('/getAllFriends/:userId', function(request, response) { + var id = request.params.userId; + var item = user.filter(function(el) { + return (el.id === id); + }); + response.send(item); +}); + +app.get('/getAllUsers', function(request, response) { + response.send(user); +}); + +app.get('/getAnUserDetail/:userId', function(request, response) { +var id = request.params.userId; + var item = userdetail.filter(function(el) { + return (el.id == id); + }); + response.send(item); +}); + + +app.listen(app.get('port'), function() { + console.log('Node app is running on port', app.get('port')); +}); diff --git a/assets/rxjava2.png b/assets/rxjava2.png deleted file mode 100644 index 6417f36..0000000 Binary files a/assets/rxjava2.png and /dev/null differ diff --git a/build.gradle b/build.gradle index 74b2ab0..c2eea8e 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' + classpath 'com.android.tools.build:gradle:2.3.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle.properties b/gradle.properties index 1f8fad9..f392872 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,5 +13,5 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Fri Jan 06 16:06:01 CST 2017 -systemProp.http.proxyHost=127.0.0.1 -systemProp.http.proxyPort=1086 +#systemProp.http.proxyHost=127.0.0.1 +#systemProp.http.proxyPort=1086 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ddbfadd..a92f2b3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip diff --git a/rx2-android-networking/.gitignore b/rx2-android-networking/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/rx2-android-networking/.gitignore @@ -0,0 +1 @@ +/build diff --git a/rx2-android-networking/build.gradle b/rx2-android-networking/build.gradle new file mode 100644 index 0000000..30cb326 --- /dev/null +++ b/rx2-android-networking/build.gradle @@ -0,0 +1,48 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 23 + buildToolsVersion '25.0.0' + + defaultConfig { + minSdkVersion 9 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + testCompile 'junit:junit:4.12' + androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.6.0' + compile 'io.reactivex.rxjava2:rxandroid:2.0.1' + compile 'io.reactivex.rxjava2:rxjava:2.0.5' + compile project(':android-networking') +} +//apply from: 'rx2-upload.gradle' \ No newline at end of file diff --git a/rx2-android-networking/proguard-rules.pro b/rx2-android-networking/proguard-rules.pro new file mode 100644 index 0000000..ab6c072 --- /dev/null +++ b/rx2-android-networking/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/owner/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/rx2-android-networking/src/androidTest/AndroidManifest.xml b/rx2-android-networking/src/androidTest/AndroidManifest.xml new file mode 100755 index 0000000..501fd9a --- /dev/null +++ b/rx2-android-networking/src/androidTest/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2GetJSONApiTest.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2GetJSONApiTest.java new file mode 100644 index 0000000..daed073 --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2GetJSONApiTest.java @@ -0,0 +1,277 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.error.ANError; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Rule; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 30/04/17. + */ + +public class Rx2GetJSONApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public Rx2GetJSONApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testJSONObjectGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getJSONObjectObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONObjectGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getJSONObjectObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONObject response) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testJSONArrayGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getJSONArrayObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONArray response) { + try { + JSONObject jsonObject = response.getJSONObject(0); + firstNameRef.set(jsonObject.getString("firstName")); + lastNameRef.set(jsonObject.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONArrayGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getJSONArrayObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONArray response) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + +} diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2GetObjectApiTest.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2GetObjectApiTest.java new file mode 100644 index 0000000..37ba8a1 --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2GetObjectApiTest.java @@ -0,0 +1,268 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.error.ANError; +import com.rx2androidnetworking.model.User; + +import org.junit.Rule; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 26/04/17. + */ + +public class Rx2GetObjectApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public Rx2GetObjectApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testObjectGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getObjectObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + latch.countDown(); + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getObjectObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(User user) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testObjectListGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getObjectListObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(List userList) { + firstNameRef.set(userList.get(0).firstName); + lastNameRef.set(userList.get(0).lastName); + latch.countDown(); + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectListGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getObjectListObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(List userList) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } +} diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2GetStringApiTest.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2GetStringApiTest.java new file mode 100644 index 0000000..d9c185c --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2GetStringApiTest.java @@ -0,0 +1,160 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.error.ANError; + +import org.junit.Rule; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 22/04/17. + */ + +public class Rx2GetStringApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public Rx2GetStringApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testStringGetRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getStringObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(String response) { + responseRef.set(response); + latch.countDown(); + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("data", responseRef.get()); + } + + public void testStringGetRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.get(server.url("/").toString()) + .build() + .getStringObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(String response) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + +} diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2MultipartJSONApiTest.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2MultipartJSONApiTest.java new file mode 100644 index 0000000..ac433be --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2MultipartJSONApiTest.java @@ -0,0 +1,281 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.error.ANError; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Rule; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 03/05/17. + */ + +public class Rx2MultipartJSONApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public Rx2MultipartJSONApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testJSONObjectMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getJSONObjectObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONObjectMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getJSONObjectObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONObject response) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testJSONArrayMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getJSONArrayObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONArray response) { + try { + JSONObject jsonObject = response.getJSONObject(0); + firstNameRef.set(jsonObject.getString("firstName")); + lastNameRef.set(jsonObject.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONArrayMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getJSONArrayObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONArray response) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + +} diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2MultipartObjectApiTest.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2MultipartObjectApiTest.java new file mode 100644 index 0000000..08ae9e9 --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2MultipartObjectApiTest.java @@ -0,0 +1,272 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.error.ANError; +import com.rx2androidnetworking.model.User; + +import org.junit.Rule; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 29/04/17. + */ + +public class Rx2MultipartObjectApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public Rx2MultipartObjectApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testObjectMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getObjectObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + latch.countDown(); + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getObjectObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(User user) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testObjectListMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getObjectListObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(List userList) { + firstNameRef.set(userList.get(0).firstName); + lastNameRef.set(userList.get(0).lastName); + latch.countDown(); + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectListMultipartRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getObjectListObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(List userList) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } +} diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2MultipartStringApiTest.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2MultipartStringApiTest.java new file mode 100644 index 0000000..d559538 --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2MultipartStringApiTest.java @@ -0,0 +1,162 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.error.ANError; + +import org.junit.Rule; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 25/04/17. + */ + +public class Rx2MultipartStringApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public Rx2MultipartStringApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testStringMultipartRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getStringObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(String response) { + responseRef.set(response); + latch.countDown(); + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("data", responseRef.get()); + } + + public void testStringPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.upload(server.url("/").toString()) + .addMultipartParameter("key", "value") + .build() + .getStringObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(String response) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + +} \ No newline at end of file diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2PostJSONApiTest.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2PostJSONApiTest.java new file mode 100644 index 0000000..93b065c --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2PostJSONApiTest.java @@ -0,0 +1,285 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.error.ANError; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Rule; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 02/05/17. + */ + +public class Rx2PostJSONApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public Rx2PostJSONApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testJSONObjectPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getJSONObjectObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONObject response) { + try { + firstNameRef.set(response.getString("firstName")); + lastNameRef.set(response.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONObjectPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getJSONObjectObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONObject response) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testJSONArrayPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getJSONArrayObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONArray response) { + try { + JSONObject jsonObject = response.getJSONObject(0); + firstNameRef.set(jsonObject.getString("firstName")); + lastNameRef.set(jsonObject.getString("lastName")); + latch.countDown(); + } catch (JSONException e) { + assertTrue(false); + } + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testJSONArrayPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getJSONArrayObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(JSONArray response) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + +} diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2PostObjectApiTest.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2PostObjectApiTest.java new file mode 100644 index 0000000..4b02b61 --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2PostObjectApiTest.java @@ -0,0 +1,276 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.error.ANError; +import com.rx2androidnetworking.model.User; + +import org.junit.Rule; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 28/04/17. + */ + +public class Rx2PostObjectApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public Rx2PostObjectApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testObjectPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getObjectObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(User user) { + firstNameRef.set(user.firstName); + lastNameRef.set(user.lastName); + latch.countDown(); + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getObjectObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(User user) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + + public void testObjectListPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("[{\"firstName\":\"Amit\", \"lastName\":\"Shekhar\"}]")); + + final AtomicReference firstNameRef = new AtomicReference<>(); + final AtomicReference lastNameRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getObjectListObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(List userList) { + firstNameRef.set(userList.get(0).firstName); + lastNameRef.set(userList.get(0).lastName); + latch.countDown(); + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("Amit", firstNameRef.get()); + assertEquals("Shekhar", lastNameRef.get()); + } + + public void testObjectListPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getObjectListObservable(User.class) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(List userList) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } +} diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2PostStringApiTest.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2PostStringApiTest.java new file mode 100644 index 0000000..947530e --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/Rx2PostStringApiTest.java @@ -0,0 +1,164 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.app.Application; +import android.test.ApplicationTestCase; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.error.ANError; + +import org.junit.Rule; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * Created by owner on 24/04/17. + */ + +public class Rx2PostStringApiTest extends ApplicationTestCase { + + @Rule + public final MockWebServer server = new MockWebServer(); + + public Rx2PostStringApiTest() { + super(Application.class); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + createApplication(); + } + + public void testStringPostRequest() throws InterruptedException { + + server.enqueue(new MockResponse().setBody("data")); + + final AtomicReference responseRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final AtomicReference isCompletedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(2); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getStringObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(String response) { + responseRef.set(response); + latch.countDown(); + } + + @Override + public void onError(Throwable e) { + assertTrue(false); + } + + @Override + public void onComplete() { + isCompletedRef.set(true); + latch.countDown(); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + assertTrue(isCompletedRef.get()); + + assertEquals("data", responseRef.get()); + } + + public void testStringPostRequest404() throws InterruptedException { + + server.enqueue(new MockResponse().setResponseCode(404).setBody("data")); + + final AtomicReference errorDetailRef = new AtomicReference<>(); + final AtomicReference errorBodyRef = new AtomicReference<>(); + final AtomicReference errorCodeRef = new AtomicReference<>(); + final AtomicReference isSubscribedRef = new AtomicReference<>(); + final CountDownLatch latch = new CountDownLatch(1); + + Rx2AndroidNetworking.post(server.url("/").toString()) + .addBodyParameter("fistName", "Amit") + .addBodyParameter("lastName", "Shekhar") + .build() + .getStringObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + isSubscribedRef.set(true); + } + + @Override + public void onNext(String response) { + assertTrue(false); + } + + @Override + public void onError(Throwable e) { + ANError anError = (ANError) e; + errorBodyRef.set(anError.getErrorBody()); + errorDetailRef.set(anError.getErrorDetail()); + errorCodeRef.set(anError.getErrorCode()); + latch.countDown(); + } + + @Override + public void onComplete() { + assertTrue(false); + } + }); + + assertTrue(latch.await(2, SECONDS)); + + assertTrue(isSubscribedRef.get()); + + assertEquals(ANConstants.RESPONSE_FROM_SERVER_ERROR, errorDetailRef.get()); + + assertEquals("data", errorBodyRef.get()); + + assertEquals(404, errorCodeRef.get().intValue()); + + } + +} \ No newline at end of file diff --git a/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/model/User.java b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/model/User.java new file mode 100644 index 0000000..f4c01fa --- /dev/null +++ b/rx2-android-networking/src/androidTest/java/com/rx2androidnetworking/model/User.java @@ -0,0 +1,31 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking.model; + +/** + * Created by owner on 26/04/17. + */ + +public class User { + + public String firstName; + public String lastName; + +} diff --git a/rx2-android-networking/src/main/AndroidManifest.xml b/rx2-android-networking/src/main/AndroidManifest.xml new file mode 100644 index 0000000..40fbb9e --- /dev/null +++ b/rx2-android-networking/src/main/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + diff --git a/rx2-android-networking/src/main/java/com/rx2androidnetworking/Rx2ANRequest.java b/rx2-android-networking/src/main/java/com/rx2androidnetworking/Rx2ANRequest.java new file mode 100644 index 0000000..161994a --- /dev/null +++ b/rx2-android-networking/src/main/java/com/rx2androidnetworking/Rx2ANRequest.java @@ -0,0 +1,223 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.graphics.Bitmap; + +import com.androidnetworking.common.ANRequest; +import com.androidnetworking.common.Method; +import com.androidnetworking.common.RequestType; +import com.androidnetworking.common.ResponseType; +import com.google.gson.internal.$Gson$Types; +import com.google.gson.reflect.TypeToken; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.List; + +import io.reactivex.Observable; + +/** + * Created by owner on 30-01-2017. + */ +@SuppressWarnings({"unchecked", "unused"}) +public class Rx2ANRequest extends ANRequest { + + public Rx2ANRequest(GetRequestBuilder builder) { + super(builder); + } + + public Rx2ANRequest(PostRequestBuilder builder) { + super(builder); + } + + public Rx2ANRequest(DownloadBuilder builder) { + super(builder); + } + + public Rx2ANRequest(MultiPartBuilder builder) { + super(builder); + } + + public Observable getJSONObjectObservable() { + this.setResponseAs(ResponseType.JSON_OBJECT); + if (this.getRequestType() == RequestType.SIMPLE) { + return Rx2InternalNetworking.generateSimpleObservable(this); + } else if (this.getRequestType() == RequestType.MULTIPART) { + return Rx2InternalNetworking.generateMultipartObservable(this); + } else { + return null; + } + } + + public Observable getJSONArrayObservable() { + this.setResponseAs(ResponseType.JSON_ARRAY); + if (this.getRequestType() == RequestType.SIMPLE) { + return Rx2InternalNetworking.generateSimpleObservable(this); + } else if (this.getRequestType() == RequestType.MULTIPART) { + return Rx2InternalNetworking.generateMultipartObservable(this); + } else { + return null; + } + } + + public Observable getBitmapObservable() { + this.setResponseAs(ResponseType.BITMAP); + if (this.getRequestType() == RequestType.SIMPLE) { + return Rx2InternalNetworking.generateSimpleObservable(this); + } else if (this.getRequestType() == RequestType.MULTIPART) { + return Rx2InternalNetworking.generateMultipartObservable(this); + } else { + return null; + } + } + + public Observable getStringObservable() { + this.setResponseAs(ResponseType.STRING); + if (this.getRequestType() == RequestType.SIMPLE) { + return Rx2InternalNetworking.generateSimpleObservable(this); + } else if (this.getRequestType() == RequestType.MULTIPART) { + return Rx2InternalNetworking.generateMultipartObservable(this); + } else { + return null; + } + } + + public Observable getDownloadObservable() { + return Rx2InternalNetworking.generateDownloadObservable(this); + } + + public Observable getParseObservable(TypeToken typeToken) { + this.setType(typeToken.getType()); + this.setResponseAs(ResponseType.PARSED); + if (this.getRequestType() == RequestType.SIMPLE) { + return Rx2InternalNetworking.generateSimpleObservable(this); + } else if (this.getRequestType() == RequestType.MULTIPART) { + return Rx2InternalNetworking.generateMultipartObservable(this); + } else { + return null; + } + } + + public Observable getObjectObservable(Class objectClass) { + this.setType(objectClass); + this.setResponseAs(ResponseType.PARSED); + if (this.getRequestType() == RequestType.SIMPLE) { + return Rx2InternalNetworking.generateSimpleObservable(this); + } else if (this.getRequestType() == RequestType.MULTIPART) { + return Rx2InternalNetworking.generateMultipartObservable(this); + } else { + return null; + } + } + + public Observable> getObjectListObservable(Class objectClass) { + this.setType($Gson$Types.newParameterizedTypeWithOwner(null, List.class, objectClass)); + this.setResponseAs(ResponseType.PARSED); + if (this.getRequestType() == RequestType.SIMPLE) { + return Rx2InternalNetworking.generateSimpleObservable(this); + } else if (this.getRequestType() == RequestType.MULTIPART) { + return Rx2InternalNetworking.generateMultipartObservable(this); + } else { + return null; + } + } + + public static class GetRequestBuilder extends ANRequest.GetRequestBuilder { + + public GetRequestBuilder(String url) { + super(url); + } + + private GetRequestBuilder(String url, int method) { + super(url, method); + } + + public Rx2ANRequest build() { + return new Rx2ANRequest(this); + } + } + + public static class HeadRequestBuilder extends GetRequestBuilder { + + public HeadRequestBuilder(String url) { + super(url, Method.HEAD); + } + } + + public static class PostRequestBuilder extends ANRequest.PostRequestBuilder { + + public PostRequestBuilder(String url) { + super(url); + } + + private PostRequestBuilder(String url, int method) { + super(url, method); + } + + public Rx2ANRequest build() { + return new Rx2ANRequest(this); + } + } + + public static class PutRequestBuilder extends PostRequestBuilder { + + public PutRequestBuilder(String url) { + super(url, Method.PUT); + } + } + + public static class DeleteRequestBuilder extends PostRequestBuilder { + + public DeleteRequestBuilder(String url) { + super(url, Method.DELETE); + } + } + + public static class PatchRequestBuilder extends PostRequestBuilder { + + public PatchRequestBuilder(String url) { + super(url, Method.PATCH); + } + } + + public static class DownloadBuilder extends ANRequest.DownloadBuilder { + + public DownloadBuilder(String url, String dirPath, String fileName) { + super(url, dirPath, fileName); + } + + public Rx2ANRequest build() { + return new Rx2ANRequest(this); + } + } + + public static class MultiPartBuilder extends ANRequest.MultiPartBuilder { + + public MultiPartBuilder(String url) { + super(url); + } + + public Rx2ANRequest build() { + return new Rx2ANRequest(this); + } + } +} diff --git a/rx2-android-networking/src/main/java/com/rx2androidnetworking/Rx2AndroidNetworking.java b/rx2-android-networking/src/main/java/com/rx2androidnetworking/Rx2AndroidNetworking.java new file mode 100644 index 0000000..9e64ba1 --- /dev/null +++ b/rx2-android-networking/src/main/java/com/rx2androidnetworking/Rx2AndroidNetworking.java @@ -0,0 +1,120 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +/** + * Created by owner on 30/01/17. + */ + +/** + * Rx2AndroidNetworking entry point. + * You must initialize this class before use. The simplest way is to just do + * {#code AndroidNetworking.initialize(context)}. + */ +public class Rx2AndroidNetworking { + + /** + * private constructor to prevent instantiation of this class + */ + private Rx2AndroidNetworking() { + } + + /** + * Method to make GET request + * + * @param url The url on which request is to be made + * @return The GetRequestBuilder + */ + public static Rx2ANRequest.GetRequestBuilder get(String url) { + return new Rx2ANRequest.GetRequestBuilder(url); + } + + /** + * Method to make HEAD request + * + * @param url The url on which request is to be made + * @return The HeadRequestBuilder + */ + public static Rx2ANRequest.HeadRequestBuilder head(String url) { + return new Rx2ANRequest.HeadRequestBuilder(url); + } + + /** + * Method to make POST request + * + * @param url The url on which request is to be made + * @return The PostRequestBuilder + */ + public static Rx2ANRequest.PostRequestBuilder post(String url) { + return new Rx2ANRequest.PostRequestBuilder(url); + } + + /** + * Method to make PUT request + * + * @param url The url on which request is to be made + * @return The PutRequestBuilder + */ + public static Rx2ANRequest.PutRequestBuilder put(String url) { + return new Rx2ANRequest.PutRequestBuilder(url); + } + + /** + * Method to make DELETE request + * + * @param url The url on which request is to be made + * @return The DeleteRequestBuilder + */ + public static Rx2ANRequest.DeleteRequestBuilder delete(String url) { + return new Rx2ANRequest.DeleteRequestBuilder(url); + } + + /** + * Method to make PATCH request + * + * @param url The url on which request is to be made + * @return The PatchRequestBuilder + */ + public static Rx2ANRequest.PatchRequestBuilder patch(String url) { + return new Rx2ANRequest.PatchRequestBuilder(url); + } + + /** + * Method to make download request + * + * @param url The url on which request is to be made + * @param dirPath The directory path on which file is to be saved + * @param fileName The file name with which file is to be saved + * @return The DownloadBuilder + */ + public static Rx2ANRequest.DownloadBuilder download(String url, String dirPath, String fileName) { + return new Rx2ANRequest.DownloadBuilder(url, dirPath, fileName); + } + + /** + * Method to make upload request + * + * @param url The url on which request is to be made + * @return The MultiPartBuilder + */ + public static Rx2ANRequest.MultiPartBuilder upload(String url) { + return new Rx2ANRequest.MultiPartBuilder(url); + } +} diff --git a/rx2-android-networking/src/main/java/com/rx2androidnetworking/Rx2InternalNetworking.java b/rx2-android-networking/src/main/java/com/rx2androidnetworking/Rx2InternalNetworking.java new file mode 100644 index 0000000..f9030ec --- /dev/null +++ b/rx2-android-networking/src/main/java/com/rx2androidnetworking/Rx2InternalNetworking.java @@ -0,0 +1,441 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import android.net.TrafficStats; + +import com.androidnetworking.common.ANConstants; +import com.androidnetworking.common.ANResponse; +import com.androidnetworking.common.ConnectionClassManager; +import com.androidnetworking.error.ANError; +import com.androidnetworking.internal.InternalNetworking; +import com.androidnetworking.internal.RequestProgressBody; +import com.androidnetworking.internal.ResponseProgressBody; +import com.androidnetworking.utils.SourceCloseUtil; +import com.androidnetworking.utils.Utils; + +import java.io.File; +import java.io.IOException; + +import io.reactivex.Observable; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.exceptions.Exceptions; +import io.reactivex.plugins.RxJavaPlugins; +import okhttp3.Call; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import static com.androidnetworking.common.Method.DELETE; +import static com.androidnetworking.common.Method.GET; +import static com.androidnetworking.common.Method.HEAD; +import static com.androidnetworking.common.Method.PATCH; +import static com.androidnetworking.common.Method.POST; +import static com.androidnetworking.common.Method.PUT; + +/** + * Created by owner on 30-01-2017. + */ +@SuppressWarnings("unchecked") +public class Rx2InternalNetworking { + + public static Observable generateSimpleObservable(Rx2ANRequest request) { + Request okHttpRequest; + Request.Builder builder = new Request.Builder().url(request.getUrl()); + InternalNetworking.addHeadersToRequestBuilder(builder, request); + RequestBody requestBody; + switch (request.getMethod()) { + case GET: { + builder = builder.get(); + break; + } + case POST: { + requestBody = request.getRequestBody(); + builder = builder.post(requestBody); + break; + } + case PUT: { + requestBody = request.getRequestBody(); + builder = builder.put(requestBody); + break; + } + case DELETE: { + requestBody = request.getRequestBody(); + builder = builder.delete(requestBody); + break; + } + case HEAD: { + builder = builder.head(); + break; + } + case PATCH: { + requestBody = request.getRequestBody(); + builder = builder.patch(requestBody); + break; + } + } + if (request.getCacheControl() != null) { + builder.cacheControl(request.getCacheControl()); + } + okHttpRequest = builder.build(); + if (request.getOkHttpClient() != null) { + request.setCall(request + .getOkHttpClient() + .newBuilder() + .cache(InternalNetworking.sHttpClient.cache()) + .build() + .newCall(okHttpRequest)); + } else { + request.setCall(InternalNetworking.sHttpClient.newCall(okHttpRequest)); + } + return new SimpleANObservable<>(request); + } + + public static Observable generateDownloadObservable(final Rx2ANRequest request) { + Request okHttpRequest; + Request.Builder builder = new Request.Builder().url(request.getUrl()); + InternalNetworking.addHeadersToRequestBuilder(builder, request); + builder = builder.get(); + if (request.getCacheControl() != null) { + builder.cacheControl(request.getCacheControl()); + } + okHttpRequest = builder.build(); + + OkHttpClient okHttpClient; + + if (request.getOkHttpClient() != null) { + okHttpClient = request + .getOkHttpClient() + .newBuilder() + .cache(InternalNetworking.sHttpClient.cache()) + .addNetworkInterceptor(new Interceptor() { + @Override + public Response intercept(Chain chain) throws IOException { + Response originalResponse = chain.proceed(chain.request()); + return originalResponse.newBuilder() + .body(new ResponseProgressBody(originalResponse.body(), + request.getDownloadProgressListener())) + .build(); + } + }).build(); + } else { + okHttpClient = InternalNetworking.sHttpClient.newBuilder() + .addNetworkInterceptor(new Interceptor() { + @Override + public Response intercept(Chain chain) throws IOException { + Response originalResponse = chain.proceed(chain.request()); + return originalResponse.newBuilder() + .body(new ResponseProgressBody(originalResponse.body(), + request.getDownloadProgressListener())) + .build(); + } + }).build(); + } + request.setCall(okHttpClient.newCall(okHttpRequest)); + return new DownloadANObservable<>(request); + } + + public static Observable generateMultipartObservable(final Rx2ANRequest request) { + return new MultipartANObservable<>(request); + } + + static final class SimpleANObservable extends Observable { + + private Rx2ANRequest request; + private final Call originalCall; + + SimpleANObservable(Rx2ANRequest request) { + this.request = request; + this.originalCall = request.getCall(); + } + + @Override + protected void subscribeActual(Observer observer) { + Call call = originalCall.clone(); + observer.onSubscribe(new ANDisposable(call)); + boolean doNotSwallowError = false; + Response okHttpResponse = null; + try { + final long startTime = System.currentTimeMillis(); + final long startBytes = TrafficStats.getTotalRxBytes(); + okHttpResponse = call.execute(); + final long timeTaken = System.currentTimeMillis() - startTime; + if (okHttpResponse.cacheResponse() == null) { + final long finalBytes = TrafficStats.getTotalRxBytes(); + final long diffBytes; + if (startBytes == TrafficStats.UNSUPPORTED || finalBytes == TrafficStats.UNSUPPORTED) { + diffBytes = okHttpResponse.body().contentLength(); + } else { + diffBytes = finalBytes - startBytes; + } + ConnectionClassManager.getInstance().updateBandwidth(diffBytes, timeTaken); + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, + (request.getRequestBody() != null && + request.getRequestBody().contentLength() != 0) ? + request.getRequestBody().contentLength() : -1, + okHttpResponse.body().contentLength(), false); + } else if (request.getAnalyticsListener() != null) { + if (okHttpResponse.networkResponse() == null) { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, 0, 0, true); + } else { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, + (request.getRequestBody() != null && request.getRequestBody().contentLength() != 0) ? + request.getRequestBody().contentLength() : -1, 0, true); + } + } + if (okHttpResponse.code() >= 400) { + if (!call.isCanceled()) { + observer.onError(Utils.getErrorForServerResponse(new ANError(okHttpResponse), + request, okHttpResponse.code())); + } + } else { + ANResponse response = request.parseResponse(okHttpResponse); + if (!response.isSuccess()) { + if (!call.isCanceled()) { + observer.onError(response.getError()); + } + } else { + if (!call.isCanceled()) { + observer.onNext(response.getResult()); + } + if (!call.isCanceled()) { + doNotSwallowError = true; + observer.onComplete(); + } + } + } + } catch (IOException ioe) { + if (!call.isCanceled()) { + observer.onError(Utils.getErrorForConnection(new ANError(ioe))); + } + } catch (Exception e) { + Exceptions.throwIfFatal(e); + if (doNotSwallowError) { + RxJavaPlugins.onError(e); + } else if (!call.isCanceled()) { + try { + observer.onError(Utils.getErrorForNetworkOnMainThreadOrConnection(e)); + } catch (Exception e1) { + Exceptions.throwIfFatal(e1); + RxJavaPlugins.onError(new CompositeException(e, e1)); + } + } + } finally { + SourceCloseUtil.close(okHttpResponse, request); + } + } + } + + static final class DownloadANObservable extends Observable { + + private final Rx2ANRequest request; + private final Call originalCall; + + DownloadANObservable(Rx2ANRequest request) { + this.request = request; + this.originalCall = request.getCall(); + } + + @Override + protected void subscribeActual(Observer observer) { + Call call = originalCall.clone(); + observer.onSubscribe(new ANDisposable(call)); + boolean doNotSwallowError = false; + Response okHttpResponse; + try { + final long startTime = System.currentTimeMillis(); + final long startBytes = TrafficStats.getTotalRxBytes(); + okHttpResponse = request.getCall().execute(); + Utils.saveFile(okHttpResponse, request.getDirPath(), request.getFileName()); + final long timeTaken = System.currentTimeMillis() - startTime; + if (okHttpResponse.cacheResponse() == null) { + final long finalBytes = TrafficStats.getTotalRxBytes(); + final long diffBytes; + if (startBytes == TrafficStats.UNSUPPORTED || + finalBytes == TrafficStats.UNSUPPORTED) { + diffBytes = okHttpResponse.body().contentLength(); + } else { + diffBytes = finalBytes - startBytes; + } + ConnectionClassManager.getInstance().updateBandwidth(diffBytes, timeTaken); + Utils.sendAnalytics(request.getAnalyticsListener(), + timeTaken, -1, okHttpResponse.body().contentLength(), false); + } else if (request.getAnalyticsListener() != null) { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, -1, 0, true); + } + if (okHttpResponse.code() >= 400) { + if (!call.isCanceled()) { + observer.onError(Utils.getErrorForServerResponse(new ANError(okHttpResponse), + request, okHttpResponse.code())); + } + } else { + if (!call.isCanceled()) { + ANResponse response = (ANResponse) ANResponse.success(ANConstants.SUCCESS); + observer.onNext(response.getResult()); + } + if (!call.isCanceled()) { + doNotSwallowError = true; + observer.onComplete(); + } + } + } catch (IOException ioe) { + try { + File destinationFile = new File(request.getDirPath() + File.separator + request.getFileName()); + if (destinationFile.exists()) { + destinationFile.delete(); + } + } catch (Exception e) { + e.printStackTrace(); + } + if (!call.isCanceled()) { + observer.onError(Utils.getErrorForConnection(new ANError(ioe))); + } + } catch (Exception e) { + Exceptions.throwIfFatal(e); + if (doNotSwallowError) { + RxJavaPlugins.onError(e); + } else if (!call.isCanceled()) { + try { + observer.onError(Utils.getErrorForNetworkOnMainThreadOrConnection(e)); + } catch (Exception e1) { + Exceptions.throwIfFatal(e1); + RxJavaPlugins.onError(new CompositeException(e, e1)); + } + } + } + } + } + + static final class MultipartANObservable extends Observable { + + private final Rx2ANRequest request; + + MultipartANObservable(Rx2ANRequest request) { + this.request = request; + } + + @Override + protected void subscribeActual(Observer observer) { + boolean doNotSwallowError = false; + Response okHttpResponse = null; + Request okHttpRequest; + try { + Request.Builder builder = new Request.Builder().url(request.getUrl()); + InternalNetworking.addHeadersToRequestBuilder(builder, request); + final RequestBody requestBody = request.getMultiPartRequestBody(); + final long requestBodyLength = requestBody.contentLength(); + builder = builder.post(new RequestProgressBody(requestBody, request.getUploadProgressListener())); + if (request.getCacheControl() != null) { + builder.cacheControl(request.getCacheControl()); + } + okHttpRequest = builder.build(); + if (request.getOkHttpClient() != null) { + request.setCall(request + .getOkHttpClient() + .newBuilder() + .cache(InternalNetworking.sHttpClient.cache()) + .build() + .newCall(okHttpRequest)); + } else { + request.setCall(InternalNetworking.sHttpClient.newCall(okHttpRequest)); + } + observer.onSubscribe(new ANDisposable(request.getCall())); + final long startTime = System.currentTimeMillis(); + okHttpResponse = request.getCall().execute(); + final long timeTaken = System.currentTimeMillis() - startTime; + if (request.getAnalyticsListener() != null) { + if (okHttpResponse.cacheResponse() == null) { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, + requestBodyLength, okHttpResponse.body().contentLength(), false); + } else { + if (okHttpResponse.networkResponse() == null) { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, 0, 0, true); + } else { + Utils.sendAnalytics(request.getAnalyticsListener(), timeTaken, + requestBodyLength != 0 ? requestBodyLength : -1, 0, true); + } + } + } + if (okHttpResponse.code() >= 400) { + if (!request.getCall().isCanceled()) { + observer.onError(Utils.getErrorForServerResponse(new ANError(okHttpResponse), + request, okHttpResponse.code())); + } + } else { + ANResponse response = request.parseResponse(okHttpResponse); + if (!response.isSuccess()) { + if (!request.getCall().isCanceled()) { + observer.onError(response.getError()); + } + } else { + if (!request.getCall().isCanceled()) { + observer.onNext(response.getResult()); + } + if (!request.getCall().isCanceled()) { + doNotSwallowError = true; + observer.onComplete(); + } + } + } + } catch (IOException ioe) { + if (!request.getCall().isCanceled()) { + observer.onError(Utils.getErrorForConnection(new ANError(ioe))); + } + } catch (Exception e) { + Exceptions.throwIfFatal(e); + if (doNotSwallowError) { + RxJavaPlugins.onError(e); + } else if (!request.getCall().isCanceled()) { + try { + observer.onError(Utils.getErrorForNetworkOnMainThreadOrConnection(e)); + } catch (Exception e1) { + Exceptions.throwIfFatal(e1); + RxJavaPlugins.onError(new CompositeException(e, e1)); + } + } + } finally { + SourceCloseUtil.close(okHttpResponse, request); + } + } + } + + private static final class ANDisposable implements Disposable { + + private final Call call; + + private ANDisposable(Call call) { + this.call = call; + } + + @Override + public void dispose() { + this.call.cancel(); + } + + @Override + public boolean isDisposed() { + return this.call.isCanceled(); + } + } +} diff --git a/rx2-android-networking/src/main/res/values/strings.xml b/rx2-android-networking/src/main/res/values/strings.xml new file mode 100644 index 0000000..c5e2584 --- /dev/null +++ b/rx2-android-networking/src/main/res/values/strings.xml @@ -0,0 +1,22 @@ + + + + Rx2AndroidNetworking + diff --git a/rx2-android-networking/src/test/java/com/rx2androidnetworking/ExampleUnitTest.java b/rx2-android-networking/src/test/java/com/rx2androidnetworking/ExampleUnitTest.java new file mode 100644 index 0000000..a650ac4 --- /dev/null +++ b/rx2-android-networking/src/test/java/com/rx2androidnetworking/ExampleUnitTest.java @@ -0,0 +1,36 @@ +/* + * + * * Copyright (C) 2016 Amit Shekhar + * * Copyright (C) 2011 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. + * + */ + +package com.rx2androidnetworking; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index e7b4def..6e43266 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app' +include ':app', ':android-networking', ':rx2-android-networking'