├── .gitignore ├── example-android ├── app │ ├── .gitignore │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── drawable-v24 │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ ├── layout │ │ │ │ │ └── activity_main.xml │ │ │ │ └── drawable │ │ │ │ │ └── ic_launcher_background.xml │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── akaita │ │ │ │ └── java │ │ │ │ └── rxjava2debug │ │ │ │ └── exampleandroid │ │ │ │ ├── Extensions.kt │ │ │ │ ├── ExampleApplication.kt │ │ │ │ └── MainActivity.kt │ │ ├── test │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── akaita │ │ │ │ └── java │ │ │ │ └── rxjava2debug │ │ │ │ └── exampleandroid │ │ │ │ └── ExampleUnitTest.kt │ │ └── androidTest │ │ │ └── java │ │ │ └── com │ │ │ └── akaita │ │ │ └── java │ │ │ └── rxjava2debug │ │ │ └── exampleandroid │ │ │ └── ExampleInstrumentedTest.kt │ ├── proguard-rules.pro │ └── build.gradle ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── .idea │ ├── vcs.xml │ ├── modules.xml │ ├── runConfigurations.xml │ ├── gradle.xml │ └── misc.xml ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── rxjava2debug ├── gradle.properties ├── settings.gradle ├── gradle │ ├── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── javadocStyleSheet.css │ └── maven.gradle ├── .travis.yml ├── .gitignore ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── akaita │ │ │ └── java │ │ │ └── rxjava2debug │ │ │ ├── extensions │ │ │ ├── MaybeOnAssemblyScalarCallable.java │ │ │ ├── SingleOnAssemblyScalarCallable.java │ │ │ ├── CompletableOnAssemblyScalarCallable.java │ │ │ ├── ObservableOnAssemblyScalarCallable.java │ │ │ ├── ObservableOnAssemblyConnectable.java │ │ │ ├── MaybeOnAssemblyCallable.java │ │ │ ├── SingleOnAssemblyCallable.java │ │ │ ├── CompletableOnAssemblyCallable.java │ │ │ ├── FlowableOnAssemblyScalarCallable.java │ │ │ ├── ObservableOnAssemblyCallable.java │ │ │ ├── FlowableOnAssemblyConnectable.java │ │ │ ├── FlowableOnAssemblyCallable.java │ │ │ ├── ParallelFlowableOnAssembly.java │ │ │ ├── ObservableOnAssembly.java │ │ │ ├── CompletableOnAssembly.java │ │ │ ├── SingleOnAssembly.java │ │ │ ├── MaybeOnAssembly.java │ │ │ ├── FlowableOnAssembly.java │ │ │ ├── RxJavaAssemblyException.java │ │ │ └── RxJavaAssemblyTracking.java │ │ │ ├── ExceptionUtils.java │ │ │ ├── StackTraceUtils.java │ │ │ └── RxJava2Debug.java │ └── test │ │ └── java │ │ └── hu │ │ └── akarnokd │ │ └── rxjava2 │ │ ├── test │ │ └── BaseTest.java │ │ └── debug │ │ └── RxJava2AssemblyTrackingTest.java ├── gradlew.bat ├── build.gradle ├── gradlew └── pmd.xml ├── screenshots ├── raw_stack_trace.png ├── raw_crash_report.png ├── enhanced_stack_trace.png └── enhanced_crash_report.png ├── HEADER ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store -------------------------------------------------------------------------------- /example-android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /rxjava2debug/gradle.properties: -------------------------------------------------------------------------------- 1 | version=1.4.0 2 | -------------------------------------------------------------------------------- /example-android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /rxjava2debug/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'rxjava2-debug' 2 | -------------------------------------------------------------------------------- /screenshots/raw_stack_trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/screenshots/raw_stack_trace.png -------------------------------------------------------------------------------- /screenshots/raw_crash_report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/screenshots/raw_crash_report.png -------------------------------------------------------------------------------- /screenshots/enhanced_stack_trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/screenshots/enhanced_stack_trace.png -------------------------------------------------------------------------------- /screenshots/enhanced_crash_report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/screenshots/enhanced_crash_report.png -------------------------------------------------------------------------------- /example-android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RxJava2Debug example 3 | 4 | -------------------------------------------------------------------------------- /rxjava2debug/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/rxjava2debug/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example-android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example-android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaita/RxJava2Debug/HEAD/example-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example-android/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /example-android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /example-android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Jan 18 19:52:53 GMT 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /rxjava2debug/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Jul 05 21:36:15 CEST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip 7 | -------------------------------------------------------------------------------- /rxjava2debug/.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk7 5 | 6 | before_install: 7 | - chmod +x gradlew 8 | 9 | after_success: 10 | - bash <(curl -s https://codecov.io/bash) 11 | 12 | # cache between builds 13 | cache: 14 | directories: 15 | - $HOME/.m2 16 | - $HOME/.gradle 17 | -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /rxjava2debug/.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | /build/ 8 | 9 | .gradle 10 | .m2 11 | /.nb-gradle/ 12 | /bin/ 13 | .settings/ 14 | .nb-gradle-properties 15 | .classpath 16 | .project 17 | .settings 18 | .metadata 19 | .checkstyle 20 | bin/ 21 | !/gradle/wrapper/gradle-wrapper.jar 22 | .pmd 23 | .ruleset 24 | local.properties 25 | .idea 26 | -------------------------------------------------------------------------------- /example-android/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example-android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /example-android/app/src/test/java/com/akaita/java/rxjava2debug/exampleandroid/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.akaita.java.rxjava2debug.exampleandroid 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /HEADER: -------------------------------------------------------------------------------- 1 | Copyright 2017-${year} Mikel Pascual 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /example-android/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /example-android/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog for RxJava2Debug 2 | 3 | ## v1.4.0 2018/11/24 4 | * Improve enhanced exception's `localisedMessage` (for example, show `caused by java.langNullPointerException: The mapper function returned a null value` instead of `null`) 5 | * Fix packages comflict with RxJava2Extensions 6 | 7 | ## v1.3.0 2018/10/28 8 | * Fixed compatibility with RxJava-2.2.1 (thanks to @akarnokd) 9 | 10 | ## v1.2.2 2017/12/08 11 | * Fix crash on some Android JVM 12 | 13 | ## v1.2.1 2017/10/21 14 | * Prevent possible crash 15 | 16 | ## v1.2.0 2017/07/30 17 | * Add ability to provide clear stack-traces for handled exceptions 18 | 19 | ## v1.1.0 2017/07/03 20 | * Add option for empty filters 21 | 22 | ## v1.0.0 2017/07/03 23 | * Initial public release 24 | -------------------------------------------------------------------------------- /example-android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext.kotlin_version = '1.2.20' 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.0.1' 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /example-android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /example-android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /example-android/app/src/androidTest/java/com/akaita/java/rxjava2debug/exampleandroid/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.akaita.java.rxjava2debug.exampleandroid 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.akaita.java.rxjava2debug.exampleandroid", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example-android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /example-android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 26 9 | defaultConfig { 10 | applicationId "com.akaita.java.rxjava2debug.exampleandroid" 11 | minSdkVersion 16 12 | targetSdkVersion 26 13 | versionCode 1 14 | versionName "1.0" 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | implementation fileTree(dir: 'libs', include: ['*.jar']) 27 | implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 28 | implementation 'com.android.support:appcompat-v7:26.1.0' 29 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 30 | testImplementation 'junit:junit:4.12' 31 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 32 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 33 | 34 | implementation 'io.reactivex.rxjava2:rxandroid:2.1.0' 35 | implementation 'io.reactivex.rxjava2:rxjava:2.2.3' 36 | 37 | implementation 'com.akaita.java:rxjava2-debug:1.4.0' 38 | } 39 | -------------------------------------------------------------------------------- /example-android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/MaybeOnAssemblyScalarCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import com.akaita.java.rxjava2debug.extensions.MaybeOnAssembly.OnAssemblyMaybeObserver; 20 | import io.reactivex.*; 21 | import io.reactivex.internal.fuseable.ScalarCallable; 22 | 23 | /** 24 | * Wraps a MaybeSource and inject the assembly info. 25 | * 26 | * @param the value type 27 | */ 28 | final class MaybeOnAssemblyScalarCallable extends Maybe implements ScalarCallable { 29 | 30 | final MaybeSource source; 31 | 32 | final RxJavaAssemblyException assembled; 33 | 34 | MaybeOnAssemblyScalarCallable(MaybeSource source) { 35 | this.source = source; 36 | this.assembled = new RxJavaAssemblyException(); 37 | } 38 | 39 | @Override 40 | protected void subscribeActual(MaybeObserver s) { 41 | source.subscribe(new OnAssemblyMaybeObserver(s, assembled)); 42 | } 43 | 44 | @SuppressWarnings("unchecked") 45 | @Override 46 | public T call() { 47 | return ((ScalarCallable)source).call(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/SingleOnAssemblyScalarCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import com.akaita.java.rxjava2debug.extensions.SingleOnAssembly.OnAssemblySingleObserver; 20 | import io.reactivex.*; 21 | import io.reactivex.internal.fuseable.ScalarCallable; 22 | 23 | /** 24 | * Wraps a Publisher and inject the assembly info. 25 | * 26 | * @param the value type 27 | */ 28 | final class SingleOnAssemblyScalarCallable extends Single implements ScalarCallable { 29 | 30 | final SingleSource source; 31 | 32 | final RxJavaAssemblyException assembled; 33 | 34 | SingleOnAssemblyScalarCallable(SingleSource source) { 35 | this.source = source; 36 | this.assembled = new RxJavaAssemblyException(); 37 | } 38 | 39 | @Override 40 | protected void subscribeActual(SingleObserver s) { 41 | source.subscribe(new OnAssemblySingleObserver(s, assembled)); 42 | } 43 | 44 | @SuppressWarnings("unchecked") 45 | @Override 46 | public T call() { 47 | return ((ScalarCallable)source).call(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/CompletableOnAssemblyScalarCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import com.akaita.java.rxjava2debug.extensions.CompletableOnAssembly.OnAssemblyCompletableObserver; 20 | import io.reactivex.*; 21 | import io.reactivex.internal.fuseable.ScalarCallable; 22 | 23 | /** 24 | * Wraps a CompletableSource and inject the assembly info. 25 | */ 26 | final class CompletableOnAssemblyScalarCallable extends Completable implements ScalarCallable { 27 | 28 | final CompletableSource source; 29 | 30 | final RxJavaAssemblyException assembled; 31 | 32 | CompletableOnAssemblyScalarCallable(CompletableSource source) { 33 | this.source = source; 34 | this.assembled = new RxJavaAssemblyException(); 35 | } 36 | 37 | @Override 38 | protected void subscribeActual(CompletableObserver s) { 39 | source.subscribe(new OnAssemblyCompletableObserver(s, assembled)); 40 | } 41 | 42 | @SuppressWarnings("unchecked") 43 | @Override 44 | public Object call() { 45 | return ((ScalarCallable)source).call(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/ObservableOnAssemblyScalarCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import com.akaita.java.rxjava2debug.extensions.ObservableOnAssembly.OnAssemblyObserver; 20 | import io.reactivex.*; 21 | import io.reactivex.internal.fuseable.ScalarCallable; 22 | 23 | /** 24 | * Wraps a ObservableSource and inject the assembly info. 25 | * 26 | * @param the value type 27 | */ 28 | final class ObservableOnAssemblyScalarCallable extends Observable implements ScalarCallable { 29 | 30 | final ObservableSource source; 31 | 32 | final RxJavaAssemblyException assembled; 33 | 34 | ObservableOnAssemblyScalarCallable(ObservableSource source) { 35 | this.source = source; 36 | this.assembled = new RxJavaAssemblyException(); 37 | } 38 | 39 | @Override 40 | protected void subscribeActual(Observer s) { 41 | source.subscribe(new OnAssemblyObserver(s, assembled)); 42 | } 43 | 44 | @SuppressWarnings("unchecked") 45 | @Override 46 | public T call() { 47 | return ((ScalarCallable)source).call(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /rxjava2debug/src/test/java/hu/akarnokd/rxjava2/test/BaseTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package hu.akarnokd.rxjava2.test; 18 | 19 | import org.reactivestreams.Publisher; 20 | 21 | import io.reactivex.*; 22 | import io.reactivex.observers.TestObserver; 23 | import io.reactivex.subscribers.TestSubscriber; 24 | 25 | public abstract class BaseTest { 26 | 27 | public static void assertResult(ObservableSource source, T... array) { 28 | TestObserver ts = new TestObserver(); 29 | 30 | source.subscribe(ts); 31 | 32 | ts.assertValues(array); 33 | ts.assertNoErrors(); 34 | ts.assertComplete(); 35 | } 36 | 37 | public static void assertResult(Publisher source, T... array) { 38 | TestSubscriber ts = new TestSubscriber(); 39 | 40 | source.subscribe(ts); 41 | 42 | ts.assertValues(array) 43 | .assertNoErrors() 44 | .assertComplete(); 45 | } 46 | 47 | 48 | public static Observable observe(T... array) { 49 | return Observable.fromArray(array); 50 | } 51 | 52 | public static Flowable flow(T... array) { 53 | return Flowable.fromArray(array); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/ObservableOnAssemblyConnectable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import com.akaita.java.rxjava2debug.extensions.ObservableOnAssembly.OnAssemblyObserver; 20 | import io.reactivex.Observer; 21 | import io.reactivex.disposables.Disposable; 22 | import io.reactivex.functions.Consumer; 23 | import io.reactivex.observables.ConnectableObservable; 24 | 25 | /** 26 | * Wraps a ObservableSource and inject the assembly info. 27 | * 28 | * @param the value type 29 | */ 30 | final class ObservableOnAssemblyConnectable extends ConnectableObservable { 31 | 32 | final ConnectableObservable source; 33 | 34 | final RxJavaAssemblyException assembled; 35 | 36 | ObservableOnAssemblyConnectable(ConnectableObservable source) { 37 | this.source = source; 38 | this.assembled = new RxJavaAssemblyException(); 39 | } 40 | 41 | @Override 42 | protected void subscribeActual(Observer s) { 43 | source.subscribe(new OnAssemblyObserver(s, assembled)); 44 | } 45 | 46 | @Override 47 | public void connect(Consumer connection) { 48 | source.connect(connection); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/MaybeOnAssemblyCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import java.util.concurrent.Callable; 20 | 21 | import com.akaita.java.rxjava2debug.extensions.MaybeOnAssembly.OnAssemblyMaybeObserver; 22 | import io.reactivex.*; 23 | import io.reactivex.exceptions.Exceptions; 24 | 25 | /** 26 | * Wraps a MaybeSource and inject the assembly info. 27 | * 28 | * @param the value type 29 | */ 30 | final class MaybeOnAssemblyCallable extends Maybe implements Callable { 31 | 32 | final MaybeSource source; 33 | 34 | final RxJavaAssemblyException assembled; 35 | 36 | MaybeOnAssemblyCallable(MaybeSource source) { 37 | this.source = source; 38 | this.assembled = new RxJavaAssemblyException(); 39 | } 40 | 41 | @Override 42 | protected void subscribeActual(MaybeObserver s) { 43 | source.subscribe(new OnAssemblyMaybeObserver(s, assembled)); 44 | } 45 | 46 | @SuppressWarnings("unchecked") 47 | @Override 48 | public T call() throws Exception { 49 | try { 50 | return ((Callable)source).call(); 51 | } catch (Exception ex) { 52 | Exceptions.throwIfFatal(ex); 53 | throw (Exception)assembled.appendLast(ex); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/SingleOnAssemblyCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import java.util.concurrent.Callable; 20 | 21 | import com.akaita.java.rxjava2debug.extensions.SingleOnAssembly.OnAssemblySingleObserver; 22 | import io.reactivex.*; 23 | import io.reactivex.exceptions.Exceptions; 24 | 25 | /** 26 | * Wraps a Publisher and inject the assembly info. 27 | * 28 | * @param the value type 29 | */ 30 | final class SingleOnAssemblyCallable extends Single implements Callable { 31 | 32 | final SingleSource source; 33 | 34 | final RxJavaAssemblyException assembled; 35 | 36 | SingleOnAssemblyCallable(SingleSource source) { 37 | this.source = source; 38 | this.assembled = new RxJavaAssemblyException(); 39 | } 40 | 41 | @Override 42 | protected void subscribeActual(SingleObserver s) { 43 | source.subscribe(new OnAssemblySingleObserver(s, assembled)); 44 | } 45 | 46 | @SuppressWarnings("unchecked") 47 | @Override 48 | public T call() throws Exception { 49 | try { 50 | return ((Callable)source).call(); 51 | } catch (Exception ex) { 52 | Exceptions.throwIfFatal(ex); 53 | throw (Exception)assembled.appendLast(ex); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/CompletableOnAssemblyCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import java.util.concurrent.Callable; 20 | 21 | import com.akaita.java.rxjava2debug.extensions.CompletableOnAssembly.OnAssemblyCompletableObserver; 22 | import io.reactivex.*; 23 | import io.reactivex.exceptions.Exceptions; 24 | 25 | /** 26 | * Wraps a CompletableSource and inject the assembly info. 27 | */ 28 | final class CompletableOnAssemblyCallable extends Completable implements Callable { 29 | 30 | final CompletableSource source; 31 | 32 | final RxJavaAssemblyException assembled; 33 | 34 | CompletableOnAssemblyCallable(CompletableSource source) { 35 | this.source = source; 36 | this.assembled = new RxJavaAssemblyException(); 37 | } 38 | 39 | @Override 40 | protected void subscribeActual(CompletableObserver s) { 41 | source.subscribe(new OnAssemblyCompletableObserver(s, assembled)); 42 | } 43 | 44 | @SuppressWarnings("unchecked") 45 | @Override 46 | public Object call() throws Exception { 47 | try { 48 | return ((Callable)source).call(); 49 | } catch (Exception ex) { 50 | Exceptions.throwIfFatal(ex); 51 | throw (Exception)assembled.appendLast(ex); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/FlowableOnAssemblyScalarCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import org.reactivestreams.*; 20 | 21 | import com.akaita.java.rxjava2debug.extensions.FlowableOnAssembly.*; 22 | import io.reactivex.Flowable; 23 | import io.reactivex.internal.fuseable.*; 24 | 25 | /** 26 | * Wraps a Publisher and inject the assembly info. 27 | * 28 | * @param the value type 29 | */ 30 | final class FlowableOnAssemblyScalarCallable extends Flowable implements ScalarCallable { 31 | 32 | final Publisher source; 33 | 34 | final RxJavaAssemblyException assembled; 35 | 36 | FlowableOnAssemblyScalarCallable(Publisher source) { 37 | this.source = source; 38 | this.assembled = new RxJavaAssemblyException(); 39 | } 40 | 41 | @Override 42 | protected void subscribeActual(Subscriber s) { 43 | if (s instanceof ConditionalSubscriber) { 44 | source.subscribe(new OnAssemblyConditionalSubscriber((ConditionalSubscriber)s, assembled)); 45 | } else { 46 | source.subscribe(new OnAssemblySubscriber(s, assembled)); 47 | } 48 | } 49 | 50 | @SuppressWarnings("unchecked") 51 | @Override 52 | public T call() { 53 | return ((ScalarCallable)source).call(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/ObservableOnAssemblyCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import java.util.concurrent.Callable; 20 | 21 | import com.akaita.java.rxjava2debug.extensions.ObservableOnAssembly.OnAssemblyObserver; 22 | import io.reactivex.*; 23 | import io.reactivex.exceptions.Exceptions; 24 | 25 | /** 26 | * Wraps a ObservableSource and inject the assembly info. 27 | * 28 | * @param the value type 29 | */ 30 | final class ObservableOnAssemblyCallable extends Observable implements Callable { 31 | 32 | final ObservableSource source; 33 | 34 | final RxJavaAssemblyException assembled; 35 | 36 | ObservableOnAssemblyCallable(ObservableSource source) { 37 | this.source = source; 38 | this.assembled = new RxJavaAssemblyException(); 39 | } 40 | 41 | @Override 42 | protected void subscribeActual(Observer s) { 43 | source.subscribe(new OnAssemblyObserver(s, assembled)); 44 | } 45 | 46 | @SuppressWarnings("unchecked") 47 | @Override 48 | public T call() throws Exception { 49 | try { 50 | return ((Callable)source).call(); 51 | } catch (Exception ex) { 52 | Exceptions.throwIfFatal(ex); 53 | throw (Exception)assembled.appendLast(ex); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /example-android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/FlowableOnAssemblyConnectable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import org.reactivestreams.Subscriber; 20 | 21 | import com.akaita.java.rxjava2debug.extensions.FlowableOnAssembly.*; 22 | import io.reactivex.disposables.Disposable; 23 | import io.reactivex.flowables.ConnectableFlowable; 24 | import io.reactivex.functions.Consumer; 25 | import io.reactivex.internal.fuseable.ConditionalSubscriber; 26 | 27 | /** 28 | * Wraps a Publisher and inject the assembly info. 29 | * 30 | * @param the value type 31 | */ 32 | final class FlowableOnAssemblyConnectable extends ConnectableFlowable { 33 | 34 | final ConnectableFlowable source; 35 | 36 | final RxJavaAssemblyException assembled; 37 | 38 | FlowableOnAssemblyConnectable(ConnectableFlowable source) { 39 | this.source = source; 40 | this.assembled = new RxJavaAssemblyException(); 41 | } 42 | 43 | @Override 44 | protected void subscribeActual(Subscriber s) { 45 | if (s instanceof ConditionalSubscriber) { 46 | source.subscribe(new OnAssemblyConditionalSubscriber((ConditionalSubscriber)s, assembled)); 47 | } else { 48 | source.subscribe(new OnAssemblySubscriber(s, assembled)); 49 | } 50 | } 51 | 52 | @Override 53 | public void connect(Consumer connection) { 54 | source.connect(connection); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/FlowableOnAssemblyCallable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import java.util.concurrent.Callable; 20 | 21 | import org.reactivestreams.*; 22 | 23 | import com.akaita.java.rxjava2debug.extensions.FlowableOnAssembly.*; 24 | import io.reactivex.Flowable; 25 | import io.reactivex.exceptions.Exceptions; 26 | import io.reactivex.internal.fuseable.ConditionalSubscriber; 27 | 28 | /** 29 | * Wraps a Publisher and inject the assembly info. 30 | * 31 | * @param the value type 32 | */ 33 | final class FlowableOnAssemblyCallable extends Flowable implements Callable { 34 | 35 | final Publisher source; 36 | 37 | final RxJavaAssemblyException assembled; 38 | 39 | FlowableOnAssemblyCallable(Publisher source) { 40 | this.source = source; 41 | this.assembled = new RxJavaAssemblyException(); 42 | } 43 | 44 | @Override 45 | protected void subscribeActual(Subscriber s) { 46 | if (s instanceof ConditionalSubscriber) { 47 | source.subscribe(new OnAssemblyConditionalSubscriber((ConditionalSubscriber)s, assembled)); 48 | } else { 49 | source.subscribe(new OnAssemblySubscriber(s, assembled)); 50 | } 51 | } 52 | 53 | @SuppressWarnings("unchecked") 54 | @Override 55 | public T call() throws Exception { 56 | try { 57 | return ((Callable)source).call(); 58 | } catch (Exception ex) { 59 | Exceptions.throwIfFatal(ex); 60 | throw (Exception)assembled.appendLast(ex); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /example-android/app/src/main/java/com/akaita/java/rxjava2debug/exampleandroid/Extensions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 akaita 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.exampleandroid 18 | 19 | /** 20 | * You don't care about this file. 21 | * This file just contains utilities for the sake of UI prettiness, nothing directly related to the usage of RxJava2Debug 22 | */ 23 | 24 | fun Throwable.toHtml(): String { 25 | val sb = StringBuilder() 26 | 27 | var t: Throwable? = this 28 | .let { 29 | sb.append("${it.javaClass.canonicalName}: ${it.message}
") 30 | sb.append(it.stackTrace.toHtml()) 31 | it.cause 32 | } 33 | 34 | while (t != null) { 35 | sb.append("Caused by: ${t.javaClass}
") 36 | sb.append(t.stackTrace.toHtml()) 37 | t = t.cause 38 | } 39 | 40 | return sb.toString() 41 | } 42 | 43 | fun Array.toHtml(): String { 44 | val sb = StringBuilder() 45 | 46 | this.forEach { element -> 47 | sb.append("\tat $element
") 48 | } 49 | 50 | return sb.toString() 51 | } 52 | 53 | fun String.highlight(patterns: Array): String { 54 | var result = this 55 | patterns.forEach { pattern -> 56 | result = result.highlight(pattern) 57 | } 58 | return result 59 | } 60 | 61 | fun String.highlight(pattern: String): String { 62 | val sb = StringBuilder() 63 | this.split("
") 64 | .forEach { line -> 65 | if (line.contains(pattern)) { 66 | sb.append("$line
") 67 | } else { 68 | sb.append("$line
") 69 | } 70 | } 71 | return sb.toString() 72 | } -------------------------------------------------------------------------------- /rxjava2debug/gradle/javadocStyleSheet.css: -------------------------------------------------------------------------------- 1 | # originally from http://sensemaya.org/files/stylesheet.css and then modified 2 | # http://sensemaya.org/maya/2009/07/10/making-javadoc-more-legible 3 | 4 | /* Javadoc style sheet */ 5 | 6 | /* Define colors, fonts and other style attributes here to override the defaults */ 7 | 8 | /* Page background color */ 9 | body { background-color: #FFFFFF; color:#333; font-size: 100%; } 10 | 11 | body { font-size: 0.875em; line-height: 1.286em; font-family: "Helvetica", "Arial", sans-serif; } 12 | 13 | code { color: #777; line-height: 1.286em; font-family: "Consolas", "Lucida Console", "Droid Sans Mono", "Andale Mono", "Monaco", "Lucida Sans Typewriter"; } 14 | 15 | a { text-decoration: none; color: #16569A; /* also try #2E85ED, #0033FF, #6C93C6, #1D7BBE, #1D8DD2 */ } 16 | a:hover { text-decoration: underline; } 17 | 18 | 19 | table[border="1"] { border: 1px solid #ddd; } 20 | table[border="1"] td, table[border="1"] th { border: 1px solid #ddd; } 21 | table[cellpadding="3"] td { padding: 0.5em; } 22 | 23 | font[size="-1"] { font-size: 0.85em; line-height: 1.5em; } 24 | font[size="-2"] { font-size: 0.8em; } 25 | font[size="+2"] { font-size: 1.4em; line-height: 1.3em; padding: 0.4em 0; } 26 | 27 | /* Headings */ 28 | h1 { font-size: 1.5em; line-height: 1.286em;} 29 | h2.title { color: #c81f08; } 30 | 31 | /* Table colors */ 32 | .TableHeadingColor { background: #ccc; color:#444; } /* Dark mauve */ 33 | .TableSubHeadingColor { background: #ddd; color:#444; } /* Light mauve */ 34 | .TableRowColor { background: #FFFFFF; color:#666; font-size: 0.95em; } /* White */ 35 | .TableRowColor code { color:#000; } /* White */ 36 | 37 | /* Font used in left-hand frame lists */ 38 | .FrameTitleFont { font-size: 100%; } 39 | .FrameHeadingFont { font-size: 90%; } 40 | .FrameItemFont { font-size: 0.9em; line-height: 1.3em; 41 | } 42 | /* Java Interfaces */ 43 | .FrameItemFont a i { 44 | font-style: normal; color: #16569A; 45 | } 46 | .FrameItemFont a:hover i { 47 | text-decoration: underline; 48 | } 49 | 50 | 51 | /* Navigation bar fonts and colors */ 52 | .NavBarCell1 { background-color:#E0E6DF; } /* Light mauve */ 53 | .NavBarCell1Rev { background-color:#16569A; color:#FFFFFF} /* Dark Blue */ 54 | .NavBarFont1 { } 55 | .NavBarFont1Rev { color:#FFFFFF; } 56 | 57 | .NavBarCell2 { background-color:#FFFFFF; color:#000000} 58 | .NavBarCell3 { background-color:#FFFFFF; color:#000000} 59 | 60 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/ParallelFlowableOnAssembly.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import org.reactivestreams.Subscriber; 20 | 21 | import com.akaita.java.rxjava2debug.extensions.FlowableOnAssembly.*; 22 | import io.reactivex.internal.fuseable.ConditionalSubscriber; 23 | import io.reactivex.parallel.ParallelFlowable; 24 | 25 | /** 26 | * Wrap a Parallel Flowable and inject the assembly info. 27 | * 28 | * @param the value type 29 | * @since 0.15.2 30 | */ 31 | final class ParallelFlowableOnAssembly extends ParallelFlowable { 32 | 33 | final ParallelFlowable source; 34 | 35 | final RxJavaAssemblyException assembled; 36 | 37 | ParallelFlowableOnAssembly(ParallelFlowable source) { 38 | this.source = source; 39 | this.assembled = new RxJavaAssemblyException(); 40 | } 41 | 42 | @Override 43 | public int parallelism() { 44 | return source.parallelism(); 45 | } 46 | 47 | @Override 48 | public void subscribe(Subscriber[] s) { 49 | if (validate(s)) { 50 | int n = s.length; 51 | @SuppressWarnings("unchecked") 52 | Subscriber[] parents = new Subscriber[n]; 53 | for (int i = 0; i < n; i++) { 54 | Subscriber z = s[i]; 55 | if (z instanceof ConditionalSubscriber) { 56 | parents[i] = new OnAssemblyConditionalSubscriber((ConditionalSubscriber)z, assembled); 57 | } else { 58 | parents[i] = new OnAssemblySubscriber(z, assembled); 59 | } 60 | } 61 | 62 | source.subscribe(parents); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/ObservableOnAssembly.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import io.reactivex.*; 20 | import io.reactivex.internal.fuseable.QueueDisposable; 21 | import io.reactivex.internal.observers.BasicFuseableObserver; 22 | 23 | /** 24 | * Wraps a ObservableSource and inject the assembly info. 25 | * 26 | * @param the value type 27 | */ 28 | final class ObservableOnAssembly extends Observable { 29 | 30 | final ObservableSource source; 31 | 32 | final RxJavaAssemblyException assembled; 33 | 34 | ObservableOnAssembly(ObservableSource source) { 35 | this.source = source; 36 | this.assembled = new RxJavaAssemblyException(); 37 | } 38 | 39 | @Override 40 | protected void subscribeActual(Observer s) { 41 | source.subscribe(new OnAssemblyObserver(s, assembled)); 42 | } 43 | 44 | static final class OnAssemblyObserver extends BasicFuseableObserver { 45 | 46 | final RxJavaAssemblyException assembled; 47 | 48 | OnAssemblyObserver(Observer actual, RxJavaAssemblyException assembled) { 49 | super(actual); 50 | this.assembled = assembled; 51 | } 52 | 53 | @Override 54 | public void onNext(T t) { 55 | downstream.onNext(t); 56 | } 57 | 58 | @Override 59 | public void onError(Throwable t) { 60 | downstream.onError(assembled.appendLast(t)); 61 | } 62 | 63 | @Override 64 | public int requestFusion(int mode) { 65 | QueueDisposable qs = this.qd; 66 | if (qs != null) { 67 | int m = qs.requestFusion(mode); 68 | sourceMode = m; 69 | return m; 70 | } 71 | return NONE; 72 | } 73 | 74 | @Override 75 | public T poll() throws Exception { 76 | return qd.poll(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /rxjava2debug/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /example-android/app/src/main/java/com/akaita/java/rxjava2debug/exampleandroid/ExampleApplication.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 akaita 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.exampleandroid 18 | 19 | import android.app.Application 20 | import android.util.Log 21 | import com.akaita.java.rxjava2debug.RxJava2Debug 22 | 23 | /** 24 | * It is good practice to enable RxJava2Debug in the app's Application class, so it is enabled as soon as possible 25 | */ 26 | class ExampleApplication : Application() { 27 | 28 | override fun onCreate() { 29 | super.onCreate() 30 | 31 | enableCrashlytics() 32 | 33 | // Enable RxJava2Debug in Application 34 | // Make sure it is enabled RIGHT AFTER setting up any Crash reporting mechanism such as Crashlytics 35 | // Provide a list of the root packages of your code, so RxJava2Debug can point you to the source of the stream 36 | RxJava2Debug.enableRxJava2AssemblyTracking(MY_CODE_PACKAGES) 37 | } 38 | 39 | /** 40 | * This method just replicates Crashlytics' behaviour: 41 | * 42 | * It sets up the same system that Crashlytics does, but instead of sending the report to Fabric it will print it to LogCat 43 | */ 44 | private fun enableCrashlytics() { 45 | val defaultUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler() 46 | Thread.setDefaultUncaughtExceptionHandler { thread, throwable -> 47 | Log.e("UnhandledException", "Error", throwable) 48 | defaultUncaughtHandler.uncaughtException(thread, throwable) 49 | } 50 | } 51 | 52 | 53 | companion object { 54 | 55 | /** 56 | * This array assumes that the code I wrote for this app is contained under three root packages 57 | * 58 | * This specific example only needs "com.akaita.java.rxjava2debug.exampleandroid". I just added two more in order to show how you could do it 59 | */ 60 | val MY_CODE_PACKAGES = arrayOf( 61 | "com.akaita.java.rxjava2debug.exampleandroid", 62 | "com.akaita.java.rxjava2debug.module1", 63 | "com.akaita.java.rxjava2debug.module2" 64 | ) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /example-android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/CompletableOnAssembly.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import io.reactivex.*; 20 | import io.reactivex.disposables.Disposable; 21 | import io.reactivex.internal.disposables.DisposableHelper; 22 | 23 | /** 24 | * Wraps a CompletableSource and inject the assembly info. 25 | */ 26 | final class CompletableOnAssembly extends Completable { 27 | 28 | final CompletableSource source; 29 | 30 | final RxJavaAssemblyException assembled; 31 | 32 | CompletableOnAssembly(CompletableSource source) { 33 | this.source = source; 34 | this.assembled = new RxJavaAssemblyException(); 35 | } 36 | 37 | @Override 38 | protected void subscribeActual(CompletableObserver s) { 39 | source.subscribe(new OnAssemblyCompletableObserver(s, assembled)); 40 | } 41 | 42 | static final class OnAssemblyCompletableObserver implements CompletableObserver, Disposable { 43 | 44 | final CompletableObserver actual; 45 | 46 | final RxJavaAssemblyException assembled; 47 | 48 | Disposable d; 49 | 50 | OnAssemblyCompletableObserver(CompletableObserver actual, RxJavaAssemblyException assembled) { 51 | this.actual = actual; 52 | this.assembled = assembled; 53 | } 54 | 55 | @Override 56 | public void onSubscribe(Disposable d) { 57 | if (DisposableHelper.validate(this.d, d)) { 58 | this.d = d; 59 | 60 | actual.onSubscribe(this); 61 | } 62 | } 63 | 64 | @Override 65 | public void onError(Throwable t) { 66 | actual.onError(assembled.appendLast(t)); 67 | } 68 | 69 | @Override 70 | public void onComplete() { 71 | actual.onComplete(); 72 | } 73 | 74 | @Override 75 | public boolean isDisposed() { 76 | return d.isDisposed(); 77 | } 78 | 79 | @Override 80 | public void dispose() { 81 | // don't break the link here 82 | d.dispose(); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/SingleOnAssembly.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import io.reactivex.*; 20 | import io.reactivex.disposables.Disposable; 21 | import io.reactivex.internal.disposables.DisposableHelper; 22 | 23 | /** 24 | * Wraps a Publisher and inject the assembly info. 25 | * 26 | * @param the value type 27 | */ 28 | final class SingleOnAssembly extends Single { 29 | 30 | final SingleSource source; 31 | 32 | final RxJavaAssemblyException assembled; 33 | 34 | SingleOnAssembly(SingleSource source) { 35 | this.source = source; 36 | this.assembled = new RxJavaAssemblyException(); 37 | } 38 | 39 | @Override 40 | protected void subscribeActual(SingleObserver s) { 41 | source.subscribe(new OnAssemblySingleObserver(s, assembled)); 42 | } 43 | 44 | static final class OnAssemblySingleObserver implements SingleObserver, Disposable { 45 | 46 | final SingleObserver actual; 47 | 48 | final RxJavaAssemblyException assembled; 49 | 50 | Disposable d; 51 | 52 | OnAssemblySingleObserver(SingleObserver actual, RxJavaAssemblyException assembled) { 53 | this.actual = actual; 54 | this.assembled = assembled; 55 | } 56 | 57 | @Override 58 | public void onSubscribe(Disposable d) { 59 | if (DisposableHelper.validate(this.d, d)) { 60 | this.d = d; 61 | 62 | actual.onSubscribe(this); 63 | } 64 | } 65 | 66 | @Override 67 | public void onSuccess(T value) { 68 | actual.onSuccess(value); 69 | } 70 | 71 | @Override 72 | public void onError(Throwable t) { 73 | actual.onError(assembled.appendLast(t)); 74 | } 75 | 76 | @Override 77 | public boolean isDisposed() { 78 | return d.isDisposed(); 79 | } 80 | 81 | @Override 82 | public void dispose() { 83 | // don't break the link here 84 | d.dispose(); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/extensions/MaybeOnAssembly.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 David Karnok 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug.extensions; 18 | 19 | import io.reactivex.*; 20 | import io.reactivex.disposables.Disposable; 21 | import io.reactivex.internal.disposables.DisposableHelper; 22 | 23 | /** 24 | * Wraps a MaybeSource and inject the assembly info. 25 | * 26 | * @param the value type 27 | */ 28 | final class MaybeOnAssembly extends Maybe { 29 | 30 | final MaybeSource source; 31 | 32 | final RxJavaAssemblyException assembled; 33 | 34 | MaybeOnAssembly(MaybeSource source) { 35 | this.source = source; 36 | this.assembled = new RxJavaAssemblyException(); 37 | } 38 | 39 | @Override 40 | protected void subscribeActual(MaybeObserver s) { 41 | source.subscribe(new OnAssemblyMaybeObserver(s, assembled)); 42 | } 43 | 44 | static final class OnAssemblyMaybeObserver implements MaybeObserver, Disposable { 45 | 46 | final MaybeObserver actual; 47 | 48 | final RxJavaAssemblyException assembled; 49 | 50 | Disposable d; 51 | 52 | OnAssemblyMaybeObserver(MaybeObserver actual, RxJavaAssemblyException assembled) { 53 | this.actual = actual; 54 | this.assembled = assembled; 55 | } 56 | 57 | @Override 58 | public void onSubscribe(Disposable d) { 59 | if (DisposableHelper.validate(this.d, d)) { 60 | this.d = d; 61 | 62 | actual.onSubscribe(this); 63 | } 64 | } 65 | 66 | @Override 67 | public void onSuccess(T value) { 68 | actual.onSuccess(value); 69 | } 70 | 71 | @Override 72 | public void onError(Throwable t) { 73 | actual.onError(assembled.appendLast(t)); 74 | } 75 | 76 | @Override 77 | public void onComplete() { 78 | actual.onComplete(); 79 | } 80 | 81 | @Override 82 | public boolean isDisposed() { 83 | return d.isDisposed(); 84 | } 85 | 86 | @Override 87 | public void dispose() { 88 | // don't break the link here 89 | d.dispose(); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /rxjava2debug/src/main/java/com/akaita/java/rxjava2debug/ExceptionUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 akaita 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.akaita.java.rxjava2debug; 18 | 19 | import com.akaita.java.rxjava2debug.extensions.RxJavaAssemblyException; 20 | import io.reactivex.annotations.NonNull; 21 | 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | 25 | class ExceptionUtils { 26 | 27 | static Throwable setRootCause(@NonNull Throwable throwable, @NonNull Throwable rootCause) { 28 | List causes = listCauses(throwable); 29 | causes.add(rootCause); 30 | return reverseAndCollapseCauses(causes); 31 | } 32 | 33 | @NonNull 34 | private static List listCauses(@NonNull Throwable throwable) { 35 | LinkedList causes = new LinkedList(); 36 | Throwable cause = throwable.getCause(); 37 | while (cause != null && !causes.contains(cause)) { 38 | causes.add(cause); 39 | cause = cause.getCause(); 40 | } 41 | return causes; 42 | } 43 | 44 | @NonNull 45 | private static Throwable reverseAndCollapseCauses(@NonNull List causes) { 46 | if (causes.size() == 0) { 47 | return new RuntimeException("Empty list of causes"); 48 | } 49 | 50 | String topMessage; 51 | if (causes.get(0) instanceof RxJavaAssemblyException) { 52 | topMessage = "caused by " + causes.get(causes.size() - 1).getLocalizedMessage(); 53 | } else { 54 | topMessage = "caused by " + causes.get(0).getClass().getName() + ": " + causes.get(0).getLocalizedMessage(); 55 | } 56 | 57 | Throwable topThrowable = null; 58 | for (int i = causes.size() - 1; i >= 0; i--) { 59 | if (i == causes.size() - 1) { 60 | topThrowable = new Throwable(topMessage, topThrowable); 61 | } else { 62 | topThrowable = new Throwable(causes.get(i).getMessage(), topThrowable); 63 | } 64 | 65 | if (causes.get(i).getStackTrace() != null) { 66 | // This array should never be null, if everybody follows the Java spec 67 | // Sometimes this part of the spec is not followed, so we better protect ourselves 68 | topThrowable.setStackTrace(causes.get(i).getStackTrace()); 69 | } 70 | } 71 | 72 | return topThrowable; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at akaita@akaita.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /rxjava2debug/gradle/maven.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven' // Java plugin has to have been already applied for the conf2scope mappings to work 2 | apply plugin: 'signing' 3 | 4 | project.status = 'release' 5 | 6 | signing { 7 | required { gradle.taskGraph.hasTask(uploadMavenCentral) } 8 | sign configurations.archives 9 | } 10 | 11 | /** 12 | * Publishing to Maven Central example provided from http://jedicoder.blogspot.com/2011/11/automated-gradle-project-deployment-to.html 13 | * artifactory will execute uploadArchives to force generation of ivy.xml, and we don't want that to trigger an upload to maven 14 | * central, so using custom upload task. 15 | */ 16 | task uploadMavenCentral(type:Upload, dependsOn: signArchives) { 17 | configuration = configurations.archives 18 | onlyIf { ['release', 'snapshot'].contains(project.status) } 19 | repositories.mavenDeployer { 20 | beforeDeployment { signing.signPom(it) } 21 | 22 | // To test deployment locally, use the following instead of oss.sonatype.org 23 | //repository(url: "file://localhost/${rootProject.rootDir}/repo") 24 | 25 | def sonatypeUsername = rootProject.hasProperty('sonatypeUsername')?rootProject.sonatypeUsername:'' 26 | def sonatypePassword = rootProject.hasProperty('sonatypePassword')?rootProject.sonatypePassword:'' 27 | 28 | repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2') { 29 | authentication(userName: sonatypeUsername, password: sonatypePassword) 30 | } 31 | 32 | snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots/') { 33 | authentication(userName: sonatypeUsername, password: sonatypePassword) 34 | } 35 | 36 | // Prevent datastamp from being appending to artifacts during deployment 37 | uniqueVersion = false 38 | 39 | // Closure to configure all the POM with extra info, common to all projects 40 | pom.project { 41 | name "${project.name}" 42 | description "${project.name} developed by Mikel Pascual" 43 | developers { 44 | developer { 45 | id 'akaita' 46 | name 'Mikel Pascual' 47 | email 'mikel@akaita.com' 48 | } 49 | } 50 | licenses { 51 | license { 52 | name 'The Apache Software License, Version 2.0' 53 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 54 | distribution 'repo' 55 | } 56 | } 57 | url "https://github.com/akaita/${rootProject.githubProjectName}" 58 | scm { 59 | connection "scm:git:git@github.com:akaita/${rootProject.githubProjectName}.git" 60 | url "scm:git:git@github.com:akaita/${rootProject.githubProjectName}.git" 61 | developerConnection "scm:git:git@github.com:akaita/${rootProject.githubProjectName}.git" 62 | } 63 | issueManagement { 64 | system 'github' 65 | url "https://github.com/akaita/${rootProject.githubProjectName}/issues" 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /example-android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 23 | 24 |