Repository: square/retrofit Branch: trunk Commit: 77e6ba21d9ba Files: 1073 Total size: 6.0 MB Directory structure: gitextract_f65trsdv/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE.md │ ├── pull_request_template.md │ ├── renovate.json5 │ └── workflows/ │ ├── .java-version │ ├── build.yml │ └── release.yaml ├── .gitignore ├── BUG-BOUNTY.md ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── RELEASING.md ├── build.gradle ├── gradle/ │ ├── libs.versions.toml │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── retrofit/ │ ├── android-test/ │ │ ├── build.gradle │ │ ├── debug.keystore │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ ├── BasicCallTest.java │ │ │ ├── CompletableFutureAndroidTest.java │ │ │ ├── DefaultMethodsAndroidTest.java │ │ │ ├── OptionalConverterFactoryAndroidTest.java │ │ │ └── UriAndroidTest.java │ │ └── main/ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── java-test/ │ │ ├── README.md │ │ ├── build.gradle │ │ └── src/ │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ ├── AnnotationArraySubject.java │ │ ├── CallAdapterTest.java │ │ ├── CallTest.java │ │ ├── CompletableFutureCallAdapterFactoryTest.java │ │ ├── CompletableFutureTest.java │ │ ├── DefaultCallAdapterFactoryTest.java │ │ ├── DefaultMethodsTest.java │ │ ├── HttpExceptionTest.java │ │ ├── InvocationTest.java │ │ ├── Java8DefaultStaticMethodsInValidationTest.java │ │ ├── MethodParameterReflectionTest.java │ │ ├── NonFatalError.java │ │ ├── OptionalConverterFactoryTest.java │ │ ├── RequestFactoryBuilderTest.java │ │ ├── RequestFactoryTest.java │ │ ├── ResponseTest.java │ │ └── RetrofitTest.java │ ├── kotlin-test/ │ │ ├── build.gradle │ │ └── src/ │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ ├── KotlinExtensionsTest.kt │ │ ├── KotlinRequestFactoryTest.java │ │ ├── KotlinSuspendRawTest.java │ │ ├── KotlinSuspendTest.kt │ │ └── KotlinUnitTest.java │ ├── robovm-test/ │ │ ├── build.gradle │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── RoboVmPlatformTest.java │ ├── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── retrofit2/ │ │ │ ├── AndroidMainExecutor.java │ │ │ ├── BuiltInConverters.java │ │ │ ├── BuiltInFactories.java │ │ │ ├── Call.java │ │ │ ├── CallAdapter.java │ │ │ ├── Callback.java │ │ │ ├── CompletableFutureCallAdapterFactory.java │ │ │ ├── Converter.java │ │ │ ├── DefaultCallAdapterFactory.java │ │ │ ├── DefaultMethodSupport.java │ │ │ ├── HttpException.java │ │ │ ├── HttpServiceMethod.java │ │ │ ├── Invocation.java │ │ │ ├── KotlinExtensions.kt │ │ │ ├── OkHttpCall.java │ │ │ ├── OptionalConverterFactory.java │ │ │ ├── ParameterHandler.java │ │ │ ├── Platform.java │ │ │ ├── Reflection.java │ │ │ ├── RequestBuilder.java │ │ │ ├── RequestFactory.java │ │ │ ├── Response.java │ │ │ ├── Retrofit.java │ │ │ ├── ServiceMethod.java │ │ │ ├── SkipCallbackExecutor.java │ │ │ ├── SkipCallbackExecutorImpl.java │ │ │ ├── Utils.java │ │ │ ├── http/ │ │ │ │ ├── Body.java │ │ │ │ ├── DELETE.java │ │ │ │ ├── Field.java │ │ │ │ ├── FieldMap.java │ │ │ │ ├── FormUrlEncoded.java │ │ │ │ ├── GET.java │ │ │ │ ├── HEAD.java │ │ │ │ ├── HTTP.java │ │ │ │ ├── Header.java │ │ │ │ ├── HeaderMap.java │ │ │ │ ├── Headers.java │ │ │ │ ├── Multipart.java │ │ │ │ ├── OPTIONS.java │ │ │ │ ├── PATCH.java │ │ │ │ ├── POST.java │ │ │ │ ├── PUT.java │ │ │ │ ├── Part.java │ │ │ │ ├── PartMap.java │ │ │ │ ├── Path.java │ │ │ │ ├── Query.java │ │ │ │ ├── QueryMap.java │ │ │ │ ├── QueryName.java │ │ │ │ ├── Streaming.java │ │ │ │ ├── Tag.java │ │ │ │ ├── Url.java │ │ │ │ └── package-info.java │ │ │ ├── internal/ │ │ │ │ └── EverythingIsNonNull.java │ │ │ └── package-info.java │ │ ├── java14/ │ │ │ └── retrofit2/ │ │ │ └── DefaultMethodSupport.java │ │ ├── java16/ │ │ │ └── retrofit2/ │ │ │ └── DefaultMethodSupport.java │ │ └── resources/ │ │ └── META-INF/ │ │ └── proguard/ │ │ └── retrofit2.pro │ └── test-helpers/ │ ├── build.gradle │ └── src/ │ └── main/ │ └── java/ │ └── retrofit2/ │ ├── TestingUtils.java │ └── helpers/ │ ├── DelegatingCallAdapterFactory.java │ ├── ExampleWithoutParameterNames.java │ ├── NonMatchingCallAdapterFactory.java │ ├── NonMatchingConverterFactory.java │ ├── NullObjectConverterFactory.java │ ├── ObjectInstanceConverterFactory.java │ └── ToStringConverterFactory.java ├── retrofit-adapters/ │ ├── README.md │ ├── guava/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── adapter/ │ │ │ └── guava/ │ │ │ ├── GuavaCallAdapterFactory.java │ │ │ ├── HttpException.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── adapter/ │ │ └── guava/ │ │ ├── GuavaCallAdapterFactoryTest.java │ │ ├── ListenableFutureTest.java │ │ └── StringConverterFactory.java │ ├── java8/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── adapter/ │ │ │ └── java8/ │ │ │ ├── HttpException.java │ │ │ ├── Java8CallAdapterFactory.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── adapter/ │ │ └── java8/ │ │ ├── CompletableFutureTest.java │ │ ├── Java8CallAdapterFactoryTest.java │ │ └── StringConverterFactory.java │ ├── rxjava/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── retrofit2/ │ │ │ │ └── adapter/ │ │ │ │ └── rxjava/ │ │ │ │ ├── BodyOnSubscribe.java │ │ │ │ ├── CallArbiter.java │ │ │ │ ├── CallEnqueueOnSubscribe.java │ │ │ │ ├── CallExecuteOnSubscribe.java │ │ │ │ ├── HttpException.java │ │ │ │ ├── Result.java │ │ │ │ ├── ResultOnSubscribe.java │ │ │ │ ├── RxJavaCallAdapter.java │ │ │ │ ├── RxJavaCallAdapterFactory.java │ │ │ │ └── package-info.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── proguard/ │ │ │ └── retrofit2-rxjava-adapter.pro │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── adapter/ │ │ └── rxjava/ │ │ ├── AsyncTest.java │ │ ├── CancelDisposeTest.java │ │ ├── CompletableTest.java │ │ ├── CompletableThrowingSafeSubscriberTest.java │ │ ├── CompletableThrowingTest.java │ │ ├── CompletableWithSchedulerTest.java │ │ ├── ForwardingSubscriber.java │ │ ├── ObservableTest.java │ │ ├── ObservableThrowingSafeSubscriberTest.java │ │ ├── ObservableThrowingTest.java │ │ ├── ObservableWithSchedulerTest.java │ │ ├── RecordingSubscriber.java │ │ ├── ResultTest.java │ │ ├── RxJavaCallAdapterFactoryTest.java │ │ ├── RxJavaPluginsResetRule.java │ │ ├── SingleTest.java │ │ ├── SingleThrowingTest.java │ │ ├── SingleWithSchedulerTest.java │ │ └── StringConverterFactory.java │ ├── rxjava2/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── retrofit2/ │ │ │ │ └── adapter/ │ │ │ │ └── rxjava2/ │ │ │ │ ├── BodyObservable.java │ │ │ │ ├── CallEnqueueObservable.java │ │ │ │ ├── CallExecuteObservable.java │ │ │ │ ├── HttpException.java │ │ │ │ ├── Result.java │ │ │ │ ├── ResultObservable.java │ │ │ │ ├── RxJava2CallAdapter.java │ │ │ │ ├── RxJava2CallAdapterFactory.java │ │ │ │ └── package-info.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── proguard/ │ │ │ └── retrofit2-rxjava2-adapter.pro │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── adapter/ │ │ └── rxjava2/ │ │ ├── AsyncTest.java │ │ ├── CancelDisposeTest.java │ │ ├── CancelDisposeTestSync.java │ │ ├── CompletableTest.java │ │ ├── CompletableThrowingTest.java │ │ ├── CompletableWithSchedulerTest.java │ │ ├── FlowableTest.java │ │ ├── FlowableThrowingTest.java │ │ ├── FlowableWithSchedulerTest.java │ │ ├── MaybeTest.java │ │ ├── MaybeThrowingTest.java │ │ ├── MaybeWithSchedulerTest.java │ │ ├── ObservableTest.java │ │ ├── ObservableThrowingTest.java │ │ ├── ObservableWithSchedulerTest.java │ │ ├── RecordingCompletableObserver.java │ │ ├── RecordingMaybeObserver.java │ │ ├── RecordingObserver.java │ │ ├── RecordingSingleObserver.java │ │ ├── RecordingSubscriber.java │ │ ├── ResultTest.java │ │ ├── RxJava2CallAdapterFactoryTest.java │ │ ├── RxJavaPluginsResetRule.java │ │ ├── SingleTest.java │ │ ├── SingleThrowingTest.java │ │ ├── SingleWithSchedulerTest.java │ │ └── StringConverterFactory.java │ ├── rxjava3/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── retrofit2/ │ │ │ │ └── adapter/ │ │ │ │ └── rxjava3/ │ │ │ │ ├── BodyObservable.java │ │ │ │ ├── CallEnqueueObservable.java │ │ │ │ ├── CallExecuteObservable.java │ │ │ │ ├── HttpException.java │ │ │ │ ├── Result.java │ │ │ │ ├── ResultObservable.java │ │ │ │ ├── RxJava3CallAdapter.java │ │ │ │ ├── RxJava3CallAdapterFactory.java │ │ │ │ └── package-info.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── proguard/ │ │ │ └── retrofit2-rxjava3-adapter.pro │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── adapter/ │ │ └── rxjava3/ │ │ ├── AsyncTest.java │ │ ├── CancelDisposeTest.java │ │ ├── CancelDisposeTestSync.java │ │ ├── CompletableTest.java │ │ ├── CompletableThrowingTest.java │ │ ├── CompletableWithSchedulerTest.java │ │ ├── FlowableTest.java │ │ ├── FlowableThrowingTest.java │ │ ├── FlowableWithSchedulerTest.java │ │ ├── MaybeTest.java │ │ ├── MaybeThrowingTest.java │ │ ├── MaybeWithSchedulerTest.java │ │ ├── ObservableTest.java │ │ ├── ObservableThrowingTest.java │ │ ├── ObservableWithSchedulerTest.java │ │ ├── RecordingCompletableObserver.java │ │ ├── RecordingMaybeObserver.java │ │ ├── RecordingObserver.java │ │ ├── RecordingSingleObserver.java │ │ ├── RecordingSubscriber.java │ │ ├── ResultTest.java │ │ ├── RxJava3CallAdapterFactoryTest.java │ │ ├── RxJavaPluginsResetRule.java │ │ ├── SingleTest.java │ │ ├── SingleThrowingTest.java │ │ ├── SingleWithSchedulerTest.java │ │ └── StringConverterFactory.java │ └── scala/ │ ├── README.md │ ├── build.gradle │ ├── gradle.properties │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── adapter/ │ │ └── scala/ │ │ ├── BodyCallAdapter.java │ │ ├── ResponseCallAdapter.java │ │ ├── ScalaCallAdapterFactory.java │ │ └── package-info.java │ └── test/ │ └── java/ │ └── retrofit2/ │ └── adapter/ │ └── scala/ │ ├── FutureTest.java │ ├── ScalaCallAdapterFactoryTest.java │ └── StringConverterFactory.java ├── retrofit-bom/ │ ├── build.gradle │ └── gradle.properties ├── retrofit-converters/ │ ├── README.md │ ├── gson/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── gson/ │ │ │ ├── GsonConverterFactory.java │ │ │ ├── GsonRequestBodyConverter.java │ │ │ ├── GsonResponseBodyConverter.java │ │ │ ├── GsonStreamingRequestBody.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── converter/ │ │ └── gson/ │ │ └── GsonConverterFactoryTest.java │ ├── guava/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── retrofit/ │ │ │ │ └── converter/ │ │ │ │ └── guava/ │ │ │ │ ├── GuavaOptionalConverterFactory.java │ │ │ │ ├── OptionalConverter.java │ │ │ │ └── package-info.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── proguard/ │ │ │ └── retrofit2-guava-converter.pro │ │ └── test/ │ │ └── java/ │ │ └── retrofit/ │ │ └── converter/ │ │ └── guava/ │ │ ├── AlwaysNullConverterFactory.java │ │ └── GuavaOptionalConverterFactoryTest.java │ ├── jackson/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── jackson/ │ │ │ ├── JacksonConverterFactory.java │ │ │ ├── JacksonRequestBodyConverter.java │ │ │ ├── JacksonResponseBodyConverter.java │ │ │ ├── JacksonStreamingRequestBody.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── converter/ │ │ └── jackson/ │ │ ├── JacksonCborConverterFactoryTest.java │ │ └── JacksonConverterFactoryTest.java │ ├── java8/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit/ │ │ │ └── converter/ │ │ │ └── java8/ │ │ │ ├── Java8OptionalConverterFactory.java │ │ │ ├── OptionalConverter.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit/ │ │ └── converter/ │ │ └── java8/ │ │ ├── AlwaysNullConverterFactory.java │ │ └── Java8OptionalConverterFactoryTest.java │ ├── jaxb/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── jaxb/ │ │ │ ├── JaxbConverterFactory.java │ │ │ ├── JaxbRequestConverter.java │ │ │ ├── JaxbResponseConverter.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── converter/ │ │ └── jaxb/ │ │ ├── Contact.java │ │ ├── JaxbConverterFactoryTest.java │ │ ├── PhoneNumber.java │ │ └── Type.java │ ├── jaxb3/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── jaxb3/ │ │ │ ├── JaxbConverterFactory.java │ │ │ ├── JaxbRequestConverter.java │ │ │ ├── JaxbResponseConverter.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── converter/ │ │ └── jaxb3/ │ │ ├── Contact.java │ │ ├── JaxbConverterFactoryTest.java │ │ ├── PhoneNumber.java │ │ └── Type.java │ ├── kotlinx-serialization/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── kotlinx/ │ │ │ └── serialization/ │ │ │ ├── DeserializationStrategyConverter.kt │ │ │ ├── Factory.kt │ │ │ ├── SerializationStrategyConverter.kt │ │ │ └── Serializer.kt │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── converter/ │ │ └── kotlinx/ │ │ └── serialization/ │ │ ├── KotlinSerializationConverterFactoryBytesTest.kt │ │ ├── KotlinSerializationConverterFactoryStringTest.kt │ │ ├── KotlinxSerializationConverterFactoryContextualListTest.kt │ │ └── KotlinxSerializationConverterFactoryContextualTest.kt │ ├── moshi/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── moshi/ │ │ │ ├── MoshiConverterFactory.java │ │ │ ├── MoshiRequestBodyConverter.java │ │ │ ├── MoshiResponseBodyConverter.java │ │ │ ├── MoshiStreamingRequestBody.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── converter/ │ │ └── moshi/ │ │ └── MoshiConverterFactoryTest.java │ ├── protobuf/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── retrofit2/ │ │ │ │ └── converter/ │ │ │ │ └── protobuf/ │ │ │ │ ├── ProtoConverterFactory.java │ │ │ │ ├── ProtoRequestBodyConverter.java │ │ │ │ ├── ProtoResponseBodyConverter.java │ │ │ │ ├── ProtoStreamingRequestBody.java │ │ │ │ └── package-info.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── proguard/ │ │ │ └── retrofit2-protobuf-converter.pro │ │ └── test/ │ │ ├── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── protobuf/ │ │ │ ├── FallbackParserFinderTest.java │ │ │ └── ProtoConverterFactoryTest.java │ │ └── proto/ │ │ └── phone.proto │ ├── scalars/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── scalars/ │ │ │ ├── ScalarRequestBodyConverter.java │ │ │ ├── ScalarResponseBodyConverters.java │ │ │ ├── ScalarsConverterFactory.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── converter/ │ │ └── scalars/ │ │ ├── ScalarsConverterFactoryTest.java │ │ └── ScalarsConverterPrimitivesFactoryTest.java │ ├── simplexml/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── simplexml/ │ │ │ ├── SimpleXmlConverterFactory.java │ │ │ ├── SimpleXmlRequestBodyConverter.java │ │ │ ├── SimpleXmlResponseBodyConverter.java │ │ │ └── package-info.java │ │ └── test/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── converter/ │ │ └── simplexml/ │ │ ├── MyObject.java │ │ └── SimpleXmlConverterFactoryTest.java │ └── wire/ │ ├── README.md │ ├── build.gradle │ ├── gradle.properties │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── retrofit2/ │ │ │ └── converter/ │ │ │ └── wire/ │ │ │ ├── WireConverterFactory.java │ │ │ ├── WireRequestBodyConverter.java │ │ │ ├── WireResponseBodyConverter.java │ │ │ ├── WireStreamingRequestBody.java │ │ │ └── package-info.java │ │ └── resources/ │ │ └── META-INF/ │ │ └── proguard/ │ │ └── retrofit2-wire-converter.pro │ └── test/ │ └── java/ │ └── retrofit2/ │ └── converter/ │ └── wire/ │ ├── CrashingPhone.java │ ├── Phone.java │ └── WireConverterFactoryTest.java ├── retrofit-mock/ │ ├── README.md │ ├── build.gradle │ ├── gradle.properties │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── retrofit2/ │ │ └── mock/ │ │ ├── BehaviorCall.java │ │ ├── BehaviorDelegate.java │ │ ├── Calls.java │ │ ├── KotlinExtensions.kt │ │ ├── MockRetrofit.java │ │ ├── MockRetrofitIOException.java │ │ ├── NetworkBehavior.java │ │ └── package-info.java │ └── test/ │ └── java/ │ └── retrofit2/ │ └── mock/ │ ├── BehaviorDelegateKotlinTest.kt │ ├── BehaviorDelegateTest.java │ ├── CallsTest.java │ ├── MockRetrofitTest.java │ └── NetworkBehaviorTest.java ├── retrofit-response-type-keeper/ │ ├── README.md │ ├── build.gradle │ ├── gradle.properties │ └── src/ │ ├── main/ │ │ ├── kotlin/ │ │ │ └── retrofit2/ │ │ │ └── keeper/ │ │ │ └── RetrofitResponseTypeKeepProcessor.kt │ │ └── resources/ │ │ └── META-INF/ │ │ ├── gradle/ │ │ │ └── incremental.annotation.processors │ │ └── services/ │ │ └── javax.annotation.processing.Processor │ └── test/ │ └── kotlin/ │ └── retrofit2/ │ └── keeper/ │ └── RetrofitResponseTypeKeepProcessorTest.kt ├── samples/ │ ├── build.gradle │ └── src/ │ └── main/ │ └── java/ │ └── com/ │ └── example/ │ └── retrofit/ │ ├── AnnotatedConverters.java │ ├── ChunkingConverter.java │ ├── ConditionalLoggingInterceptor.kt │ ├── Crawler.java │ ├── DeserializeErrorBody.java │ ├── DynamicBaseUrl.java │ ├── ErrorHandlingAdapter.java │ ├── InvocationMetrics.java │ ├── JsonAndXmlConverters.java │ ├── JsonQueryParameters.java │ ├── RxJavaObserveOnMainThread.java │ ├── SimpleMockService.java │ ├── SimpleService.java │ └── package-info.java ├── settings.gradle └── website/ ├── .gitignore ├── README.md ├── astro.config.mjs ├── package.json ├── public/ │ ├── 1.x/ │ │ ├── converter-jackson/ │ │ │ ├── allclasses-frame.html │ │ │ ├── allclasses-noframe.html │ │ │ ├── constant-values.html │ │ │ ├── deprecated-list.html │ │ │ ├── help-doc.html │ │ │ ├── index-all.html │ │ │ ├── index.html │ │ │ ├── overview-tree.html │ │ │ ├── package-list │ │ │ ├── retrofit/ │ │ │ │ └── converter/ │ │ │ │ ├── JacksonConverter.html │ │ │ │ ├── class-use/ │ │ │ │ │ └── JacksonConverter.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ ├── script.js │ │ │ ├── stylesheet.css │ │ │ └── version.txt │ │ ├── converter-protobuf/ │ │ │ ├── allclasses-frame.html │ │ │ ├── allclasses-noframe.html │ │ │ ├── constant-values.html │ │ │ ├── deprecated-list.html │ │ │ ├── help-doc.html │ │ │ ├── index-all.html │ │ │ ├── index.html │ │ │ ├── overview-tree.html │ │ │ ├── package-list │ │ │ ├── retrofit/ │ │ │ │ └── converter/ │ │ │ │ ├── ProtoConverter.html │ │ │ │ ├── class-use/ │ │ │ │ │ └── ProtoConverter.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ ├── script.js │ │ │ ├── stylesheet.css │ │ │ └── version.txt │ │ ├── converter-simplexml/ │ │ │ ├── allclasses-frame.html │ │ │ ├── allclasses-noframe.html │ │ │ ├── constant-values.html │ │ │ ├── deprecated-list.html │ │ │ ├── help-doc.html │ │ │ ├── index-all.html │ │ │ ├── index.html │ │ │ ├── overview-tree.html │ │ │ ├── package-list │ │ │ ├── retrofit/ │ │ │ │ └── converter/ │ │ │ │ ├── SimpleXMLConverter.html │ │ │ │ ├── class-use/ │ │ │ │ │ └── SimpleXMLConverter.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ ├── script.js │ │ │ ├── stylesheet.css │ │ │ └── version.txt │ │ ├── converter-wire/ │ │ │ ├── allclasses-frame.html │ │ │ ├── allclasses-noframe.html │ │ │ ├── constant-values.html │ │ │ ├── deprecated-list.html │ │ │ ├── help-doc.html │ │ │ ├── index-all.html │ │ │ ├── index.html │ │ │ ├── overview-tree.html │ │ │ ├── package-list │ │ │ ├── retrofit/ │ │ │ │ └── converter/ │ │ │ │ ├── WireConverter.html │ │ │ │ ├── class-use/ │ │ │ │ │ └── WireConverter.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ ├── script.js │ │ │ ├── stylesheet.css │ │ │ └── version.txt │ │ ├── retrofit/ │ │ │ ├── allclasses-frame.html │ │ │ ├── allclasses-noframe.html │ │ │ ├── constant-values.html │ │ │ ├── deprecated-list.html │ │ │ ├── help-doc.html │ │ │ ├── index-all.html │ │ │ ├── index.html │ │ │ ├── overview-frame.html │ │ │ ├── overview-summary.html │ │ │ ├── overview-tree.html │ │ │ ├── package-list │ │ │ ├── retrofit/ │ │ │ │ ├── Callback.html │ │ │ │ ├── Endpoint.html │ │ │ │ ├── Endpoints.html │ │ │ │ ├── ErrorHandler.html │ │ │ │ ├── Profiler.RequestInformation.html │ │ │ │ ├── Profiler.html │ │ │ │ ├── RequestInterceptor.RequestFacade.html │ │ │ │ ├── RequestInterceptor.html │ │ │ │ ├── ResponseCallback.html │ │ │ │ ├── RestAdapter.Builder.html │ │ │ │ ├── RestAdapter.Log.html │ │ │ │ ├── RestAdapter.LogLevel.html │ │ │ │ ├── RestAdapter.html │ │ │ │ ├── RetrofitError.Kind.html │ │ │ │ ├── RetrofitError.html │ │ │ │ ├── android/ │ │ │ │ │ ├── AndroidApacheClient.html │ │ │ │ │ ├── AndroidLog.html │ │ │ │ │ ├── MainThreadExecutor.html │ │ │ │ │ ├── class-use/ │ │ │ │ │ │ ├── AndroidApacheClient.html │ │ │ │ │ │ ├── AndroidLog.html │ │ │ │ │ │ └── MainThreadExecutor.html │ │ │ │ │ ├── package-frame.html │ │ │ │ │ ├── package-summary.html │ │ │ │ │ ├── package-tree.html │ │ │ │ │ └── package-use.html │ │ │ │ ├── appengine/ │ │ │ │ │ ├── UrlFetchClient.html │ │ │ │ │ ├── class-use/ │ │ │ │ │ │ └── UrlFetchClient.html │ │ │ │ │ ├── package-frame.html │ │ │ │ │ ├── package-summary.html │ │ │ │ │ ├── package-tree.html │ │ │ │ │ └── package-use.html │ │ │ │ ├── class-use/ │ │ │ │ │ ├── Callback.html │ │ │ │ │ ├── Endpoint.html │ │ │ │ │ ├── Endpoints.html │ │ │ │ │ ├── ErrorHandler.html │ │ │ │ │ ├── Profiler.RequestInformation.html │ │ │ │ │ ├── Profiler.html │ │ │ │ │ ├── RequestInterceptor.RequestFacade.html │ │ │ │ │ ├── RequestInterceptor.html │ │ │ │ │ ├── ResponseCallback.html │ │ │ │ │ ├── RestAdapter.Builder.html │ │ │ │ │ ├── RestAdapter.Log.html │ │ │ │ │ ├── RestAdapter.LogLevel.html │ │ │ │ │ ├── RestAdapter.html │ │ │ │ │ ├── RetrofitError.Kind.html │ │ │ │ │ └── RetrofitError.html │ │ │ │ ├── client/ │ │ │ │ │ ├── ApacheClient.html │ │ │ │ │ ├── Client.Provider.html │ │ │ │ │ ├── Client.html │ │ │ │ │ ├── Header.html │ │ │ │ │ ├── OkClient.html │ │ │ │ │ ├── Request.html │ │ │ │ │ ├── Response.html │ │ │ │ │ ├── UrlConnectionClient.html │ │ │ │ │ ├── class-use/ │ │ │ │ │ │ ├── ApacheClient.html │ │ │ │ │ │ ├── Client.Provider.html │ │ │ │ │ │ ├── Client.html │ │ │ │ │ │ ├── Header.html │ │ │ │ │ │ ├── OkClient.html │ │ │ │ │ │ ├── Request.html │ │ │ │ │ │ ├── Response.html │ │ │ │ │ │ └── UrlConnectionClient.html │ │ │ │ │ ├── package-frame.html │ │ │ │ │ ├── package-summary.html │ │ │ │ │ ├── package-tree.html │ │ │ │ │ └── package-use.html │ │ │ │ ├── converter/ │ │ │ │ │ ├── ConversionException.html │ │ │ │ │ ├── Converter.html │ │ │ │ │ ├── GsonConverter.html │ │ │ │ │ ├── class-use/ │ │ │ │ │ │ ├── ConversionException.html │ │ │ │ │ │ ├── Converter.html │ │ │ │ │ │ └── GsonConverter.html │ │ │ │ │ ├── package-frame.html │ │ │ │ │ ├── package-summary.html │ │ │ │ │ ├── package-tree.html │ │ │ │ │ └── package-use.html │ │ │ │ ├── http/ │ │ │ │ │ ├── Body.html │ │ │ │ │ ├── DELETE.html │ │ │ │ │ ├── EncodedPath.html │ │ │ │ │ ├── EncodedQuery.html │ │ │ │ │ ├── EncodedQueryMap.html │ │ │ │ │ ├── Field.html │ │ │ │ │ ├── FieldMap.html │ │ │ │ │ ├── FormUrlEncoded.html │ │ │ │ │ ├── GET.html │ │ │ │ │ ├── HEAD.html │ │ │ │ │ ├── Header.html │ │ │ │ │ ├── Headers.html │ │ │ │ │ ├── Multipart.html │ │ │ │ │ ├── PATCH.html │ │ │ │ │ ├── POST.html │ │ │ │ │ ├── PUT.html │ │ │ │ │ ├── Part.html │ │ │ │ │ ├── PartMap.html │ │ │ │ │ ├── Path.html │ │ │ │ │ ├── Query.html │ │ │ │ │ ├── QueryMap.html │ │ │ │ │ ├── RestMethod.html │ │ │ │ │ ├── Streaming.html │ │ │ │ │ ├── class-use/ │ │ │ │ │ │ ├── Body.html │ │ │ │ │ │ ├── DELETE.html │ │ │ │ │ │ ├── EncodedPath.html │ │ │ │ │ │ ├── EncodedQuery.html │ │ │ │ │ │ ├── EncodedQueryMap.html │ │ │ │ │ │ ├── Field.html │ │ │ │ │ │ ├── FieldMap.html │ │ │ │ │ │ ├── FormUrlEncoded.html │ │ │ │ │ │ ├── GET.html │ │ │ │ │ │ ├── HEAD.html │ │ │ │ │ │ ├── Header.html │ │ │ │ │ │ ├── Headers.html │ │ │ │ │ │ ├── Multipart.html │ │ │ │ │ │ ├── PATCH.html │ │ │ │ │ │ ├── POST.html │ │ │ │ │ │ ├── PUT.html │ │ │ │ │ │ ├── Part.html │ │ │ │ │ │ ├── PartMap.html │ │ │ │ │ │ ├── Path.html │ │ │ │ │ │ ├── Query.html │ │ │ │ │ │ ├── QueryMap.html │ │ │ │ │ │ ├── RestMethod.html │ │ │ │ │ │ └── Streaming.html │ │ │ │ │ ├── package-frame.html │ │ │ │ │ ├── package-summary.html │ │ │ │ │ ├── package-tree.html │ │ │ │ │ └── package-use.html │ │ │ │ ├── mime/ │ │ │ │ │ ├── FormUrlEncodedTypedOutput.html │ │ │ │ │ ├── MimeUtil.html │ │ │ │ │ ├── MultipartTypedOutput.html │ │ │ │ │ ├── TypedByteArray.html │ │ │ │ │ ├── TypedFile.html │ │ │ │ │ ├── TypedInput.html │ │ │ │ │ ├── TypedOutput.html │ │ │ │ │ ├── TypedString.html │ │ │ │ │ ├── class-use/ │ │ │ │ │ │ ├── FormUrlEncodedTypedOutput.html │ │ │ │ │ │ ├── MimeUtil.html │ │ │ │ │ │ ├── MultipartTypedOutput.html │ │ │ │ │ │ ├── TypedByteArray.html │ │ │ │ │ │ ├── TypedFile.html │ │ │ │ │ │ ├── TypedInput.html │ │ │ │ │ │ ├── TypedOutput.html │ │ │ │ │ │ └── TypedString.html │ │ │ │ │ ├── package-frame.html │ │ │ │ │ ├── package-summary.html │ │ │ │ │ ├── package-tree.html │ │ │ │ │ └── package-use.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ ├── script.js │ │ │ ├── serialized-form.html │ │ │ ├── stylesheet.css │ │ │ └── version.txt │ │ └── retrofit-mock/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-frame.html │ │ ├── overview-summary.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit/ │ │ │ ├── MockHttpException.html │ │ │ ├── MockRestAdapter.ValueChangeListener.html │ │ │ ├── MockRestAdapter.html │ │ │ ├── android/ │ │ │ │ ├── AndroidMockValuePersistence.html │ │ │ │ ├── class-use/ │ │ │ │ │ └── AndroidMockValuePersistence.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ ├── class-use/ │ │ │ │ ├── MockHttpException.html │ │ │ │ ├── MockRestAdapter.ValueChangeListener.html │ │ │ │ └── MockRestAdapter.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ ├── script.js │ │ ├── serialized-form.html │ │ ├── stylesheet.css │ │ └── version.txt │ └── 2.x/ │ ├── adapter-guava/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── adapter/ │ │ │ └── guava/ │ │ │ ├── GuavaCallAdapterFactory.html │ │ │ ├── HttpException.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ ├── serialized-form.html │ │ └── stylesheet.css │ ├── adapter-java8/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── adapter/ │ │ │ └── java8/ │ │ │ ├── HttpException.html │ │ │ ├── Java8CallAdapterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ ├── serialized-form.html │ │ └── stylesheet.css │ ├── adapter-rxjava/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── adapter/ │ │ │ └── rxjava/ │ │ │ ├── HttpException.html │ │ │ ├── Result.html │ │ │ ├── RxJavaCallAdapterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ ├── serialized-form.html │ │ └── stylesheet.css │ ├── adapter-rxjava2/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── adapter/ │ │ │ └── rxjava2/ │ │ │ ├── HttpException.html │ │ │ ├── Result.html │ │ │ ├── RxJava2CallAdapterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ ├── serialized-form.html │ │ └── stylesheet.css │ ├── adapter-rxjava3/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── adapter/ │ │ │ └── rxjava3/ │ │ │ ├── HttpException.html │ │ │ ├── Result.html │ │ │ ├── RxJava3CallAdapterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ ├── serialized-form.html │ │ └── stylesheet.css │ ├── adapter-scala/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── adapter/ │ │ │ └── scala/ │ │ │ ├── ScalaCallAdapterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-gson/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── converter/ │ │ │ └── gson/ │ │ │ ├── GsonConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-guava/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit/ │ │ │ └── converter/ │ │ │ └── guava/ │ │ │ ├── GuavaOptionalConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-jackson/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── converter/ │ │ │ └── jackson/ │ │ │ ├── JacksonConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-java8/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit/ │ │ │ └── converter/ │ │ │ └── java8/ │ │ │ ├── Java8OptionalConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-jaxb/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── converter/ │ │ │ └── jaxb/ │ │ │ ├── JaxbConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-jaxb3/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── converter/ │ │ │ └── jaxb3/ │ │ │ ├── JaxbConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-kotlinx-serialization/ │ │ ├── index.html │ │ ├── kotlinx-serialization/ │ │ │ ├── package-list │ │ │ └── retrofit2.converter.kotlinx.serialization/ │ │ │ ├── as-converter-factory.html │ │ │ └── index.html │ │ ├── navigation.html │ │ ├── scripts/ │ │ │ ├── clipboard.js │ │ │ ├── main.js │ │ │ ├── navigation-loader.js │ │ │ ├── pages.json │ │ │ ├── platform-content-handler.js │ │ │ ├── prism.js │ │ │ ├── sourceset_dependencies.js │ │ │ └── symbol-parameters-wrapper_deferred.js │ │ └── styles/ │ │ ├── font-jb-sans-auto.css │ │ ├── logo-styles.css │ │ ├── main.css │ │ ├── prism.css │ │ └── style.css │ ├── converter-moshi/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── converter/ │ │ │ └── moshi/ │ │ │ ├── MoshiConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-protobuf/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── converter/ │ │ │ └── protobuf/ │ │ │ ├── ProtoConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-scalars/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── converter/ │ │ │ └── scalars/ │ │ │ ├── ScalarsConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-simplexml/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── converter/ │ │ │ └── simplexml/ │ │ │ ├── SimpleXmlConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── converter-wire/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ └── converter/ │ │ │ └── wire/ │ │ │ ├── WireConverterFactory.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ └── stylesheet.css │ ├── retrofit/ │ │ ├── allclasses-frame.html │ │ ├── allclasses-noframe.html │ │ ├── constant-values.html │ │ ├── deprecated-list.html │ │ ├── help-doc.html │ │ ├── index-all.html │ │ ├── index.html │ │ ├── overview-frame.html │ │ ├── overview-summary.html │ │ ├── overview-tree.html │ │ ├── package-list │ │ ├── retrofit2/ │ │ │ ├── Call.html │ │ │ ├── CallAdapter.Factory.html │ │ │ ├── CallAdapter.html │ │ │ ├── Callback.html │ │ │ ├── Converter.Factory.html │ │ │ ├── Converter.html │ │ │ ├── HttpException.html │ │ │ ├── Invocation.html │ │ │ ├── OptionalConverterFactory.html │ │ │ ├── Response.html │ │ │ ├── Retrofit.Builder.html │ │ │ ├── Retrofit.html │ │ │ ├── SkipCallbackExecutor.html │ │ │ ├── http/ │ │ │ │ ├── Body.html │ │ │ │ ├── DELETE.html │ │ │ │ ├── Field.html │ │ │ │ ├── FieldMap.html │ │ │ │ ├── FormUrlEncoded.html │ │ │ │ ├── GET.html │ │ │ │ ├── HEAD.html │ │ │ │ ├── HTTP.html │ │ │ │ ├── Header.html │ │ │ │ ├── HeaderMap.html │ │ │ │ ├── Headers.html │ │ │ │ ├── Multipart.html │ │ │ │ ├── OPTIONS.html │ │ │ │ ├── PATCH.html │ │ │ │ ├── POST.html │ │ │ │ ├── PUT.html │ │ │ │ ├── Part.html │ │ │ │ ├── PartMap.html │ │ │ │ ├── Path.html │ │ │ │ ├── Query.html │ │ │ │ ├── QueryMap.html │ │ │ │ ├── QueryName.html │ │ │ │ ├── Streaming.html │ │ │ │ ├── Tag.html │ │ │ │ ├── Url.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ └── package-tree.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ └── package-tree.html │ │ ├── script.js │ │ ├── serialized-form.html │ │ └── stylesheet.css │ └── retrofit-mock/ │ ├── allclasses-frame.html │ ├── allclasses-noframe.html │ ├── constant-values.html │ ├── deprecated-list.html │ ├── help-doc.html │ ├── index-all.html │ ├── index.html │ ├── overview-tree.html │ ├── package-list │ ├── retrofit2/ │ │ └── mock/ │ │ ├── BehaviorDelegate.html │ │ ├── Calls.html │ │ ├── MockRetrofit.Builder.html │ │ ├── MockRetrofit.html │ │ ├── NetworkBehavior.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── script.js │ └── stylesheet.css ├── src/ │ ├── content/ │ │ └── docs/ │ │ ├── configuration.md │ │ ├── contributing.md │ │ ├── declarations.md │ │ ├── download.mdx │ │ └── index.md │ ├── content.config.ts │ └── styles/ │ └── theme.css └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] indent_size = 2 charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.{kt,kts}] ij_kotlin_allow_trailing_comma = true ij_kotlin_allow_trailing_comma_on_call_site = true ij_kotlin_imports_layout = * [*.mjs] indent_style = tab [*.ts] indent_style = tab [*.css] indent_style = tab ================================================ FILE: .gitattributes ================================================ * text=auto eol=lf *.bat text eol=crlf *.jar binary ================================================ FILE: .github/CONTRIBUTING.md ================================================ Contributing ============ If you would like to contribute code to Retrofit you can do so through GitHub by forking the repository and sending a pull request. When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible. Please also make sure your code compiles by running `./gradlew build` (or `gradlew.bat build` on Windows). Before your code can be accepted into the project you must also sign the [Individual Contributor License Agreement (CLA)][1]. [1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1 ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ What kind of issue is this? - [ ] Question. This issue tracker is not the place for questions. If you want to ask how to do something, or to understand why something isn't working the way you expect it to, use Stack Overflow. https://stackoverflow.com/questions/tagged/retrofit - [ ] Bug report. If you’ve found a bug, spend the time to write a failing test. Bugs with tests get fixed. Here’s an example: https://gist.github.com/swankjesse/6608b4713ad80988cdc9 - [ ] Feature Request. Start by telling us what problem you’re trying to solve. Often a solution already exists! Don’t send pull requests to implement new features without first getting our support. Sometimes we leave features out on purpose to keep the project small. ================================================ FILE: .github/pull_request_template.md ================================================ --- - [ ] `CHANGELOG.md`'s "Unreleased" section has been updated, if applicable. ================================================ FILE: .github/renovate.json5 ================================================ { $schema: 'https://docs.renovatebot.com/renovate-schema.json', extends: [ 'config:recommended', ], ignorePresets: [ // Ensure we get the latest version and are not pinned to old versions. 'workarounds:javaLTSVersions', ], customManagers: [ // Update .java-version file with the latest JDK version. { customType: 'regex', fileMatch: [ '\\.java-version$', ], matchStrings: [ '(?.*)\\n', ], datasourceTemplate: 'java-version', depNameTemplate: 'java', // Only write the major version. extractVersionTemplate: '^(?\\d+)', }, ] } ================================================ FILE: .github/workflows/.java-version ================================================ 25 ================================================ FILE: .github/workflows/build.yml ================================================ name: build on: pull_request: {} workflow_dispatch: {} push: branches: - 'trunk' tags-ignore: - '**' env: GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false -Dkotlin.incremental=false -Dorg.gradle.logging.stacktrace=full" jobs: jvm: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: distribution: 'zulu' java-version-file: .github/workflows/.java-version - uses: gradle/actions/setup-gradle@v5 - run: ./gradlew build android: runs-on: ubuntu-latest strategy: fail-fast: false matrix: api-level: - 21 - 24 - 26 - 29 steps: - name: Enable KVM group perms run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm ls /dev/kvm - uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: distribution: 'zulu' java-version-file: .github/workflows/.java-version - uses: gradle/actions/setup-gradle@v5 - name: Run Tests uses: reactivecircus/android-emulator-runner@v2 with: api-level: ${{ matrix.api-level }} script: ./gradlew connectedCheck env: API_LEVEL: ${{ matrix.api-level }} robovm: runs-on: macos-15-intel steps: - uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: distribution: 'zulu' java-version-file: .github/workflows/.java-version - uses: gradle/actions/setup-gradle@v5 - name: Run Tests run: ./gradlew retrofit:robovm-test:robovmTest website: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: distribution: 'zulu' java-version-file: .github/workflows/.java-version - uses: gradle/actions/setup-gradle@v5 - name: Build snapshot website run: | ./gradlew copyWebsiteDocs cd website npm install && npm run build -- --mode snapshot - uses: actions/upload-artifact@v7 with: name: website path: website/dist if-no-files-found: error final-status: runs-on: ubuntu-latest if: ${{ !cancelled() }} needs: - jvm - android - robovm - website steps: - name: Check run: | results=$(tr -d '\n' <<< '${{ toJSON(needs.*.result) }}') if ! grep -q -v -E '(failure|cancelled)' <<< "$results"; then echo "One or more required jobs failed" exit 1 fi publish: runs-on: ubuntu-latest if: github.repository == 'square/retrofit' && github.ref == 'refs/heads/trunk' needs: - final-status steps: - uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: distribution: 'zulu' java-version-file: .github/workflows/.java-version - uses: gradle/actions/setup-gradle@v5 - run: ./gradlew publish env: ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_CENTRAL_USERNAME }} ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_CENTRAL_PASSWORD }} ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SECRET_KEY }} ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SECRET_PASSPHRASE }} - uses: actions/download-artifact@v8 with: name: website path: website/dist - name: Deploy snapshot website uses: JamesIves/github-pages-deploy-action@releases/v3 with: branch: site folder: website/dist target_folder: latest clean: true ================================================ FILE: .github/workflows/release.yaml ================================================ name: release on: push: tags: - '**' env: GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false -Dkotlin.incremental=false -Dorg.gradle.logging.stacktrace=full" jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-java@v5 with: distribution: 'zulu' java-version-file: .github/workflows/.java-version - run: ./gradlew publish env: ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_CENTRAL_USERNAME }} ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_CENTRAL_PASSWORD }} ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SECRET_KEY }} ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SECRET_PASSPHRASE }} - name: Extract release notes id: release_notes uses: ffurrer2/extract-release-notes@v3 - name: Create release uses: ncipollo/release-action@v1 with: body: ${{ steps.release_notes.outputs.release_notes }} discussionCategory: Announcements - name: Build release website run: | ./gradlew copyWebsiteDocs cd website npm install && npm run build -- --mode release - name: Deploy release website uses: JamesIves/github-pages-deploy-action@releases/v3 with: branch: site folder: website/dist clean: true clean-exclude: | .nojekyll latest/** ================================================ FILE: .gitignore ================================================ # Gradle .gradle build /reports local.properties # Idea .idea *.iml ================================================ FILE: BUG-BOUNTY.md ================================================ Serious about security ====================== Square recognizes the important contributions the security research community can make. We therefore encourage reporting security issues with the code contained in this repository. If you believe you have discovered a security vulnerability, please follow the guidelines at https://bugcrowd.com/squareopensource ================================================ FILE: CHANGELOG.md ================================================ # Change Log ## [Unreleased] [Unreleased]: https://github.com/square/retrofit/compare/3.0.0...HEAD **New** - Add explicit keep rules for RxJava `Result` types to prevent their generic information from being removed. - Add `allowoptimization` flags for most kept types. - Add `Invocation.annotationUrl` which returns the original URL from the method annotation. **Changed** - In-development snapshots are now published to the Central Portal Snapshots repository at https://central.sonatype.com/repository/maven-snapshots/. **Fixed** - Nothing yet! ## [3.0.0] - 2025-05-15 [3.0.0]: https://github.com/square/retrofit/releases/tag/3.0.0 **Changed** - Upgrade to OkHttp 4.12 (from 3.14). This is the version of OkHttp that is written in Kotlin, and as a result Retrofit now has a transitive Kotlin dependency. However, this is also the _supported_ version of OkHttp whereas the previous version was out of support for nearly 4 years. Note: The 3.x versions of Retrofit maintain forward binary-compatibility with the 2.x versions. This means libraries compiled against 2.x can still be used with the 3.x versions. ## [2.12.0] - 2025-05-15 [2.12.0]: https://github.com/square/retrofit/releases/tag/2.12.0 **New** - First-party converters now support deferring serialization to happen when the request body is written (i.e., during HTTP execution) rather than when the HTTP request is created. In some cases this moves conversion from a calling thread to a background thread, such as in the case when using `Call.enqueue` directly. The following converters support this feature through a new `withStreaming()` factory method: - Gson - Jackson - Moshi - Protobuf - Wire **Fixed** - Primitive types used with `@Tag` now work by storing the value boxed with the boxed class as the key. ## [2.11.0] - 2024-03-28 **New** - The built-in `OptionalConverterFactory` is now public to allow installing it before other converters which consume all types (e.g., Moshi, Gson, Jackson, etc.). **Fixed** - Ensure that exceptions thrown from failure to parse method annotations can be observed by multiple threads/callers. Previously only the first caller would see the actual parsing exception and other callers would get a cryptic `ClassCastException`. ## [2.10.0] - 2024-03-18 **New** - Support using `Unit` as a response type. This can be used for non-body HTTP methods like `HEAD` or body-containing HTTP methods like `GET` where the body will be discarded without deserialization. - kotlinx.serialization converter! This was imported from [github.com/JakeWharton/retrofit2-kotlinx-serialization-converter/](https://github.com/JakeWharton/retrofit2-kotlinx-serialization-converter/) and remains unchanged from its 1.0.0 release. The Maven coordinates are `com.squareup.retrofit2:converter-kotlinx-serialization`. - JAXB 3 converter! The Maven coordinates are `com.squareup.retrofit2:converter-jaxb3`. - `@Header`, `@Headers`, and `@HeaderMap` can now set non-ASCII values through the `allowUnsafeNonAsciiValues` annotation property. These are not technically compliant with the HTTP specification, but are often supported or required by services. - Publish a BOM of all modules. The Maven coordinates are `com.squareup.retrofit2:retrofit-bom`. - `Invocation` now exposes the service `Class` and the instance on which the method was invoked. This disambiguates the source when service inheritence is used. - A response type keeper annotation processor is now available for generating shrinker rules for all referenced types in your service interface. In some cases, it's impossible for static shrinker rules to keep the entirety of what Retrofit needs at runtime. This annotation processor generates those additional rules. For more info see [its README](https://github.com/square/retrofit/tree/trunk/retrofit-response-type-keeper#readme). **Changed** - Add shrinker rules to retain the generic signatures of built-in types (`Call`, `Response`, etc.) which are used via reflection at runtime. - Remove backpressure support from RxJava 2 and 3 adapters. Since we only deliver a single value and the Reactive Streams specification states that callers must request a non-zero subscription value, we never need to honor backpressure. - Kotlin `Retrofit.create` function now has a non-null lower bound. Even if you specified a nullable type before this function would never return null. - Suspend functions now capture and defer all `Throwable` subtypes (not just `Exception` subtypes) to avoid Java's `UndeclaredThrowableException` when thrown synchronously. - Eagerly reject `suspend fun` functions that return `Call`. These are never correct, and should declare a return type of `Body` directly. - Support for Java 14-specific and Java 16-specific reflection needed to invoke default methods on interfaces have been moved to separate versions of a class through a multi-release jar. This should have no observable impact other than the jar now contains classes which target Java 14 and Java 16 bytecode that might trip up some static analysis tools which are not aware of multi-release jars. - Parameter names are now displayed in exception messages when available in the underlying Java bytecode. - Jackson converter now supports binary formats by using byte streams rather than character streams in its implementation. Use the `create(ObjectMapper, MediaType)` overload to supply the value of the `Content-Type` header for your format. **Fixed** - Do not include synthetic methods when doing eager validation. - Use per-method rather than per-class locking when parsing annotations. This eliminates contention when multiple calls are made in quick succession at the beginning of the process lifetime. ## [2.9.0] - 2020-05-20 * New: RxJava 3 adapter! The Maven coordinates are `com.squareup.retrofit2:adapter-rxjava3`. Unlike the RxJava 1 and RxJava 2 adapters, the RxJava 3 adapter's `create()` method will produce asynchronous HTTP requests by default. For synchronous requests use `createSynchronous()` and for synchronous on a scheduler use `createWithScheduler(..)`. ## [2.8.2] - 2020-05-18 * Fix: Detect running on the Android platform by using system property rather than the presence of classes. This ensures that even when you're running on the JVM with Android classes present on the classpath you get JVM semantics. * Fix: Update to OkHttp 3.14.9 which contains an associated Android platform detection fix. ## [2.8.1] - 2020-03-25 * Fix: Do not access `MethodHandles.Lookup` on Android API 24 and 25. The class is only available on Android API 26 and higher. ## [2.8.0] - 2020-03-23 * New: Add `Call.timeout()` which returns the `okio.Timeout` of the full call. * Fix: Change `Call.awaitResponse()` to accept a nullable response type. * Fix: Support default methods on Java 14+. We had been working around a bug in earlier versions of Java. That bug was fixed in Java 14, and the fix broke our workaround. ## [2.7.2] - 2020-02-24 * Fix: Update to OkHttp 3.14.7 for compatibility with Android R (API 30). ## [2.7.1] - 2020-01-02 * Fix: Support 'suspend' functions in services interfaces when using 'retrofit-mock' artifact. ## [2.7.0] - 2019-12-09 **This release changes the minimum requirements to Java 8+ or Android 5+.** See [this blog post](https://cashapp.github.io/2019-02-05/okhttp-3-13-requires-android-5) for more information on the change. * New: Upgrade to OkHttp 3.14.4. Please see [its changelog for 3.x](https://square.github.io/okhttp/changelog_3x/). * Fix: Allow service interfaces to extend other interfaces. * Fix: Ensure a non-null body is returned by `Response.error`. ## [2.6.4] - 2020-01-02 * Fix: Support 'suspend' functions in services interfaces when using 'retrofit-mock' artifact. ## [2.6.3] - 2019-12-09 * Fix: Change mechanism for avoiding `UndeclaredThrowableException` in rare cases from using `yield` an explicit dispatch which ensures that it will work even on dispatchers which do not support yielding. ## [2.6.2] - 2019-09-23 * Fix: Avoid `IOException`s being wrapped in `UndeclaredThrowableException` in rare cases when using `Response<..>` as a return type for Kotlin 'suspend' functions. ## [2.6.1] - 2019-07-31 * Fix: Avoid `IOException`s being wrapped in `UndeclaredThrowableException` in rare cases. * Fix: Include no-content `ResponseBody` for responses created by `Response.error`. * Fix: Update embedded R8/ProGuard rules to not warn about nested classes used for Kotlin extensions. ## [2.6.0] - 2019-06-05 * New: Support `suspend` modifier on functions for Kotlin! This allows you to express the asynchrony of HTTP requests in an idiomatic fashion for the language. ```kotlin @GET("users/{id}") suspend fun user(@Path("id") id: Long): User ``` Behind the scenes this behaves as if defined as `fun user(...): Call` and then invoked with `Call.enqueue`. You can also return `Response` for access to the response metadata. Currently this integration only supports non-null response body types. Follow [issue 3075](https://github.com/square/retrofit/issues/3075) for nullable type support. * New: **`@Tag`** parameter annotation for setting tags on the underlying OkHttp `Request` object. These can be read in `CallAdapter`s or OkHttp `Interceptor`s for tracing, analytics, varying behavior, and more. * New: **`@SkipCallbackExecutor`** method annotation will result in your `Call` invoking its `Callback` on the background thread on which the HTTP call was made. * New: Support OkHttp's `Headers` type for `@HeaderMap` parameters. * New: Add `Retrofit.Builder.baseUrl(URL)` overload. * Fix: Add embedded R8/ProGuard rule which retains Retrofit interfaces (while still allowing obfuscation). This is needed because R8 running in 'full mode' (i.e., not in ProGuard-compatibility mode) will see that there are no subtypes of these interfaces and rewrite any code which references instances to null. * Fix: Mark `HttpException.response()` as `@Nullable` as serializing the exception does not retain this instance. * Fix: Fatal errors (such as stack overflows, out of memory, etc.) now propagate to the OkHttp `Dispatcher` thread on which they are running. * Fix: Ensure JAX-B converter closes the response body when an exception is thrown during deserialization. * Fix: Ignore static methods when performing eager validation of interface methods. * Fix: Ensure that calling `source()` twice on the `ResponseBody` passed to a `Converter` always returns the same instance. Prior to the fix, intermediate buffering would cause response data to be lost. ## [2.5.0] - 2018-11-18 * New: Built-in support for Kotlin's `Unit` type. This behaves the same as Java's `Void` where the body content is ignored and immediately discarded. * New: Built-in support for Java 8's `Optional` and `CompletableFuture` types. Previously the 'converter-java8' and 'adapter-java8' dependencies were needed and explicitly adding `Java8OptionalConverterFactory` and/or `Java8CallAdapterFactory` to your `Retrofit.Builder` in order to use these types. Support is now built-in and those types and their artifacts are marked as deprecated. * New: `Invocation` class provides a reference to the invoked method and argument list as a tag on the underlying OkHttp `Call`. This can be accessed from an OkHttp interceptor for things like logging, analytics, or metrics aggregation. * New: Kotlin extension for `Retrofit` which allows you call `create` passing the interface type only as a generic parameter (e.g., `retrofit.create()`). * New: Added `Response.success` overload which allows specifying a custom 2xx status code. * New: Added `Calls.failure` overload which allows passing any `Throwable` subtype. * New: Minimal R8 rules now ship inside the jar requiring no client configuration in the common case. * Fix: Do not propagate fatal errors to the callback. They are sent to the thread's uncaught exception handler. * Fix: Do not enqueue/execute an otherwise useless call when the RxJava type is disposed by `onSubscribe`. * Fix: Call `RxJavaPlugins` assembly hook when creating an RxJava 2 type. * Fix: Ensure both the Guava and Java 8 `Optional` converters delegate properly. This ensures that converters registered prior to the optional converter can be used for deserializing the body type. * Fix: Prevent `@Path` values from participating in path-traversal. This ensures untrusted input passed as a path value cannot cause you to make a request to an un-intended relative URL. * Fix: Simple XML converter (which is deprecated) no longer wraps subtypes of `RuntimeException` or `IOException` when it fails. * Fix: Prevent JAXB converter from loading remote entities and DTDs. * Fix: Correctly detect default methods in interfaces on Android (API 24+). These still do not work, but now a correct exception will be thrown when detected. * Fix: Report more accurate exceptions when a `@QueryName` or `@QueryMap` precedes a `@Url` parameter. * Update OkHttp dependency to 3.12. ## [2.4.0] - 2018-03-14 * New: `Retrofit.Builder` exposes mutable lists of the added converter and call adapter factories. * New: Call adapter added for Scala's `Future`. * New: Converter for JAXB replaces the now-deprecated converter for Simple XML Framework. * New: Add Java 9 automatic module names for each artifact corresponding to their root package. * Fix: Do not swallow `Error`s from callbacks (usually `OutOfMemoryError`). * Fix: Moshi and Gson converters now assert that the full response was consumed. This prevents hiding bugs in faulty adapters which might not have consumed the full JSON input which would then cause failures on the next request over that connection. * Fix: Do not conflate OkHttp `Call` cancelation with RxJava unsubscription/disposal. Prior to this change, canceling of a `Call` would prevent a cancelation exception from propagating down the Rx stream. ## [2.3.0] - 2017-05-13 * **Retrofit now uses `@Nullable` to annotate all possibly-null values.** We've added a compile-time dependency on the JSR 305 annotations. This is a [provided][maven_provided] dependency and does not need to be included in your build configuration, `.jar` file, or `.apk`. We use `@ParametersAreNonnullByDefault` and all parameters and return types are never null unless explicitly annotated `@Nullable`. **Warning: this release is source-incompatible for Kotlin users.** Nullability was previously ambiguous and lenient but now the compiler will enforce strict null checks. * New: Converters added for Java 8's and Guava's `Optional` which wrap a potentially-nullable response body. These converters still rely on normal serialization library converters for parsing the response bytes into an object. * New: String converters that return `null` for an `@Query` or `@Field` parameter are now skipped. * New: The mock module's `NetworkBehavior` now throws a custom subclass of `IOException` to more clearly indicate the exception's source. * RxJava 1.x converter updated to 1.3.0 which stabilizes the use of `Completable`. * Fix: Add explicit handling for `OnCompleteFailedException`, `OnErrorFailedException`, and `OnErrorNotImplementedException` for RxJava 1.x to ensure they're correct delivered to the plugins/hooks for handling. * Fix: `NoSuchElementException` thrown when unsubscribing from an RxJava 1.x `Single`. ## [2.2.0] - 2017-02-21 * RxJava 2.x is now supported with a first-party 'adapter-rxjava2' artifact. * New: `@QueryName` annotation allows creating a query parameter with no '=' separator or value. * New: Support for messages generated by Protobuf 3.0 or newer when using the converter for Google's protobuf. * New: RxJava 1.x call adapter now correctly handles broken subscribers whose methods throw exceptions. * New: Add `toString()` implementations for `Response` and `Result`. * New: The Moshi converter factory now offers methods for enabling null serialization and lenient parsing. * New: Add `createAsync()` to RxJava 1.x call adapter factory which executes requests using `Call.enqueue()` using the underlying HTTP client's asynchronous support. * New: `NetworkBehavior` now allows setting an error percentage and returns HTTP errors when triggered. * `HttpException` has been moved into the main artifact and should be used instead of the versions embedded in each adapter (which have been deprecated). * Promote the response body generic type on `CallAdapter` from the `adapt` method to the enclosing class. This is a source-incompatible but binary-compatible change which is only relevant if you are implementing your own `CallAdapter`s. * Remove explicit handling of the now-defunct RoboVM platform. * Fix: Close response on HTTP 204 and 205 to avoid resource leak. * Fix: Reflect the canceled state of the HTTP client's `Call` in Retrofit's `Call`. * Fix: Use supplied string converters for the `String` type on non-body parameters. This allows user converters to handle cases such as when annotating string parameters instead of them always using the raw string. * Fix: Skip a UTF-8 BOM (if present) when using the converter for Moshi. ## [2.1.0] - 2016-06-15 * New: `@HeaderMap` annotation and support for supplying an arbitrary number of headers to an endpoint. * New: `@JsonAdapter` annotations on the `@Body` parameter and on the method will be propagated to Moshi for creating the request and response adapters, respectively. * Fix: Honor the `Content-Type` encoding of XML responses when deserializing response bodies. * Fix: Remove the stacktrace from fake network exceptions created from retrofit-mock's `NetworkBehavior`. They had the potential to be misleading and look like a library issue. * Fix: Eagerly catch malformed `Content-Type` headers supplied via `@Header` or `@Headers`. ## [2.0.2] - 2016-04-14 * New: `ProtoConverterFactory.createWithRegistry()` method accepts an extension registry to be used when deserializing protos. * Fix: Pass the correct `Call` instance to `Callback`'s `onResponse` and `onFailure` methods such that calling `clone()` retains the correct threading behavior. * Fix: Reduce the per-request allocation overhead for the RxJava call adapter. ## [2.0.1] - 2016-03-30 * New: Support OkHttp's `HttpUrl` as a `@Url` parameter type. * New: Support iterable and array `@Part` parameters using OkHttp's `MultipartBody.Part`. * Fix: Honor backpressure in `Observable`s created from the RxJavaCallAdapterFactory. ## [2.0.0] - 2016-03-11 Retrofit 2 is a major release focused on extensibility. The API changes are numerous but solve shortcomings of the previous version and provide a path for future enhancement. Because the release includes breaking API changes, we're changing the project's package name from `retrofit` to `retrofit2`. This should make it possible for large applications and libraries to migrate incrementally. The Maven group ID is now `com.squareup.retrofit2`. For an explanation of this strategy, see Jake Wharton's post, [Java Interoperability Policy for Major Version Updates](http://jakewharton.com/java-interoperability-policy-for-major-version-updates/). * **Service methods return `Call`.** This allows them to be executed synchronously or asynchronously using the same method definition. A `Call` instance represents a single request/response pair so it can only be used once, but you can `clone()` it for re-use. Invoking `cancel()` will cancel in-flight requests or prevent the request from even being performed if it has not already. * **Multiple converters for multiple serialization formats.** API calls returning different formats (like JSON, protocol buffers, and plain text) no longer need to be separated into separate service interfaces. Combine them together and add multiple converters. Converters are chosen based on the response type you declare. Gson is no longer included by default, so you will always need to add a converter for any serialization support. OkHttp's `RequestBody` and `ResponseBody` types can always be used without adding one, however. * **Call adapters allow different execution mechanisms.** While `Call` is the built-in mechanism, support for additional ones can be added similar to how different converters can be added. RxJava's `Observable` support has moved into a separate artifact as a result, and support for Java 8's `CompletableFuture` and Guava's `ListenableFuture` are also provided as additional artifacts. * **Generic response type includes HTTP information and deserialized body.** You no longer have to choose between the deserialized body and reading HTTP information. Every `Call` automatically receives both via the `Response` type and the RxJava, Guava, and Java 8 call adapters also support it. * **@Url for hypermedia-like APIs.** When your API returns links for pagination, additional resources, or updated content they can now be used with a service method whose first parameter is annotated with `@Url`. Changes from beta 4: * New: `RxJavaCallAdapterFactory` now supports service methods which return `Completable` which ignores and discards response bodies, if any. * New: `RxJavaCallAdapterFactory` supports supplying a default `Scheduler` which will be used for `subscribeOn` on returned `Observable`, `Single`, and `Completable` instances. * New: `MoshiConverterFactory` supports creating an instance which uses lenient parsing. * New: `@Part` can omit the part name and use OkHttp's `MultipartBody.Part` type for supplying parts. This lets you customize the headers, name, and filename and provide the part body in a single argument. * The `BaseUrl` interface and support for changeable base URLs was removed. This functionality can be done using an OkHttp interceptor and a sample showcasing it was added. * `Response.isSuccess()` was renamed to `Response.isSuccessful()` for parity with the name of OkHttp's version of that method. * Fix: Throw a more appropriate exception with a message when a resolved url (base URL + relative URL) is malformed. * Fix: `GsonConverterFactory` now honors settings on the `Gson` instance (like leniency). * Fix: `ScalarsConverterFactory` now supports primitive scalar types in addition to boxed for response body parsing. * Fix: `Retrofit.callbackExecutor()` may now return an executor even when one was not explicitly provided. This allows custom `CallAdapter.Factory` implementations to use it when triggering callbacks to ensure they happen on the appropriate thread for the platform (e.g., Android). ## [2.0.0-beta4] - 2016-02-04 * New: `Call` instance is now passed to both `onResponse` and `onFailure` methods of `Callback`. This aids in detecting when `onFailure` is called as a result of `Call.cancel()` by checking `Call.isCanceled()`. * New: `Call.request()` returns (optionally creating) the `Request` object for the call. Note: If this is called before `Call.execute()` or `Call.enqueue()` this will do relatively expensive work synchronously. Doing so in performance-critical sections (like on the Android main thread) should be avoided. * New: Support for the release version of OkHttp 3.0 and newer. * New: `adapter-guava` module provides a `CallAdapter.Factory` for Guava's `ListenableFuture`. * New: `adapter-java8` module provides a `CallAdapter.Factory` for Java 8's `CompleteableFuture`. * New: `ScalarsConverterFactory` (from `converter-scalars` module) now supports parsing response bodies into either `String`, the 8 primitive types, or the 8 boxed primitive types. * New: Automatic support for sending callbacks to the iOS main thread when running via RoboVM. * New: Method annotations are now passed to the factory for request body converters. This allows converters to alter the structure of both request bodies and response bodies with a single method-level annotation. * Each converter has been moved to its own package under `retrofit2.converter.`. This prevents type collisions when many converters are simultaneously in use. * Fix: Exceptions thrown when unable to locate a `CallAdapter.Factory` for a method return type now correctly list the `CallAdapter.Factory` instances checked. * Fix: Ensure default methods on service interfaces can be invoked. * Fix: Correctly resolve the generic parameter types of collection interfaces when subclasses of those collections are used as method parameters. * Fix: Do not encode `/` characters in `@Path` replacements when `encoded = true`. ## [2.0.0-beta3] - 2016-01-05 * New: All classes have been migrated to the `retrofit2.*` package name. The Maven groupId is now `com.squareup.retrofit2`. This is in accordance with the [Java Interoperability Policy for Major Version Updates](http://jakewharton.com/java-interoperability-policy-for-major-version-updates/). With this change Retrofit 2.x can coexiest with Retrofit 1.x in the same project. * New: Update to use the OkHttp 3 API and OkHttp 3.0.0-RC1 or newer is now required. Similar to the previous point, OkHttp has a new package name (`okhttp3.*`) and Maven groupId (`com.squareup.okhttp3`) which allow it to coexist with OkHttp 2.x in the same project. * New: String converters allow for custom serialization of parameters that end up as strings (such as `@Path`, `@Query`, `@Header`, etc.). `Converter.Factory` has a new `stringConverter` method which receives the parameter type and annotations and can return a converter for that type. This allows providing custom rendering of types like `Date`, `User`, etc. to a string before being used for its purpose. A default converter will call `toString()` for any type which retains the mimics the previous behavior. * New: OkHttp's `Call.Factory` type is now used as the HTTP client rather than using the `OkHttpClient` type directly (`OkHttpClient` does implement `Call.Factory`). A `callFactory` method has been added to both `Retrofit.Builder` and `Retrofit` to allow supplying alternate implementations of an HTTP client. The `client(OkHttpClient)` method on `Retrofit.Builder` still exists as a convenience. * New: `isExecuted()` method returns whether a `Call` has been synchronously or asynchronously executed. * New: `isCanceled()` method returns whether a `Call` has been canceled. Use this in `onFailure` to determine whether the callback was invoked from cancellation or actual transport failure. * New: `converter-scalars` module provides a `Converter.Factory` for converting `String`, the 8 primitive types, and the 8 boxed primitive types as `text/plain` bodies. Install this before your normal converter to avoid passing these simple scalars through, for example, a JSON converter. * New: `Converter.Factory` methods now receive a `Retrofit` instance which also now has methods for querying the next converter for a given type. This allows implementations to delegate to others and provide additional behavior without complete reimplementation. * New: `@OPTIONS` annotation more easily allows for making OPTIONS requests. * New: `@Part` annotation now supports `List` and array types. * New: The `@Url` annotation now allows using `java.net.URI` or `android.net.Uri` (in addition to `String`) as parameter types for providing relative or absolute endpoint URLs dynamically. * New: The `retrofit-mock` module has been rewritten with a new `BehaviorDelegate` class for implementing fake network behavior in a local mock implementation of your service endpoints. Documentation and more tests are forthcoming, but the `SimpleMockService` demonstrates its use for now. * Fix: Forbid Retrofit's `Response` type and OkHttp's `Response` type as the response body type given to a `Call` (i.e., `Call`). OkHttp's `ResponseBody` type is the correct one to use when the raw body contents are desired. * Fix: The Gson converter now respects settings on the supplied `Gson` instance (such as `serializeNulls`). This requires Gson 2.4 or newer. * The Wire converter has been updated to the Wire 2.0 API. * The change in 2.0.0-beta2 which provided the `Retrofit` instance to the `onResponse` callback of `Callback` has been reverted. There are too many edge cases around providing the `Retrofit` object in order to allow deserialization of the error body. To accommodate this use case, pass around the `Retrofit` response manually or implement a custom `CallAdapter.Factory` does so automatically. ## [2.0.0-beta2] - 2015-09-28 * New: Using a response type of `Void` (e.g., `Call`) will ignore and discard the response body. This can be used when there will be no response body (such as in a 201 response) or whenever the body is not needed. `@Head` requests are now forced to use this as their response type. * New: `validateEagerly()` method on `Retrofit.Builder` will verify the correctness of all service methods on calls to `create()` instead of lazily validating on first use. * New: `Converter` is now parameterized over both 'from' and 'to' types with a single `convert` method. `Converter.Factory` is now an abstract class and has factory methods for both request body and response body. * New: `Converter.Factory` and `CallAdapter.Factory` now receive the method annotations when being created for a return/response type and the parameter annotations when being created for a parameter type. * New: `callAdapter()` method on `Retrofit` allows querying a `CallAdapter` for a given type. The `nextCallAdapter()` method allows delegating to another `CallAdapter` from within a `CallAdapter.Factory`. This is useful for composing call adapters to incrementally build up behavior. * New: `requestConverter()` and `responseConverter()` methods on `Retrofit` allow querying a `Converter` for a given type. * New: `onResponse` method in `Callback` now receives the `Retrofit` instance. Combined with the `responseConverter()` method on `Retrofit`, this provides a way of deserializing an error body on `Response`. See the `DeserializeErrorBody` sample for an example. * New: The `MoshiConverterFactory` has been updated for its v1.0.0. * Fix: Using `ResponseBody` for the response type or `RequestBody` for a parameter type is now correctly identified. Previously these types would erroneously be passed to the supplied converter. * Fix: The encoding of `@Path` values has been corrected to conform to OkHttp's `HttpUrl`. * Fix: Use form-data content disposition subtype for `@Multipart`. * Fix: `Observable` and `Single`-based execution of requests now behave synchronously (and thus requires `subscribeOn()` for running in the background). * Fix: Correct `GsonConverterFactory` to honor the configuration of the `Gson` instances (such as not serializing null values, the default). ## [2.0.0-beta1] - 2015-08-27 * New: `Call` encapsulates a single request/response HTTP call. A call can by run synchronously via `execute()` or asynchronously via `enqueue()` and can be canceled with `cancel()`. * New: `Response` is now parameterized and includes the deserialized body object. * New: `@Url` parameter annotation allows passing a complete URL for an endpoint. * New: OkHttp is now required as a dependency. Types like `TypedInput` and `TypedOutput` (and its implementations), `Request`, and `Header` have been replaced with OkHttp types like `RequestBody`, `ResponseBody`, and `Headers`. * New: `CallAdapter` (and `Factory`) provides extension point for supporting multiple execution mechanisms. An RxJava implementation is provided by a sibling module. * New: `Converter` (and `Factory`) provides extension point for supporting multiple serialization mechanisms. Gson, Jackson, Moshi, Protobuf, Wire, and SimpleXml implementations are provided by sibling modules. * Fix: A lot of things. * Hello Droidcon NYC 2015! ## [1.9.0] - 2015-01-07 * Update to OkHttp 2.x's native API. If you are using OkHttp you must use version 2.0 or newer (the latest is 2.2 at time of writing) and you no longer need to use the `okhttp-urlconnection` shim. * New: Allow disabling Simple XML Framework's strict parsing. * New: `@Header` now accepts a `List` or array for a type. * New: `@Field` and `@FieldMap` now have options for enabling or disabling URL encoding of names and values. * Fix: Remove query parameters from thread name when running background requests for asynchronous use. ## [1.8.0] - 2014-11-18 * Update to RxJava 1.0. This comes with the project's 'groupId' change from `com.netflix.rxjava` to `io.reactivex` which is why the minor version was bumped. ## [1.7.1] - 2014-10-23 * Fix: Correctly log `null` request arguments for `HEADERS_AND_ARGS` log level. ## [1.7.0] - 2014-10-08 * New: `RetrofitError`'s `getKind()` now disambiguates the type of error represented. * New: `HEADERS_AND_ARGS` log level displays parameters passed to method invocation along with normal header list. * New: `@Part` and `@PartMap` now support specifying the `Content-Transfer-Encoding` of their respective values. * New: `@Path`, `@Query`, and `@QueryMap` now have options for enabling or disabling URL encoding on names (where appropriate) and values. * `@Header` now accepts all object types, invoking `String.valueOf` when neccesary. * Attempting to use a `@Path` replacement block (`{name}`) in a query parameter now suggested `@Query` in the exception message. * Fix: Correct NPE when `Content-Type` override is specified on requests without a body. * Fix: `WireConverter` now correctly throws `ConversionException` on incorrect MIME types for parity with `ProtoConverter`. * Fix: Include `Content-Type` on AppEngine requests. * Fix: Account for NPE on AppEngine when the response URL was not automatically populated in certain cases. * Fix: `MockRestAdapter`'s RxJava support now correctly schedules work on the HTTP executor, specifically when chaining multiple requests together. * Experimental RxJava support updated for v0.20. ## [1.6.1] - 2014-07-02 * Fix: Add any explicitly-specified 'Content-Type' header (via annotation or param) to the request even if there is no request body (e.g., DELETE). * Fix: Include trailing CRLF in multi-part uploads to work around a bug in .NET MVC 4 parsing. * Fix: Allow `null` mock exception bodies and use the success type from the declared service interface. ## [1.6.0] - 2014-06-06 * New: `@Streaming` on a `Response` type will skip buffering the body to a `byte[]` before delivering. * When using OkHttp, version 1.6.0 or newer (including 2.0.0+) is now required. * The absence of a response body and an empty body are now differentiated in the log messages. * Fix: If set, the `RequestInterceptor` is now applied at the time of `Observable` subscription rather than at the time of its creation. * Fix: `Callback` subtypes are now supported when using `MockRestAdapter`. * Fix: `RetrofitError` now contains a useful message indicating the reason for the failure. * Fix: Exceptions thrown when parsing the response type of the interface are now properly propagated. * Fix: Calling `Response#getBody` when `null` body now correctly returns instead of throwing an NPE. * Experimental RxJava support updated for v0.19. * The `Content-Type` and `Content-Length` headers are no longer automatically added to the header list on the `Request` object. This reverts erroneous behavior added in v1.5.0. Custom `Client` implementations should revert to adding these headers based on the `TypedInput` body of the `Request`. ## [1.5.1] - 2014-05-08 * New: `@PartMap` annotation accepts a `Map` of key/value pairs for multi-part. * Fix: `MockRestAdpater` uses the `ErrorHandler` from its parent `RestAdapter`. * Experimental RxJava support updated for v0.18 and is now lazily initialized. ## [1.5.0] - 2014-03-20 * New: Support for AppEngine's [URL Fetch](https://developers.google.com/appengine/docs/java/urlfetch/) HTTP client. * New: Multipart requests of unknown length are now supported. * New: HTTP `Content-Type` can be overridden with a method-level or paramter header annotation. * New: Exceptions from malformed interface methods now include detailed information. * Fix: Support empty HTTP response status reason. * If an `ErrorHandler` is supplied it will be invoked for `Callback` and `Observable` methods. * HTTP `PATCH` method using `HttpUrlConnection` is no longer supported. Add the [OkHttp](https://square.github.io/okhttp) jar to your project if you need this behavior. * Custom `Client` implementations should no longer set `Content-Type` or `Content-Length` headers based on the `TypedInput` body of the `Request`. These headers will now be added automatically as part of the standard `Request` header list. ## [1.4.1] - 2014-02-01 * Fix: `@QueryMap`, `@EncodedFieldMap`, and `@FieldMap` now correctly detect `Map`-based parameter types. ## [1.4.0] - 2014-01-31 * New: `@Query` and `@EncodedQuery` now accept `List` or arrays for multiple values. * New: `@QueryMap` and `@EncodedQueryMap` accept a `Map` of key/value pairs for query parameters. * New: `@Field` now accepts `List` or arrays for multiple values. * New: `@FieldMap` accepts a `Map` of name/value pairs for form URL-encoded request bodies. * New: `Endpoint` replaces `Server` as the representation of the remote API root. The `Endpoints` utility class contains factories methods for creating instances. `Server` and `ChangeableServer` are now deprecated. * `SimpleXmlConverter` and `JacksonConverter` now have a default constructor. * `Response` now includes the URL. * Fix: Hide references to optional classes to prevent over-eager class verifiers from complaining (e.g., Dalvik). * Fix: Properly detect and reject interfaces which extend from other interfaces. ## [1.3.0] - 2013-11-25 * New: Converter module for SimpleXML. * New: Mock module which allows simulating real network behavior for local service interface implementations. See 'mock-github-client' example for a demo. * New: RxJava `Observable` support! Declare a return type of `Observable` on your service interfaces to automatically get an observable for that request. (Experimental API) * Fix: Use `ObjectMapper`'s type factory when deserializing (Jackson converter). * Multipart POST requests now stream their individual part bodies. * Log chunking to 4000 characters now only happens on the Android platform. ## [1.2.2] - 2013-09-12 * Fix: Respect connection and read timeouts on supplied `OkHttpClient` instances. * Fix: Ensure connection is closed on non-200 responses. ## [1.2.1] - 2013-08-30 * New: Converter for [Wire protocol buffers](https://github.com/square/wire)! ## [1.2.0] - 2013-08-23 * New: Additional first-party converters for Jackson and Protocol Buffers! These are provided as separate modules that you can include and pass to `RestAdapter.Builder`'s `setConverter`. * New: `@EncodedPath` and `@EncodedQuery` annotations allow provided path and query params that are already URL-encoded. * New: `@PATCH` HTTP method annotation. * Fix: Properly support custom HTTP method annotations in `UrlConnectionClient`. * Fix: Apply `RequestInterceptor` during method invocation rather than at request execution time. * Change `setDebug` to `setLogLevel` on `RestAdapter` and `RestAdapter.Builder` and provide two levels of logging via `LogLevel`. * Query parameters can now be added in a request interceptor. ## [1.1.1] - 2013-06-25 * Fix: Ensure `@Headers`-defined headers are correctly added to requests. * Fix: Supply reasonable connection and read timeouts for default clients. * Fix: Allow passing `null` for a `@Part`-annotated argument to remove it from the multipart request body. ## [1.1.0] - 2013-06-20 * Introduce `RequestInterceptor` to replace `RequestHeaders`. An interceptor provided to the `RestAdapter.Builder` will be called for every request and allow setting both headers and additional path parameter replacements. * Add `ErrorHandler` for customizing the exceptions which are thrown when synchronous methods return non-200 error codes. * Properly parse responses which erroneously omit the "Content-Type" header. ## [1.0.2] - 2013-05-23 * Allow uppercase letters in path replacement identifiers. * Fix: Static query parameters in the URL are now correctly appended with a separating '?'. * Fix: Explicitly allow or forbid `null` as a value for method parameters. * `@Path` - Forbidden * `@Query` - Allowed * `@Field` - Allowed * `@Part` - Forbidden * `@Body` - Forbidden * `@Header` - Allowed ## [1.0.1] - 2013-05-13 * Fix: Correct bad regex behavior on Android. ## [1.0.0] - 2013-05-13 Initial release. [2.11.0]: https://github.com/square/retrofit/releases/tag/2.11.0 [2.10.0]: https://github.com/square/retrofit/releases/tag/2.10.0 [2.9.0]: https://github.com/square/retrofit/releases/tag/2.9.0 [2.8.2]: https://github.com/square/retrofit/releases/tag/2.8.2 [2.8.1]: https://github.com/square/retrofit/releases/tag/parent-2.8.1 [2.8.0]: https://github.com/square/retrofit/releases/tag/parent-2.8.0 [2.7.2]: https://github.com/square/retrofit/releases/tag/parent-2.7.2 [2.7.1]: https://github.com/square/retrofit/releases/tag/parent-2.7.1 [2.7.0]: https://github.com/square/retrofit/releases/tag/parent-2.7.0 [2.6.4]: https://github.com/square/retrofit/releases/tag/parent-2.6.4 [2.6.3]: https://github.com/square/retrofit/releases/tag/parent-2.6.3 [2.6.2]: https://github.com/square/retrofit/releases/tag/parent-2.6.2 [2.6.1]: https://github.com/square/retrofit/releases/tag/parent-2.6.1 [2.6.0]: https://github.com/square/retrofit/releases/tag/parent-2.6.0 [2.5.0]: https://github.com/square/retrofit/releases/tag/parent-2.5.0 [2.4.0]: https://github.com/square/retrofit/releases/tag/parent-2.4.0 [2.3.0]: https://github.com/square/retrofit/releases/tag/parent-2.3.0 [2.2.0]: https://github.com/square/retrofit/releases/tag/parent-2.2.0 [2.1.0]: https://github.com/square/retrofit/releases/tag/parent-2.1.0 [2.0.2]: https://github.com/square/retrofit/releases/tag/parent-2.0.2 [2.0.1]: https://github.com/square/retrofit/releases/tag/parent-2.0.1 [2.0.0]: https://github.com/square/retrofit/releases/tag/parent-2.0.0 [2.0.0-beta4]: https://github.com/square/retrofit/releases/tag/parent-2.0.0-beta4 [2.0.0-beta3]: https://github.com/square/retrofit/releases/tag/parent-2.0.0-beta3 [2.0.0-beta2]: https://github.com/square/retrofit/releases/tag/parent-2.0.0-beta2 [2.0.0-beta1]: https://github.com/square/retrofit/releases/tag/parent-2.0.0-beta1 [1.9.0]: https://github.com/square/retrofit/releases/tag/parent-1.9.0 [1.8.0]: https://github.com/square/retrofit/releases/tag/parent-1.8.0 [1.7.1]: https://github.com/square/retrofit/releases/tag/parent-1.7.1 [1.7.0]: https://github.com/square/retrofit/releases/tag/parent-1.7.0 [1.6.1]: https://github.com/square/retrofit/releases/tag/parent-1.6.1 [1.6.0]: https://github.com/square/retrofit/releases/tag/parent-1.6.0 [1.5.1]: https://github.com/square/retrofit/releases/tag/parent-1.5.1 [1.5.0]: https://github.com/square/retrofit/releases/tag/parent-1.5.0 [1.4.1]: https://github.com/square/retrofit/releases/tag/parent-1.4.1 [1.4.0]: https://github.com/square/retrofit/releases/tag/parent-1.4.0 [1.3.0]: https://github.com/square/retrofit/releases/tag/parent-1.3.0 [1.2.2]: https://github.com/square/retrofit/releases/tag/parent-1.2.2 [1.2.1]: https://github.com/square/retrofit/releases/tag/parent-1.2.1 [1.2.0]: https://github.com/square/retrofit/releases/tag/parent-1.2.0 [1.1.1]: https://github.com/square/retrofit/releases/tag/parent-1.1.1 [1.1.0]: https://github.com/square/retrofit/releases/tag/parent-1.1.0 [1.0.2]: https://github.com/square/retrofit/releases/tag/parent-1.0.2 [1.0.1]: https://github.com/square/retrofit/releases/tag/parent-1.0.1 [1.0.0]: https://github.com/square/retrofit/releases/tag/parent-1.0.0 [maven_provided]: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html ================================================ FILE: LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ Retrofit ======== A type-safe HTTP client for Android and Java. For more information please see [the website][1]. Download -------- Download [the latest JAR][2] or grab from Maven central at the coordinates `com.squareup.retrofit2:retrofit:3.0.0`. Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. Retrofit requires at minimum Java 8+ or Android API 21+. R8 / ProGuard ------------- If you are using R8 the shrinking and obfuscation rules are included automatically. ProGuard users must manually add the options from [retrofit2.pro][proguard file]. You might also need [rules for OkHttp][okhttp proguard] which is a dependency of this library. License ======= Copyright 2013 Square, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. [1]: https://square.github.io/retrofit/ [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=retrofit&v=LATEST [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ [proguard file]: https://github.com/square/retrofit/blob/master/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro [okhttp proguard]: https://square.github.io/okhttp/r8_proguard/ [okio proguard]: https://square.github.io/okio/#r8-proguard ================================================ FILE: RELEASING.md ================================================ # Releasing 1. Update the `VERSION_NAME` in `gradle.properties` to the release version. 2. Update the `CHANGELOG.md`: 1. Change the `Unreleased` header to the release version. 2. Add a link URL to ensure the header link works. 3. Add a new `Unreleased` section to the top. 3. Update the `README.md` so the "Download" section reflects the new release version. 4. Commit ``` $ git commit -am "Prepare version X.Y.Z" ``` 5. Tag ``` $ git tag -am "Version X.Y.Z" X.Y.Z ``` 6. Update the `VERSION_NAME` in `gradle.properties` to the next "SNAPSHOT" version. 7. Commit ``` $ git commit -am "Prepare next development version" ``` 8. Push! ``` $ git push && git push --tags ``` This will trigger a GitHub Action workflow which will create a GitHub release and upload the release artifacts to Maven Central. ================================================ FILE: build.gradle ================================================ import net.ltgt.gradle.errorprone.CheckSeverity buildscript { dependencies { classpath libs.androidPlugin classpath libs.kotlin.gradlePlugin classpath libs.kotlin.serializationPlugin classpath libs.dokkaPlugin classpath libs.gradleMavenPublishPlugin classpath libs.spotlessPlugin classpath libs.errorpronePlugin classpath libs.animalSnifferPlugin classpath libs.protobufPlugin } repositories { mavenCentral() google() gradlePluginPortal() } } subprojects { tasks.withType(JavaCompile).configureEach { task -> task.options.encoding = 'UTF-8' } plugins.withType(JavaBasePlugin).configureEach { java.toolchain { languageVersion.set(JavaLanguageVersion.of(8)) } } tasks.withType(Test).configureEach { testLogging { if (System.getenv("CI") == "true") { events = ["failed", "skipped", "passed"] } exceptionFormat "full" } } apply plugin: 'net.ltgt.errorprone' dependencies { errorproneJavac libs.errorproneJavac errorprone libs.errorproneCore } tasks.withType(JavaCompile).configureEach { task -> task.options.errorprone { excludedPaths = '.*/build/generated/sources/proto/.*' check('MissingFail', CheckSeverity.ERROR) check('MissingOverride', CheckSeverity.ERROR) check('UnusedException', CheckSeverity.ERROR) check('UnusedMethod', CheckSeverity.ERROR) check('UnusedNestedClass', CheckSeverity.ERROR) check('UnusedVariable', CheckSeverity.ERROR) check('WildcardImport', CheckSeverity.ERROR) } } plugins.withId('java-library') { project.apply plugin: 'ru.vyarus.animalsniffer' animalsniffer { sourceSets = [sourceSets.main] // Only check main sources, ignore test code. } dependencies { signature 'org.codehaus.mojo.signature:java18:1.0@signature' if (project.path != ':retrofit-converters:java8' && project.path != ':retrofit-converters:jaxb' && project.path != ':retrofit-converters:jaxb3' && project.path != ':retrofit-adapters:java8') { signature 'net.sf.androidscents.signature:android-api-level-21:5.0.1_r2@signature' } } plugins.apply('com.diffplug.spotless') spotless { java { googleJavaFormat(libs.googleJavaFormat.get().version) .formatJavadoc(false) removeUnusedImports() target 'src/*/java*/**/*.java' } kotlin { ktfmt(libs.ktfmt.get().version).googleStyle() target 'src/**/*.kt' } } } } tasks.register('clean', Delete) { delete = layout.buildDirectory } tasks.register('copyWebsiteDocs', Copy) { description = 'Copies generated documentation to the website' group = JavaBasePlugin.DOCUMENTATION_GROUP into layout.projectDirectory.dir('website/public/3.x') subprojects { subproject -> if (subproject.name == 'retrofit-bom') return if (!subproject.plugins.hasPlugin('com.vanniktech.maven.publish')) return into(subproject.POM_ARTIFACT_ID) { if (subproject.plugins.hasPlugin('org.jetbrains.dokka')) { from subproject.tasks.named('dokkaGeneratePublicationHtml').flatMap { it.outputDirectory } } else { from subproject.tasks.named('javadoc').map { it.destinationDir } } } } } ================================================ FILE: gradle/libs.versions.toml ================================================ # Copyright (C) 2021 Square, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://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. [versions] kotlin = "2.3.10" okhttp = "5.3.2" protobuf = "3.25.8" robovm = "2.3.14" kotlinx-serialization = "1.10.0" autoService = "1.1.1" incap = "1.0.0" jackson = "2.21.1" [libraries] androidPlugin = "com.android.tools.build:gradle:9.1.0" robovmPlugin = { module = "com.mobidevelop.robovm:robovm-gradle-plugin", version.ref = "robovm" } dokkaPlugin = "org.jetbrains.dokka:dokka-gradle-plugin:2.1.0" gradleMavenPublishPlugin = "com.vanniktech:gradle-maven-publish-plugin:0.36.0" spotlessPlugin = "com.diffplug.spotless:spotless-plugin-gradle:8.3.0" kotlin-stdLib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } kotlin-serializationPlugin = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } errorpronePlugin = "net.ltgt.gradle:gradle-errorprone-plugin:4.4.0" errorproneCore = { module = "com.google.errorprone:error_prone_core", version = "2.10.0" } errorproneJavac = { module = "com.google.errorprone:javac", version = "9+181-r4173-1" } animalSnifferPlugin = "ru.vyarus:gradle-animalsniffer-plugin:2.0.1" animalSnifferAnnotations = { module = "org.codehaus.mojo:animal-sniffer-annotations", version = "1.27" } protobufPlugin = "com.google.protobuf:protobuf-gradle-plugin:0.9.6" protobuf = { module = "com.google.protobuf:protobuf-java", version.ref = "protobuf" } protoc = { module = "com.google.protobuf:protoc", version.ref = "protobuf" } kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.10.2" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinx-serialization" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } kotlinx-serialization-proto = { module = "org.jetbrains.kotlinx:kotlinx-serialization-protobuf", version.ref = "kotlinx-serialization" } okhttp-client = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } okhttp-loggingInterceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" } okhttp-mockwebserver = { module = "com.squareup.okhttp3:mockwebserver", version.ref = "okhttp" } junit = { module = "junit:junit", version = "4.13.2" } truth = "com.google.truth:truth:1.4.5" guava = { module = "com.google.guava:guava", version = "33.5.0-jre" } android = { module = "com.google.android:android", version = "4.1.1.4" } findBugsAnnotations = { module = "com.google.code.findbugs:jsr305", version = "3.0.2" } androidxTestRunner = { module = "androidx.test:runner", version = "1.4.0" } rxjava = { module = "io.reactivex:rxjava", version = "1.3.8" } rxjava2 = { module = "io.reactivex.rxjava2:rxjava", version = "2.2.21" } rxjava3 = { module = "io.reactivex.rxjava3:rxjava", version = "3.1.12" } reactiveStreams = { module = "org.reactivestreams:reactive-streams", version = "1.0.4" } scalaLibrary = { module = "org.scala-lang:scala-library", version = "2.13.18" } gson = { module = "com.google.code.gson:gson", version = "2.13.2" } jacksonDatabind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } jacksonDataformatCbor = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-cbor", version.ref = "jackson" } jaxbApi = { module = "javax.xml.bind:jaxb-api", version = "2.3.1" } jaxbImpl = { module = "org.glassfish.jaxb:jaxb-runtime", version = "4.0.7" } jaxb3Api = { module = "jakarta.xml.bind:jakarta.xml.bind-api", version = "3.0.1" } jaxb3Impl = { module = "com.sun.xml.bind:jaxb-impl", version = "3.0.2" } moshi = { module = "com.squareup.moshi:moshi", version = "1.15.2" } simpleXml = { module = "org.simpleframework:simple-xml", version = "2.7.1" } wireRuntime = { module = "com.squareup.wire:wire-runtime", version = "5.5.1" } jsoup = { module = "org.jsoup:jsoup", version = "1.22.1" } robovm = { module = "com.mobidevelop.robovm:robovm-rt", version.ref = "robovm" } googleJavaFormat = "com.google.googlejavaformat:google-java-format:1.35.0" ktfmt = "com.facebook:ktfmt:0.61" compileTesting = "com.google.testing.compile:compile-testing:0.23.0" testParameterInjector = "com.google.testparameterinjector:test-parameter-injector:1.21" ================================================ FILE: gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists ================================================ FILE: gradle.properties ================================================ GROUP=com.squareup.retrofit2 VERSION_NAME=3.1.0-SNAPSHOT POM_URL=https://github.com/square/retrofit POM_SCM_URL=https://github.com/square/retrofit/ POM_SCM_CONNECTION=scm:git:git://github.com/square/retrofit.git POM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/square/retrofit.git POM_LICENCE_NAME=The Apache Software License, Version 2.0 POM_LICENCE_URL=https://www.apache.org/licenses/LICENSE-2.0.txt POM_LICENCE_DIST=repo POM_DEVELOPER_ID=square POM_DEVELOPER_NAME=Square, Inc. # Publishing SHA 256 and 512 hashes of maven-metadata is not supported by Sonatype and Nexus. # See https://github.com/gradle/gradle/issues/11308 and https://issues.sonatype.org/browse/NEXUS-21802 systemProp.org.gradle.internal.publish.checksums.insecure=true android.useAndroidX=true mavenCentralPublishing=true mavenCentralAutomaticPublishing=true signAllPublications=true ================================================ FILE: gradlew ================================================ #!/bin/sh # # Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://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. # # SPDX-License-Identifier: Apache-2.0 # ############################################################################## # # Gradle start up script for POSIX generated by Gradle. # # Important for running: # # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is # noncompliant, but you have some other compliant shell such as ksh or # bash, then to run this script, type that shell name before the whole # command line, like: # # ksh Gradle # # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», # «${var#prefix}», «${var%suffix}», and «$( cmd )»; # * compound commands having a testable exit status, especially «case»; # * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # # (2) This script targets any POSIX shell, so it avoids extensions provided # by Bash, Ksh, etc; in particular arrays are avoided. # # The "traditional" practice of packing multiple parameters into a # space-separated string is a well documented source of bugs and security # problems, so this is (mostly) avoided, by progressively accumulating # options in "$@", and eventually passing that to Java. # # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; # see the in-line comments for details. # # There are tweaks for specific operating systems such as AIX, CygWin, # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. # ############################################################################## # Attempt to set APP_HOME # Resolve links: $0 may be a link app_path=$0 # Need this for daisy-chained symlinks. while APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path [ -h "$app_path" ] do ls=$( ls -ld "$app_path" ) link=${ls#*' -> '} case $link in #( /*) app_path=$link ;; #( *) app_path=$APP_HOME$link ;; esac done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s ' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum warn () { echo "$*" } >&2 die () { echo echo "$*" echo exit 1 } >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false case "$( uname )" in #( CYGWIN* ) cygwin=true ;; #( Darwin* ) darwin=true ;; #( MSYS* | MINGW* ) msys=true ;; #( NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD=$JAVA_HOME/jre/sh/java else JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD=java if ! command -v java >/dev/null 2>&1 then die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi # Collect all arguments for the java command, stacking in reverse order: # * args from the command line # * the main class name # * -classpath # * -D...appname settings # * --module-path (only if needed) # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) # Now convert the arguments - kludge to limit ourselves to /bin/sh for arg do if case $arg in #( -*) false ;; # don't mess with options #( /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath [ -e "$t" ] ;; #( *) false ;; esac then arg=$( cygpath --path --ignore --mixed "$arg" ) fi # Roll the args list around exactly as many times as the number of # args, so each arg winds up back in the position where it started, but # possibly modified. # # NB: a `for` loop captures its iteration list before it begins, so # changing the positional parameters here affects neither the number of # iterations, nor the values presented in `arg`. shift # remove old arg set -- "$@" "$arg" # push replacement arg done fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ org.gradle.wrapper.GradleWrapperMain \ "$@" # Stop when "xargs" is not available. if ! command -v xargs >/dev/null 2>&1 then die "xargs is not available" fi # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. # # In Bash we could simply go: # # readarray ARGS < <( xargs -n1 <<<"$var" ) && # set -- "${ARGS[@]}" "$@" # # but POSIX shell has neither arrays nor command substitution, so instead we # post-process each arg (as a line of input to sed) to backslash-escape any # character that might be a shell metacharacter, then use eval to reverse # that process (while maintaining the separation between arguments), and wrap # the whole thing up as a single "set" statement. # # This will of course break if any of these variables contains a newline or # an unmatched quote. # eval "set -- $( printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | xargs -n1 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | tr '\n' ' ' )" '"$@"' exec "$JAVACMD" "$@" ================================================ FILE: gradlew.bat ================================================ @rem @rem Copyright 2015 the original author or authors. @rem @rem Licensed under the Apache License, Version 2.0 (the "License"); @rem you may not use this file except in compliance with the License. @rem You may obtain a copy of the License at @rem @rem https://www.apache.org/licenses/LICENSE-2.0 @rem @rem Unless required by applicable law or agreed to in writing, software @rem distributed under the License is distributed on an "AS IS" BASIS, @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem @rem SPDX-License-Identifier: Apache-2.0 @rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Resolve any "." and ".." in APP_HOME to make it shorter. for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute echo. 1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute echo. 1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 goto fail :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! set EXIT_CODE=%ERRORLEVEL% if %EXIT_CODE% equ 0 set EXIT_CODE=1 if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: retrofit/android-test/build.gradle ================================================ apply plugin: 'com.android.library' android { compileSdk = 36 namespace 'retrofit2.android' defaultConfig { minSdk = 21 // We need to disable D8 desugaring of default methods for the default method tests to work // correctly. This works in Android Studio because it sets the minSdk automatically based on // your deployment target. This environment variable is set by the GitHub Action. def emulatorApiLevel = System.getenv("API_LEVEL") if (emulatorApiLevel != null) { try { minSdk = Integer.parseInt(emulatorApiLevel) } catch (NumberFormatException ignored) { } } testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } signingConfigs { debug { storeFile file('debug.keystore') storePassword 'retrofit' keyAlias 'retrofit' keyPassword 'retrofit' } } buildTypes { debug { signingConfig signingConfigs.debug } } } dependencies { androidTestImplementation projects.retrofit androidTestImplementation projects.retrofit.testHelpers androidTestImplementation libs.junit androidTestImplementation libs.truth androidTestImplementation libs.okhttp.mockwebserver androidTestImplementation libs.androidxTestRunner } ================================================ FILE: retrofit/android-test/src/androidTest/java/retrofit2/BasicCallTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.io.IOException; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Rule; import org.junit.Test; import retrofit2.http.GET; import static org.junit.Assert.assertEquals; public final class BasicCallTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Call getBody(); } @Test public void responseBody() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("1234")); Response response = example.getBody().execute(); assertEquals("1234", response.body().string()); } } ================================================ FILE: retrofit/android-test/src/androidTest/java/retrofit2/CompletableFutureAndroidTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import androidx.test.filters.SdkSuppress; import java.util.concurrent.CompletableFuture; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.ToStringConverterFactory; import retrofit2.http.GET; import static com.google.common.truth.Truth.assertThat; @SdkSuppress(minSdkVersion = 24) public final class CompletableFutureAndroidTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") CompletableFuture endpoint(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); service = retrofit.create(Service.class); } @Test public void completableFutureApi24() throws Exception { server.enqueue(new MockResponse().setBody("Hi")); CompletableFuture future = service.endpoint(); assertThat(future.get()).isEqualTo("Hi"); } } ================================================ FILE: retrofit/android-test/src/androidTest/java/retrofit2/DefaultMethodsAndroidTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import androidx.test.filters.SdkSuppress; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.ToStringConverterFactory; import retrofit2.http.GET; import retrofit2.http.Query; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; public final class DefaultMethodsAndroidTest { @Rule public final MockWebServer server = new MockWebServer(); interface Example { @GET("/") Call user(@Query("name") String name); default Call user() { return user("hey"); } } @Test @SdkSuppress(minSdkVersion = 24, maxSdkVersion = 25) public void failsOnApi24And25() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Example example = retrofit.create(Example.class); try { example.user(); fail(); } catch (UnsupportedOperationException e) { assertThat(e).hasMessageThat().isEqualTo("Calling default methods on API 24 and 25 is not supported"); } } @Test @SdkSuppress(minSdkVersion = 26) public void doesNotFailOnApi26() throws IOException, InterruptedException { server.enqueue(new MockResponse()); server.enqueue(new MockResponse()); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Example example = retrofit.create(Example.class); example.user().execute(); assertThat(server.takeRequest().getRequestUrl().queryParameter("name")).isEqualTo("hey"); example.user("hi").execute(); assertThat(server.takeRequest().getRequestUrl().queryParameter("name")).isEqualTo("hi"); } } ================================================ FILE: retrofit/android-test/src/androidTest/java/retrofit2/OptionalConverterFactoryAndroidTest.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import androidx.test.filters.SdkSuppress; import java.io.IOException; import java.util.Optional; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.ObjectInstanceConverterFactory; import retrofit2.http.GET; import static com.google.common.truth.Truth.assertThat; @SdkSuppress(minSdkVersion = 24) public final class OptionalConverterFactoryAndroidTest { interface Service { @GET("/") Call> optional(); @GET("/") Call object(); } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ObjectInstanceConverterFactory()) .build(); service = retrofit.create(Service.class); } @Test public void optionalApi24() throws IOException { server.enqueue(new MockResponse()); Optional optional = service.optional().execute().body(); assertThat(optional.get()).isSameInstanceAs(ObjectInstanceConverterFactory.VALUE); } @Test public void onlyMatchesOptional() throws IOException { server.enqueue(new MockResponse()); Object body = service.object().execute().body(); assertThat(body).isSameInstanceAs(ObjectInstanceConverterFactory.VALUE); } } ================================================ FILE: retrofit/android-test/src/androidTest/java/retrofit2/UriAndroidTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import android.net.Uri; import java.io.IOException; import okhttp3.HttpUrl; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.http.GET; import retrofit2.http.Url; import static com.google.common.truth.Truth.assertThat; public final class UriAndroidTest { @Rule public final MockWebServer server1 = new MockWebServer(); @Rule public final MockWebServer server2 = new MockWebServer(); interface Service { @GET Call method(@Url Uri url); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server1.url("/")) .build(); service = retrofit.create(Service.class); } @Test public void getWithAndroidUriUrl() throws IOException, InterruptedException { server1.enqueue(new MockResponse().setBody("Hi")); service.method(Uri.parse("foo/bar/")).execute(); assertThat(server1.takeRequest().getRequestUrl()).isEqualTo(server1.url("foo/bar/")); } @Test public void getWithAndroidUriUrlAbsolute() throws IOException, InterruptedException { server2.enqueue(new MockResponse().setBody("Hi")); HttpUrl url = server2.url("/"); service.method(Uri.parse(url.toString())).execute(); assertThat(server2.takeRequest().getRequestUrl()).isEqualTo(url); } } ================================================ FILE: retrofit/android-test/src/main/AndroidManifest.xml ================================================ ================================================ FILE: retrofit/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'com.vanniktech.maven.publish' def addMultiReleaseSourceSet(int version) { def sourceSet = sourceSets.create("java$version") sourceSet.java.srcDir("src/main/java$version") // Propagate dependencies to be visible to this version's source set. configurations.getByName("java${version}Implementation").extendsFrom(configurations.getByName('implementation')) configurations.getByName("java${version}Api").extendsFrom(configurations.getByName('api')) configurations.getByName("java${version}CompileOnly").extendsFrom(configurations.getByName('compileOnly')) // Allow types in the main source set to be visible to this version's source set. dependencies.add("java${version}Implementation", sourceSets.getByName("main").output) tasks.named("compileJava${version}Java", JavaCompile) { javaCompiler = javaToolchains.compilerFor { languageVersion = JavaLanguageVersion.of(version) vendor = JvmVendorSpec.AZUL } } tasks.named('jar', Jar) { from(sourceSet.output) { into("META-INF/versions/$version") } } } addMultiReleaseSourceSet(14) addMultiReleaseSourceSet(16) dependencies { api libs.okhttp.client compileOnly libs.android compileOnly libs.kotlinx.coroutines compileOnly libs.animalSnifferAnnotations compileOnly libs.findBugsAnnotations } javadoc { exclude('retrofit2/internal/**') } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2' attributes 'Multi-Release': 'true' } } ================================================ FILE: retrofit/gradle.properties ================================================ POM_ARTIFACT_ID=retrofit POM_NAME=Retrofit POM_DESCRIPTION=A type-safe HTTP client for Android and Java. ================================================ FILE: retrofit/java-test/README.md ================================================ # Retrofit Java Tests These are in a separate module for two reasons: - It ensures optional dependencies (Kotlin stuff) are completely absent. - It uses the multi-release jar on the classpath rather than only the classes folder. ================================================ FILE: retrofit/java-test/build.gradle ================================================ apply plugin: 'java-library' dependencies { testImplementation projects.retrofit testImplementation projects.retrofit.testHelpers testImplementation libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.guava testImplementation libs.okhttp.mockwebserver } tasks.withType(JavaCompile).configureEach { options.compilerArgs << '-parameters' } // Create a test task for each supported JDK. (8..24).each { majorVersion -> def jdkTest = tasks.register("testJdk$majorVersion", Test) { javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(majorVersion) vendor = JvmVendorSpec.AZUL } description = "Runs the test suite on JDK $majorVersion" group = LifecycleBasePlugin.VERIFICATION_GROUP // Wire directly to the test source set outputs for proper task dependencies. testClassesDirs = sourceSets.test.output.classesDirs classpath = sourceSets.test.runtimeClasspath } tasks.named("check").configure { dependsOn(jdkTest) } } // We don't need the built-in task which uses Gradle's JVM given the above variants. tasks.getByName('test').enabled = false ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/AnnotationArraySubject.java ================================================ package retrofit2; import static com.google.common.truth.Fact.simpleFact; import static com.google.common.truth.Truth.assertAbout; import com.google.common.truth.FailureMetadata; import com.google.common.truth.Subject; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.List; public final class AnnotationArraySubject extends Subject { public static Factory annotationArrays() { return AnnotationArraySubject::new; } public static AnnotationArraySubject assertThat(Annotation[] actual) { return assertAbout(annotationArrays()).that(actual); } private final List actual; private AnnotationArraySubject(FailureMetadata metadata, Annotation[] actual) { super(metadata, actual); this.actual = new ArrayList<>(actual.length); Collections.addAll(this.actual, actual); } public void hasAtLeastOneElementOfType(Class cls) { for (Annotation annotation : actual) { if (cls.isAssignableFrom(annotation.annotationType())) { return; } } failWithActual(simpleFact("No annotations of instance " + cls)); } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/CallAdapterTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import static retrofit2.CallAdapter.Factory.getParameterUpperBound; import static retrofit2.CallAdapter.Factory.getRawType; import com.google.common.reflect.TypeToken; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; import org.junit.Test; public final class CallAdapterTest { @Test public void parameterizedTypeInvalidIndex() { ParameterizedType listOfString = (ParameterizedType) new TypeToken>() {}.getType(); try { getParameterUpperBound(-1, listOfString); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Index -1 not in range [0,1) for java.util.List"); } try { getParameterUpperBound(1, listOfString); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Index 1 not in range [0,1) for java.util.List"); } } @Test public void parameterizedTypes() { ParameterizedType one = (ParameterizedType) new TypeToken>() {}.getType(); assertThat(getParameterUpperBound(0, one)).isSameInstanceAs(String.class); ParameterizedType two = (ParameterizedType) new TypeToken>() {}.getType(); assertThat(getParameterUpperBound(0, two)).isSameInstanceAs(String.class); assertThat(getParameterUpperBound(1, two)).isSameInstanceAs(String.class); ParameterizedType wild = (ParameterizedType) new TypeToken>() {}.getType(); assertThat(getParameterUpperBound(0, wild)).isSameInstanceAs(CharSequence.class); } @Test public void rawTypeThrowsOnNull() { try { getRawType(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("type == null"); } } @Test public void rawTypes() throws NoSuchMethodException { assertThat(getRawType(String.class)).isSameInstanceAs(String.class); Type listOfString = new TypeToken>() {}.getType(); assertThat(getRawType(listOfString)).isSameInstanceAs(List.class); Type stringArray = new TypeToken() {}.getType(); assertThat(getRawType(stringArray)).isSameInstanceAs(String[].class); Type wild = ((ParameterizedType) new TypeToken>() {}.getType()) .getActualTypeArguments()[0]; assertThat(getRawType(wild)).isSameInstanceAs(CharSequence.class); Type wildParam = ((ParameterizedType) new TypeToken>>() {}.getType()) .getActualTypeArguments()[0]; assertThat(getRawType(wildParam)).isSameInstanceAs(List.class); Type typeVar = A.class.getDeclaredMethod("method").getGenericReturnType(); assertThat(getRawType(typeVar)).isSameInstanceAs(Object.class); } @SuppressWarnings("unused") // Used reflectively. static class A { T method() { return null; } } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/CallTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_DURING_RESPONSE_BODY; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static retrofit2.TestingUtils.repeat; import java.io.IOException; import java.io.InterruptedIOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import okhttp3.OkHttpClient; import okhttp3.RequestBody; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.SocketPolicy; import okio.Buffer; import okio.BufferedSource; import okio.ForwardingSource; import okio.Okio; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.ToStringConverterFactory; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.Path; import retrofit2.http.Streaming; public final class CallTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Call getString(); @GET("/") Call getBody(); @GET("/") @Streaming Call getStreamingBody(); @POST("/") Call postString(@Body String body); @POST("/{a}") Call postRequestBody(@Path("a") Object a); } @Test public void http200Sync() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); Response response = example.getString().execute(); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isEqualTo("Hi"); } @Test public void http200Async() throws InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); final AtomicReference> responseRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); example .getString() .enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { responseRef.set(response); latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); } }); assertTrue(latch.await(10, SECONDS)); Response response = responseRef.get(); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isEqualTo("Hi"); } @Test public void http404Sync() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setResponseCode(404).setBody("Hi")); Response response = example.getString().execute(); assertThat(response.isSuccessful()).isFalse(); assertThat(response.code()).isEqualTo(404); assertThat(response.errorBody().string()).isEqualTo("Hi"); } @Test public void http404Async() throws InterruptedException, IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setResponseCode(404).setBody("Hi")); final AtomicReference> responseRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); example .getString() .enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { responseRef.set(response); latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); } }); assertTrue(latch.await(10, SECONDS)); Response response = responseRef.get(); assertThat(response.isSuccessful()).isFalse(); assertThat(response.code()).isEqualTo(404); assertThat(response.errorBody().string()).isEqualTo("Hi"); } @Test public void transportProblemSync() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AT_START)); Call call = example.getString(); try { call.execute(); fail(); } catch (IOException ignored) { } } @Test public void transportProblemAsync() throws InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AT_START)); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); example .getString() .enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); latch.countDown(); } }); assertTrue(latch.await(10, SECONDS)); Throwable failure = failureRef.get(); assertThat(failure).isInstanceOf(IOException.class); } @Test public void conversionProblemOutgoingSync() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new ToStringConverterFactory() { @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return value -> { throw new UnsupportedOperationException("I am broken!"); }; } }) .build(); Service example = retrofit.create(Service.class); Call call = example.postString("Hi"); try { call.execute(); fail(); } catch (UnsupportedOperationException e) { assertThat(e).hasMessageThat().isEqualTo("I am broken!"); } } @Test public void conversionProblemOutgoingAsync() throws InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new ToStringConverterFactory() { @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return value -> { throw new UnsupportedOperationException("I am broken!"); }; } }) .build(); Service example = retrofit.create(Service.class); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); example .postString("Hi") .enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); latch.countDown(); } }); assertTrue(latch.await(10, SECONDS)); Throwable failure = failureRef.get(); assertThat(failure).isInstanceOf(UnsupportedOperationException.class); assertThat(failure).hasMessageThat().isEqualTo("I am broken!"); } @Test public void conversionProblemIncomingSync() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new ToStringConverterFactory() { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return value -> { throw new UnsupportedOperationException("I am broken!"); }; } }) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); Call call = example.postString("Hi"); try { call.execute(); fail(); } catch (UnsupportedOperationException e) { assertThat(e).hasMessageThat().isEqualTo("I am broken!"); } } @Test public void conversionProblemIncomingMaskedByConverterIsUnwrapped() throws IOException { // MWS has no way to trigger IOExceptions during the response body so use an interceptor. OkHttpClient client = new OkHttpClient.Builder() // .addInterceptor( chain -> { okhttp3.Response response = chain.proceed(chain.request()); ResponseBody body = response.body(); BufferedSource source = Okio.buffer( new ForwardingSource(body.source()) { @Override public long read(Buffer sink, long byteCount) throws IOException { throw new IOException("cause"); } }); body = ResponseBody.create(body.contentType(), body.contentLength(), source); return response.newBuilder().body(body).build(); }) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .client(client) .addConverterFactory( new ToStringConverterFactory() { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return value -> { try { return value.string(); } catch (IOException e) { // Some serialization libraries mask transport problems in runtime // exceptions. Bad! throw new RuntimeException("wrapper", e); } }; } }) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); Call call = example.getString(); try { call.execute(); fail(); } catch (IOException e) { assertThat(e).hasMessageThat().isEqualTo("cause"); } } @Test public void conversionProblemIncomingAsync() throws InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new ToStringConverterFactory() { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return value -> { throw new UnsupportedOperationException("I am broken!"); }; } }) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); example .postString("Hi") .enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); latch.countDown(); } }); assertTrue(latch.await(10, SECONDS)); Throwable failure = failureRef.get(); assertThat(failure).isInstanceOf(UnsupportedOperationException.class); assertThat(failure).hasMessageThat().isEqualTo("I am broken!"); } @Test public void http204SkipsConverter() throws IOException { final Converter converter = value -> { throw new AssertionError(); }; Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new ToStringConverterFactory() { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return converter; } }) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setStatus("HTTP/1.1 204 Nothin")); Response response = example.getString().execute(); assertThat(response.code()).isEqualTo(204); assertThat(response.body()).isNull(); } @Test public void http205SkipsConverter() throws IOException { final Converter converter = value -> { throw new AssertionError(); }; Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new ToStringConverterFactory() { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return converter; } }) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setStatus("HTTP/1.1 205 Nothin")); Response response = example.getString().execute(); assertThat(response.code()).isEqualTo(205); assertThat(response.body()).isNull(); } @Test public void converterBodyDoesNotLeakContentInIntermediateBuffers() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new Converter.Factory() { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return value -> { String prefix = value.source().readUtf8(2); value.source().skip(20_000 - 4); String suffix = value.source().readUtf8(); return prefix + suffix; }; } }) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody(repeat('a', 10_000) + repeat('b', 10_000))); Response response = example.getString().execute(); assertThat(response.body()).isEqualTo("aabb"); } @Test public void executeCallOnce() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse()); Call call = example.getString(); call.execute(); try { call.execute(); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessageThat().isEqualTo("Already executed."); } } @Test public void successfulRequestResponseWhenMimeTypeMissing() throws Exception { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi").removeHeader("Content-Type")); Response response = example.getString().execute(); assertThat(response.body()).isEqualTo("Hi"); } @Test public void responseBody() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("1234")); Response response = example.getBody().execute(); assertThat(response.body().string()).isEqualTo("1234"); } @Test public void responseBodyBuffers() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue( new MockResponse().setBody("1234").setSocketPolicy(DISCONNECT_DURING_RESPONSE_BODY)); Call buffered = example.getBody(); // When buffering we will detect all socket problems before returning the Response. try { buffered.execute(); fail(); } catch (IOException e) { assertThat(e).hasMessageThat().isEqualTo("unexpected end of stream"); } } @Test public void responseBodyStreams() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue( new MockResponse().setBody("1234").setSocketPolicy(DISCONNECT_DURING_RESPONSE_BODY)); Response response = example.getStreamingBody().execute(); ResponseBody streamedBody = response.body(); // When streaming we only detect socket problems as the ResponseBody is read. try { streamedBody.string(); fail(); } catch (IOException e) { assertThat(e).hasMessageThat().isEqualTo("unexpected end of stream"); } } @Test public void rawResponseContentTypeAndLengthButNoSource() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi").addHeader("Content-Type", "text/greeting")); Response response = example.getString().execute(); assertThat(response.body()).isEqualTo("Hi"); ResponseBody rawBody = response.raw().body(); assertThat(rawBody.contentLength()).isEqualTo(2); assertThat(rawBody.contentType().toString()).isEqualTo("text/greeting"); try { rawBody.source(); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Cannot read raw response body of a converted body."); } } @Test public void emptyResponse() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("").addHeader("Content-Type", "text/stringy")); Response response = example.getString().execute(); assertThat(response.body()).isEqualTo(""); ResponseBody rawBody = response.raw().body(); assertThat(rawBody.contentLength()).isEqualTo(0); assertThat(rawBody.contentType().toString()).isEqualTo("text/stringy"); } @Test public void reportsExecutedSync() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); Call call = example.getString(); assertThat(call.isExecuted()).isFalse(); call.execute(); assertThat(call.isExecuted()).isTrue(); } @Test public void reportsExecutedAsync() throws InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); Call call = example.getString(); assertThat(call.isExecuted()).isFalse(); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) {} @Override public void onFailure(Call call, Throwable t) {} }); assertThat(call.isExecuted()).isTrue(); } @Test public void cancelBeforeExecute() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); Call call = service.getString(); call.cancel(); assertThat(call.isCanceled()).isTrue(); try { call.execute(); fail(); } catch (IOException e) { assertThat(e).hasMessageThat().isEqualTo("Canceled"); } } @Test public void cancelBeforeEnqueue() throws Exception { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); Call call = service.getString(); call.cancel(); assertThat(call.isCanceled()).isTrue(); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); latch.countDown(); } }); assertTrue(latch.await(10, SECONDS)); assertThat(failureRef.get()).hasMessageThat().isEqualTo("Canceled"); } @Test public void cloningExecutedRequestDoesNotCopyState() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hello")); Call call = service.getString(); assertThat(call.execute().body()).isEqualTo("Hi"); Call cloned = call.clone(); assertThat(cloned.execute().body()).isEqualTo("Hello"); } @Test public void cancelRequest() throws InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.NO_RESPONSE)); Call call = service.getString(); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); latch.countDown(); } }); call.cancel(); assertThat(call.isCanceled()).isTrue(); assertTrue(latch.await(10, SECONDS)); Throwable failure = failureRef.get(); assertThat(failure).isInstanceOf(IOException.class); assertThat(failure).hasMessageThat().isEqualTo("Canceled"); } @Test public void cancelOkHttpRequest() throws InterruptedException { OkHttpClient client = new OkHttpClient(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .client(client) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.NO_RESPONSE)); Call call = service.getString(); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); latch.countDown(); } }); // Cancel the underlying HTTP Call. Should be reflected accurately back in the Retrofit Call. client.dispatcher().cancelAll(); assertThat(call.isCanceled()).isTrue(); assertTrue(latch.await(10, SECONDS)); Throwable failure = failureRef.get(); assertThat(failure).isInstanceOf(IOException.class); assertThat(failure).hasMessageThat().isEqualTo("Canceled"); } @Test public void requestBeforeExecuteCreates() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); return "Hello"; } }; Call call = service.postRequestBody(a); call.request(); assertThat(writeCount.get()).isEqualTo(1); call.execute(); assertThat(writeCount.get()).isEqualTo(1); } @Test public void requestThrowingBeforeExecuteFailsExecute() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new RuntimeException("Broken!"); } }; Call call = service.postRequestBody(a); try { call.request(); fail(); } catch (RuntimeException e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); try { call.execute(); fail(); } catch (RuntimeException e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); } @Test public void requestThrowingNonFatalErrorBeforeExecuteFailsExecute() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new NonFatalError("Broken!"); } }; Call call = service.postRequestBody(a); try { call.request(); fail(); } catch (NonFatalError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); try { call.execute(); fail(); } catch (NonFatalError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); } @Test public void requestAfterExecuteReturnsCachedValue() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); return "Hello"; } }; Call call = service.postRequestBody(a); call.execute(); assertThat(writeCount.get()).isEqualTo(1); call.request(); assertThat(writeCount.get()).isEqualTo(1); } @Test public void requestAfterExecuteThrowingAlsoThrows() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new RuntimeException("Broken!"); } }; Call call = service.postRequestBody(a); try { call.execute(); fail(); } catch (RuntimeException e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); try { call.request(); fail(); } catch (RuntimeException e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); } @Test public void requestAfterExecuteThrowingAlsoThrowsForNonFatalErrors() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new NonFatalError("Broken!"); } }; Call call = service.postRequestBody(a); try { call.execute(); fail(); } catch (NonFatalError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); try { call.request(); fail(); } catch (NonFatalError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); } @Test public void requestBeforeEnqueueCreates() throws IOException, InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); return "Hello"; } }; Call call = service.postRequestBody(a); call.request(); assertThat(writeCount.get()).isEqualTo(1); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { assertThat(writeCount.get()).isEqualTo(1); latch.countDown(); } @Override public void onFailure(Call call, Throwable t) {} }); assertTrue(latch.await(10, SECONDS)); } @Test public void requestThrowingBeforeEnqueueFailsEnqueue() throws IOException, InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new RuntimeException("Broken!"); } }; Call call = service.postRequestBody(a); try { call.request(); fail(); } catch (RuntimeException e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) {} @Override public void onFailure(Call call, Throwable t) { // Exact instance check as opposed to isInstanceOf's subtype checking. assertThat(t.getClass()).isEqualTo(RuntimeException.class); assertThat(t).hasMessageThat().isEqualTo("Broken!"); assertThat(writeCount.get()).isEqualTo(1); latch.countDown(); } }); assertTrue(latch.await(10, SECONDS)); } @Test public void requestThrowingNonFatalErrorBeforeEnqueueFailsEnqueue() throws IOException, InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new NonFatalError("Broken!"); } }; Call call = service.postRequestBody(a); try { call.request(); fail(); } catch (NonFatalError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) {} @Override public void onFailure(Call call, Throwable t) { // Exact instance check as opposed to isInstanceOf's subtype checking. assertThat(t.getClass()).isEqualTo(NonFatalError.class); assertThat(t).hasMessageThat().isEqualTo("Broken!"); assertThat(writeCount.get()).isEqualTo(1); latch.countDown(); } }); assertTrue(latch.await(10, SECONDS)); } @Test public void requestAfterEnqueueReturnsCachedValue() throws IOException, InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); return "Hello"; } }; Call call = service.postRequestBody(a); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { assertThat(writeCount.get()).isEqualTo(1); latch.countDown(); } @Override public void onFailure(Call call, Throwable t) {} }); assertTrue(latch.await(10, SECONDS)); call.request(); assertThat(writeCount.get()).isEqualTo(1); } @Test public void requestAfterEnqueueFailingThrows() throws IOException, InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new RuntimeException("Broken!"); } }; Call call = service.postRequestBody(a); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) {} @Override public void onFailure(Call call, Throwable t) { // Exact instance check as opposed to isInstanceOf's subtype checking. assertThat(t.getClass()).isEqualTo(RuntimeException.class); assertThat(t).hasMessageThat().isEqualTo("Broken!"); assertThat(writeCount.get()).isEqualTo(1); latch.countDown(); } }); assertTrue(latch.await(10, SECONDS)); try { call.request(); fail(); } catch (RuntimeException e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); } @Test public void requestAfterEnqueueFailingThrowsForNonFatalErrors() throws IOException, InterruptedException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new NonFatalError("Broken!"); } }; Call call = service.postRequestBody(a); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) {} @Override public void onFailure(Call call, Throwable t) { // Exact instance check as opposed to isInstanceOf's subtype checking. assertThat(t.getClass()).isEqualTo(NonFatalError.class); assertThat(t).hasMessageThat().isEqualTo("Broken!"); assertThat(writeCount.get()).isEqualTo(1); latch.countDown(); } }); assertTrue(latch.await(10, SECONDS)); try { call.request(); fail(); } catch (NonFatalError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); } @Test public void fatalErrorsAreNotCaughtRequest() throws Exception { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new OutOfMemoryError("Broken!"); } }; Call call = service.postRequestBody(a); try { call.request(); fail(); } catch (OutOfMemoryError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); try { call.request(); fail(); } catch (OutOfMemoryError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(2); } @Test public void fatalErrorsAreNotCaughtEnqueue() throws Exception { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new OutOfMemoryError("Broken!"); } }; Call call = service.postRequestBody(a); try { final AtomicBoolean callsFailureSynchronously = new AtomicBoolean(); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) {} @Override public void onFailure(Call call, Throwable t) { callsFailureSynchronously.set(true); // Will not be called for fatal errors. } }); assertThat(callsFailureSynchronously.get()).isFalse(); fail(); } catch (OutOfMemoryError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); try { call.request(); fail(); } catch (OutOfMemoryError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(2); } @Test public void fatalErrorsAreNotCaughtExecute() throws Exception { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service service = retrofit.create(Service.class); server.enqueue(new MockResponse()); final AtomicInteger writeCount = new AtomicInteger(); Object a = new Object() { @Override public String toString() { writeCount.incrementAndGet(); throw new OutOfMemoryError("Broken!"); } }; Call call = service.postRequestBody(a); try { call.execute(); fail(); } catch (OutOfMemoryError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(1); try { call.request(); fail(); } catch (OutOfMemoryError e) { assertThat(e).hasMessageThat().isEqualTo("Broken!"); } assertThat(writeCount.get()).isEqualTo(2); } @Test public void timeoutExceeded() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setHeadersDelay(500, TimeUnit.MILLISECONDS)); Call call = example.getString(); call.timeout().timeout(100, TimeUnit.MILLISECONDS); try { call.execute(); fail(); } catch (InterruptedIOException expected) { } } @Test public void deadlineExceeded() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setHeadersDelay(500, TimeUnit.MILLISECONDS)); Call call = example.getString(); call.timeout().deadline(100, TimeUnit.MILLISECONDS); try { call.execute(); fail(); } catch (InterruptedIOException expected) { } } @Test public void timeoutEnabledButNotExceeded() throws IOException { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setHeadersDelay(100, TimeUnit.MILLISECONDS)); Call call = example.getString(); call.timeout().deadline(500, TimeUnit.MILLISECONDS); Response response = call.execute(); assertThat(response.isSuccessful()).isTrue(); } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/CompletableFutureCallAdapterFactoryTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.reflect.TypeToken; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import java.util.concurrent.CompletableFuture; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.ToStringConverterFactory; public final class CompletableFutureCallAdapterFactoryTest { private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; @Rule public final MockWebServer server = new MockWebServer(); private final CallAdapter.Factory factory = new CompletableFutureCallAdapterFactory(); private Retrofit retrofit; @Before public void setUp() { retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); } @Test public void responseType() { Type bodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(bodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type bodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(bodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type bodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(bodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type responseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(responseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type responseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(responseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type resultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(resultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type resultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(resultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); } @Test public void nonListenableFutureReturnsNull() { CallAdapter adapter = factory.get(String.class, NO_ANNOTATIONS, retrofit); assertThat(adapter).isNull(); } @Test public void rawTypeThrows() { Type observableType = new TypeToken() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "CompletableFuture return type must be parameterized as CompletableFuture or CompletableFuture"); } } @Test public void rawResponseTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/CompletableFutureTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import static org.junit.Assert.fail; import java.io.IOException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.ToStringConverterFactory; import retrofit2.http.GET; public final class CompletableFutureTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") CompletableFuture body(); @GET("/") CompletableFuture> response(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() throws Exception { server.enqueue(new MockResponse().setBody("Hi")); CompletableFuture future = service.body(); assertThat(future.get()).isEqualTo("Hi"); } @Test public void bodySuccess404() throws Exception { server.enqueue(new MockResponse().setResponseCode(404)); CompletableFuture future = service.body(); try { future.get(); fail(); } catch (ExecutionException e) { Throwable cause = e.getCause(); assertThat(cause).isInstanceOf(HttpException.class); assertThat(cause).hasMessageThat().isEqualTo("HTTP 404 Client Error"); } } @Test public void bodyFailure() throws Exception { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); CompletableFuture future = service.body(); try { future.get(); fail(); } catch (ExecutionException e) { assertThat(e).hasCauseThat().isInstanceOf(IOException.class); } } @Test public void responseSuccess200() throws Exception { server.enqueue(new MockResponse().setBody("Hi")); CompletableFuture> future = service.response(); Response response = future.get(); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isEqualTo("Hi"); } @Test public void responseSuccess404() throws Exception { server.enqueue(new MockResponse().setResponseCode(404).setBody("Hi")); CompletableFuture> future = service.response(); Response response = future.get(); assertThat(response.isSuccessful()).isFalse(); assertThat(response.errorBody().string()).isEqualTo("Hi"); } @Test public void responseFailure() throws Exception { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); CompletableFuture> future = service.response(); try { future.get(); fail(); } catch (ExecutionException e) { assertThat(e).hasCauseThat().isInstanceOf(IOException.class); } } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/DefaultCallAdapterFactoryTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import com.google.common.reflect.TypeToken; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import okhttp3.Request; import okio.Timeout; import org.junit.Test; @SuppressWarnings("unchecked") public final class DefaultCallAdapterFactoryTest { private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; private final Retrofit retrofit = new Retrofit.Builder().baseUrl("http://localhost:1").build(); private final CallAdapter.Factory factory = new DefaultCallAdapterFactory(Runnable::run); @Test public void rawTypeThrows() { try { factory.get(Call.class, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Call return type must be parameterized as Call or Call"); } } @Test public void responseType() { Type classType = new TypeToken>() {}.getType(); assertThat(factory.get(classType, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type wilcardType = new TypeToken>() {}.getType(); assertThat(factory.get(wilcardType, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type genericType = new TypeToken>>() {}.getType(); assertThat(factory.get(genericType, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); } @Test public void adaptedCallExecute() throws IOException { Type returnType = new TypeToken>() {}.getType(); CallAdapter> adapter = (CallAdapter>) factory.get(returnType, NO_ANNOTATIONS, retrofit); final Response response = Response.success("Hi"); Call call = adapter.adapt( new EmptyCall() { @Override public Response execute() { return response; } }); assertThat(call.execute()).isSameInstanceAs(response); } @Test public void adaptedCallCloneDeepCopy() { Type returnType = new TypeToken>() {}.getType(); CallAdapter> adapter = (CallAdapter>) factory.get(returnType, NO_ANNOTATIONS, retrofit); final AtomicBoolean cloned = new AtomicBoolean(); Call delegate = new EmptyCall() { @Override public Call clone() { cloned.set(true); return this; } }; Call call = adapter.adapt(delegate); assertThat(call.clone()).isNotSameInstanceAs(call); assertTrue(cloned.get()); } @Test public void adaptedCallCancel() { Type returnType = new TypeToken>() {}.getType(); CallAdapter> adapter = (CallAdapter>) factory.get(returnType, NO_ANNOTATIONS, retrofit); final AtomicBoolean canceled = new AtomicBoolean(); Call delegate = new EmptyCall() { @Override public void cancel() { canceled.set(true); } }; Call call = adapter.adapt(delegate); call.cancel(); assertTrue(canceled.get()); } static class EmptyCall implements Call { @Override public void enqueue(Callback callback) { throw new UnsupportedOperationException(); } @Override public boolean isExecuted() { return false; } @Override public Response execute() throws IOException { throw new UnsupportedOperationException(); } @Override public void cancel() { throw new UnsupportedOperationException(); } @Override public boolean isCanceled() { return false; } @Override public Call clone() { throw new UnsupportedOperationException(); } @Override public Request request() { throw new UnsupportedOperationException(); } @Override public Timeout timeout() { return Timeout.NONE; } } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/DefaultMethodsTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.ToStringConverterFactory; import retrofit2.http.GET; import retrofit2.http.Query; public final class DefaultMethodsTest { @Rule public final MockWebServer server = new MockWebServer(); interface Example { @GET("/") Call user(@Query("name") String name); default Call user() { return user("hey"); } } @Test public void test() throws IOException { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hi")); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); Example example = retrofit.create(Example.class); Response response = example.user().execute(); assertThat(response.body()).isEqualTo("Hi"); Response response2 = example.user("Hi").execute(); assertThat(response2.body()).isEqualTo("Hi"); } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/HttpExceptionTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import org.junit.Test; public final class HttpExceptionTest { @Test public void response() { Response response = Response.success("Hi"); HttpException exception = new HttpException(response); assertThat(exception.code()).isEqualTo(200); assertThat(exception.message()).isEqualTo("OK"); assertThat(exception.response()).isSameInstanceAs(response); } @Test public void nullResponseThrows() { try { new HttpException(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("response == null"); } } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/InvocationTest.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.RequestBody; import okhttp3.ResponseBody; import org.junit.Test; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.Path; import retrofit2.http.Query; import retrofit2.http.Url; public final class InvocationTest { interface Example { @POST("/{p1}") // Call postMethod( @Path("p1") String p1, @Query("p2") String p2, @Body RequestBody body); @GET // Call urlMethod(@Url String url); } interface ExampleSub extends Example {} @Test public void invocationObjectOnCallAndRequestTag() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .callFactory(new OkHttpClient()) .build(); Example example = retrofit.create(Example.class); RequestBody requestBody = RequestBody.create(MediaType.get("text/plain"), "three"); Call call = example.postMethod("one", "two", requestBody); Invocation invocation = call.request().tag(Invocation.class); Method method = invocation.method(); assertThat(method.getName()).isEqualTo("postMethod"); assertThat(method.getDeclaringClass()).isEqualTo(Example.class); assertThat(invocation.arguments()).isEqualTo(Arrays.asList("one", "two", requestBody)); assertThat(invocation.annotationUrl()).isEqualTo("/{p1}"); } @Test public void invocationCorrectlyIdentifiesServiceMethodInvocation() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .callFactory(new OkHttpClient()) .build(); ExampleSub example = retrofit.create(ExampleSub.class); RequestBody requestBody = RequestBody.create(MediaType.get("text/plain"), "three"); Call call = example.postMethod("one", "two", requestBody); Invocation invocation = call.request().tag(Invocation.class); assertThat(invocation.service()).isEqualTo(ExampleSub.class); assertThat(invocation.instance()).isSameInstanceAs(example); assertThat(invocation.method().getName()).isEqualTo("postMethod"); assertThat(invocation.method().getDeclaringClass()).isEqualTo(Example.class); assertThat(invocation.arguments()).isEqualTo(Arrays.asList("one", "two", requestBody)); assertThat(invocation.annotationUrl()).isEqualTo("/{p1}"); } @Test public void annotationUrlAbsent() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .callFactory(new OkHttpClient()) .build(); Example example = retrofit.create(Example.class); Call call = example.urlMethod("/abc"); Invocation invocation = call.request().tag(Invocation.class); Method method = invocation.method(); assertThat(method.getName()).isEqualTo("urlMethod"); assertThat(method.getDeclaringClass()).isEqualTo(Example.class); assertThat(invocation.arguments()).isEqualTo(Arrays.asList("/abc")); assertThat(invocation.annotationUrl()).isNull(); } @Test public void ofInstance() { try { Invocation.of( null, new Object(), Object.class.getDeclaredMethods()[0], Arrays.asList("one", "two")); fail(); } catch (NullPointerException expected) { assertThat(expected).hasMessageThat().isEqualTo("service == null"); } } @Test public void nullService() { Object service = new Object(); Method method = Object.class.getDeclaredMethods()[0]; List arguments = Arrays.asList("one", "two"); Invocation invocation = Invocation.of(Object.class, service, method, arguments, "/abc"); assertThat(invocation.service()).isEqualTo(Object.class); assertThat(invocation.instance()).isEqualTo(service); assertThat(invocation.method()).isEqualTo(method); assertThat(invocation.arguments()).isEqualTo(arguments); assertThat(invocation.annotationUrl()).isEqualTo("/abc"); } @Test public void nullInstance() { try { Invocation.of( Object.class, null, Object.class.getDeclaredMethods()[0], Arrays.asList("one", "two"), null); fail(); } catch (NullPointerException expected) { assertThat(expected).hasMessageThat().isEqualTo("instance == null"); } } @Test public void nullMethod() { try { Invocation.of(Object.class, new Object(), null, Arrays.asList("one", "two"), null); fail(); } catch (NullPointerException expected) { assertThat(expected).hasMessageThat().isEqualTo("method == null"); } } @Test public void nullArguments() { try { Invocation.of(Object.class, new Object(), Example.class.getDeclaredMethods()[0], null, null); fail(); } catch (NullPointerException expected) { assertThat(expected).hasMessageThat().isEqualTo("arguments == null"); } } @Test public void deprecatedNullMethod() { try { Invocation.of(null, Arrays.asList("one", "two")); fail(); } catch (NullPointerException expected) { assertThat(expected).hasMessageThat().isEqualTo("method == null"); } } @Test public void deprecatedNullArguments() { try { Invocation.of(Example.class.getDeclaredMethods()[0], null); fail(); } catch (NullPointerException expected) { assertThat(expected).hasMessageThat().isEqualTo("arguments == null"); } } @Test public void argumentsAreImmutable() { List mutableList = new ArrayList<>(Arrays.asList("one", "two")); Invocation invocation = Invocation.of(Example.class.getDeclaredMethods()[0], mutableList); mutableList.add("three"); assertThat(invocation.arguments()).isEqualTo(Arrays.asList("one", "two")); try { invocation.arguments().clear(); fail(); } catch (UnsupportedOperationException expected) { } } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/Java8DefaultStaticMethodsInValidationTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static org.junit.Assert.assertNotNull; import okhttp3.mockwebserver.MockWebServer; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.ToStringConverterFactory; import retrofit2.http.GET; import retrofit2.http.Query; public final class Java8DefaultStaticMethodsInValidationTest { @Rule public final MockWebServer server = new MockWebServer(); interface Example { @GET("/") Call user(@Query("name") String name); default Call user() { return user("hey"); } static String staticMethod() { return "Hi"; } } @Test public void test() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .validateEagerly(true) .build(); assertNotNull(retrofit.create(Example.class)); } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/MethodParameterReflectionTest.java ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import okhttp3.ResponseBody; import org.junit.Test; import retrofit2.helpers.ExampleWithoutParameterNames; import retrofit2.http.GET; public final class MethodParameterReflectionTest { private final Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").validateEagerly(true).build(); @Test public void paramIndexIsUsedWithoutParamReflection() { try { retrofit.create(ExampleWithoutParameterNames.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "No Retrofit annotation found. (parameter #1)\n for method ExampleWithoutParameterNames.method"); } } /** This module is compiled with parameter names embedded in the class file. */ interface ExampleWithParameterNames { @GET("/") // Call method(String theFirstParameter); } @Test public void paramNameIsUsedWithParamReflection() { try { retrofit.create(ExampleWithParameterNames.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "No Retrofit annotation found. (parameter 'theFirstParameter')\n for method ExampleWithParameterNames.method"); } } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/NonFatalError.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; final class NonFatalError extends Error { NonFatalError(String message) { super(message); } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/OptionalConverterFactoryTest.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import java.io.IOException; import java.util.Optional; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.ObjectInstanceConverterFactory; import retrofit2.http.GET; public final class OptionalConverterFactoryTest { interface Service { @GET("/") Call> optional(); @GET("/") Call object(); } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ObjectInstanceConverterFactory()) .build(); service = retrofit.create(Service.class); } @Test public void optional() throws IOException { server.enqueue(new MockResponse()); Optional optional = service.optional().execute().body(); assertThat(optional).isNotNull(); assertThat(optional.get()).isSameInstanceAs(ObjectInstanceConverterFactory.VALUE); } @Test public void onlyMatchesOptional() throws IOException { server.enqueue(new MockResponse()); Object body = service.object().execute().body(); assertThat(body).isSameInstanceAs(ObjectInstanceConverterFactory.VALUE); } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/RequestFactoryBuilderTest.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import java.util.Set; import org.junit.Test; // TODO this test is far too white box, migrate to black box. public final class RequestFactoryBuilderTest { @Test public void pathParameterParsing() throws Exception { expectParams("/"); expectParams("/foo"); expectParams("/foo/bar"); expectParams("/foo/bar/{}"); expectParams("/foo/bar/{taco}", "taco"); expectParams("/foo/bar/{t}", "t"); expectParams("/foo/bar/{!!!}/"); // Invalid parameter. expectParams("/foo/bar/{}/{taco}", "taco"); expectParams("/foo/bar/{taco}/or/{burrito}", "taco", "burrito"); expectParams("/foo/bar/{taco}/or/{taco}", "taco"); expectParams("/foo/bar/{taco-shell}", "taco-shell"); expectParams("/foo/bar/{taco_shell}", "taco_shell"); expectParams("/foo/bar/{sha256}", "sha256"); expectParams("/foo/bar/{TACO}", "TACO"); expectParams("/foo/bar/{taco}/{tAco}/{taCo}", "taco", "tAco", "taCo"); expectParams("/foo/bar/{1}"); // Invalid parameter, name cannot start with digit. } private static void expectParams(String path, String... expected) { Set calculated = RequestFactory.Builder.parsePathParameters(path); assertThat(calculated).containsExactlyElementsIn(expected); } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/RequestFactoryTest.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import static retrofit2.TestingUtils.buildRequest; import java.io.IOException; import java.math.BigInteger; import java.net.URI; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import okhttp3.HttpUrl; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.ResponseBody; import okio.Buffer; import org.junit.Ignore; import org.junit.Test; import retrofit2.helpers.NullObjectConverterFactory; import retrofit2.http.Body; import retrofit2.http.DELETE; import retrofit2.http.Field; import retrofit2.http.FieldMap; import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; import retrofit2.http.HEAD; import retrofit2.http.HTTP; import retrofit2.http.Header; import retrofit2.http.HeaderMap; import retrofit2.http.Headers; import retrofit2.http.Multipart; import retrofit2.http.OPTIONS; import retrofit2.http.PATCH; import retrofit2.http.POST; import retrofit2.http.PUT; import retrofit2.http.Part; import retrofit2.http.PartMap; import retrofit2.http.Path; import retrofit2.http.Query; import retrofit2.http.QueryMap; import retrofit2.http.QueryName; import retrofit2.http.Tag; import retrofit2.http.Url; @SuppressWarnings({"UnusedParameters", "unused"}) // Parameters inspected reflectively. public final class RequestFactoryTest { private static final MediaType TEXT_PLAIN = MediaType.get("text/plain"); @Test public void customMethodNoBody() { class Example { @HTTP(method = "CUSTOM1", path = "/foo") Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("CUSTOM1"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo"); assertThat(request.body()).isNull(); } @Test public void customMethodWithBody() { class Example { @HTTP(method = "CUSTOM2", path = "/foo", hasBody = true) Call method(@Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "hi"); Request request = buildRequest(Example.class, body); assertThat(request.method()).isEqualTo("CUSTOM2"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo"); assertBody(request.body(), "hi"); } @Test public void onlyOneEncodingIsAllowedMultipartFirst() { class Example { @Multipart // @FormUrlEncoded // @POST("/") // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Only one encoding annotation is allowed.\n for method Example.method"); } } @Test public void onlyOneEncodingIsAllowedFormEncodingFirst() { class Example { @FormUrlEncoded // @Multipart // @POST("/") // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Only one encoding annotation is allowed.\n for method Example.method"); } } @Test public void invalidPathParam() throws Exception { class Example { @GET("/") // Call method(@Path("hey!") String thing) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Path parameter name must match \\{([a-zA-Z][a-zA-Z0-9_-]*)\\}." + " Found: hey! (parameter 'thing')\n for method Example.method"); } } @Test public void pathParamNotAllowedInQuery() throws Exception { class Example { @GET("/foo?bar={bar}") // Call method(@Path("bar") String thing) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "URL query string \"bar={bar}\" must not have replace block." + " For dynamic query parameters use @Query.\n for method Example.method"); } } @Test public void multipleParameterAnnotationsNotAllowed() throws Exception { class Example { @GET("/") // Call method(@Body @Query("nope") String o) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Multiple Retrofit annotations found, only one allowed. (parameter 'o')\n for method Example.method"); } } @interface NonNull {} @Test public void multipleParameterAnnotationsOnlyOneRetrofitAllowed() throws Exception { class Example { @GET("/") // Call method(@Query("maybe") @NonNull Object o) { return null; } } Request request = buildRequest(Example.class, "yep"); assertThat(request.url().toString()).isEqualTo("http://example.com/?maybe=yep"); } @Test public void twoMethodsFail() { class Example { @PATCH("/foo") // @POST("/foo") // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isAnyOf( "Only one HTTP method is allowed. Found: PATCH and POST.\n for method Example.method", "Only one HTTP method is allowed. Found: POST and PATCH.\n for method Example.method"); } } @Test public void lackingMethod() { class Example { Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "HTTP method annotation is required (e.g., @GET, @POST, etc.).\n for method Example.method"); } } @Test public void implicitMultipartForbidden() { class Example { @POST("/") // Call method(@Part("a") int a) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Part parameters can only be used with multipart encoding. (parameter 'a')\n for method Example.method"); } } @Test public void implicitMultipartWithPartMapForbidden() { class Example { @POST("/") // Call method(@PartMap Map params) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@PartMap parameters can only be used with multipart encoding. (parameter 'params')\n for method Example.method"); } } @Test public void multipartFailsOnNonBodyMethod() { class Example { @Multipart // @GET("/") // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Multipart can only be specified on HTTP methods with request body (e.g., @POST).\n for method Example.method"); } } @Test public void multipartFailsWithNoParts() { class Example { @Multipart // @POST("/") // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Multipart method must contain at least one @Part.\n for method Example.method"); } } @Test public void implicitFormEncodingByFieldForbidden() { class Example { @POST("/") // Call method(@Field("a") int a) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Field parameters can only be used with form encoding. (parameter 'a')\n for method Example.method"); } } @Test public void implicitFormEncodingByFieldMapForbidden() { class Example { @POST("/") // Call method(@FieldMap Map a) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@FieldMap parameters can only be used with form encoding. (parameter 'a')\n for method Example.method"); } } @Test public void formEncodingFailsOnNonBodyMethod() { class Example { @FormUrlEncoded // @GET("/") // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).\n for method Example.method"); } } @Test public void formEncodingFailsWithNoParts() { class Example { @FormUrlEncoded // @POST("/") // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Form-encoded method must contain at least one @Field.\n for method Example.method"); } } @Test public void headersFailWhenEmptyOnMethod() { class Example { @GET("/") // @Headers({}) // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("@Headers annotation is empty.\n for method Example.method"); } } @Test public void headersFailWhenMalformed() { class Example { @GET("/") // @Headers("Malformed") // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Headers value must be in the form \"Name: Value\". Found: \"Malformed\"\n for method Example.method"); } } @Test public void pathParamNonPathParamAndTypedBytes() { class Example { @PUT("/{a}") // Call method(@Path("a") int a, @Path("b") int b, @Body int c) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "URL \"/{a}\" does not contain \"{b}\". (parameter 'b')\n for method Example.method"); } } @Test public void parameterWithoutAnnotation() { class Example { @GET("/") // Call method(String a) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "No Retrofit annotation found. (parameter 'a')\n for method Example.method"); } } @Test public void nonBodyHttpMethodWithSingleEntity() { class Example { @GET("/") // Call method(@Body String o) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Non-body HTTP method cannot contain @Body.\n for method Example.method"); } } @Test public void queryMapMustBeAMap() { class Example { @GET("/") // Call method(@QueryMap List a) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@QueryMap parameter type must be Map. (parameter 'a')\n for method Example.method"); } } @Test public void queryMapSupportsSubclasses() { class Foo extends HashMap {} class Example { @GET("/") // Call method(@QueryMap Foo a) { return null; } } Foo foo = new Foo(); foo.put("hello", "world"); Request request = buildRequest(Example.class, foo); assertThat(request.url().toString()).isEqualTo("http://example.com/?hello=world"); } @Test public void queryMapRejectsNull() { class Example { @GET("/") // Call method(@QueryMap Map a) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Query map was null (parameter 'a')\n" + " for method Example.method"); } } @Test public void queryMapRejectsNullKeys() { class Example { @GET("/") // Call method(@QueryMap Map a) { return null; } } Map queryParams = new LinkedHashMap<>(); queryParams.put("ping", "pong"); queryParams.put(null, "kat"); try { buildRequest(Example.class, queryParams); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Query map contained null key. (parameter 'a')\n" + " for method Example.method"); } } @Test public void queryMapRejectsNullValues() { class Example { @GET("/") // Call method(@QueryMap Map a) { return null; } } Map queryParams = new LinkedHashMap<>(); queryParams.put("ping", "pong"); queryParams.put("kit", null); try { buildRequest(Example.class, queryParams); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Query map contained null value for key 'kit'. (parameter 'a')\n" + " for method Example.method"); } } @Test public void getWithHeaderMap() { class Example { @GET("/search") Call method(@HeaderMap Map headers) { return null; } } Map headers = new LinkedHashMap<>(); headers.put("Accept", "text/plain"); headers.put("Accept-Charset", "utf-8"); Request request = buildRequest(Example.class, headers); assertThat(request.method()).isEqualTo("GET"); assertThat(request.url().toString()).isEqualTo("http://example.com/search"); assertThat(request.body()).isNull(); assertThat(request.headers().size()).isEqualTo(2); assertThat(request.header("Accept")).isEqualTo("text/plain"); assertThat(request.header("Accept-Charset")).isEqualTo("utf-8"); } @Test public void headerMapMustBeAMapOrHeaders() { class Example { @GET("/") Call method( @HeaderMap okhttp3.Headers headers, @HeaderMap List headerMap) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@HeaderMap parameter type must be Map or Headers. (parameter 'headerMap')\n for method Example.method"); } } @Test public void headerMapSupportsSubclasses() { class Foo extends HashMap {} class Example { @GET("/search") Call method(@HeaderMap Foo headers) { return null; } } Foo headers = new Foo(); headers.put("Accept", "text/plain"); Request request = buildRequest(Example.class, headers); assertThat(request.url().toString()).isEqualTo("http://example.com/search"); assertThat(request.headers().size()).isEqualTo(1); assertThat(request.header("Accept")).isEqualTo("text/plain"); } @Test public void headerMapRejectsNull() { class Example { @GET("/") Call method(@HeaderMap Map headers) { return null; } } try { buildRequest(Example.class, (Map) null); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Header map was null. (parameter 'headers')\n" + " for method Example.method"); } } @Test public void headerMapRejectsNullKeys() { class Example { @GET("/") Call method(@HeaderMap Map headers) { return null; } } Map headers = new LinkedHashMap<>(); headers.put("Accept", "text/plain"); headers.put(null, "utf-8"); try { buildRequest(Example.class, headers); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Header map contained null key. (parameter 'headers')\n" + " for method Example.method"); } } @Test public void headerMapRejectsNullValues() { class Example { @GET("/") Call method(@HeaderMap Map headers) { return null; } } Map headers = new LinkedHashMap<>(); headers.put("Accept", "text/plain"); headers.put("Accept-Charset", null); try { buildRequest(Example.class, headers); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Header map contained null value for key 'Accept-Charset'. (parameter 'headers')\n" + " for method Example.method"); } } @Test public void getWithHeaders() { class Example { @GET("/search") Call method(@HeaderMap okhttp3.Headers headers) { throw new AssertionError(); } } okhttp3.Headers headers = new okhttp3.Headers.Builder() .add("Accept", "text/plain") .add("Accept", "application/json") .add("Accept-Charset", "utf-8") .build(); Request request = buildRequest(Example.class, headers); assertThat(request.method()).isEqualTo("GET"); assertThat(request.url().toString()).isEqualTo("http://example.com/search"); assertThat(request.body()).isNull(); assertThat(request.headers().size()).isEqualTo(3); assertThat(request.headers("Accept")).isEqualTo(asList("text/plain", "application/json")); assertThat(request.header("Accept-Charset")).isEqualTo("utf-8"); } @Test public void getWithHeadersAndHeaderMap() { class Example { @GET("/search") Call method( @HeaderMap okhttp3.Headers headers, @HeaderMap Map headerMap) { throw new AssertionError(); } } okhttp3.Headers headers = new okhttp3.Headers.Builder() .add("Accept", "text/plain") .add("Accept-Charset", "utf-8") .build(); Map headerMap = Collections.singletonMap("Accept", "application/json"); Request request = buildRequest(Example.class, headers, headerMap); assertThat(request.method()).isEqualTo("GET"); assertThat(request.url().toString()).isEqualTo("http://example.com/search"); assertThat(request.body()).isNull(); assertThat(request.headers().size()).isEqualTo(3); assertThat(request.headers("Accept")).isEqualTo(asList("text/plain", "application/json")); assertThat(request.header("Accept-Charset")).isEqualTo("utf-8"); } @Test public void headersRejectsNull() { class Example { @GET("/") Call method(@HeaderMap okhttp3.Headers headers) { throw new AssertionError(); } } try { buildRequest(Example.class, (okhttp3.Headers) null); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Headers parameter must not be null. (parameter 'headers')\n" + " for method Example.method"); } } @Test public void getWithHeaderMapAllowingUnsafeNonAsciiValues() { class Example { @GET("/search") Call method( @HeaderMap(allowUnsafeNonAsciiValues = true) Map headers) { return null; } } Map headers = new LinkedHashMap<>(); headers.put("Accept", "text/plain"); headers.put("Title", "Kein plötzliches"); Request request = buildRequest(Example.class, headers); assertThat(request.method()).isEqualTo("GET"); assertThat(request.url().toString()).isEqualTo("http://example.com/search"); assertThat(request.body()).isNull(); assertThat(request.headers().size()).isEqualTo(2); assertThat(request.header("Accept")).isEqualTo("text/plain"); assertThat(request.header("Title")).isEqualTo("Kein plötzliches"); } @Test public void twoBodies() { class Example { @PUT("/") // Call method(@Body String o1, @Body String o2) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Multiple @Body method annotations found. (parameter 'o2')\n for method Example.method"); } } @Test public void bodyInNonBodyRequest() { class Example { @Multipart // @PUT("/") // Call method(@Part("one") String o1, @Body String o2) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Body parameters cannot be used with form or multi-part encoding. (parameter 'o2')\n for method Example.method"); } } @Test public void get() { class Example { @GET("/foo/bar/") // Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void delete() { class Example { @DELETE("/foo/bar/") // Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("DELETE"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertNull(request.body()); } @Test public void headVoid() { class Example { @HEAD("/foo/bar/") // Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("HEAD"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Ignore("This test is valid but isn't validated by RequestFactory so it needs moved") @Test public void headWithoutVoidThrows() { class Example { @HEAD("/foo/bar/") // Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "HEAD method must use Void or Unit as response type.\n for method Example.method"); } } @Test public void post() { class Example { @POST("/foo/bar/") // Call method(@Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "hi"); Request request = buildRequest(Example.class, body); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertBody(request.body(), "hi"); } @Test public void put() { class Example { @PUT("/foo/bar/") // Call method(@Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "hi"); Request request = buildRequest(Example.class, body); assertThat(request.method()).isEqualTo("PUT"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertBody(request.body(), "hi"); } @Test public void patch() { class Example { @PATCH("/foo/bar/") // Call method(@Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "hi"); Request request = buildRequest(Example.class, body); assertThat(request.method()).isEqualTo("PATCH"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertBody(request.body(), "hi"); } @Test public void options() { class Example { @OPTIONS("/foo/bar/") // Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("OPTIONS"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void getWithPathParam() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path("ping") String ping) { return null; } } Request request = buildRequest(Example.class, "po ng"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/po%20ng/"); assertThat(request.body()).isNull(); } @Test public void getWithUnusedAndInvalidNamedPathParam() { class Example { @GET("/foo/bar/{ping}/{kit,kat}/") // Call method(@Path("ping") String ping) { return null; } } Request request = buildRequest(Example.class, "pong"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/pong/%7Bkit,kat%7D/"); assertThat(request.body()).isNull(); } @Test public void getWithEncodedPathParam() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path(value = "ping", encoded = true) String ping) { return null; } } Request request = buildRequest(Example.class, "po%20ng"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/po%20ng/"); assertThat(request.body()).isNull(); } @Test public void getWithEncodedPathSegments() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path(value = "ping", encoded = true) String ping) { return null; } } Request request = buildRequest(Example.class, "baz/pong/more"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/baz/pong/more/"); assertThat(request.body()).isNull(); } @Test public void getWithUnencodedPathSegmentsPreventsRequestSplitting() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path(value = "ping", encoded = false) String ping) { return null; } } Request request = buildRequest(Example.class, "baz/\r\nheader: blue"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/baz%2F%0D%0Aheader:%20blue/"); assertThat(request.body()).isNull(); } @Test public void getWithEncodedPathStillPreventsRequestSplitting() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path(value = "ping", encoded = true) String ping) { return null; } } Request request = buildRequest(Example.class, "baz/\r\npong"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/baz/pong/"); assertThat(request.body()).isNull(); } @Test public void pathParametersAndPathTraversal() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path(value = "ping") String ping) { return null; } } assertMalformedRequest(Example.class, "."); assertMalformedRequest(Example.class, ".."); assertThat(buildRequest(Example.class, "./a").url().encodedPath()).isEqualTo("/foo/bar/.%2Fa/"); assertThat(buildRequest(Example.class, "a/.").url().encodedPath()).isEqualTo("/foo/bar/a%2F./"); assertThat(buildRequest(Example.class, "a/..").url().encodedPath()) .isEqualTo("/foo/bar/a%2F../"); assertThat(buildRequest(Example.class, "../a").url().encodedPath()) .isEqualTo("/foo/bar/..%2Fa/"); assertThat(buildRequest(Example.class, "..\\..").url().encodedPath()) .isEqualTo("/foo/bar/..%5C../"); assertThat(buildRequest(Example.class, "%2E").url().encodedPath()).isEqualTo("/foo/bar/%252E/"); assertThat(buildRequest(Example.class, "%2E%2E").url().encodedPath()) .isEqualTo("/foo/bar/%252E%252E/"); } @Test public void encodedPathParametersAndPathTraversal() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path(value = "ping", encoded = true) String ping) { return null; } } assertMalformedRequest(Example.class, "."); assertMalformedRequest(Example.class, "%2E"); assertMalformedRequest(Example.class, "%2e"); assertMalformedRequest(Example.class, ".."); assertMalformedRequest(Example.class, "%2E."); assertMalformedRequest(Example.class, "%2e."); assertMalformedRequest(Example.class, ".%2E"); assertMalformedRequest(Example.class, ".%2e"); assertMalformedRequest(Example.class, "%2E%2e"); assertMalformedRequest(Example.class, "%2e%2E"); assertMalformedRequest(Example.class, "./a"); assertMalformedRequest(Example.class, "a/."); assertMalformedRequest(Example.class, "../a"); assertMalformedRequest(Example.class, "a/.."); assertMalformedRequest(Example.class, "a/../b"); assertMalformedRequest(Example.class, "a/%2e%2E/b"); assertThat(buildRequest(Example.class, "...").url().encodedPath()).isEqualTo("/foo/bar/.../"); assertThat(buildRequest(Example.class, "a..b").url().encodedPath()).isEqualTo("/foo/bar/a..b/"); assertThat(buildRequest(Example.class, "a..").url().encodedPath()).isEqualTo("/foo/bar/a../"); assertThat(buildRequest(Example.class, "a..b").url().encodedPath()).isEqualTo("/foo/bar/a..b/"); assertThat(buildRequest(Example.class, "..b").url().encodedPath()).isEqualTo("/foo/bar/..b/"); assertThat(buildRequest(Example.class, "..\\..").url().encodedPath()) .isEqualTo("/foo/bar/..%5C../"); } @Test public void dotDotsOkayWhenNotFullPathSegment() { class Example { @GET("/foo{ping}bar/") // Call method(@Path(value = "ping", encoded = true) String ping) { return null; } } assertMalformedRequest(Example.class, "/./"); assertMalformedRequest(Example.class, "/../"); assertThat(buildRequest(Example.class, ".").url().encodedPath()).isEqualTo("/foo.bar/"); assertThat(buildRequest(Example.class, "..").url().encodedPath()).isEqualTo("/foo..bar/"); } @Test public void pathParamRequired() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path("ping") String ping) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e.getMessage()) .isEqualTo( "Path parameter \"ping\" value must not be null. (parameter 'ping')\n" + " for method Example.method"); } } @Test public void getWithQueryParam() { class Example { @GET("/foo/bar/") // Call method(@Query("ping") String ping) { return null; } } Request request = buildRequest(Example.class, "pong"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?ping=pong"); assertThat(request.body()).isNull(); } @Test public void getWithEncodedQueryParam() { class Example { @GET("/foo/bar/") // Call method(@Query(value = "pi%20ng", encoded = true) String ping) { return null; } } Request request = buildRequest(Example.class, "p%20o%20n%20g"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/?pi%20ng=p%20o%20n%20g"); assertThat(request.body()).isNull(); } @Test public void queryParamOptionalOmitsQuery() { class Example { @GET("/foo/bar/") // Call method(@Query("ping") String ping) { return null; } } Request request = buildRequest(Example.class, new Object[] {null}); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); } @Test public void queryParamOptional() { class Example { @GET("/foo/bar/") // Call method( @Query("foo") String foo, @Query("ping") String ping, @Query("kit") String kit) { return null; } } Request request = buildRequest(Example.class, "bar", null, "kat"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?foo=bar&kit=kat"); } @Test public void getWithQueryUrlAndParam() { class Example { @GET("/foo/bar/?hi=mom") // Call method(@Query("ping") String ping) { return null; } } Request request = buildRequest(Example.class, "pong"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?hi=mom&ping=pong"); assertThat(request.body()).isNull(); } @Test public void getWithQuery() { class Example { @GET("/foo/bar/?hi=mom") // Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?hi=mom"); assertThat(request.body()).isNull(); } @Test public void getWithPathAndQueryParam() { class Example { @GET("/foo/bar/{ping}/") // Call method( @Path("ping") String ping, @Query("kit") String kit, @Query("riff") String riff) { return null; } } Request request = buildRequest(Example.class, "pong", "kat", "raff"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/pong/?kit=kat&riff=raff"); assertThat(request.body()).isNull(); } @Test public void getWithQueryThenPathThrows() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Query("kit") String kit, @Path("ping") String ping) { return null; } } try { buildRequest(Example.class, "kat", "pong"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "A @Path parameter must not come after a @Query. (parameter 'ping')\n" + " for method Example.method"); } } @Test public void getWithQueryNameThenPathThrows() { class Example { @GET("/foo/bar/{ping}/") // Call method(@QueryName String kit, @Path("ping") String ping) { throw new AssertionError(); } } try { buildRequest(Example.class, "kat", "pong"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "A @Path parameter must not come after a @QueryName. (parameter 'ping')\n" + " for method Example.method"); } } @Test public void getWithQueryMapThenPathThrows() { class Example { @GET("/foo/bar/{ping}/") // Call method(@QueryMap Map queries, @Path("ping") String ping) { throw new AssertionError(); } } try { buildRequest(Example.class, Collections.singletonMap("kit", "kat"), "pong"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "A @Path parameter must not come after a @QueryMap. (parameter 'ping')\n" + " for method Example.method"); } } @Test public void getWithPathAndQueryQuestionMarkParam() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path("ping") String ping, @Query("kit") String kit) { return null; } } Request request = buildRequest(Example.class, "pong?", "kat?"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/pong%3F/?kit=kat%3F"); assertThat(request.body()).isNull(); } @Test public void getWithPathAndQueryAmpersandParam() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path("ping") String ping, @Query("kit") String kit) { return null; } } Request request = buildRequest(Example.class, "pong&", "kat&"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/pong&/?kit=kat%26"); assertThat(request.body()).isNull(); } @Test public void getWithPathAndQueryHashParam() { class Example { @GET("/foo/bar/{ping}/") // Call method(@Path("ping") String ping, @Query("kit") String kit) { return null; } } Request request = buildRequest(Example.class, "pong#", "kat#"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/pong%23/?kit=kat%23"); assertThat(request.body()).isNull(); } @Test public void getWithQueryParamList() { class Example { @GET("/foo/bar/") // Call method(@Query("key") List keys) { return null; } } List values = Arrays.asList(1, 2, null, "three", "1"); Request request = buildRequest(Example.class, values); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/?key=1&key=2&key=three&key=1"); assertThat(request.body()).isNull(); } @Test public void getWithQueryParamArray() { class Example { @GET("/foo/bar/") // Call method(@Query("key") Object[] keys) { return null; } } Object[] values = {1, 2, null, "three", "1"}; Request request = buildRequest(Example.class, new Object[] {values}); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/?key=1&key=2&key=three&key=1"); assertThat(request.body()).isNull(); } @Test public void getWithQueryParamPrimitiveArray() { class Example { @GET("/foo/bar/") // Call method(@Query("key") int[] keys) { return null; } } int[] values = {1, 2, 3, 1}; Request request = buildRequest(Example.class, new Object[] {values}); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/?key=1&key=2&key=3&key=1"); assertThat(request.body()).isNull(); } @Test public void getWithQueryNameParam() { class Example { @GET("/foo/bar/") // Call method(@QueryName String ping) { return null; } } Request request = buildRequest(Example.class, "pong"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?pong"); assertThat(request.body()).isNull(); } @Test public void getWithEncodedQueryNameParam() { class Example { @GET("/foo/bar/") // Call method(@QueryName(encoded = true) String ping) { return null; } } Request request = buildRequest(Example.class, "p%20o%20n%20g"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?p%20o%20n%20g"); assertThat(request.body()).isNull(); } @Test public void queryNameParamOptionalOmitsQuery() { class Example { @GET("/foo/bar/") // Call method(@QueryName String ping) { return null; } } Request request = buildRequest(Example.class, new Object[] {null}); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); } @Test public void getWithQueryNameParamList() { class Example { @GET("/foo/bar/") // Call method(@QueryName List keys) { return null; } } List values = Arrays.asList(1, 2, null, "three", "1"); Request request = buildRequest(Example.class, values); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?1&2&three&1"); assertThat(request.body()).isNull(); } @Test public void getWithQueryNameParamArray() { class Example { @GET("/foo/bar/") // Call method(@QueryName Object[] keys) { return null; } } Object[] values = {1, 2, null, "three", "1"}; Request request = buildRequest(Example.class, new Object[] {values}); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?1&2&three&1"); assertThat(request.body()).isNull(); } @Test public void getWithQueryNameParamPrimitiveArray() { class Example { @GET("/foo/bar/") // Call method(@QueryName int[] keys) { return null; } } int[] values = {1, 2, 3, 1}; Request request = buildRequest(Example.class, new Object[] {values}); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?1&2&3&1"); assertThat(request.body()).isNull(); } @Test public void getWithQueryParamMap() { class Example { @GET("/foo/bar/") // Call method(@QueryMap Map query) { return null; } } Map params = new LinkedHashMap<>(); params.put("kit", "kat"); params.put("ping", "pong"); Request request = buildRequest(Example.class, params); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?kit=kat&ping=pong"); assertThat(request.body()).isNull(); } @Test public void getWithEncodedQueryParamMap() { class Example { @GET("/foo/bar/") // Call method(@QueryMap(encoded = true) Map query) { return null; } } Map params = new LinkedHashMap<>(); params.put("kit", "k%20t"); params.put("pi%20ng", "p%20g"); Request request = buildRequest(Example.class, params); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()) .isEqualTo("http://example.com/foo/bar/?kit=k%20t&pi%20ng=p%20g"); assertThat(request.body()).isNull(); } @Test public void getAbsoluteUrl() { class Example { @GET("http://example2.com/foo/bar/") Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example2.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void getWithStringUrl() { class Example { @GET Call method(@Url String url) { return null; } } Request request = buildRequest(Example.class, "foo/bar/"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void getWithJavaUriUrl() { class Example { @GET Call method(@Url URI url) { return null; } } Request request = buildRequest(Example.class, URI.create("foo/bar/")); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void getWithStringUrlAbsolute() { class Example { @GET Call method(@Url String url) { return null; } } Request request = buildRequest(Example.class, "https://example2.com/foo/bar/"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("https://example2.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void getWithJavaUriUrlAbsolute() { class Example { @GET Call method(@Url URI url) { return null; } } Request request = buildRequest(Example.class, URI.create("https://example2.com/foo/bar/")); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("https://example2.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void getWithUrlAbsoluteSameHost() { class Example { @GET Call method(@Url String url) { return null; } } Request request = buildRequest(Example.class, "http://example.com/foo/bar/"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void getWithHttpUrl() { class Example { @GET Call method(@Url HttpUrl url) { return null; } } Request request = buildRequest(Example.class, HttpUrl.get("http://example.com/foo/bar/")); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url()).isEqualTo(HttpUrl.get("http://example.com/foo/bar/")); assertThat(request.body()).isNull(); } @Test public void getWithNullUrl() { class Example { @GET Call method(@Url HttpUrl url) { return null; } } try { buildRequest(Example.class, (HttpUrl) null); fail(); } catch (IllegalArgumentException expected) { assertThat(expected) .hasMessageThat() .isEqualTo( "@Url parameter is null. (parameter 'url')\n" + " for method Example.method"); } } @Test public void getWithNonStringUrlThrows() { class Example { @GET Call method(@Url Object url) { return null; } } try { buildRequest(Example.class, "foo/bar"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Url must be okhttp3.HttpUrl, String, java.net.URI, or android.net.Uri type." + " (parameter 'url')\n" + " for method Example.method"); } } @Test public void getUrlAndUrlParamThrows() { class Example { @GET("foo/bar") Call method(@Url Object url) { return null; } } try { buildRequest(Example.class, "foo/bar"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Url cannot be used with @GET URL (parameter 'url')\n" + " for method Example.method"); } } @Test public void getWithoutUrlThrows() { class Example { @GET Call method() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Missing either @GET URL or @Url parameter.\n" + " for method Example.method"); } } @Test public void getWithUrlThenPathThrows() { class Example { @GET Call method(@Url String url, @Path("hey") String hey) { return null; } } try { buildRequest(Example.class, "foo/bar"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Path parameters may not be used with @Url. (parameter 'hey')\n" + " for method Example.method"); } } @Test public void getWithPathThenUrlThrows() { class Example { @GET Call method(@Path("hey") String hey, @Url Object url) { return null; } } try { buildRequest(Example.class, "foo/bar"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Path can only be used with relative url on @GET (parameter 'hey')\n" + " for method Example.method"); } } @Test public void getWithQueryThenUrlThrows() { class Example { @GET("foo/bar") Call method(@Query("hey") String hey, @Url Object url) { return null; } } try { buildRequest(Example.class, "hey", "foo/bar/"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "A @Url parameter must not come after a @Query. (parameter 'url')\n" + " for method Example.method"); } } @Test public void getWithQueryNameThenUrlThrows() { class Example { @GET Call method(@QueryName String name, @Url String url) { throw new AssertionError(); } } try { buildRequest(Example.class, Collections.singletonMap("kit", "kat"), "foo/bar/"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "A @Url parameter must not come after a @QueryName. (parameter 'url')\n" + " for method Example.method"); } } @Test public void getWithQueryMapThenUrlThrows() { class Example { @GET Call method(@QueryMap Map queries, @Url String url) { throw new AssertionError(); } } try { buildRequest(Example.class, Collections.singletonMap("kit", "kat"), "foo/bar/"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "A @Url parameter must not come after a @QueryMap. (parameter 'url')\n" + " for method Example.method"); } } @Test public void getWithUrlThenQuery() { class Example { @GET Call method(@Url String url, @Query("hey") String hey) { return null; } } Request request = buildRequest(Example.class, "foo/bar/", "hey!"); assertThat(request.method()).isEqualTo("GET"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/?hey=hey%21"); } @Test public void postWithUrl() { class Example { @POST Call method(@Url String url, @Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "hi"); Request request = buildRequest(Example.class, "http://example.com/foo/bar", body); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar"); assertBody(request.body(), "hi"); } @Test public void normalPostWithPathParam() { class Example { @POST("/foo/bar/{ping}/") // Call method(@Path("ping") String ping, @Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "Hi!"); Request request = buildRequest(Example.class, "pong", body); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/pong/"); assertBody(request.body(), "Hi!"); } @Test public void emptyBody() { class Example { @POST("/foo/bar/") // Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertBody(request.body(), ""); } @Test public void customMethodEmptyBody() { class Example { @HTTP(method = "CUSTOM", path = "/foo/bar/", hasBody = true) // Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("CUSTOM"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertBody(request.body(), ""); } @Test public void bodyRequired() { class Example { @POST("/foo/bar/") // Call method(@Body RequestBody body) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e.getMessage()) .isEqualTo( "Body parameter value must not be null. (parameter 'body')\n" + " for method Example.method"); } } @Test public void bodyWithPathParams() { class Example { @POST("/foo/bar/{ping}/{kit}/") // Call method( @Path("ping") String ping, @Body RequestBody body, @Path("kit") String kit) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "Hi!"); Request request = buildRequest(Example.class, "pong", body, "kat"); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/pong/kat/"); assertBody(request.body(), "Hi!"); } @Test public void simpleMultipart() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part("ping") String ping, @Part("kit") RequestBody kit) { return null; } } Request request = buildRequest(Example.class, "pong", RequestBody.create(TEXT_PLAIN, "kat")); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); assertThat(body.contentType().toString()).startsWith("multipart/form-data; boundary="); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"ping\"\r\n"); assertThat(bodyString).contains("\r\npong\r\n--"); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"kit\""); assertThat(bodyString).contains("\r\nkat\r\n--"); } @Test public void multipartArray() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part("ping") String[] ping) { return null; } } Request request = buildRequest(Example.class, new Object[] {new String[] {"pong1", "pong2"}}); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"ping\"\r\n"); assertThat(bodyString).contains("\r\npong1\r\n--"); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"ping\""); assertThat(bodyString).contains("\r\npong2\r\n--"); } @Test public void multipartRequiresName() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part RequestBody part) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Part annotation must supply a name or use MultipartBody.Part parameter type. (parameter 'part')\n" + " for method Example.method"); } } @Test public void multipartIterableRequiresName() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part List part) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Part annotation must supply a name or use MultipartBody.Part parameter type. (parameter 'part')\n" + " for method Example.method"); } } @Test public void multipartArrayRequiresName() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part RequestBody[] part) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Part annotation must supply a name or use MultipartBody.Part parameter type. (parameter 'part')\n" + " for method Example.method"); } } @Test public void multipartOkHttpPartForbidsName() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part("name") MultipartBody.Part part) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Part parameters using the MultipartBody.Part must not include a part name in the annotation. (parameter 'part')\n" + " for method Example.method"); } } @Test public void multipartOkHttpPart() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part MultipartBody.Part part) { return null; } } MultipartBody.Part part = MultipartBody.Part.createFormData("kit", "kat"); Request request = buildRequest(Example.class, part); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"kit\"\r\n"); assertThat(bodyString).contains("\r\nkat\r\n--"); } @Test public void multipartOkHttpIterablePart() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part List part) { return null; } } MultipartBody.Part part1 = MultipartBody.Part.createFormData("foo", "bar"); MultipartBody.Part part2 = MultipartBody.Part.createFormData("kit", "kat"); Request request = buildRequest(Example.class, asList(part1, part2)); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"foo\"\r\n"); assertThat(bodyString).contains("\r\nbar\r\n--"); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"kit\"\r\n"); assertThat(bodyString).contains("\r\nkat\r\n--"); } @Test public void multipartOkHttpArrayPart() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part MultipartBody.Part[] part) { return null; } } MultipartBody.Part part1 = MultipartBody.Part.createFormData("foo", "bar"); MultipartBody.Part part2 = MultipartBody.Part.createFormData("kit", "kat"); Request request = buildRequest(Example.class, new Object[] {new MultipartBody.Part[] {part1, part2}}); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"foo\"\r\n"); assertThat(bodyString).contains("\r\nbar\r\n--"); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"kit\"\r\n"); assertThat(bodyString).contains("\r\nkat\r\n--"); } @Test public void multipartOkHttpPartWithFilename() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part MultipartBody.Part part) { return null; } } MultipartBody.Part part = MultipartBody.Part.createFormData("kit", "kit.txt", RequestBody.create(null, "kat")); Request request = buildRequest(Example.class, part); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"kit\"; filename=\"kit.txt\"\r\n"); assertThat(bodyString).contains("\r\nkat\r\n--"); } @Test public void multipartIterable() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part("ping") List ping) { return null; } } Request request = buildRequest(Example.class, asList("pong1", "pong2")); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"ping\"\r\n"); assertThat(bodyString).contains("\r\npong1\r\n--"); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"ping\""); assertThat(bodyString).contains("\r\npong2\r\n--"); } @Test public void multipartIterableOkHttpPart() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part("ping") List part) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Part parameters using the MultipartBody.Part must not include a part name in the annotation. (parameter 'part')\n" + " for method Example.method"); } } @Test public void multipartArrayOkHttpPart() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part("ping") MultipartBody.Part[] part) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Part parameters using the MultipartBody.Part must not include a part name in the annotation. (parameter 'part')\n" + " for method Example.method"); } } @Test public void multipartWithEncoding() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method( @Part(value = "ping", encoding = "8-bit") String ping, @Part(value = "kit", encoding = "7-bit") RequestBody kit) { return null; } } Request request = buildRequest(Example.class, "pong", RequestBody.create(TEXT_PLAIN, "kat")); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"ping\"\r\n"); assertThat(bodyString).contains("Content-Transfer-Encoding: 8-bit"); assertThat(bodyString).contains("\r\npong\r\n--"); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"kit\""); assertThat(bodyString).contains("Content-Transfer-Encoding: 7-bit"); assertThat(bodyString).contains("\r\nkat\r\n--"); } @Test public void multipartPartMap() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@PartMap Map parts) { return null; } } Map params = new LinkedHashMap<>(); params.put("ping", RequestBody.create(null, "pong")); params.put("kit", RequestBody.create(null, "kat")); Request request = buildRequest(Example.class, params); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"ping\"\r\n"); assertThat(bodyString).contains("\r\npong\r\n--"); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"kit\""); assertThat(bodyString).contains("\r\nkat\r\n--"); } @Test public void multipartPartMapWithEncoding() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@PartMap(encoding = "8-bit") Map parts) { return null; } } Map params = new LinkedHashMap<>(); params.put("ping", RequestBody.create(null, "pong")); params.put("kit", RequestBody.create(null, "kat")); Request request = buildRequest(Example.class, params); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"ping\"\r\n"); assertThat(bodyString).contains("Content-Transfer-Encoding: 8-bit"); assertThat(bodyString).contains("\r\npong\r\n--"); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"kit\""); assertThat(bodyString).contains("Content-Transfer-Encoding: 8-bit"); assertThat(bodyString).contains("\r\nkat\r\n--"); } @Test public void multipartPartMapRejectsNonStringKeys() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@PartMap Map parts) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@PartMap keys must be of type String: class java.lang.Object (parameter 'parts')\n" + " for method Example.method"); } } @Test public void multipartPartMapRejectsOkHttpPartValues() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@PartMap Map parts) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@PartMap values cannot be MultipartBody.Part. Use @Part List or a different value type instead. (parameter 'parts')\n" + " for method Example.method"); } } @Test public void multipartPartMapRejectsNull() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@PartMap Map parts) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Part map was null. (parameter 'parts')\n" + " for method Example.method"); } } @Test public void multipartPartMapRejectsNullKeys() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@PartMap Map parts) { return null; } } Map params = new LinkedHashMap<>(); params.put("ping", RequestBody.create(null, "pong")); params.put(null, RequestBody.create(null, "kat")); try { buildRequest(Example.class, params); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Part map contained null key. (parameter 'parts')\n" + " for method Example.method"); } } @Test public void multipartPartMapRejectsNullValues() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@PartMap Map parts) { return null; } } Map params = new LinkedHashMap<>(); params.put("ping", RequestBody.create(null, "pong")); params.put("kit", null); try { buildRequest(Example.class, params); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Part map contained null value for key 'kit'. (parameter 'parts')\n" + " for method Example.method"); } } @Test public void multipartPartMapMustBeMap() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@PartMap List parts) { return null; } } try { buildRequest(Example.class, emptyList()); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@PartMap parameter type must be Map. (parameter 'parts')\n for method Example.method"); } } @Test public void multipartPartMapSupportsSubclasses() throws IOException { class Foo extends HashMap {} class Example { @Multipart // @POST("/foo/bar/") // Call method(@PartMap Foo parts) { return null; } } Foo foo = new Foo(); foo.put("hello", "world"); Request request = buildRequest(Example.class, foo); Buffer buffer = new Buffer(); request.body().writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("name=\"hello\""); assertThat(bodyString).contains("\r\n\r\nworld\r\n--"); } @Test public void multipartNullRemovesPart() throws IOException { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part("ping") String ping, @Part("fizz") String fizz) { return null; } } Request request = buildRequest(Example.class, "pong", null); assertThat(request.method()).isEqualTo("POST"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); RequestBody body = request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String bodyString = buffer.readUtf8(); assertThat(bodyString).contains("Content-Disposition: form-data;"); assertThat(bodyString).contains("name=\"ping\""); assertThat(bodyString).contains("\r\npong\r\n--"); } @Test public void multipartPartOptional() { class Example { @Multipart // @POST("/foo/bar/") // Call method(@Part("ping") RequestBody ping) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalStateException e) { assertThat(e.getMessage()).isEqualTo("Multipart body must have at least one part."); } } @Test public void simpleFormEncoded() { class Example { @FormUrlEncoded // @POST("/foo") // Call method(@Field("foo") String foo, @Field("ping") String ping) { return null; } } Request request = buildRequest(Example.class, "bar", "pong"); RequestBody body = request.body(); assertBody(body, "foo=bar&ping=pong"); assertThat(body.contentType().toString()).isEqualTo("application/x-www-form-urlencoded"); } @Test public void formEncodedWithEncodedNameFieldParam() { class Example { @FormUrlEncoded // @POST("/foo") // Call method(@Field(value = "na%20me", encoded = true) String foo) { return null; } } Request request = buildRequest(Example.class, "ba%20r"); assertBody(request.body(), "na%20me=ba%20r"); } @Test public void formEncodedFieldOptional() { class Example { @FormUrlEncoded // @POST("/foo") // Call method( @Field("foo") String foo, @Field("ping") String ping, @Field("kit") String kit) { return null; } } Request request = buildRequest(Example.class, "bar", null, "kat"); assertBody(request.body(), "foo=bar&kit=kat"); } @Test public void formEncodedFieldList() { class Example { @FormUrlEncoded // @POST("/foo") // Call method(@Field("foo") List fields, @Field("kit") String kit) { return null; } } List values = Arrays.asList("foo", "bar", null, 3); Request request = buildRequest(Example.class, values, "kat"); assertBody(request.body(), "foo=foo&foo=bar&foo=3&kit=kat"); } @Test public void formEncodedFieldArray() { class Example { @FormUrlEncoded // @POST("/foo") // Call method(@Field("foo") Object[] fields, @Field("kit") String kit) { return null; } } Object[] values = {1, 2, null, "three"}; Request request = buildRequest(Example.class, values, "kat"); assertBody(request.body(), "foo=1&foo=2&foo=three&kit=kat"); } @Test public void formEncodedFieldPrimitiveArray() { class Example { @FormUrlEncoded // @POST("/foo") // Call method(@Field("foo") int[] fields, @Field("kit") String kit) { return null; } } int[] values = {1, 2, 3}; Request request = buildRequest(Example.class, values, "kat"); assertBody(request.body(), "foo=1&foo=2&foo=3&kit=kat"); } @Test public void formEncodedWithEncodedNameFieldParamMap() { class Example { @FormUrlEncoded // @POST("/foo") // Call method(@FieldMap(encoded = true) Map fieldMap) { return null; } } Map fieldMap = new LinkedHashMap<>(); fieldMap.put("k%20it", "k%20at"); fieldMap.put("pin%20g", "po%20ng"); Request request = buildRequest(Example.class, fieldMap); assertBody(request.body(), "k%20it=k%20at&pin%20g=po%20ng"); } @Test public void formEncodedFieldMap() { class Example { @FormUrlEncoded // @POST("/foo") // Call method(@FieldMap Map fieldMap) { return null; } } Map fieldMap = new LinkedHashMap<>(); fieldMap.put("kit", "kat"); fieldMap.put("ping", "pong"); Request request = buildRequest(Example.class, fieldMap); assertBody(request.body(), "kit=kat&ping=pong"); } @Test public void fieldMapRejectsNull() { class Example { @FormUrlEncoded // @POST("/") // Call method(@FieldMap Map a) { return null; } } try { buildRequest(Example.class, new Object[] {null}); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Field map was null. (parameter 'a')\n" + " for method Example.method"); } } @Test public void fieldMapRejectsNullKeys() { class Example { @FormUrlEncoded // @POST("/") // Call method(@FieldMap Map a) { return null; } } Map fieldMap = new LinkedHashMap<>(); fieldMap.put("kit", "kat"); fieldMap.put(null, "pong"); try { buildRequest(Example.class, fieldMap); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Field map contained null key. (parameter 'a')\n" + " for method Example.method"); } } @Test public void fieldMapRejectsNullValues() { class Example { @FormUrlEncoded // @POST("/") // Call method(@FieldMap Map a) { return null; } } Map fieldMap = new LinkedHashMap<>(); fieldMap.put("kit", "kat"); fieldMap.put("foo", null); try { buildRequest(Example.class, fieldMap); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Field map contained null value for key 'foo'. (parameter 'a')\n" + " for method Example.method"); } } @Test public void fieldMapMustBeAMap() { class Example { @FormUrlEncoded // @POST("/") // Call method(@FieldMap List a) { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@FieldMap parameter type must be Map. (parameter 'a')\n for method Example.method"); } } @Test public void fieldMapSupportsSubclasses() throws IOException { class Foo extends HashMap {} class Example { @FormUrlEncoded // @POST("/") // Call method(@FieldMap Foo a) { return null; } } Foo foo = new Foo(); foo.put("hello", "world"); Request request = buildRequest(Example.class, foo); Buffer buffer = new Buffer(); request.body().writeTo(buffer); assertThat(buffer.readUtf8()).isEqualTo("hello=world"); } @Test public void simpleHeaders() { class Example { @GET("/foo/bar/") @Headers({"ping: pong", "kit: kat"}) Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("GET"); okhttp3.Headers headers = request.headers(); assertThat(headers.size()).isEqualTo(2); assertThat(headers.get("ping")).isEqualTo("pong"); assertThat(headers.get("kit")).isEqualTo("kat"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void simpleHeadersAllowingUnsafeNonAsciiValues() { class Example { @GET("/foo/bar/") @Headers( value = {"ping: pong", "title: Kein plötzliches"}, allowUnsafeNonAsciiValues = true) Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("GET"); okhttp3.Headers headers = request.headers(); assertThat(headers.size()).isEqualTo(2); assertThat(headers.get("ping")).isEqualTo("pong"); assertThat(headers.get("title")).isEqualTo("Kein plötzliches"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void headersDoNotOverwriteEachOther() { class Example { @GET("/foo/bar/") @Headers({ "ping: pong", "kit: kat", "kit: -kat", }) Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("GET"); okhttp3.Headers headers = request.headers(); assertThat(headers.size()).isEqualTo(3); assertThat(headers.get("ping")).isEqualTo("pong"); assertThat(headers.values("kit")).containsExactly("kat", "-kat"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void headerParamToString() { class Example { @GET("/foo/bar/") // Call method(@Header("kit") BigInteger kit) { return null; } } Request request = buildRequest(Example.class, new BigInteger("1234")); assertThat(request.method()).isEqualTo("GET"); okhttp3.Headers headers = request.headers(); assertThat(headers.size()).isEqualTo(1); assertThat(headers.get("kit")).isEqualTo("1234"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void headerParam() { class Example { @GET("/foo/bar/") // @Headers("ping: pong") // Call method(@Header("kit") String kit) { return null; } } Request request = buildRequest(Example.class, "kat"); assertThat(request.method()).isEqualTo("GET"); okhttp3.Headers headers = request.headers(); assertThat(headers.size()).isEqualTo(2); assertThat(headers.get("ping")).isEqualTo("pong"); assertThat(headers.get("kit")).isEqualTo("kat"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void headerParamAllowingUnsafeNonAsciiValues() { class Example { @GET("/foo/bar/") // @Headers("ping: pong") // Call method( @Header(value = "title", allowUnsafeNonAsciiValues = true) String kit) { return null; } } Request request = buildRequest(Example.class, "Kein plötzliches"); assertThat(request.method()).isEqualTo("GET"); okhttp3.Headers headers = request.headers(); assertThat(headers.size()).isEqualTo(2); assertThat(headers.get("ping")).isEqualTo("pong"); assertThat(headers.get("title")).isEqualTo("Kein plötzliches"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void headerParamList() { class Example { @GET("/foo/bar/") // Call method(@Header("foo") List kit) { return null; } } Request request = buildRequest(Example.class, asList("bar", null, "baz")); assertThat(request.method()).isEqualTo("GET"); okhttp3.Headers headers = request.headers(); assertThat(headers.size()).isEqualTo(2); assertThat(headers.values("foo")).containsExactly("bar", "baz"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void headerParamArray() { class Example { @GET("/foo/bar/") // Call method(@Header("foo") String[] kit) { return null; } } Request request = buildRequest(Example.class, (Object) new String[] {"bar", null, "baz"}); assertThat(request.method()).isEqualTo("GET"); okhttp3.Headers headers = request.headers(); assertThat(headers.size()).isEqualTo(2); assertThat(headers.values("foo")).containsExactly("bar", "baz"); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } @Test public void contentTypeAnnotationHeaderOverrides() { class Example { @POST("/") // @Headers("Content-Type: text/not-plain") // Call method(@Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "hi"); Request request = buildRequest(Example.class, body); assertThat(request.body().contentType().toString()).isEqualTo("text/not-plain"); } @Test public void contentTypeAnnotationHeaderOverridesFormEncoding() { class Example { @FormUrlEncoded // @POST("/foo") // @Headers("Content-Type: text/not-plain") // Call method(@Field("foo") String foo, @Field("ping") String ping) { return null; } } Request request = buildRequest(Example.class, "bar", "pong"); assertThat(request.body().contentType().toString()).isEqualTo("text/not-plain"); } @Test public void contentTypeAnnotationHeaderOverridesMultipart() { class Example { @Multipart // @POST("/foo/bar/") // @Headers("Content-Type: text/not-plain") // Call method(@Part("ping") String ping, @Part("kit") RequestBody kit) { return null; } } Request request = buildRequest(Example.class, "pong", RequestBody.create(TEXT_PLAIN, "kat")); RequestBody body = request.body(); assertThat(request.body().contentType().toString()).isEqualTo("text/not-plain"); } @Test public void malformedContentTypeHeaderThrows() { class Example { @POST("/") // @Headers("Content-Type: hello, world!") // Call method(@Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "hi"); try { buildRequest(Example.class, body); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Malformed content type: hello, world!\n" + " for method Example.method"); assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class); // OkHttp's cause. } } @Test public void contentTypeAnnotationHeaderAddsHeaderWithNoBodyGet() { class Example { @GET("/") // @Headers("Content-Type: text/not-plain") // Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.headers().get("Content-Type")).isEqualTo("text/not-plain"); } @Test public void contentTypeAnnotationHeaderAddsHeaderWithNoBodyDelete() { class Example { @DELETE("/") // @Headers("Content-Type: text/not-plain") // Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.headers().get("Content-Type")).isEqualTo("text/not-plain"); } @Test public void contentTypeParameterHeaderOverrides() { class Example { @POST("/") // Call method( @Header("Content-Type") String contentType, @Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "Plain"); Request request = buildRequest(Example.class, "text/not-plain", body); assertThat(request.body().contentType().toString()).isEqualTo("text/not-plain"); } @Test public void malformedContentTypeParameterThrows() { class Example { @POST("/") // Call method( @Header("Content-Type") String contentType, @Body RequestBody body) { return null; } } RequestBody body = RequestBody.create(TEXT_PLAIN, "hi"); try { buildRequest(Example.class, "hello, world!", body); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("Malformed content type: hello, world!"); assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class); // OkHttp's cause. } } @Test public void malformedAnnotationRelativeUrlThrows() { class Example { @GET("ftp://example.org") Call get() { return null; } } try { buildRequest(Example.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Malformed URL. Base: http://example.com/, Relative: ftp://example.org"); } } @Test public void malformedParameterRelativeUrlThrows() { class Example { @GET Call get(@Url String relativeUrl) { return null; } } try { buildRequest(Example.class, "ftp://example.org"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Malformed URL. Base: http://example.com/, Relative: ftp://example.org"); } } @Test public void multipartPartsShouldBeInOrder() throws IOException { class Example { @Multipart @POST("/foo") Call get( @Part("first") String data, @Part("second") String dataTwo, @Part("third") String dataThree) { return null; } } Request request = buildRequest(Example.class, "firstParam", "secondParam", "thirdParam"); MultipartBody body = (MultipartBody) request.body(); Buffer buffer = new Buffer(); body.writeTo(buffer); String readBody = buffer.readUtf8(); assertThat(readBody.indexOf("firstParam")).isLessThan(readBody.indexOf("secondParam")); assertThat(readBody.indexOf("secondParam")).isLessThan(readBody.indexOf("thirdParam")); } @Test public void queryParamsSkippedIfConvertedToNull() throws Exception { class Example { @GET("/query") Call queryPath(@Query("a") Object a) { return null; } } Retrofit.Builder retrofitBuilder = new Retrofit.Builder() .baseUrl("http://example.com") .addConverterFactory(new NullObjectConverterFactory()); Request request = buildRequest(Example.class, retrofitBuilder, "Ignored"); assertThat(request.url().toString()).doesNotContain("Ignored"); } @Test public void queryParamMapsConvertedToNullShouldError() throws Exception { class Example { @GET("/query") Call queryPath(@QueryMap Map a) { return null; } } Retrofit.Builder retrofitBuilder = new Retrofit.Builder() .baseUrl("http://example.com") .addConverterFactory(new NullObjectConverterFactory()); Map queryMap = Collections.singletonMap("kit", "kat"); try { buildRequest(Example.class, retrofitBuilder, queryMap); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .contains( "Query map value 'kat' converted to null by retrofit2.helpers.NullObjectConverterFactory$1 for key 'kit'."); } } @Test public void fieldParamsSkippedIfConvertedToNull() throws Exception { class Example { @FormUrlEncoded @POST("/query") Call queryPath(@Field("a") Object a) { return null; } } Retrofit.Builder retrofitBuilder = new Retrofit.Builder() .baseUrl("http://example.com") .addConverterFactory(new NullObjectConverterFactory()); Request request = buildRequest(Example.class, retrofitBuilder, "Ignored"); assertThat(request.url().toString()).doesNotContain("Ignored"); } @Test public void fieldParamMapsConvertedToNullShouldError() throws Exception { class Example { @FormUrlEncoded @POST("/query") Call queryPath(@FieldMap Map a) { return null; } } Retrofit.Builder retrofitBuilder = new Retrofit.Builder() .baseUrl("http://example.com") .addConverterFactory(new NullObjectConverterFactory()); Map queryMap = Collections.singletonMap("kit", "kat"); try { buildRequest(Example.class, retrofitBuilder, queryMap); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .contains( "Field map value 'kat' converted to null by retrofit2.helpers.NullObjectConverterFactory$1 for key 'kit'."); } } @Test public void tag() { class Example { @GET("/") Call method(@Tag String tag) { return null; } } Request request = buildRequest(Example.class, "tagValue"); assertThat(request.tag(String.class)).isEqualTo("tagValue"); } @Test public void tagPrimitive() { class Example { @GET("/") Call method(@Tag long timestamp) { return null; } } Request request = buildRequest(Example.class, 42L); assertThat(request.tag(Long.class)).isEqualTo(42L); } @Test public void tagGeneric() { class Example { @GET("/") Call method(@Tag List tag) { return null; } } List strings = asList("tag", "value"); Request request = buildRequest(Example.class, strings); assertThat(request.tag(List.class)).isSameInstanceAs(strings); } @Test public void tagDuplicateFails() { class Example { @GET("/") Call method(@Tag String one, @Tag String two) { return null; } } try { buildRequest(Example.class, "one", "two"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Tag type java.lang.String is duplicate of parameter 'one' and would always overwrite its value. (parameter 'two')\n" + " for method Example.method"); } } @Test public void tagGenericDuplicateFails() { class Example { @GET("/") Call method(@Tag List one, @Tag List two) { return null; } } try { buildRequest(Example.class, emptyList(), emptyList()); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "@Tag type java.util.List is duplicate of parameter 'one' and would always overwrite its value. (parameter 'two')\n" + " for method Example.method"); } } private static void assertBody(RequestBody body, String expected) { assertThat(body).isNotNull(); Buffer buffer = new Buffer(); try { body.writeTo(buffer); assertThat(buffer.readUtf8()).isEqualTo(expected); } catch (IOException e) { throw new RuntimeException(e); } } static void assertMalformedRequest(Class cls, Object... args) { try { Request request = buildRequest(cls, args); fail("expected a malformed request but was " + request); } catch (IllegalArgumentException expected) { // Ignored } } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/ResponseTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import okhttp3.Headers; import okhttp3.MediaType; import okhttp3.Protocol; import okhttp3.ResponseBody; import org.junit.Test; public final class ResponseTest { private final okhttp3.Response successResponse = new okhttp3.Response.Builder() // .code(200) .message("OK") .protocol(Protocol.HTTP_1_1) .request(new okhttp3.Request.Builder().url("http://localhost").build()) .build(); private final okhttp3.Response errorResponse = new okhttp3.Response.Builder() // .code(400) .message("Broken!") .protocol(Protocol.HTTP_1_1) .request(new okhttp3.Request.Builder().url("http://localhost").build()) .build(); @Test public void success() { Object body = new Object(); Response response = Response.success(body); assertThat(response.raw()).isNotNull(); assertThat(response.code()).isEqualTo(200); assertThat(response.message()).isEqualTo("OK"); assertThat(response.headers().size()).isEqualTo(0); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isSameInstanceAs(body); assertThat(response.errorBody()).isNull(); } @Test public void successNullAllowed() { Response response = Response.success(null); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isNull(); } @Test public void successWithHeaders() { Object body = new Object(); Headers headers = Headers.of("foo", "bar"); Response response = Response.success(body, headers); assertThat(response.raw()).isNotNull(); assertThat(response.code()).isEqualTo(200); assertThat(response.message()).isEqualTo("OK"); assertThat(response.headers().toMultimap()).isEqualTo(headers.toMultimap()); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isSameInstanceAs(body); assertThat(response.errorBody()).isNull(); } @Test public void successWithNullHeadersThrows() { try { Response.success("", (okhttp3.Headers) null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("headers == null"); } } @Test public void successWithStatusCode() { Object body = new Object(); Response response = Response.success(204, body); assertThat(response.code()).isEqualTo(204); assertThat(response.message()).isEqualTo("Response.success()"); assertThat(response.headers().size()).isEqualTo(0); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isSameInstanceAs(body); assertThat(response.errorBody()).isNull(); } @Test public void successWithRawResponse() { Object body = new Object(); Response response = Response.success(body, successResponse); assertThat(response.raw()).isSameInstanceAs(successResponse); assertThat(response.code()).isEqualTo(200); assertThat(response.message()).isEqualTo("OK"); assertThat(response.headers().size()).isEqualTo(0); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isSameInstanceAs(body); assertThat(response.errorBody()).isNull(); } @Test public void successWithNullRawResponseThrows() { try { Response.success("", (okhttp3.Response) null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("rawResponse == null"); } } @Test public void successWithErrorRawResponseThrows() { try { Response.success("", errorResponse); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("rawResponse must be successful response"); } } @Test public void error() { MediaType plainText = MediaType.get("text/plain; charset=utf-8"); ResponseBody errorBody = ResponseBody.create(plainText, "Broken!"); Response response = Response.error(400, errorBody); assertThat(response.raw()).isNotNull(); assertThat(response.raw().body().contentType()).isEqualTo(plainText); assertThat(response.raw().body().contentLength()).isEqualTo(7); try { response.raw().body().source(); fail(); } catch (IllegalStateException expected) { } assertThat(response.code()).isEqualTo(400); assertThat(response.message()).isEqualTo("Response.error()"); assertThat(response.headers().size()).isEqualTo(0); assertThat(response.isSuccessful()).isFalse(); assertThat(response.body()).isNull(); assertThat(response.errorBody()).isSameInstanceAs(errorBody); } @Test public void nullErrorThrows() { try { Response.error(400, null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("body == null"); } } @Test public void errorWithSuccessCodeThrows() { ResponseBody errorBody = ResponseBody.create(null, "Broken!"); try { Response.error(200, errorBody); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("code < 400: 200"); } } @Test public void errorWithRawResponse() { ResponseBody errorBody = ResponseBody.create(null, "Broken!"); Response response = Response.error(errorBody, errorResponse); assertThat(response.raw()).isSameInstanceAs(errorResponse); assertThat(response.code()).isEqualTo(400); assertThat(response.message()).isEqualTo("Broken!"); assertThat(response.headers().size()).isEqualTo(0); assertThat(response.isSuccessful()).isFalse(); assertThat(response.body()).isNull(); assertThat(response.errorBody()).isSameInstanceAs(errorBody); } @Test public void nullErrorWithRawResponseThrows() { try { Response.error(null, errorResponse); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("body == null"); } } @Test public void errorWithNullRawResponseThrows() { ResponseBody errorBody = ResponseBody.create(null, "Broken!"); try { Response.error(errorBody, null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("rawResponse == null"); } } @Test public void errorWithSuccessRawResponseThrows() { ResponseBody errorBody = ResponseBody.create(null, "Broken!"); try { Response.error(errorBody, successResponse); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("rawResponse should not be successful response"); } } } ================================================ FILE: retrofit/java-test/src/test/java/retrofit2/RetrofitTest.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AT_START; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static retrofit2.AnnotationArraySubject.assertThat; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nullable; import okhttp3.HttpUrl; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.RequestBody; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Rule; import org.junit.Test; import retrofit2.helpers.DelegatingCallAdapterFactory; import retrofit2.helpers.NonMatchingCallAdapterFactory; import retrofit2.helpers.NonMatchingConverterFactory; import retrofit2.helpers.ToStringConverterFactory; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.Query; public final class RetrofitTest { @Rule public final MockWebServer server = new MockWebServer(); interface CallMethod { @GET("/") Call disallowed(); @POST("/") Call disallowed(@Body String body); @GET("/") Call badType1(); @GET("/") Call badType2(); @GET("/") Call getResponseBody(); @SkipCallbackExecutor @GET("/") Call getResponseBodySkippedExecutor(); @GET("/") Call getVoid(); @POST("/") Call postRequestBody(@Body RequestBody body); @GET("/") Call queryString(@Query("foo") String foo); @GET("/") Call queryObject(@Query("foo") Object foo); } interface FutureMethod { @GET("/") Future method(); } interface Extending extends CallMethod {} interface TypeParam {} interface ExtendingTypeParam extends TypeParam {} interface StringService { @GET("/") String get(); } interface UnresolvableResponseType { @GET("/") Call typeVariable(); @GET("/") Call typeVariableUpperBound(); @GET("/") Call>>> crazy(); @GET("/") Call wildcard(); @GET("/") Call wildcardUpperBound(); } interface UnresolvableParameterType { @POST("/") Call typeVariable(@Body T body); @POST("/") Call typeVariableUpperBound(@Body T body); @POST("/") Call crazy(@Body List>> body); @POST("/") Call wildcard(@Body List body); @POST("/") Call wildcardUpperBound(@Body List body); } interface VoidService { @GET("/") void nope(); } interface Annotated { @GET("/") @Foo Call method(); @POST("/") Call bodyParameter(@Foo @Body String param); @GET("/") Call queryParameter(@Foo @Query("foo") Object foo); @Retention(RUNTIME) @interface Foo {} } interface MutableParameters { @GET("/") Call method(@Query("i") AtomicInteger value); } // We are explicitly testing this behavior. @SuppressWarnings({"EqualsBetweenInconvertibleTypes", "EqualsIncompatibleType"}) @Test public void objectMethodsStillWork() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod example = retrofit.create(CallMethod.class); assertThat(example.hashCode()).isNotEqualTo(0); assertThat(example.equals(this)).isFalse(); assertThat(example.toString()).isNotEmpty(); } @Test public void interfaceWithTypeParameterThrows() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); server.enqueue(new MockResponse().setBody("Hi")); try { retrofit.create(TypeParam.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo("Type parameters are unsupported on retrofit2.RetrofitTest$TypeParam"); } } @Test public void interfaceWithExtend() throws IOException { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); server.enqueue(new MockResponse().setBody("Hi")); Extending extending = retrofit.create(Extending.class); String result = extending.getResponseBody().execute().body().string(); assertEquals("Hi", result); } @Test public void interfaceWithExtendWithTypeParameterThrows() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); server.enqueue(new MockResponse().setBody("Hi")); try { retrofit.create(ExtendingTypeParam.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Type parameters are unsupported on retrofit2.RetrofitTest$TypeParam " + "which is an interface of retrofit2.RetrofitTest$ExtendingTypeParam"); } } @Test public void cloneSharesStatefulInstances() { CallAdapter.Factory callAdapter = new CallAdapter.Factory() { @Nullable @Override public CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { throw new AssertionError(); } }; Converter.Factory converter = new Converter.Factory() {}; HttpUrl baseUrl = server.url("/"); Executor executor = Runnable::run; okhttp3.Call.Factory callFactory = request -> { throw new AssertionError(); }; Retrofit one = new Retrofit.Builder() .addCallAdapterFactory(callAdapter) .addConverterFactory(converter) .baseUrl(baseUrl) .callbackExecutor(executor) .callFactory(callFactory) .build(); CallAdapter.Factory callAdapter2 = new CallAdapter.Factory() { @Nullable @Override public CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { throw new AssertionError(); } }; Converter.Factory converter2 = new Converter.Factory() {}; Retrofit two = one.newBuilder() .addCallAdapterFactory(callAdapter2) .addConverterFactory(converter2) .build(); assertEquals(one.callAdapterFactories().size() + 1, two.callAdapterFactories().size()); assertThat(two.callAdapterFactories()).containsAtLeast(callAdapter, callAdapter2); assertEquals(one.converterFactories().size() + 1, two.converterFactories().size()); assertThat(two.converterFactories()).containsAtLeast(converter, converter2); assertSame(baseUrl, two.baseUrl()); assertSame(executor, two.callbackExecutor()); assertSame(callFactory, two.callFactory()); } @Test public void builtInConvertersAbsentInCloneBuilder() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); assertEquals(0, retrofit.newBuilder().converterFactories().size()); } @Test public void responseTypeCannotBeRetrofitResponse() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod service = retrofit.create(CallMethod.class); try { service.badType1(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Response must include generic type (e.g., Response)\n" + " for method CallMethod.badType1"); } } @Test public void responseTypeCannotBeOkHttpResponse() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod service = retrofit.create(CallMethod.class); try { service.badType2(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "'okhttp3.Response' is not a valid response body type. Did you mean ResponseBody?\n" + " for method CallMethod.badType2"); } } @Test public void voidReturnTypeNotAllowed() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); VoidService service = retrofit.create(VoidService.class); try { service.nope(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .startsWith("Service methods cannot return void.\n for method VoidService.nope"); } } @Test public void validateEagerlyDisabledByDefault() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); // Should not throw exception about incorrect configuration of the VoidService retrofit.create(VoidService.class); } @Test public void validateEagerlyDisabledByUser() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).validateEagerly(false).build(); // Should not throw exception about incorrect configuration of the VoidService retrofit.create(VoidService.class); } @Test public void validateEagerlyFailsAtCreation() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).validateEagerly(true).build(); try { retrofit.create(VoidService.class); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .startsWith("Service methods cannot return void.\n for method VoidService.nope"); } } @Test public void callCallAdapterAddedByDefault() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod example = retrofit.create(CallMethod.class); assertThat(example.getResponseBody()).isNotNull(); } @Test public void callCallCustomAdapter() { final AtomicBoolean factoryCalled = new AtomicBoolean(); final AtomicBoolean adapterCalled = new AtomicBoolean(); class MyCallAdapterFactory extends CallAdapter.Factory { @Override public @Nullable CallAdapter get( final Type returnType, Annotation[] annotations, Retrofit retrofit) { factoryCalled.set(true); if (getRawType(returnType) != Call.class) { return null; } return new CallAdapter>() { @Override public Type responseType() { return getParameterUpperBound(0, (ParameterizedType) returnType); } @Override public Call adapt(Call call) { adapterCalled.set(true); return call; } }; } } Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(new MyCallAdapterFactory()) .build(); CallMethod example = retrofit.create(CallMethod.class); assertThat(example.getResponseBody()).isNotNull(); assertThat(factoryCalled.get()).isTrue(); assertThat(adapterCalled.get()).isTrue(); } @Test public void customCallAdapter() { class GreetingCallAdapterFactory extends CallAdapter.Factory { @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != String.class) { return null; } return new CallAdapter() { @Override public Type responseType() { return String.class; } @Override public String adapt(Call call) { return "Hi!"; } }; } } Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .addCallAdapterFactory(new GreetingCallAdapterFactory()) .build(); StringService example = retrofit.create(StringService.class); assertThat(example.get()).isEqualTo("Hi!"); } @Test public void methodAnnotationsPassedToCallAdapter() { final AtomicReference annotationsRef = new AtomicReference<>(); class MyCallAdapterFactory extends CallAdapter.Factory { @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { annotationsRef.set(annotations); return null; } } Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .addCallAdapterFactory(new MyCallAdapterFactory()) .build(); Annotated annotated = retrofit.create(Annotated.class); annotated.method(); // Trigger internal setup. Annotation[] annotations = annotationsRef.get(); assertThat(annotations).hasAtLeastOneElementOfType(Annotated.Foo.class); } @Test public void customCallAdapterMissingThrows() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); FutureMethod example = retrofit.create(FutureMethod.class); try { example.method(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Unable to create call adapter for java.util.concurrent.Future\n" + " for method FutureMethod.method"); assertThat(e.getCause()) .hasMessageThat() .isEqualTo( "" + "Could not locate call adapter for java.util.concurrent.Future.\n" + " Tried:\n" + " * retrofit2.CompletableFutureCallAdapterFactory\n" + " * retrofit2.DefaultCallAdapterFactory"); } } @Test public void methodAnnotationsPassedToResponseBodyConverter() { final AtomicReference annotationsRef = new AtomicReference<>(); class MyConverterFactory extends Converter.Factory { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { annotationsRef.set(annotations); return new ToStringConverterFactory().responseBodyConverter(type, annotations, retrofit); } } Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new MyConverterFactory()) .build(); Annotated annotated = retrofit.create(Annotated.class); annotated.method(); // Trigger internal setup. Annotation[] annotations = annotationsRef.get(); assertThat(annotations).hasAtLeastOneElementOfType(Annotated.Foo.class); } @Test public void methodAndParameterAnnotationsPassedToRequestBodyConverter() { final AtomicReference parameterAnnotationsRef = new AtomicReference<>(); final AtomicReference methodAnnotationsRef = new AtomicReference<>(); class MyConverterFactory extends Converter.Factory { @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { parameterAnnotationsRef.set(parameterAnnotations); methodAnnotationsRef.set(methodAnnotations); return new ToStringConverterFactory() .requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit); } } Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new MyConverterFactory()) .build(); Annotated annotated = retrofit.create(Annotated.class); annotated.bodyParameter(null); // Trigger internal setup. assertThat(parameterAnnotationsRef.get()).hasAtLeastOneElementOfType(Annotated.Foo.class); assertThat(methodAnnotationsRef.get()).hasAtLeastOneElementOfType(POST.class); } @Test public void parameterAnnotationsPassedToStringConverter() { final AtomicReference annotationsRef = new AtomicReference<>(); class MyConverterFactory extends Converter.Factory { @Override public Converter stringConverter( Type type, Annotation[] annotations, Retrofit retrofit) { annotationsRef.set(annotations); return (Converter) String::valueOf; } } Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new MyConverterFactory()) .build(); Annotated annotated = retrofit.create(Annotated.class); annotated.queryParameter(null); // Trigger internal setup. Annotation[] annotations = annotationsRef.get(); assertThat(annotations).hasAtLeastOneElementOfType(Annotated.Foo.class); } @Test public void stringConverterCalledForString() { final AtomicBoolean factoryCalled = new AtomicBoolean(); class MyConverterFactory extends Converter.Factory { @Override public @Nullable Converter stringConverter( Type type, Annotation[] annotations, Retrofit retrofit) { factoryCalled.set(true); return null; } } Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new MyConverterFactory()) .build(); CallMethod service = retrofit.create(CallMethod.class); Call call = service.queryString(null); assertThat(call).isNotNull(); assertThat(factoryCalled.get()).isTrue(); } @Test public void stringConverterReturningNullResultsInDefault() { final AtomicBoolean factoryCalled = new AtomicBoolean(); class MyConverterFactory extends Converter.Factory { @Override public @Nullable Converter stringConverter( Type type, Annotation[] annotations, Retrofit retrofit) { factoryCalled.set(true); return null; } } Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new MyConverterFactory()) .build(); CallMethod service = retrofit.create(CallMethod.class); Call call = service.queryObject(null); assertThat(call).isNotNull(); assertThat(factoryCalled.get()).isTrue(); } @Test public void missingConverterThrowsOnNonRequestBody() throws IOException { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod example = retrofit.create(CallMethod.class); try { example.disallowed("Hi!"); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Unable to create @Body converter for class java.lang.String (parameter 'body')\n" + " for method CallMethod.disallowed"); assertThat(e.getCause()) .hasMessageThat() .isEqualTo( "" + "Could not locate RequestBody converter for class java.lang.String.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.OptionalConverterFactory"); } } @Test public void missingConverterThrowsOnNonResponseBody() throws IOException { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod example = retrofit.create(CallMethod.class); server.enqueue(new MockResponse().setBody("Hi")); try { example.disallowed(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Unable to create converter for class java.lang.String\n" + " for method CallMethod.disallowed"); assertThat(e.getCause()) .hasMessageThat() .isEqualTo( "" + "Could not locate ResponseBody converter for class java.lang.String.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.OptionalConverterFactory"); } } @Test public void requestBodyOutgoingAllowed() throws IOException { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod example = retrofit.create(CallMethod.class); server.enqueue(new MockResponse().setBody("Hi")); Response response = example.getResponseBody().execute(); assertThat(response.body().string()).isEqualTo("Hi"); } @Test public void voidOutgoingAllowed() throws IOException { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod example = retrofit.create(CallMethod.class); server.enqueue(new MockResponse().setBody("Hi")); Response response = example.getVoid().execute(); assertThat(response.body()).isNull(); } @Test public void voidResponsesArePooled() throws Exception { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod example = retrofit.create(CallMethod.class); server.enqueue(new MockResponse().setBody("abc")); server.enqueue(new MockResponse().setBody("def")); example.getVoid().execute(); example.getVoid().execute(); assertThat(server.takeRequest().getSequenceNumber()).isEqualTo(0); assertThat(server.takeRequest().getSequenceNumber()).isEqualTo(1); } @Test public void responseBodyIncomingAllowed() throws IOException, InterruptedException { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); CallMethod example = retrofit.create(CallMethod.class); server.enqueue(new MockResponse().setBody("Hi")); RequestBody body = RequestBody.create(MediaType.get("text/plain"), "Hey"); Response response = example.postRequestBody(body).execute(); assertThat(response.body().string()).isEqualTo("Hi"); assertThat(server.takeRequest().getBody().readUtf8()).isEqualTo("Hey"); } @Test public void unresolvableResponseTypeThrows() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); UnresolvableResponseType example = retrofit.create(UnresolvableResponseType.class); try { example.typeVariable(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Method return type must not include a type variable or wildcard: " + "retrofit2.Call\n for method UnresolvableResponseType.typeVariable"); } try { example.typeVariableUpperBound(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Method return type must not include a type variable or wildcard: " + "retrofit2.Call\n for method UnresolvableResponseType.typeVariableUpperBound"); } try { example.crazy(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Method return type must not include a type variable or wildcard: " + "retrofit2.Call>>>\n" + " for method UnresolvableResponseType.crazy"); } try { example.wildcard(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Method return type must not include a type variable or wildcard: " + "retrofit2.Call\n for method UnresolvableResponseType.wildcard"); } try { example.wildcardUpperBound(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Method return type must not include a type variable or wildcard: " + "retrofit2.Call\n" + " for method UnresolvableResponseType.wildcardUpperBound"); } } @Test public void unresolvableParameterTypeThrows() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); UnresolvableParameterType example = retrofit.create(UnresolvableParameterType.class); try { example.typeVariable(null); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Parameter type must not include a type variable or wildcard: " + "T (parameter 'body')\n for method UnresolvableParameterType.typeVariable"); } try { example.typeVariableUpperBound(null); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Parameter type must not include a type variable or wildcard: " + "T (parameter 'body')\n for method UnresolvableParameterType.typeVariableUpperBound"); } try { example.crazy(null); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Parameter type must not include a type variable or wildcard: " + "java.util.List>> (parameter 'body')\n" + " for method UnresolvableParameterType.crazy"); } try { example.wildcard(null); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Parameter type must not include a type variable or wildcard: " + "java.util.List (parameter 'body')\n for method UnresolvableParameterType.wildcard"); } try { example.wildcardUpperBound(null); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Parameter type must not include a type variable or wildcard: " + "java.util.List (parameter 'body')\n" + " for method UnresolvableParameterType.wildcardUpperBound"); } } @Test public void baseUrlRequired() { try { new Retrofit.Builder().build(); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessageThat().isEqualTo("Base URL required."); } } @Test public void baseUrlNullThrows() { try { new Retrofit.Builder().baseUrl((String) null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("baseUrl == null"); } try { new Retrofit.Builder().baseUrl((HttpUrl) null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("baseUrl == null"); } } @Test public void baseUrlInvalidThrows() { try { new Retrofit.Builder().baseUrl("ftp://foo/bar"); fail(); } catch (IllegalArgumentException ignored) { } } @Test public void baseUrlNoTrailingSlashThrows() { try { new Retrofit.Builder().baseUrl("http://example.com/api"); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("baseUrl must end in /: http://example.com/api"); } HttpUrl parsed = HttpUrl.get("http://example.com/api"); try { new Retrofit.Builder().baseUrl(parsed); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("baseUrl must end in /: http://example.com/api"); } } @Test public void baseUrlStringPropagated() { Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").build(); HttpUrl baseUrl = retrofit.baseUrl(); assertThat(baseUrl).isEqualTo(HttpUrl.get("http://example.com/")); } @Test public void baseHttpUrlPropagated() { HttpUrl url = HttpUrl.get("http://example.com/"); Retrofit retrofit = new Retrofit.Builder().baseUrl(url).build(); assertThat(retrofit.baseUrl()).isSameInstanceAs(url); } @Test public void baseJavaUrlPropagated() throws MalformedURLException { URL url = new URL("http://example.com/"); Retrofit retrofit = new Retrofit.Builder().baseUrl(url).build(); assertThat(retrofit.baseUrl()).isEqualTo(HttpUrl.get("http://example.com/")); } @Test public void clientNullThrows() { try { new Retrofit.Builder().client(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("client == null"); } } @Test public void callFactoryDefault() { Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com").build(); assertThat(retrofit.callFactory()).isNotNull(); } @Test public void callFactoryPropagated() { okhttp3.Call.Factory callFactory = request -> { throw new AssertionError(); }; Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").callFactory(callFactory).build(); assertThat(retrofit.callFactory()).isSameInstanceAs(callFactory); } @Test public void callFactoryClientPropagated() { OkHttpClient client = new OkHttpClient(); Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").client(client).build(); assertThat(retrofit.callFactory()).isSameInstanceAs(client); } @Test public void callFactoryUsed() throws IOException { final AtomicBoolean called = new AtomicBoolean(); okhttp3.Call.Factory callFactory = request -> { called.set(true); return new OkHttpClient().newCall(request); }; Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).callFactory(callFactory).build(); server.enqueue(new MockResponse()); CallMethod service = retrofit.create(CallMethod.class); service.getResponseBody().execute(); assertTrue(called.get()); } @Test public void callFactoryReturningNullThrows() throws IOException { okhttp3.Call.Factory callFactory = request -> null; Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").callFactory(callFactory).build(); server.enqueue(new MockResponse()); CallMethod service = retrofit.create(CallMethod.class); Call call = service.getResponseBody(); try { call.execute(); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("Call.Factory returned null."); } } @Test public void callFactoryThrowingPropagates() { final RuntimeException cause = new RuntimeException("Broken!"); okhttp3.Call.Factory callFactory = request -> { throw cause; }; Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").callFactory(callFactory).build(); server.enqueue(new MockResponse()); CallMethod service = retrofit.create(CallMethod.class); Call call = service.getResponseBody(); try { call.execute(); fail(); } catch (Exception e) { assertThat(e).isSameInstanceAs(cause); } } @Test public void converterNullThrows() { try { new Retrofit.Builder().addConverterFactory(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("factory == null"); } } @Test public void converterFactoryDefault() { Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").build(); List converterFactories = retrofit.converterFactories(); assertThat(converterFactories).hasSize(2); assertThat(converterFactories.get(0)).isInstanceOf(BuiltInConverters.class); } @Test public void builtInConvertersFirstInClone() { Converter.Factory factory = new Converter.Factory() { @Nullable @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { throw new AssertionError( "User converter factory shouldn't be called for built-in types"); } }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(factory) .build() .newBuilder() // Do a newBuilder().builder() dance to force the internal list to clone. .build(); assertNotNull(retrofit.responseBodyConverter(Void.class, new Annotation[0])); } @Test public void requestConverterFactoryQueried() { final Converter expectedAdapter = new Converter() { @Nullable @Override public RequestBody convert(Object value) { throw new AssertionError(); } }; Converter.Factory factory = new Converter.Factory() { @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return String.class.equals(type) ? expectedAdapter : null; } }; Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").addConverterFactory(factory).build(); Converter actualAdapter = retrofit.requestBodyConverter(String.class, new Annotation[0], new Annotation[0]); assertThat(actualAdapter).isSameInstanceAs(expectedAdapter); } @Test public void requestConverterFactoryNoMatchThrows() { Type type = String.class; Annotation[] annotations = new Annotation[0]; NonMatchingConverterFactory nonMatchingFactory = new NonMatchingConverterFactory(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(nonMatchingFactory) .build(); try { retrofit.requestBodyConverter(type, annotations, annotations); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Could not locate RequestBody converter for class java.lang.String.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.helpers.NonMatchingConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } assertThat(nonMatchingFactory.called).isTrue(); } @Test public void requestConverterFactorySkippedNoMatchThrows() { Type type = String.class; Annotation[] annotations = new Annotation[0]; NonMatchingConverterFactory nonMatchingFactory1 = new NonMatchingConverterFactory(); NonMatchingConverterFactory nonMatchingFactory2 = new NonMatchingConverterFactory(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(nonMatchingFactory1) .addConverterFactory(nonMatchingFactory2) .build(); try { retrofit.nextRequestBodyConverter(nonMatchingFactory1, type, annotations, annotations); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Could not locate RequestBody converter for class java.lang.String.\n" + " Skipped:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.helpers.NonMatchingConverterFactory\n" + " Tried:\n" + " * retrofit2.helpers.NonMatchingConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } assertThat(nonMatchingFactory1.called).isFalse(); assertThat(nonMatchingFactory2.called).isTrue(); } @Test public void responseConverterFactoryQueried() { final Converter expectedAdapter = new Converter() { @Nullable @Override public Object convert(ResponseBody value) { throw new AssertionError(); } }; Converter.Factory factory = new Converter.Factory() { @Nullable @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return String.class.equals(type) ? expectedAdapter : null; } }; Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").addConverterFactory(factory).build(); Converter actualAdapter = retrofit.responseBodyConverter(String.class, new Annotation[0]); assertThat(actualAdapter).isSameInstanceAs(expectedAdapter); } @Test public void responseConverterFactoryNoMatchThrows() { Type type = String.class; Annotation[] annotations = new Annotation[0]; NonMatchingConverterFactory nonMatchingFactory = new NonMatchingConverterFactory(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(nonMatchingFactory) .build(); try { retrofit.responseBodyConverter(type, annotations); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Could not locate ResponseBody converter for class java.lang.String.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.helpers.NonMatchingConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } assertThat(nonMatchingFactory.called).isTrue(); } @Test public void responseConverterFactorySkippedNoMatchThrows() { Type type = String.class; Annotation[] annotations = new Annotation[0]; NonMatchingConverterFactory nonMatchingFactory1 = new NonMatchingConverterFactory(); NonMatchingConverterFactory nonMatchingFactory2 = new NonMatchingConverterFactory(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(nonMatchingFactory1) .addConverterFactory(nonMatchingFactory2) .build(); try { retrofit.nextResponseBodyConverter(nonMatchingFactory1, type, annotations); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Could not locate ResponseBody converter for class java.lang.String.\n" + " Skipped:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.helpers.NonMatchingConverterFactory\n" + " Tried:\n" + " * retrofit2.helpers.NonMatchingConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } assertThat(nonMatchingFactory1.called).isFalse(); assertThat(nonMatchingFactory2.called).isTrue(); } @Test public void stringConverterFactoryQueried() { final Converter expectedConverter = new Converter() { @Nullable @Override public String convert(Object value) { throw new AssertionError(); } }; Converter.Factory factory = new Converter.Factory() { @Nullable @Override public Converter stringConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return Object.class.equals(type) ? expectedConverter : null; } }; Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").addConverterFactory(factory).build(); Converter actualConverter = retrofit.stringConverter(Object.class, new Annotation[0]); assertThat(actualConverter).isSameInstanceAs(expectedConverter); } @Test public void converterFactoryPropagated() { Converter.Factory factory = new Converter.Factory() {}; Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").addConverterFactory(factory).build(); assertThat(retrofit.converterFactories()).contains(factory); } @Test public void callAdapterFactoryNullThrows() { try { new Retrofit.Builder().addCallAdapterFactory(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("factory == null"); } } @Test public void callAdapterFactoryDefault() { Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").build(); assertThat(retrofit.callAdapterFactories()).isNotEmpty(); } @Test public void callAdapterFactoryPropagated() { CallAdapter.Factory factory = new CallAdapter.Factory() { @Nullable @Override public CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { throw new AssertionError(); } }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addCallAdapterFactory(factory) .build(); assertThat(retrofit.callAdapterFactories()).contains(factory); } @Test public void callAdapterFactoryQueried() { final CallAdapter expectedAdapter = new CallAdapter() { @Override public Type responseType() { throw new AssertionError(); } @Override public Object adapt(Call call) { throw new AssertionError(); } }; CallAdapter.Factory factory = new CallAdapter.Factory() { @Nullable @Override public CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { return String.class.equals(returnType) ? expectedAdapter : null; } }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addCallAdapterFactory(factory) .build(); CallAdapter actualAdapter = retrofit.callAdapter(String.class, new Annotation[0]); assertThat(actualAdapter).isSameInstanceAs(expectedAdapter); } @Test public void callAdapterFactoryQueriedCanDelegate() { final CallAdapter expectedAdapter = new CallAdapter() { @Override public Type responseType() { throw new AssertionError(); } @Override public Object adapt(Call call) { throw new AssertionError(); } }; CallAdapter.Factory factory2 = new CallAdapter.Factory() { @Override public CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { return expectedAdapter; } }; final AtomicBoolean factory1called = new AtomicBoolean(); CallAdapter.Factory factory1 = new CallAdapter.Factory() { @Override public CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { factory1called.set(true); return retrofit.nextCallAdapter(this, returnType, annotations); } }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addCallAdapterFactory(factory1) .addCallAdapterFactory(factory2) .build(); CallAdapter actualAdapter = retrofit.callAdapter(String.class, new Annotation[0]); assertThat(actualAdapter).isSameInstanceAs(expectedAdapter); assertTrue(factory1called.get()); } @Test public void callAdapterFactoryQueriedCanDelegateTwiceWithoutRecursion() { Type type = String.class; Annotation[] annotations = new Annotation[0]; final CallAdapter expectedAdapter = new CallAdapter() { @Override public Type responseType() { throw new AssertionError(); } @Override public Object adapt(Call call) { throw new AssertionError(); } }; CallAdapter.Factory factory3 = new CallAdapter.Factory() { @Override public CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { return expectedAdapter; } }; final AtomicBoolean factory2called = new AtomicBoolean(); CallAdapter.Factory factory2 = new CallAdapter.Factory() { @Override public CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { factory2called.set(true); return retrofit.nextCallAdapter(this, returnType, annotations); } }; final AtomicBoolean factory1called = new AtomicBoolean(); CallAdapter.Factory factory1 = new CallAdapter.Factory() { @Override public CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { factory1called.set(true); return retrofit.nextCallAdapter(this, returnType, annotations); } }; Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addCallAdapterFactory(factory1) .addCallAdapterFactory(factory2) .addCallAdapterFactory(factory3) .build(); CallAdapter actualAdapter = retrofit.callAdapter(type, annotations); assertThat(actualAdapter).isSameInstanceAs(expectedAdapter); assertTrue(factory1called.get()); assertTrue(factory2called.get()); } @Test public void callAdapterFactoryNoMatchThrows() { Type type = String.class; Annotation[] annotations = new Annotation[0]; NonMatchingCallAdapterFactory nonMatchingFactory = new NonMatchingCallAdapterFactory(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addCallAdapterFactory(nonMatchingFactory) .build(); try { retrofit.callAdapter(type, annotations); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Could not locate call adapter for class java.lang.String.\n" + " Tried:\n" + " * retrofit2.helpers.NonMatchingCallAdapterFactory\n" + " * retrofit2.CompletableFutureCallAdapterFactory\n" + " * retrofit2.DefaultCallAdapterFactory"); } assertThat(nonMatchingFactory.called).isTrue(); } @Test public void callAdapterFactoryDelegateNoMatchThrows() { Type type = String.class; Annotation[] annotations = new Annotation[0]; DelegatingCallAdapterFactory delegatingFactory1 = new DelegatingCallAdapterFactory(); DelegatingCallAdapterFactory delegatingFactory2 = new DelegatingCallAdapterFactory(); NonMatchingCallAdapterFactory nonMatchingFactory = new NonMatchingCallAdapterFactory(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addCallAdapterFactory(delegatingFactory1) .addCallAdapterFactory(delegatingFactory2) .addCallAdapterFactory(nonMatchingFactory) .build(); try { retrofit.callAdapter(type, annotations); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Could not locate call adapter for class java.lang.String.\n" + " Skipped:\n" + " * retrofit2.helpers.DelegatingCallAdapterFactory\n" + " * retrofit2.helpers.DelegatingCallAdapterFactory\n" + " Tried:\n" + " * retrofit2.helpers.NonMatchingCallAdapterFactory\n" + " * retrofit2.CompletableFutureCallAdapterFactory\n" + " * retrofit2.DefaultCallAdapterFactory"); } assertThat(delegatingFactory1.called).isTrue(); assertThat(delegatingFactory2.called).isTrue(); assertThat(nonMatchingFactory.called).isTrue(); } @Test public void platformAwareAdapterAbsentInCloneBuilder() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); assertEquals(0, retrofit.newBuilder().callAdapterFactories().size()); } @Test public void callbackExecutorNullThrows() { try { new Retrofit.Builder().callbackExecutor(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("executor == null"); } } @Test public void callbackExecutorPropagated() { Executor executor = command -> { throw new AssertionError(); }; Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com/").callbackExecutor(executor).build(); assertThat(retrofit.callbackExecutor()).isSameInstanceAs(executor); } @Test public void callbackExecutorUsedForSuccess() throws InterruptedException { final CountDownLatch runnableLatch = new CountDownLatch(1); final AtomicReference runnableRef = new AtomicReference<>(); Executor executor = command -> { runnableRef.set(command); runnableLatch.countDown(); }; Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).callbackExecutor(executor).build(); CallMethod service = retrofit.create(CallMethod.class); Call call = service.getResponseBody(); server.enqueue(new MockResponse()); final CountDownLatch callbackLatch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { callbackLatch.countDown(); } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); } }); assertTrue(runnableLatch.await(2, TimeUnit.SECONDS)); assertEquals(1, callbackLatch.getCount()); // Callback not run yet. runnableRef.get().run(); assertTrue(callbackLatch.await(2, TimeUnit.SECONDS)); } @Test public void callbackExecutorUsedForFailure() throws InterruptedException { final CountDownLatch runnableLatch = new CountDownLatch(1); final AtomicReference runnableRef = new AtomicReference<>(); Executor executor = command -> { runnableRef.set(command); runnableLatch.countDown(); }; Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).callbackExecutor(executor).build(); CallMethod service = retrofit.create(CallMethod.class); Call call = service.getResponseBody(); server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AT_START)); final CountDownLatch callbackLatch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { callbackLatch.countDown(); } }); assertTrue(runnableLatch.await(2, TimeUnit.SECONDS)); assertEquals(1, callbackLatch.getCount()); // Callback not run yet. runnableRef.get().run(); assertTrue(callbackLatch.await(2, TimeUnit.SECONDS)); } @Test public void skippedCallbackExecutorNotUsedForSuccess() throws InterruptedException { Executor executor = command -> fail(); Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).callbackExecutor(executor).build(); CallMethod service = retrofit.create(CallMethod.class); Call call = service.getResponseBodySkippedExecutor(); server.enqueue(new MockResponse()); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); } }); assertTrue(latch.await(2, TimeUnit.SECONDS)); } @Test public void skippedCallbackExecutorNotUsedForFailure() throws InterruptedException { Executor executor = command -> fail(); Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).callbackExecutor(executor).build(); CallMethod service = retrofit.create(CallMethod.class); Call call = service.getResponseBodySkippedExecutor(); server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AT_START)); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { latch.countDown(); } }); assertTrue(latch.await(2, TimeUnit.SECONDS)); } /** Confirm that Retrofit encodes parameters when the call is executed, and not earlier. */ @Test public void argumentCapture() throws Exception { AtomicInteger i = new AtomicInteger(); server.enqueue(new MockResponse().setBody("a")); server.enqueue(new MockResponse().setBody("b")); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ToStringConverterFactory()) .build(); MutableParameters mutableParameters = retrofit.create(MutableParameters.class); i.set(100); Call call1 = mutableParameters.method(i); i.set(101); Response response1 = call1.execute(); i.set(102); assertEquals("a", response1.body()); assertEquals("/?i=101", server.takeRequest().getPath()); i.set(200); Call call2 = call1.clone(); i.set(201); Response response2 = call2.execute(); i.set(202); assertEquals("b", response2.body()); assertEquals("/?i=201", server.takeRequest().getPath()); } @Test public void annotationParsingFailureObservedByWaitingThreads() throws InterruptedException { AtomicInteger fails = new AtomicInteger(); CountDownLatch startedParsing = new CountDownLatch(1); CountDownLatch failParsing = new CountDownLatch(1); RuntimeException failure = new RuntimeException("boom!"); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new Converter.Factory() { @Nullable @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { startedParsing.countDown(); try { failParsing.await(); } catch (InterruptedException e) { throw new AssertionError(e); } fails.incrementAndGet(); throw failure; } }) .build(); Annotated service = retrofit.create(Annotated.class); AtomicReference result1 = new AtomicReference<>(); Thread thread1 = new Thread( () -> { try { service.method(); } catch (RuntimeException e) { result1.set(e); } }); thread1.start(); // Wait for thread1 to enter the converter. This means it has inserted and taken a lock on // parsing for the method. startedParsing.await(); CountDownLatch thread2Locked = new CountDownLatch(1); AtomicReference result2 = new AtomicReference<>(); Thread thread2 = new Thread( () -> { try { thread2Locked.countDown(); service.method(); } catch (RuntimeException e) { result2.set(e); } }); thread2.start(); thread2Locked.await(); // Wait for thread2 to lock on the shared object. This should be pretty fast after the last // signal, but we have no way of knowing for sure it happened. Thread.sleep(1_000); failParsing.countDown(); thread1.join(); thread2.join(); RuntimeException failure1 = result1.get(); assertThat(failure1).isInstanceOf(IllegalArgumentException.class); assertThat(failure1).hasCauseThat().isSameInstanceAs(failure); RuntimeException failure2 = result2.get(); assertThat(failure2).isInstanceOf(IllegalArgumentException.class); assertThat(failure2).hasCauseThat().isSameInstanceAs(failure); // Importantly, even though the second thread was locked waiting on the first, failure of the // first thread caused the second thread to retry parsing. assertThat(fails.get()).isEqualTo(2); // Make sure now that both threads have released the lock, new callers also retry. RuntimeException failure3 = assertThrows(IllegalArgumentException.class, service::method); assertThat(failure3).hasCauseThat().isSameInstanceAs(failure); assertThat(fails.get()).isEqualTo(3); } } ================================================ FILE: retrofit/kotlin-test/build.gradle ================================================ apply plugin: 'org.jetbrains.kotlin.jvm' dependencies { testImplementation projects.retrofit testImplementation projects.retrofit.testHelpers testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver testImplementation libs.kotlinx.coroutines } ================================================ FILE: retrofit/kotlin-test/src/test/java/retrofit2/KotlinExtensionsTest.kt ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2 import okhttp3.mockwebserver.MockWebServer import org.junit.Assert.assertNotNull import org.junit.Rule import org.junit.Test class KotlinExtensionsTest { @get:Rule val server = MockWebServer() interface Empty @Test fun reifiedCreate() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .build() assertNotNull(retrofit.create()) } } ================================================ FILE: retrofit/kotlin-test/src/test/java/retrofit2/KotlinRequestFactoryTest.java ================================================ package retrofit2; import kotlin.Unit; import okhttp3.Request; import org.junit.Test; import retrofit2.http.HEAD; import static com.google.common.truth.Truth.assertThat; import static retrofit2.TestingUtils.buildRequest; public final class KotlinRequestFactoryTest { @Test public void headUnit() { class Example { @HEAD("/foo/bar/") Call method() { return null; } } Request request = buildRequest(Example.class); assertThat(request.method()).isEqualTo("HEAD"); assertThat(request.headers().size()).isEqualTo(0); assertThat(request.url().toString()).isEqualTo("http://example.com/foo/bar/"); assertThat(request.body()).isNull(); } } ================================================ FILE: retrofit/kotlin-test/src/test/java/retrofit2/KotlinSuspendRawTest.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import kotlin.coroutines.Continuation; import okhttp3.mockwebserver.MockWebServer; import org.junit.Rule; import org.junit.Test; import retrofit2.http.GET; /** * This code path can only be tested from Java because Kotlin does not allow you specify a raw * Response type. Win! We still test this codepath for completeness. */ public final class KotlinSuspendRawTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Object body(Continuation response); } @Test public void raw() { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); Service service = retrofit.create(Service.class); try { service.body(null); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat().isEqualTo( "Response must include generic type (e.g., Response)\n" + " for method Service.body"); } } } ================================================ FILE: retrofit/kotlin-test/src/test/java/retrofit2/KotlinSuspendTest.kt ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2 import com.google.common.truth.Truth.assertThat import java.io.IOException import java.lang.reflect.ParameterizedType import java.lang.reflect.Type import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST import okhttp3.mockwebserver.SocketPolicy.NO_RESPONSE import org.junit.Assert.assertTrue import org.junit.Assert.fail import org.junit.Ignore import org.junit.Rule import org.junit.Test import retrofit2.helpers.ToStringConverterFactory import retrofit2.http.GET import retrofit2.http.HEAD import retrofit2.http.Path class KotlinSuspendTest { @get:Rule val server = MockWebServer() interface Service { @GET("/") suspend fun body(): String @GET("/") suspend fun bodyNullable(): String? @GET("/") suspend fun response(): Response @GET("/") suspend fun unit() @HEAD("/") suspend fun headUnit() @GET("/{a}/{b}/{c}") suspend fun params( @Path("a") a: String, @Path("b") b: String, @Path("c") c: String, ): String @GET("/") suspend fun bodyWithCallType(): Call } @Test fun body() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setBody("Hi")) val body = runBlocking { example.body() } assertThat(body).isEqualTo("Hi") } @Test fun body404() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setResponseCode(404)) try { runBlocking { example.body() } fail() } catch (e: HttpException) { assertThat(e.code()).isEqualTo(404) } } @Test fun bodyFailure() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)) try { runBlocking { example.body() } fail() } catch (e: IOException) { } } @Test fun bodyThrowsOnNull() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setResponseCode(204)) try { runBlocking { example.body() } fail() } catch (e: KotlinNullPointerException) { // Coroutines wraps exceptions with a synthetic trace so fall back to cause message. val message = e.message ?: (e.cause as KotlinNullPointerException).message assertThat(message).isEqualTo( "Response from retrofit2.KotlinSuspendTest\$Service.body was null but response body type was declared as non-null", ) } } @Ignore("Not working yet") @Test fun bodyNullable() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setResponseCode(204)) val body = runBlocking { example.bodyNullable() } assertThat(body).isNull() } @Test fun response() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setBody("Hi")) val response = runBlocking { example.response() } assertThat(response.code()).isEqualTo(200) assertThat(response.body()).isEqualTo("Hi") } @Test fun response404() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setResponseCode(404)) val response = runBlocking { example.response() } assertThat(response.code()).isEqualTo(404) } @Test fun responseFailure() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)) try { runBlocking { example.response() } fail() } catch (e: IOException) { } } @Test fun unit() { val retrofit = Retrofit.Builder().baseUrl(server.url("/")).build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setBody("Unit")) runBlocking { example.unit() } } @Test fun unitNullableBody() { val retrofit = Retrofit.Builder().baseUrl(server.url("/")).build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setResponseCode(204)) runBlocking { example.unit() } } @Test fun headUnit() { val retrofit = Retrofit.Builder().baseUrl(server.url("/")).build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse()) runBlocking { example.headUnit() } } @Test fun params() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse()) runBlocking { example.params("1", "2", "3") } val request = server.takeRequest() assertThat(request.path).isEqualTo("/1/2/3") } @Test fun cancelationWorks() { lateinit var call: okhttp3.Call val okHttpClient = OkHttpClient() val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .callFactory { val newCall = okHttpClient.newCall(it) call = newCall newCall } .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) // This leaves the connection open indefinitely allowing us to cancel without racing a body. server.enqueue(MockResponse().setSocketPolicy(NO_RESPONSE)) val deferred = GlobalScope.async { example.body() } // This will block until the server has received the request ensuring it's in flight. server.takeRequest() deferred.cancel() assertTrue(call.isCanceled()) } @Test fun doesNotUseCallbackExecutor() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .callbackExecutor { fail() } .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setBody("Hi")) val body = runBlocking { example.body() } assertThat(body).isEqualTo("Hi") } @Test fun usesCallAdapterForCall() { val callAdapterFactory = object : CallAdapter.Factory() { override fun get( returnType: Type, annotations: Array, retrofit: Retrofit, ): CallAdapter<*, *>? { if (getRawType(returnType) != Call::class.java) { return null } if (getParameterUpperBound(0, returnType as ParameterizedType) != String::class.java) { return null } return object : CallAdapter> { override fun responseType() = String::class.java override fun adapt(call: Call): Call { return object : Call by call { override fun enqueue(callback: Callback) { call.enqueue(object : Callback by callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful) { callback.onResponse(call, Response.success(response.body()?.repeat(5))) } else { callback.onResponse(call, response) } } }) } } } } } } val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(callAdapterFactory) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.enqueue(MockResponse().setBody("Hi")) val body = runBlocking { example.body() } assertThat(body).isEqualTo("HiHiHiHiHi") } @Test fun checkedExceptionsAreNotSynchronouslyThrownForBody() = runBlocking { val retrofit = Retrofit.Builder() .baseUrl("https://unresolved-host.com/") .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.shutdown() // Run with a dispatcher that prevents yield from actually deferring work. An old workaround // for this problem relied on yield, but it is not guaranteed to prevent direct execution. withContext(DirectUnconfinedDispatcher) { // The problematic behavior of the UnknownHostException being synchronously thrown is // probabilistic based on thread preemption. Running a thousand times will almost always // trigger it, so we run an order of magnitude more to be safe. repeat(10000) { try { example.body() fail() } catch (_: IOException) { // We expect IOException, the bad behavior will wrap this in UndeclaredThrowableException. } } } } @Test fun checkedExceptionsAreNotSynchronouslyThrownForResponse() = runBlocking { val retrofit = Retrofit.Builder() .baseUrl("https://unresolved-host.com/") .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) server.shutdown() // Run with a dispatcher that prevents yield from actually deferring work. An old workaround // for this problem relied on yield, but it is not guaranteed to prevent direct execution. withContext(DirectUnconfinedDispatcher) { // The problematic behavior of the UnknownHostException being synchronously thrown is // probabilistic based on thread preemption. Running a thousand times will almost always // trigger it, so we run an order of magnitude more to be safe. repeat(10000) { try { example.response() fail() } catch (_: IOException) { // We expect IOException, the bad behavior will wrap this in UndeclaredThrowableException. } } } } @Test fun rejectCallReturnTypeWhenUsingSuspend() { val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ToStringConverterFactory()) .build() val example = retrofit.create(Service::class.java) try { runBlocking { example.bodyWithCallType() } fail() } catch (e: IllegalArgumentException) { assertThat(e).hasMessageThat().isEqualTo( "Suspend functions should not return Call, as they already execute asynchronously.\n" + "Change its return type to class java.lang.String\n" + " for method Service.bodyWithCallType", ) } } @Suppress("EXPERIMENTAL_OVERRIDE") private object DirectUnconfinedDispatcher : CoroutineDispatcher() { override fun isDispatchNeeded(context: CoroutineContext): Boolean = false override fun dispatch(context: CoroutineContext, block: Runnable) = block.run() } } ================================================ FILE: retrofit/kotlin-test/src/test/java/retrofit2/KotlinUnitTest.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static com.google.common.truth.Truth.assertThat; import java.io.IOException; import kotlin.Unit; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Rule; import org.junit.Test; import retrofit2.http.GET; import retrofit2.http.HEAD; public final class KotlinUnitTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Call empty(); @HEAD("/") Call head(); } @Test public void unitGet() throws IOException { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); Response response = example.empty().execute(); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isSameInstanceAs(Unit.INSTANCE); } @Test public void unitHead() throws IOException { Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).build(); Service example = retrofit.create(Service.class); server.enqueue(new MockResponse().setBody("Hi")); Response response = example.head().execute(); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isSameInstanceAs(Unit.INSTANCE); } } ================================================ FILE: retrofit/robovm-test/build.gradle ================================================ // Normally we want all buildscript classpath dependencies to be at the root so that they // participate in a single round of dependency resolution. However, the RoboVM plugin // bundles outdated dependencies like BouncyCastle that are essential to other plugins (namely, AGP) // without shading them into a new package. Moving it to this project works around this problem. buildscript { dependencies { classpath libs.robovmPlugin } repositories { mavenCentral() } } apply plugin: 'java' apply plugin: 'robovm' ext.mainClassName = 'retrofit2.RoboVmPlatformTest' robovm { archs = 'x86_64' } dependencies { implementation projects.retrofit implementation libs.robovm } task robovmTest(type: Exec) { dependsOn { robovmInstall } commandLine './build/robovm/retrofit2.RoboVmPlatformTest' } ================================================ FILE: retrofit/robovm-test/src/main/java/retrofit2/RoboVmPlatformTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; public final class RoboVmPlatformTest { public static void main(String[] args) { Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com") .callFactory(c -> { throw new AssertionError(); }) .build(); if (retrofit.callAdapterFactories().size() > 1) { // Everyone gets the callback executor adapter. If RoboVM was correctly detected it will NOT // get the Java 8-supporting CompletableFuture call adapter factory. System.exit(1); } } private RoboVmPlatformTest() { } } ================================================ FILE: retrofit/src/main/java/retrofit2/AndroidMainExecutor.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import android.os.Handler; import android.os.Looper; import java.util.concurrent.Executor; final class AndroidMainExecutor implements Executor { private final Handler handler = new Handler(Looper.getMainLooper()); @Override public void execute(Runnable r) { handler.post(r); } } ================================================ FILE: retrofit/src/main/java/retrofit2/BuiltInConverters.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import kotlin.Unit; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.http.Streaming; final class BuiltInConverters extends Converter.Factory { @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (type == ResponseBody.class) { return Utils.isAnnotationPresent(annotations, Streaming.class) ? StreamingResponseBodyConverter.INSTANCE : BufferingResponseBodyConverter.INSTANCE; } if (type == Void.class) { return VoidResponseBodyConverter.INSTANCE; } if (Utils.isUnit(type)) { return UnitResponseBodyConverter.INSTANCE; } return null; } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) { return RequestBodyConverter.INSTANCE; } return null; } static final class VoidResponseBodyConverter implements Converter { static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter(); @Override public Void convert(ResponseBody value) { value.close(); return null; } } static final class UnitResponseBodyConverter implements Converter { static final UnitResponseBodyConverter INSTANCE = new UnitResponseBodyConverter(); @Override public Unit convert(ResponseBody value) { value.close(); return Unit.INSTANCE; } } static final class RequestBodyConverter implements Converter { static final RequestBodyConverter INSTANCE = new RequestBodyConverter(); @Override public RequestBody convert(RequestBody value) { return value; } } static final class StreamingResponseBodyConverter implements Converter { static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter(); @Override public ResponseBody convert(ResponseBody value) { return value; } } static final class BufferingResponseBodyConverter implements Converter { static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter(); @Override public ResponseBody convert(ResponseBody value) throws IOException { try { // Buffer the entire body to avoid future I/O. return Utils.buffer(value); } finally { value.close(); } } } static final class ToStringConverter implements Converter { static final ToStringConverter INSTANCE = new ToStringConverter(); @Override public String convert(Object value) { return value.toString(); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/BuiltInFactories.java ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import android.annotation.TargetApi; import java.util.List; import java.util.concurrent.Executor; import javax.annotation.Nullable; class BuiltInFactories { List createDefaultCallAdapterFactories( @Nullable Executor callbackExecutor) { return singletonList(new DefaultCallAdapterFactory(callbackExecutor)); } List createDefaultConverterFactories() { return emptyList(); } @TargetApi(24) static final class Java8 extends BuiltInFactories { @Override List createDefaultCallAdapterFactories( @Nullable Executor callbackExecutor) { return asList( new CompletableFutureCallAdapterFactory(), new DefaultCallAdapterFactory(callbackExecutor)); } @Override List createDefaultConverterFactories() { return singletonList(new OptionalConverterFactory()); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/Call.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.io.IOException; import okhttp3.Request; import okio.Timeout; /** * An invocation of a Retrofit method that sends a request to a webserver and returns a response. * Each call yields its own HTTP request and response pair. Use {@link #clone} to make multiple * calls with the same parameters to the same webserver; this may be used to implement polling or to * retry a failed call. * *

Calls may be executed synchronously with {@link #execute}, or asynchronously with {@link * #enqueue}. In either case the call can be canceled at any time with {@link #cancel}. A call that * is busy writing its request or reading its response may receive a {@link IOException}; this is * working as designed. * * @param Successful response body type. */ public interface Call extends Cloneable { /** * Synchronously send the request and return its response. * * @throws IOException if a problem occurred talking to the server. * @throws RuntimeException (and subclasses) if an unexpected error occurs creating the request or * decoding the response. */ Response execute() throws IOException; /** * Asynchronously send the request and notify {@code callback} of its response or if an error * occurred talking to the server, creating the request, or processing the response. */ void enqueue(Callback callback); /** * Returns true if this call has been either {@linkplain #execute() executed} or {@linkplain * #enqueue(Callback) enqueued}. It is an error to execute or enqueue a call more than once. */ boolean isExecuted(); /** * Cancel this call. An attempt will be made to cancel in-flight calls, and if the call has not * yet been executed it never will be. */ void cancel(); /** True if {@link #cancel()} was called. */ boolean isCanceled(); /** * Create a new, identical call to this one which can be enqueued or executed even if this call * has already been. */ Call clone(); /** The original HTTP request. */ Request request(); /** * Returns a timeout that spans the entire call: resolving DNS, connecting, writing the request * body, server processing, and reading the response body. If the call requires redirects or * retries all must complete within one timeout period. */ Timeout timeout(); } ================================================ FILE: retrofit/src/main/java/retrofit2/CallAdapter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.annotation.Nullable; /** * Adapts a {@link Call} with response type {@code R} into the type of {@code T}. Instances are * created by {@linkplain Factory a factory} which is {@linkplain * Retrofit.Builder#addCallAdapterFactory(Factory) installed} into the {@link Retrofit} instance. */ public interface CallAdapter { /** * Returns the value type that this adapter uses when converting the HTTP response body to a Java * object. For example, the response type for {@code Call} is {@code Repo}. This type is * used to prepare the {@code call} passed to {@code #adapt}. * *

Note: This is typically not the same type as the {@code returnType} provided to this call * adapter's factory. */ Type responseType(); /** * Returns an instance of {@code T} which delegates to {@code call}. * *

For example, given an instance for a hypothetical utility, {@code Async}, this instance * would return a new {@code Async} which invoked {@code call} when run. * *


   * @Override
   * public <R> Async<R> adapt(final Call<R> call) {
   *   return Async.create(new Callable<Response<R>>() {
   *     @Override
   *     public Response<R> call() throws Exception {
   *       return call.execute();
   *     }
   *   });
   * }
   * 
*/ T adapt(Call call); /** * Creates {@link CallAdapter} instances based on the return type of {@linkplain * Retrofit#create(Class) the service interface} methods. */ abstract class Factory { /** * Returns a call adapter for interface methods that return {@code returnType}, or null if it * cannot be handled by this factory. */ public abstract @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit); /** * Extract the upper bound of the generic parameter at {@code index} from {@code type}. For * example, index 1 of {@code Map} returns {@code Runnable}. */ protected static Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); } /** * Extract the raw class type from {@code type}. For example, the type representing {@code * List} returns {@code List.class}. */ protected static Class getRawType(Type type) { return Utils.getRawType(type); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/Callback.java ================================================ /* * Copyright (C) 2012 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; /** * Communicates responses from a server or offline requests. One and only one method will be invoked * in response to a given request. * *

Callback methods are executed using the {@link Retrofit} callback executor. When none is * specified, the following defaults are used: * *

    *
  • Android: Callbacks are executed on the application's main (UI) thread. *
  • JVM: Callbacks are executed on the background thread which performed the request. *
* * @param Successful response body type. */ public interface Callback { /** * Invoked for a received HTTP response. * *

Note: An HTTP response may still indicate an application-level failure such as a 404 or 500. * Call {@link Response#isSuccessful()} to determine if the response indicates success. */ void onResponse(Call call, Response response); /** * Invoked when a network exception occurred talking to the server or when an unexpected exception * occurred creating the request or processing the response. */ void onFailure(Call call, Throwable t); } ================================================ FILE: retrofit/src/main/java/retrofit2/CompletableFutureCallAdapterFactory.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import android.annotation.TargetApi; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.concurrent.CompletableFuture; import javax.annotation.Nullable; import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; @IgnoreJRERequirement // Only added when CompletableFuture is available (Java 8+ / Android API 24+). @TargetApi(24) final class CompletableFutureCallAdapterFactory extends CallAdapter.Factory { @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != CompletableFuture.class) { return null; } if (!(returnType instanceof ParameterizedType)) { throw new IllegalStateException( "CompletableFuture return type must be parameterized" + " as CompletableFuture or CompletableFuture"); } Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType); if (getRawType(innerType) != Response.class) { // Generic type is not Response. Use it for body-only adapter. return new BodyCallAdapter<>(innerType); } // Generic type is Response. Extract T and create the Response version of the adapter. if (!(innerType instanceof ParameterizedType)) { throw new IllegalStateException( "Response must be parameterized" + " as Response or Response"); } Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType); return new ResponseCallAdapter<>(responseType); } @IgnoreJRERequirement private static final class BodyCallAdapter implements CallAdapter> { private final Type responseType; BodyCallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public CompletableFuture adapt(final Call call) { CompletableFuture future = new CallCancelCompletableFuture<>(call); call.enqueue(new BodyCallback(future)); return future; } @IgnoreJRERequirement private class BodyCallback implements Callback { private final CompletableFuture future; public BodyCallback(CompletableFuture future) { this.future = future; } @Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { future.complete(response.body()); } else { future.completeExceptionally(new HttpException(response)); } } @Override public void onFailure(Call call, Throwable t) { future.completeExceptionally(t); } } } @IgnoreJRERequirement private static final class ResponseCallAdapter implements CallAdapter>> { private final Type responseType; ResponseCallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public CompletableFuture> adapt(final Call call) { CompletableFuture> future = new CallCancelCompletableFuture<>(call); call.enqueue(new ResponseCallback(future)); return future; } @IgnoreJRERequirement private class ResponseCallback implements Callback { private final CompletableFuture> future; public ResponseCallback(CompletableFuture> future) { this.future = future; } @Override public void onResponse(Call call, Response response) { future.complete(response); } @Override public void onFailure(Call call, Throwable t) { future.completeExceptionally(t); } } } @IgnoreJRERequirement private static final class CallCancelCompletableFuture extends CompletableFuture { private final Call call; CallCancelCompletableFuture(Call call) { this.call = call; } @Override public boolean cancel(boolean mayInterruptIfRunning) { if (mayInterruptIfRunning) { call.cancel(); } return super.cancel(mayInterruptIfRunning); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/Converter.java ================================================ /* * Copyright (C) 2012 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.http.Body; import retrofit2.http.Field; import retrofit2.http.FieldMap; import retrofit2.http.Header; import retrofit2.http.HeaderMap; import retrofit2.http.Part; import retrofit2.http.PartMap; import retrofit2.http.Path; import retrofit2.http.Query; import retrofit2.http.QueryMap; /** * Convert objects to and from their representation in HTTP. Instances are created by {@linkplain * Factory a factory} which is {@linkplain Retrofit.Builder#addConverterFactory(Factory) installed} * into the {@link Retrofit} instance. */ public interface Converter { @Nullable T convert(F value) throws IOException; /** Creates {@link Converter} instances based on a type and target usage. */ abstract class Factory { /** * Returns a {@link Converter} for converting an HTTP response body to {@code type}, or null if * {@code type} cannot be handled by this factory. This is used to create converters for * response types such as {@code SimpleResponse} from a {@code Call} * declaration. */ public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return null; } /** * Returns a {@link Converter} for converting {@code type} to an HTTP request body, or null if * {@code type} cannot be handled by this factory. This is used to create converters for types * specified by {@link Body @Body}, {@link Part @Part}, and {@link PartMap @PartMap} values. */ public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return null; } /** * Returns a {@link Converter} for converting {@code type} to a {@link String}, or null if * {@code type} cannot be handled by this factory. This is used to create converters for types * specified by {@link Field @Field}, {@link FieldMap @FieldMap} values, {@link Header @Header}, * {@link HeaderMap @HeaderMap}, {@link Path @Path}, {@link Query @Query}, and {@link * QueryMap @QueryMap} values. */ public @Nullable Converter stringConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return null; } /** * Extract the upper bound of the generic parameter at {@code index} from {@code type}. For * example, index 1 of {@code Map} returns {@code Runnable}. */ protected static Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); } /** * Extract the raw class type from {@code type}. For example, the type representing {@code * List} returns {@code List.class}. */ protected static Class getRawType(Type type) { return Utils.getRawType(type); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/DefaultCallAdapterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Objects; import java.util.concurrent.Executor; import javax.annotation.Nullable; import okhttp3.Request; import okio.Timeout; final class DefaultCallAdapterFactory extends CallAdapter.Factory { private final @Nullable Executor callbackExecutor; DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) { this.callbackExecutor = callbackExecutor; } @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != Call.class) { return null; } if (!(returnType instanceof ParameterizedType)) { throw new IllegalArgumentException( "Call return type must be parameterized as Call or Call"); } final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType); final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : callbackExecutor; return new CallAdapter>() { @Override public Type responseType() { return responseType; } @Override public Call adapt(Call call) { return executor == null ? call : new ExecutorCallbackCall<>(executor, call); } }; } static final class ExecutorCallbackCall implements Call { final Executor callbackExecutor; final Call delegate; ExecutorCallbackCall(Executor callbackExecutor, Call delegate) { this.callbackExecutor = callbackExecutor; this.delegate = delegate; } @Override public void enqueue(final Callback callback) { Objects.requireNonNull(callback, "callback == null"); delegate.enqueue( new Callback() { @Override public void onResponse(Call call, final Response response) { callbackExecutor.execute( () -> { if (delegate.isCanceled()) { // Emulate OkHttp's behavior of throwing/delivering an IOException on // cancellation. callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled")); } else { callback.onResponse(ExecutorCallbackCall.this, response); } }); } @Override public void onFailure(Call call, final Throwable t) { callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t)); } }); } @Override public boolean isExecuted() { return delegate.isExecuted(); } @Override public Response execute() throws IOException { return delegate.execute(); } @Override public void cancel() { delegate.cancel(); } @Override public boolean isCanceled() { return delegate.isCanceled(); } @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone. @Override public Call clone() { return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone()); } @Override public Request request() { return delegate.request(); } @Override public Timeout timeout() { return delegate.timeout(); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/DefaultMethodSupport.java ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import javax.annotation.Nullable; import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; /** * From Java 8 to Java 13, the only way to invoke a default method on a proxied interface is by * reflectively creating a trusted {@link Lookup} to invoke a method handle. *

* Note: This class has multi-release jar variants for newer versions of Java. */ final class DefaultMethodSupport { private static @Nullable Constructor lookupConstructor; @IgnoreJRERequirement // Only used on JVM or Android API 24+. @Nullable static Object invoke( Method method, Class declaringClass, Object proxy, @Nullable Object[] args) throws Throwable { Constructor constructor = lookupConstructor; if (constructor == null) { constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class); constructor.setAccessible(true); lookupConstructor = constructor; } return constructor .newInstance(declaringClass, -1 /* trusted */) .unreflectSpecial(method, declaringClass) .bindTo(proxy) .invokeWithArguments(args); } private DefaultMethodSupport() {} } ================================================ FILE: retrofit/src/main/java/retrofit2/HttpException.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.util.Objects; import javax.annotation.Nullable; /** Exception for an unexpected, non-2xx HTTP response. */ public class HttpException extends RuntimeException { private static String getMessage(Response response) { Objects.requireNonNull(response, "response == null"); return "HTTP " + response.code() + " " + response.message(); } private final int code; private final String message; private final transient Response response; public HttpException(Response response) { super(getMessage(response)); this.code = response.code(); this.message = response.message(); this.response = response; } /** HTTP status code. */ public int code() { return code; } /** HTTP status message. */ public String message() { return message; } /** The full HTTP response. This may be null if the exception was serialized. */ public @Nullable Response response() { return response; } } ================================================ FILE: retrofit/src/main/java/retrofit2/HttpServiceMethod.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static retrofit2.Utils.getRawType; import static retrofit2.Utils.methodError; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.annotation.Nullable; import kotlin.Unit; import kotlin.coroutines.Continuation; import okhttp3.ResponseBody; /** Adapts an invocation of an interface method into an HTTP call. */ abstract class HttpServiceMethod extends ServiceMethod { /** * Inspects the annotations on an interface method to construct a reusable service method that * speaks HTTP. This requires potentially-expensive reflection so it is best to build each service * method only once and reuse it. */ static HttpServiceMethod parseAnnotations( Retrofit retrofit, Method method, RequestFactory requestFactory) { boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction; boolean continuationWantsResponse = false; boolean continuationBodyNullable = false; boolean continuationIsUnit = false; Annotation[] annotations = method.getAnnotations(); Type adapterType; if (isKotlinSuspendFunction) { Type[] parameterTypes = method.getGenericParameterTypes(); Type responseType = Utils.getParameterLowerBound( 0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]); if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) { // Unwrap the actual body type from Response. responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType); continuationWantsResponse = true; } else { if (getRawType(responseType) == Call.class) { throw methodError( method, "Suspend functions should not return Call, as they already execute asynchronously.\n" + "Change its return type to %s", Utils.getParameterUpperBound(0, (ParameterizedType) responseType)); } continuationIsUnit = Utils.isUnit(responseType); // TODO figure out if type is nullable or not // Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class) // Find the entry for method // Determine if return type is nullable or not } adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType); annotations = SkipCallbackExecutorImpl.ensurePresent(annotations); } else { adapterType = method.getGenericReturnType(); } CallAdapter callAdapter = createCallAdapter(retrofit, method, adapterType, annotations); Type responseType = callAdapter.responseType(); if (responseType == okhttp3.Response.class) { throw methodError( method, "'" + getRawType(responseType).getName() + "' is not a valid response body type. Did you mean ResponseBody?"); } if (responseType == Response.class) { throw methodError(method, "Response must include generic type (e.g., Response)"); } if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType) && !Utils.isUnit(responseType)) { throw methodError(method, "HEAD method must use Void or Unit as response type."); } Converter responseConverter = createResponseConverter(retrofit, method, responseType); okhttp3.Call.Factory callFactory = retrofit.callFactory; if (!isKotlinSuspendFunction) { return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter); } else if (continuationWantsResponse) { //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object. return (HttpServiceMethod) new SuspendForResponse<>( requestFactory, callFactory, responseConverter, (CallAdapter>) callAdapter); } else { //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object. return (HttpServiceMethod) new SuspendForBody<>( requestFactory, callFactory, responseConverter, (CallAdapter>) callAdapter, continuationBodyNullable, continuationIsUnit); } } private static CallAdapter createCallAdapter( Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) { try { //noinspection unchecked return (CallAdapter) retrofit.callAdapter(returnType, annotations); } catch (RuntimeException e) { // Wide exception range because factories are user code. throw methodError(method, e, "Unable to create call adapter for %s", returnType); } } private static Converter createResponseConverter( Retrofit retrofit, Method method, Type responseType) { Annotation[] annotations = method.getAnnotations(); try { return retrofit.responseBodyConverter(responseType, annotations); } catch (RuntimeException e) { // Wide exception range because factories are user code. throw methodError(method, e, "Unable to create converter for %s", responseType); } } private final RequestFactory requestFactory; private final okhttp3.Call.Factory callFactory; private final Converter responseConverter; HttpServiceMethod( RequestFactory requestFactory, okhttp3.Call.Factory callFactory, Converter responseConverter) { this.requestFactory = requestFactory; this.callFactory = callFactory; this.responseConverter = responseConverter; } @Override final @Nullable ReturnT invoke(Object instance, Object[] args) { Call call = new OkHttpCall<>(requestFactory, instance, args, callFactory, responseConverter); return adapt(call, args); } protected abstract @Nullable ReturnT adapt(Call call, Object[] args); static final class CallAdapted extends HttpServiceMethod { private final CallAdapter callAdapter; CallAdapted( RequestFactory requestFactory, okhttp3.Call.Factory callFactory, Converter responseConverter, CallAdapter callAdapter) { super(requestFactory, callFactory, responseConverter); this.callAdapter = callAdapter; } @Override protected ReturnT adapt(Call call, Object[] args) { return callAdapter.adapt(call); } } static final class SuspendForResponse extends HttpServiceMethod { private final CallAdapter> callAdapter; SuspendForResponse( RequestFactory requestFactory, okhttp3.Call.Factory callFactory, Converter responseConverter, CallAdapter> callAdapter) { super(requestFactory, callFactory, responseConverter); this.callAdapter = callAdapter; } @Override protected Object adapt(Call call, Object[] args) { call = callAdapter.adapt(call); //noinspection unchecked Checked by reflection inside RequestFactory. Continuation> continuation = (Continuation>) args[args.length - 1]; // See SuspendForBody for explanation about this try/catch. try { return KotlinExtensions.awaitResponse(call, continuation); } catch (Exception e) { return KotlinExtensions.suspendAndThrow(e, continuation); } } } static final class SuspendForBody extends HttpServiceMethod { private final CallAdapter> callAdapter; private final boolean isNullable; private final boolean isUnit; SuspendForBody( RequestFactory requestFactory, okhttp3.Call.Factory callFactory, Converter responseConverter, CallAdapter> callAdapter, boolean isNullable, boolean isUnit) { super(requestFactory, callFactory, responseConverter); this.callAdapter = callAdapter; this.isNullable = isNullable; this.isUnit = isUnit; } @Override protected Object adapt(Call call, Object[] args) { call = callAdapter.adapt(call); //noinspection unchecked Checked by reflection inside RequestFactory. Continuation continuation = (Continuation) args[args.length - 1]; // Calls to OkHttp Call.enqueue() like those inside await and awaitNullable can sometimes // invoke the supplied callback with an exception before the invoking stack frame can return. // Coroutines will intercept the subsequent invocation of the Continuation and throw the // exception synchronously. A Java Proxy cannot throw checked exceptions without them being // declared on the interface method. To avoid the synchronous checked exception being wrapped // in an UndeclaredThrowableException, it is intercepted and supplied to a helper which will // force suspension to occur so that it can be instead delivered to the continuation to // bypass this restriction. try { if (isUnit) { //noinspection unchecked Checked by isUnit return KotlinExtensions.awaitUnit((Call) call, (Continuation) continuation); } else if (isNullable) { return KotlinExtensions.awaitNullable(call, continuation); } else { return KotlinExtensions.await(call, continuation); } } catch (VirtualMachineError | ThreadDeath | LinkageError e) { // Do not attempt to capture fatal throwables. This list is derived RxJava's `throwIfFatal`. throw e; } catch (Throwable e) { return KotlinExtensions.suspendAndThrow(e, continuation); } } } } ================================================ FILE: retrofit/src/main/java/retrofit2/Invocation.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import javax.annotation.Nullable; /** * A single invocation of a Retrofit service interface method. This class captures both the method * that was called and the arguments to the method. * *

Retrofit automatically adds an invocation to each OkHttp request as a tag. You can retrieve * the invocation in an OkHttp interceptor for metrics and monitoring. * *


 * class InvocationLogger implements Interceptor {
 *   @Override public Response intercept(Chain chain) throws IOException {
 *     Request request = chain.request();
 *     Invocation invocation = request.tag(Invocation.class);
 *     if (invocation != null) {
 *       System.out.printf("%s.%s %s%n",
 *           invocation.service().getSimpleName(),
 *           invocation.method().getName(),
 *           invocation.arguments());
 *     }
 *     return chain.proceed(request);
 *   }
 * }
 * 
* * Note: use caution when examining an invocation's arguments. Although the * arguments list is unmodifiable, the arguments themselves may be mutable. They may also be unsafe * for concurrent access. For best results declare Retrofit service interfaces using only immutable * types for parameters! */ public final class Invocation { public static Invocation of( Class service, T instance, Method method, List arguments, @Nullable String annotationUrl) { Objects.requireNonNull(service, "service == null"); Objects.requireNonNull(instance, "instance == null"); Objects.requireNonNull(method, "method == null"); Objects.requireNonNull(arguments, "arguments == null"); // Make a defensive copy of arguments. return new Invocation(service, instance, method, new ArrayList<>(arguments), annotationUrl); } public static Invocation of(Class service, T instance, Method method, List arguments) { return of(service, instance, method, arguments, null); } @Deprecated public static Invocation of(Method method, List arguments) { Objects.requireNonNull(method, "method == null"); Objects.requireNonNull(arguments, "arguments == null"); // Make a defensive copy of arguments. return new Invocation( method.getDeclaringClass(), null, method, new ArrayList<>(arguments), null); } private final Class service; @Nullable private final Object instance; private final Method method; private final List arguments; @Nullable private final String annotationUrl; /** Trusted constructor assumes ownership of {@code arguments}. */ Invocation( Class service, @Nullable Object instance, Method method, List arguments, @Nullable String annotationUrl) { this.service = service; this.instance = instance; this.method = method; this.arguments = Collections.unmodifiableList(arguments); this.annotationUrl = annotationUrl; } public Class service() { return service; } /** * The instance of {@link #service}. *

* This will never be null when created by Retrofit. Null will only be returned when created * by {@link #of(Method, List)}. */ @Nullable public Object instance() { return instance; } public Method method() { return method; } public List arguments() { return arguments; } /** * The URL from the annotation like {@link retrofit2.http.GET @GET} or * {@link retrofit2.http.POST @POST}. *

* If the method uses the {@link retrofit2.http.Path @Path} annotation, this is the template URL * before path substitution, as it occurs in source code. *

* This value will be null if one of the method's parameter is annotated * {@link retrofit2.http.Url @Url}. It will also be null if this Invocation was created using one * of the {@linkplain #of factory-functions} that don't have this value. */ @Nullable public String annotationUrl() { return annotationUrl; } @Override public String toString() { return String.format("%s.%s() %s", service.getName(), method.getName(), arguments); } } ================================================ FILE: retrofit/src/main/java/retrofit2/KotlinExtensions.kt ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:JvmName("KotlinExtensions") package retrofit2 import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED import kotlin.coroutines.intrinsics.intercepted import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.suspendCancellableCoroutine inline fun Retrofit.create(): T = create(T::class.java) suspend fun Call.await(): T { return suspendCancellableCoroutine { continuation -> continuation.invokeOnCancellation { cancel() } enqueue( object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful) { val body = response.body() if (body == null) { val invocation = call.request().tag(Invocation::class.java)!! val service = invocation.service() val method = invocation.method() val e = KotlinNullPointerException( "Response from ${service.name}.${method.name}" + " was null but response body type was declared as non-null" ) continuation.resumeWithException(e) } else { continuation.resume(body) } } else { continuation.resumeWithException(HttpException(response)) } } override fun onFailure(call: Call, t: Throwable) { continuation.resumeWithException(t) } } ) } } @JvmName("awaitNullable") suspend fun Call.await(): T? { return suspendCancellableCoroutine { continuation -> continuation.invokeOnCancellation { cancel() } enqueue( object : Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful) { continuation.resume(response.body()) } else { continuation.resumeWithException(HttpException(response)) } } override fun onFailure(call: Call, t: Throwable) { continuation.resumeWithException(t) } } ) } } @JvmName("awaitUnit") suspend fun Call.await() { @Suppress("UNCHECKED_CAST") (this as Call).await() } suspend fun Call.awaitResponse(): Response { return suspendCancellableCoroutine { continuation -> continuation.invokeOnCancellation { cancel() } enqueue( object : Callback { override fun onResponse(call: Call, response: Response) { continuation.resume(response) } override fun onFailure(call: Call, t: Throwable) { continuation.resumeWithException(t) } } ) } } /** * Force the calling coroutine to suspend before throwing [this]. * * This is needed when a checked exception is synchronously caught in a [java.lang.reflect.Proxy] * invocation to avoid being wrapped in [java.lang.reflect.UndeclaredThrowableException]. * * The implementation is derived from: * https://github.com/Kotlin/kotlinx.coroutines/pull/1667#issuecomment-556106349 */ internal suspend fun Throwable.suspendAndThrow(): Nothing { suspendCoroutineUninterceptedOrReturn { continuation -> Dispatchers.Default.dispatch(continuation.context) { continuation.intercepted().resumeWithException(this@suspendAndThrow) } COROUTINE_SUSPENDED } } ================================================ FILE: retrofit/src/main/java/retrofit2/OkHttpCall.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static retrofit2.Utils.throwIfFatal; import java.io.IOException; import java.util.Objects; import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; import okhttp3.MediaType; import okhttp3.Request; import okhttp3.ResponseBody; import okio.Buffer; import okio.BufferedSource; import okio.ForwardingSource; import okio.Okio; import okio.Timeout; final class OkHttpCall implements Call { private final RequestFactory requestFactory; private final Object instance; private final Object[] args; private final okhttp3.Call.Factory callFactory; private final Converter responseConverter; private volatile boolean canceled; @GuardedBy("this") private @Nullable okhttp3.Call rawCall; @GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException. private @Nullable Throwable creationFailure; @GuardedBy("this") private boolean executed; OkHttpCall( RequestFactory requestFactory, Object instance, Object[] args, okhttp3.Call.Factory callFactory, Converter responseConverter) { this.requestFactory = requestFactory; this.instance = instance; this.args = args; this.callFactory = callFactory; this.responseConverter = responseConverter; } @SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state. @Override public OkHttpCall clone() { return new OkHttpCall<>(requestFactory, instance, args, callFactory, responseConverter); } @Override public synchronized Request request() { try { return getRawCall().request(); } catch (IOException e) { throw new RuntimeException("Unable to create request.", e); } } @Override public synchronized Timeout timeout() { try { return getRawCall().timeout(); } catch (IOException e) { throw new RuntimeException("Unable to create call.", e); } } /** * Returns the raw call, initializing it if necessary. Throws if initializing the raw call throws, * or has thrown in previous attempts to create it. */ @GuardedBy("this") private okhttp3.Call getRawCall() throws IOException { okhttp3.Call call = rawCall; if (call != null) return call; // Re-throw previous failures if this isn't the first attempt. if (creationFailure != null) { if (creationFailure instanceof IOException) { throw (IOException) creationFailure; } else if (creationFailure instanceof RuntimeException) { throw (RuntimeException) creationFailure; } else { throw (Error) creationFailure; } } // Create and remember either the success or the failure. try { return rawCall = createRawCall(); } catch (RuntimeException | Error | IOException e) { throwIfFatal(e); // Do not assign a fatal error to creationFailure. creationFailure = e; throw e; } } @Override public void enqueue(final Callback callback) { Objects.requireNonNull(callback, "callback == null"); okhttp3.Call call; Throwable failure; synchronized (this) { if (executed) throw new IllegalStateException("Already executed."); executed = true; call = rawCall; failure = creationFailure; if (call == null && failure == null) { try { call = rawCall = createRawCall(); } catch (Throwable t) { throwIfFatal(t); failure = creationFailure = t; } } } if (failure != null) { callback.onFailure(this, failure); return; } if (canceled) { call.cancel(); } call.enqueue( new okhttp3.Callback() { @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) { Response response; try { response = parseResponse(rawResponse); } catch (Throwable e) { throwIfFatal(e); callFailure(e); return; } try { callback.onResponse(OkHttpCall.this, response); } catch (Throwable t) { throwIfFatal(t); t.printStackTrace(); // TODO this is not great } } @Override public void onFailure(okhttp3.Call call, IOException e) { callFailure(e); } private void callFailure(Throwable e) { try { callback.onFailure(OkHttpCall.this, e); } catch (Throwable t) { throwIfFatal(t); t.printStackTrace(); // TODO this is not great } } }); } @Override public synchronized boolean isExecuted() { return executed; } @Override public Response execute() throws IOException { okhttp3.Call call; synchronized (this) { if (executed) throw new IllegalStateException("Already executed."); executed = true; call = getRawCall(); } if (canceled) { call.cancel(); } return parseResponse(call.execute()); } private okhttp3.Call createRawCall() throws IOException { okhttp3.Call call = callFactory.newCall(requestFactory.create(instance, args)); if (call == null) { throw new NullPointerException("Call.Factory returned null."); } return call; } Response parseResponse(okhttp3.Response rawResponse) throws IOException { ResponseBody rawBody = rawResponse.body(); // Remove the body's source (the only stateful object) so we can pass the response along. rawResponse = rawResponse .newBuilder() .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength())) .build(); int code = rawResponse.code(); if (code < 200 || code >= 300) { try { // Buffer the entire body to avoid future I/O. ResponseBody bufferedBody = Utils.buffer(rawBody); return Response.error(bufferedBody, rawResponse); } finally { rawBody.close(); } } if (code == 204 || code == 205) { rawBody.close(); return Response.success(null, rawResponse); } ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody); try { T body = responseConverter.convert(catchingBody); return Response.success(body, rawResponse); } catch (RuntimeException e) { // If the underlying source threw an exception, propagate that rather than indicating it was // a runtime exception. catchingBody.throwIfCaught(); throw e; } } @Override public void cancel() { canceled = true; okhttp3.Call call; synchronized (this) { call = rawCall; } if (call != null) { call.cancel(); } } @Override public boolean isCanceled() { if (canceled) { return true; } synchronized (this) { return rawCall != null && rawCall.isCanceled(); } } static final class NoContentResponseBody extends ResponseBody { private final @Nullable MediaType contentType; private final long contentLength; NoContentResponseBody(@Nullable MediaType contentType, long contentLength) { this.contentType = contentType; this.contentLength = contentLength; } @Override public MediaType contentType() { return contentType; } @Override public long contentLength() { return contentLength; } @Override public BufferedSource source() { throw new IllegalStateException("Cannot read raw response body of a converted body."); } } static final class ExceptionCatchingResponseBody extends ResponseBody { private final ResponseBody delegate; private final BufferedSource delegateSource; @Nullable IOException thrownException; ExceptionCatchingResponseBody(ResponseBody delegate) { this.delegate = delegate; this.delegateSource = Okio.buffer( new ForwardingSource(delegate.source()) { @Override public long read(Buffer sink, long byteCount) throws IOException { try { return super.read(sink, byteCount); } catch (IOException e) { thrownException = e; throw e; } } }); } @Override public MediaType contentType() { return delegate.contentType(); } @Override public long contentLength() { return delegate.contentLength(); } @Override public BufferedSource source() { return delegateSource; } @Override public void close() { delegate.close(); } void throwIfCaught() throws IOException { if (thrownException != null) { throw thrownException; } } } } ================================================ FILE: retrofit/src/main/java/retrofit2/OptionalConverterFactory.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import android.annotation.TargetApi; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Optional; import javax.annotation.Nullable; import okhttp3.ResponseBody; import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; /** * A {@link Converter.Factory} which supports Java's {@link Optional} to wrap null values from * another converter. *

* This factory is installed by default on the JVM and Android API 24+. If you are using another * converter which tries to serialize all types, such as Moshi or Gson, the default installation * of this factory never gets a chance to run. To work around this, you can explicitly install this * factory before your serialization library converter. */ @IgnoreJRERequirement // Only added when Optional is available (Java 8+ / Android API 24+). @TargetApi(24) public final class OptionalConverterFactory extends Converter.Factory { public static OptionalConverterFactory create() { return new OptionalConverterFactory(); } OptionalConverterFactory() {} @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (getRawType(type) != Optional.class) { return null; } Type innerType = getParameterUpperBound(0, (ParameterizedType) type); Converter delegate = retrofit.responseBodyConverter(innerType, annotations); return new OptionalConverter<>(delegate); } @IgnoreJRERequirement static final class OptionalConverter implements Converter> { private final Converter delegate; OptionalConverter(Converter delegate) { this.delegate = delegate; } @Override public Optional convert(ResponseBody value) throws IOException { return Optional.ofNullable(delegate.convert(value)); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/ParameterHandler.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.util.Map; import java.util.Objects; import javax.annotation.Nullable; import okhttp3.MultipartBody; import okhttp3.RequestBody; abstract class ParameterHandler { abstract void apply(RequestBuilder builder, @Nullable T value) throws IOException; final ParameterHandler> iterable() { return new ParameterHandler>() { @Override void apply(RequestBuilder builder, @Nullable Iterable values) throws IOException { if (values == null) return; // Skip null values. for (T value : values) { ParameterHandler.this.apply(builder, value); } } }; } final ParameterHandler array() { return new ParameterHandler() { @Override void apply(RequestBuilder builder, @Nullable Object values) throws IOException { if (values == null) return; // Skip null values. for (int i = 0, size = Array.getLength(values); i < size; i++) { //noinspection unchecked ParameterHandler.this.apply(builder, (T) Array.get(values, i)); } } }; } static final class RelativeUrl extends ParameterHandler { private final Method method; private final int p; RelativeUrl(Method method, int p) { this.method = method; this.p = p; } @Override void apply(RequestBuilder builder, @Nullable Object value) { if (value == null) { throw Utils.parameterError(method, p, "@Url parameter is null."); } builder.setRelativeUrl(value); } } static final class Header extends ParameterHandler { private final String name; private final Converter valueConverter; private final boolean allowUnsafeNonAsciiValues; Header(String name, Converter valueConverter, boolean allowUnsafeNonAsciiValues) { this.name = Objects.requireNonNull(name, "name == null"); this.valueConverter = valueConverter; this.allowUnsafeNonAsciiValues = allowUnsafeNonAsciiValues; } @Override void apply(RequestBuilder builder, @Nullable T value) throws IOException { if (value == null) return; // Skip null values. String headerValue = valueConverter.convert(value); if (headerValue == null) return; // Skip converted but null values. builder.addHeader(name, headerValue, allowUnsafeNonAsciiValues); } } static final class Path extends ParameterHandler { private final Method method; private final int p; private final String name; private final Converter valueConverter; private final boolean encoded; Path(Method method, int p, String name, Converter valueConverter, boolean encoded) { this.method = method; this.p = p; this.name = Objects.requireNonNull(name, "name == null"); this.valueConverter = valueConverter; this.encoded = encoded; } @Override void apply(RequestBuilder builder, @Nullable T value) throws IOException { if (value == null) { throw Utils.parameterError( method, p, "Path parameter \"" + name + "\" value must not be null."); } builder.addPathParam(name, valueConverter.convert(value), encoded); } } static final class Query extends ParameterHandler { private final String name; private final Converter valueConverter; private final boolean encoded; Query(String name, Converter valueConverter, boolean encoded) { this.name = Objects.requireNonNull(name, "name == null"); this.valueConverter = valueConverter; this.encoded = encoded; } @Override void apply(RequestBuilder builder, @Nullable T value) throws IOException { if (value == null) return; // Skip null values. String queryValue = valueConverter.convert(value); if (queryValue == null) return; // Skip converted but null values builder.addQueryParam(name, queryValue, encoded); } } static final class QueryName extends ParameterHandler { private final Converter nameConverter; private final boolean encoded; QueryName(Converter nameConverter, boolean encoded) { this.nameConverter = nameConverter; this.encoded = encoded; } @Override void apply(RequestBuilder builder, @Nullable T value) throws IOException { if (value == null) return; // Skip null values. builder.addQueryParam(nameConverter.convert(value), null, encoded); } } static final class QueryMap extends ParameterHandler> { private final Method method; private final int p; private final Converter valueConverter; private final boolean encoded; QueryMap(Method method, int p, Converter valueConverter, boolean encoded) { this.method = method; this.p = p; this.valueConverter = valueConverter; this.encoded = encoded; } @Override void apply(RequestBuilder builder, @Nullable Map value) throws IOException { if (value == null) { throw Utils.parameterError(method, p, "Query map was null"); } for (Map.Entry entry : value.entrySet()) { String entryKey = entry.getKey(); if (entryKey == null) { throw Utils.parameterError(method, p, "Query map contained null key."); } T entryValue = entry.getValue(); if (entryValue == null) { throw Utils.parameterError( method, p, "Query map contained null value for key '" + entryKey + "'."); } String convertedEntryValue = valueConverter.convert(entryValue); if (convertedEntryValue == null) { throw Utils.parameterError( method, p, "Query map value '" + entryValue + "' converted to null by " + valueConverter.getClass().getName() + " for key '" + entryKey + "'."); } builder.addQueryParam(entryKey, convertedEntryValue, encoded); } } } static final class HeaderMap extends ParameterHandler> { private final Method method; private final int p; private final Converter valueConverter; private final boolean allowUnsafeNonAsciiValues; HeaderMap( Method method, int p, Converter valueConverter, boolean allowUnsafeNonAsciiValues) { this.method = method; this.p = p; this.valueConverter = valueConverter; this.allowUnsafeNonAsciiValues = allowUnsafeNonAsciiValues; } @Override void apply(RequestBuilder builder, @Nullable Map value) throws IOException { if (value == null) { throw Utils.parameterError(method, p, "Header map was null."); } for (Map.Entry entry : value.entrySet()) { String headerName = entry.getKey(); if (headerName == null) { throw Utils.parameterError(method, p, "Header map contained null key."); } T headerValue = entry.getValue(); if (headerValue == null) { throw Utils.parameterError( method, p, "Header map contained null value for key '" + headerName + "'."); } builder.addHeader( headerName, valueConverter.convert(headerValue), allowUnsafeNonAsciiValues); } } } static final class Headers extends ParameterHandler { private final Method method; private final int p; Headers(Method method, int p) { this.method = method; this.p = p; } @Override void apply(RequestBuilder builder, @Nullable okhttp3.Headers headers) { if (headers == null) { throw Utils.parameterError(method, p, "Headers parameter must not be null."); } builder.addHeaders(headers); } } static final class Field extends ParameterHandler { private final String name; private final Converter valueConverter; private final boolean encoded; Field(String name, Converter valueConverter, boolean encoded) { this.name = Objects.requireNonNull(name, "name == null"); this.valueConverter = valueConverter; this.encoded = encoded; } @Override void apply(RequestBuilder builder, @Nullable T value) throws IOException { if (value == null) return; // Skip null values. String fieldValue = valueConverter.convert(value); if (fieldValue == null) return; // Skip null converted values builder.addFormField(name, fieldValue, encoded); } } static final class FieldMap extends ParameterHandler> { private final Method method; private final int p; private final Converter valueConverter; private final boolean encoded; FieldMap(Method method, int p, Converter valueConverter, boolean encoded) { this.method = method; this.p = p; this.valueConverter = valueConverter; this.encoded = encoded; } @Override void apply(RequestBuilder builder, @Nullable Map value) throws IOException { if (value == null) { throw Utils.parameterError(method, p, "Field map was null."); } for (Map.Entry entry : value.entrySet()) { String entryKey = entry.getKey(); if (entryKey == null) { throw Utils.parameterError(method, p, "Field map contained null key."); } T entryValue = entry.getValue(); if (entryValue == null) { throw Utils.parameterError( method, p, "Field map contained null value for key '" + entryKey + "'."); } String fieldEntry = valueConverter.convert(entryValue); if (fieldEntry == null) { throw Utils.parameterError( method, p, "Field map value '" + entryValue + "' converted to null by " + valueConverter.getClass().getName() + " for key '" + entryKey + "'."); } builder.addFormField(entryKey, fieldEntry, encoded); } } } static final class Part extends ParameterHandler { private final Method method; private final int p; private final okhttp3.Headers headers; private final Converter converter; Part(Method method, int p, okhttp3.Headers headers, Converter converter) { this.method = method; this.p = p; this.headers = headers; this.converter = converter; } @Override void apply(RequestBuilder builder, @Nullable T value) { if (value == null) return; // Skip null values. RequestBody body; try { body = converter.convert(value); } catch (IOException e) { throw Utils.parameterError(method, p, "Unable to convert " + value + " to RequestBody", e); } builder.addPart(headers, body); } } static final class RawPart extends ParameterHandler { static final RawPart INSTANCE = new RawPart(); private RawPart() {} @Override void apply(RequestBuilder builder, @Nullable MultipartBody.Part value) { if (value != null) { // Skip null values. builder.addPart(value); } } } static final class PartMap extends ParameterHandler> { private final Method method; private final int p; private final Converter valueConverter; private final String transferEncoding; PartMap( Method method, int p, Converter valueConverter, String transferEncoding) { this.method = method; this.p = p; this.valueConverter = valueConverter; this.transferEncoding = transferEncoding; } @Override void apply(RequestBuilder builder, @Nullable Map value) throws IOException { if (value == null) { throw Utils.parameterError(method, p, "Part map was null."); } for (Map.Entry entry : value.entrySet()) { String entryKey = entry.getKey(); if (entryKey == null) { throw Utils.parameterError(method, p, "Part map contained null key."); } T entryValue = entry.getValue(); if (entryValue == null) { throw Utils.parameterError( method, p, "Part map contained null value for key '" + entryKey + "'."); } okhttp3.Headers headers = okhttp3.Headers.of( "Content-Disposition", "form-data; name=\"" + entryKey + "\"", "Content-Transfer-Encoding", transferEncoding); builder.addPart(headers, valueConverter.convert(entryValue)); } } } static final class Body extends ParameterHandler { private final Method method; private final int p; private final Converter converter; Body(Method method, int p, Converter converter) { this.method = method; this.p = p; this.converter = converter; } @Override void apply(RequestBuilder builder, @Nullable T value) { if (value == null) { throw Utils.parameterError(method, p, "Body parameter value must not be null."); } RequestBody body; try { body = converter.convert(value); } catch (IOException e) { throw Utils.parameterError(method, e, p, "Unable to convert " + value + " to RequestBody"); } builder.setBody(body); } } static final class Tag extends ParameterHandler { final Class cls; Tag(Class cls) { this.cls = cls; } @Override void apply(RequestBuilder builder, @Nullable T value) { builder.addTag(cls, value); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/Platform.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static android.os.Build.VERSION.SDK_INT; import java.util.concurrent.Executor; import javax.annotation.Nullable; final class Platform { static final @Nullable Executor callbackExecutor; static final Reflection reflection; static final BuiltInFactories builtInFactories; static { switch (System.getProperty("java.vm.name")) { case "Dalvik": callbackExecutor = new AndroidMainExecutor(); if (SDK_INT >= 24) { reflection = new Reflection.Android24(); builtInFactories = new BuiltInFactories.Java8(); } else { reflection = new Reflection(); builtInFactories = new BuiltInFactories(); } break; case "RoboVM": callbackExecutor = null; reflection = new Reflection(); builtInFactories = new BuiltInFactories(); break; default: callbackExecutor = null; reflection = new Reflection.Java8(); builtInFactories = new BuiltInFactories.Java8(); break; } } private Platform() {} } ================================================ FILE: retrofit/src/main/java/retrofit2/Reflection.java ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import android.annotation.TargetApi; import android.os.Build; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import javax.annotation.Nullable; import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; class Reflection { boolean isDefaultMethod(Method method) { return false; } @Nullable Object invokeDefaultMethod( Method method, Class declaringClass, Object proxy, @Nullable Object[] args) throws Throwable { throw new AssertionError(); } String describeMethodParameter(Method method, int index) { return "parameter #" + (index + 1); } @IgnoreJRERequirement // Only used on JVM. static class Java8 extends Reflection { @Override boolean isDefaultMethod(Method method) { return method.isDefault(); } @Override Object invokeDefaultMethod( Method method, Class declaringClass, Object proxy, @Nullable Object[] args) throws Throwable { return DefaultMethodSupport.invoke(method, declaringClass, proxy, args); } @Override String describeMethodParameter(Method method, int index) { Parameter parameter = method.getParameters()[index]; if (parameter.isNamePresent()) { return "parameter '" + parameter.getName() + '\''; } return super.describeMethodParameter(method, index); } } /** * Android does not support MR jars, so this uses the Java 8 support class. * Default methods and the reflection API to detect them were added to API 24 * as part of the initial Java 8 set. MethodHandle, our means of invoking the default method * through the proxy, was not added until API 26. */ @TargetApi(24) @IgnoreJRERequirement // Only used on Android API 24+. static final class Android24 extends Reflection { @Override boolean isDefaultMethod(Method method) { return method.isDefault(); } @Override Object invokeDefaultMethod( Method method, Class declaringClass, Object proxy, @Nullable Object[] args) throws Throwable { if (Build.VERSION.SDK_INT < 26) { throw new UnsupportedOperationException( "Calling default methods on API 24 and 25 is not supported"); } return DefaultMethodSupport.invoke(method, declaringClass, proxy, args); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/RequestBuilder.java ================================================ /* * Copyright (C) 2012 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.io.IOException; import java.util.regex.Pattern; import javax.annotation.Nullable; import okhttp3.FormBody; import okhttp3.Headers; import okhttp3.HttpUrl; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.Request; import okhttp3.RequestBody; import okio.Buffer; import okio.BufferedSink; final class RequestBuilder { private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private static final String PATH_SEGMENT_ALWAYS_ENCODE_SET = " \"<>^`{}|\\?#"; /** * Matches strings that contain {@code .} or {@code ..} as a complete path segment. This also * matches dots in their percent-encoded form, {@code %2E}. * *

It is okay to have these strings within a larger path segment (like {@code a..z} or {@code * index.html}) but when alone they have a special meaning. A single dot resolves to no path * segment so {@code /one/./three/} becomes {@code /one/three/}. A double-dot pops the preceding * directory, so {@code /one/../three/} becomes {@code /three/}. * *

We forbid these in Retrofit paths because they're likely to have the unintended effect. For * example, passing {@code ..} to {@code DELETE /account/book/{isbn}/} yields {@code DELETE * /account/}. */ private static final Pattern PATH_TRAVERSAL = Pattern.compile("(.*/)?(\\.|%2e|%2E){1,2}(/.*)?"); private final String method; private final HttpUrl baseUrl; private @Nullable String relativeUrl; private @Nullable HttpUrl.Builder urlBuilder; private final Request.Builder requestBuilder; private final Headers.Builder headersBuilder; private @Nullable MediaType contentType; private final boolean hasBody; private @Nullable MultipartBody.Builder multipartBuilder; private @Nullable FormBody.Builder formBuilder; private @Nullable RequestBody body; RequestBuilder( String method, HttpUrl baseUrl, @Nullable String relativeUrl, @Nullable Headers headers, @Nullable MediaType contentType, boolean hasBody, boolean isFormEncoded, boolean isMultipart) { this.method = method; this.baseUrl = baseUrl; this.relativeUrl = relativeUrl; this.requestBuilder = new Request.Builder(); this.contentType = contentType; this.hasBody = hasBody; if (headers != null) { headersBuilder = headers.newBuilder(); } else { headersBuilder = new Headers.Builder(); } if (isFormEncoded) { // Will be set to 'body' in 'build'. formBuilder = new FormBody.Builder(); } else if (isMultipart) { // Will be set to 'body' in 'build'. multipartBuilder = new MultipartBody.Builder(); multipartBuilder.setType(MultipartBody.FORM); } } void setRelativeUrl(Object relativeUrl) { this.relativeUrl = relativeUrl.toString(); } void addHeader(String name, String value, boolean allowUnsafeNonAsciiValues) { if ("Content-Type".equalsIgnoreCase(name)) { try { contentType = MediaType.get(value); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Malformed content type: " + value, e); } } else if (allowUnsafeNonAsciiValues) { headersBuilder.addUnsafeNonAscii(name, value); } else { headersBuilder.add(name, value); } } void addHeaders(Headers headers) { headersBuilder.addAll(headers); } void addPathParam(String name, String value, boolean encoded) { if (relativeUrl == null) { // The relative URL is cleared when the first query parameter is set. throw new AssertionError(); } String replacement = canonicalizeForPath(value, encoded); String newRelativeUrl = relativeUrl.replace("{" + name + "}", replacement); if (PATH_TRAVERSAL.matcher(newRelativeUrl).matches()) { throw new IllegalArgumentException( "@Path parameters shouldn't perform path traversal ('.' or '..'): " + value); } relativeUrl = newRelativeUrl; } private static String canonicalizeForPath(String input, boolean alreadyEncoded) { int codePoint; for (int i = 0, limit = input.length(); i < limit; i += Character.charCount(codePoint)) { codePoint = input.codePointAt(i); if (codePoint < 0x20 || codePoint >= 0x7f || PATH_SEGMENT_ALWAYS_ENCODE_SET.indexOf(codePoint) != -1 || (!alreadyEncoded && (codePoint == '/' || codePoint == '%'))) { // Slow path: the character at i requires encoding! Buffer out = new Buffer(); out.writeUtf8(input, 0, i); canonicalizeForPath(out, input, i, limit, alreadyEncoded); return out.readUtf8(); } } // Fast path: no characters required encoding. return input; } private static void canonicalizeForPath( Buffer out, String input, int pos, int limit, boolean alreadyEncoded) { Buffer utf8Buffer = null; // Lazily allocated. int codePoint; for (int i = pos; i < limit; i += Character.charCount(codePoint)) { codePoint = input.codePointAt(i); if (alreadyEncoded && (codePoint == '\t' || codePoint == '\n' || codePoint == '\f' || codePoint == '\r')) { // Skip this character. } else if (codePoint < 0x20 || codePoint >= 0x7f || PATH_SEGMENT_ALWAYS_ENCODE_SET.indexOf(codePoint) != -1 || (!alreadyEncoded && (codePoint == '/' || codePoint == '%'))) { // Percent encode this character. if (utf8Buffer == null) { utf8Buffer = new Buffer(); } utf8Buffer.writeUtf8CodePoint(codePoint); for (long j = 0, size = utf8Buffer.size(); j < size; j++) { int b = utf8Buffer.getByte(j) & 0xff; out.writeByte('%'); out.writeByte(HEX_DIGITS[(b >> 4) & 0xf]); out.writeByte(HEX_DIGITS[b & 0xf]); } utf8Buffer.clear(); } else { // This character doesn't need encoding. Just copy it over. out.writeUtf8CodePoint(codePoint); } } } void addQueryParam(String name, @Nullable String value, boolean encoded) { if (relativeUrl != null) { // Do a one-time combination of the built relative URL and the base URL. urlBuilder = baseUrl.newBuilder(relativeUrl); if (urlBuilder == null) { throw new IllegalArgumentException( "Malformed URL. Base: " + baseUrl + ", Relative: " + relativeUrl); } relativeUrl = null; } if (encoded) { //noinspection ConstantConditions Checked to be non-null by above 'if' block. urlBuilder.addEncodedQueryParameter(name, value); } else { //noinspection ConstantConditions Checked to be non-null by above 'if' block. urlBuilder.addQueryParameter(name, value); } } @SuppressWarnings("ConstantConditions") // Only called when isFormEncoded was true. void addFormField(String name, String value, boolean encoded) { if (encoded) { formBuilder.addEncoded(name, value); } else { formBuilder.add(name, value); } } @SuppressWarnings("ConstantConditions") // Only called when isMultipart was true. void addPart(Headers headers, RequestBody body) { multipartBuilder.addPart(headers, body); } @SuppressWarnings("ConstantConditions") // Only called when isMultipart was true. void addPart(MultipartBody.Part part) { multipartBuilder.addPart(part); } void setBody(RequestBody body) { this.body = body; } void addTag(Class cls, @Nullable T value) { requestBuilder.tag(cls, value); } Request.Builder get() { HttpUrl url; HttpUrl.Builder urlBuilder = this.urlBuilder; if (urlBuilder != null) { url = urlBuilder.build(); } else { // No query parameters triggered builder creation, just combine the relative URL and base URL. //noinspection ConstantConditions Non-null if urlBuilder is null. url = baseUrl.resolve(relativeUrl); if (url == null) { throw new IllegalArgumentException( "Malformed URL. Base: " + baseUrl + ", Relative: " + relativeUrl); } } RequestBody body = this.body; if (body == null) { // Try to pull from one of the builders. if (formBuilder != null) { body = formBuilder.build(); } else if (multipartBuilder != null) { body = multipartBuilder.build(); } else if (hasBody) { // Body is absent, make an empty body. body = RequestBody.create(null, new byte[0]); } } MediaType contentType = this.contentType; if (contentType != null) { if (body != null) { body = new ContentTypeOverridingRequestBody(body, contentType); } else { headersBuilder.add("Content-Type", contentType.toString()); } } return requestBuilder.url(url).headers(headersBuilder.build()).method(method, body); } private static class ContentTypeOverridingRequestBody extends RequestBody { private final RequestBody delegate; private final MediaType contentType; ContentTypeOverridingRequestBody(RequestBody delegate, MediaType contentType) { this.delegate = delegate; this.contentType = contentType; } @Override public MediaType contentType() { return contentType; } @Override public long contentLength() throws IOException { return delegate.contentLength(); } @Override public void writeTo(BufferedSink sink) throws IOException { delegate.writeTo(sink); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/RequestFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static retrofit2.Utils.methodError; import static retrofit2.Utils.parameterError; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.net.URI; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nullable; import kotlin.coroutines.Continuation; import okhttp3.Headers; import okhttp3.HttpUrl; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.RequestBody; import retrofit2.http.Body; import retrofit2.http.DELETE; import retrofit2.http.Field; import retrofit2.http.FieldMap; import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; import retrofit2.http.HEAD; import retrofit2.http.HTTP; import retrofit2.http.Header; import retrofit2.http.HeaderMap; import retrofit2.http.Multipart; import retrofit2.http.OPTIONS; import retrofit2.http.PATCH; import retrofit2.http.POST; import retrofit2.http.PUT; import retrofit2.http.Part; import retrofit2.http.PartMap; import retrofit2.http.Path; import retrofit2.http.Query; import retrofit2.http.QueryMap; import retrofit2.http.QueryName; import retrofit2.http.Tag; import retrofit2.http.Url; final class RequestFactory { static RequestFactory parseAnnotations(Retrofit retrofit, Class service, Method method) { return new Builder(retrofit, service, method).build(); } private final Class service; private final Method method; private final HttpUrl baseUrl; final String httpMethod; private final @Nullable String relativeUrl; private final @Nullable Headers headers; private final @Nullable MediaType contentType; private final boolean hasBody; private final boolean isFormEncoded; private final boolean isMultipart; private final ParameterHandler[] parameterHandlers; final boolean isKotlinSuspendFunction; RequestFactory(Builder builder) { service = builder.service; method = builder.method; baseUrl = builder.retrofit.baseUrl; httpMethod = builder.httpMethod; relativeUrl = builder.relativeUrl; headers = builder.headers; contentType = builder.contentType; hasBody = builder.hasBody; isFormEncoded = builder.isFormEncoded; isMultipart = builder.isMultipart; parameterHandlers = builder.parameterHandlers; isKotlinSuspendFunction = builder.isKotlinSuspendFunction; } okhttp3.Request create(@Nullable Object instance, Object[] args) throws IOException { @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types. ParameterHandler[] handlers = (ParameterHandler[]) parameterHandlers; int argumentCount = args.length; if (argumentCount != handlers.length) { throw new IllegalArgumentException( "Argument count (" + argumentCount + ") doesn't match expected count (" + handlers.length + ")"); } RequestBuilder requestBuilder = new RequestBuilder( httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody, isFormEncoded, isMultipart); if (isKotlinSuspendFunction) { // The Continuation is the last parameter and the handlers array contains null at that index. argumentCount--; } List argumentList = new ArrayList<>(argumentCount); for (int p = 0; p < argumentCount; p++) { argumentList.add(args[p]); handlers[p].apply(requestBuilder, args[p]); } return requestBuilder .get() .tag(Invocation.class, new Invocation(service, instance, method, argumentList, relativeUrl)) .build(); } /** * Inspects the annotations on an interface method to construct a reusable service method. This * requires potentially-expensive reflection so it is best to build each service method only once * and reuse it. Builders cannot be reused. */ static final class Builder { // Upper and lower characters, digits, underscores, and hyphens, starting with a character. private static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*"; private static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}"); private static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM); final Retrofit retrofit; final Class service; final Method method; final Annotation[] methodAnnotations; final Annotation[][] parameterAnnotationsArray; final Type[] parameterTypes; boolean gotField; boolean gotPart; boolean gotBody; boolean gotPath; boolean gotQuery; boolean gotQueryName; boolean gotQueryMap; boolean gotUrl; @Nullable String httpMethod; boolean hasBody; boolean isFormEncoded; boolean isMultipart; @Nullable String relativeUrl; @Nullable Headers headers; @Nullable MediaType contentType; @Nullable Set relativeUrlParamNames; @Nullable ParameterHandler[] parameterHandlers; boolean isKotlinSuspendFunction; Builder(Retrofit retrofit, Class service, Method method) { this.retrofit = retrofit; this.service = service; this.method = method; this.methodAnnotations = method.getAnnotations(); this.parameterTypes = method.getGenericParameterTypes(); this.parameterAnnotationsArray = method.getParameterAnnotations(); } RequestFactory build() { for (Annotation annotation : methodAnnotations) { parseMethodAnnotation(annotation); } if (httpMethod == null) { throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.)."); } if (!hasBody) { if (isMultipart) { throw methodError( method, "Multipart can only be specified on HTTP methods with request body (e.g., @POST)."); } if (isFormEncoded) { throw methodError( method, "FormUrlEncoded can only be specified on HTTP methods with " + "request body (e.g., @POST)."); } } int parameterCount = parameterAnnotationsArray.length; parameterHandlers = new ParameterHandler[parameterCount]; for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) { parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter); } if (relativeUrl == null && !gotUrl) { throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod); } if (!isFormEncoded && !isMultipart && !hasBody && gotBody) { throw methodError(method, "Non-body HTTP method cannot contain @Body."); } if (isFormEncoded && !gotField) { throw methodError(method, "Form-encoded method must contain at least one @Field."); } if (isMultipart && !gotPart) { throw methodError(method, "Multipart method must contain at least one @Part."); } return new RequestFactory(this); } private void parseMethodAnnotation(Annotation annotation) { if (annotation instanceof DELETE) { parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false); } else if (annotation instanceof GET) { parseHttpMethodAndPath("GET", ((GET) annotation).value(), false); } else if (annotation instanceof HEAD) { parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false); } else if (annotation instanceof PATCH) { parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true); } else if (annotation instanceof POST) { parseHttpMethodAndPath("POST", ((POST) annotation).value(), true); } else if (annotation instanceof PUT) { parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true); } else if (annotation instanceof OPTIONS) { parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false); } else if (annotation instanceof HTTP) { HTTP http = (HTTP) annotation; parseHttpMethodAndPath(http.method(), http.path(), http.hasBody()); } else if (annotation instanceof retrofit2.http.Headers) { retrofit2.http.Headers headers = (retrofit2.http.Headers) annotation; String[] headersToParse = headers.value(); if (headersToParse.length == 0) { throw methodError(method, "@Headers annotation is empty."); } this.headers = parseHeaders(headersToParse, headers.allowUnsafeNonAsciiValues()); } else if (annotation instanceof Multipart) { if (isFormEncoded) { throw methodError(method, "Only one encoding annotation is allowed."); } isMultipart = true; } else if (annotation instanceof FormUrlEncoded) { if (isMultipart) { throw methodError(method, "Only one encoding annotation is allowed."); } isFormEncoded = true; } } private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) { if (this.httpMethod != null) { throw methodError( method, "Only one HTTP method is allowed. Found: %s and %s.", this.httpMethod, httpMethod); } this.httpMethod = httpMethod; this.hasBody = hasBody; if (value.isEmpty()) { return; } // Get the relative URL path and existing query string, if present. int question = value.indexOf('?'); if (question != -1 && question < value.length() - 1) { // Ensure the query string does not have any named parameters. String queryParams = value.substring(question + 1); Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams); if (queryParamMatcher.find()) { throw methodError( method, "URL query string \"%s\" must not have replace block. " + "For dynamic query parameters use @Query.", queryParams); } } this.relativeUrl = value; this.relativeUrlParamNames = parsePathParameters(value); } private Headers parseHeaders(String[] headers, boolean allowUnsafeNonAsciiValues) { Headers.Builder builder = new Headers.Builder(); for (String header : headers) { int colon = header.indexOf(':'); if (colon == -1 || colon == 0 || colon == header.length() - 1) { throw methodError( method, "@Headers value must be in the form \"Name: Value\". Found: \"%s\"", header); } String headerName = header.substring(0, colon); String headerValue = header.substring(colon + 1).trim(); if ("Content-Type".equalsIgnoreCase(headerName)) { try { contentType = MediaType.get(headerValue); } catch (IllegalArgumentException e) { throw methodError(method, e, "Malformed content type: %s", headerValue); } } else if (allowUnsafeNonAsciiValues) { builder.addUnsafeNonAscii(headerName, headerValue); } else { builder.add(headerName, headerValue); } } return builder.build(); } private @Nullable ParameterHandler parseParameter( int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) { ParameterHandler result = null; if (annotations != null) { for (Annotation annotation : annotations) { ParameterHandler annotationAction = parseParameterAnnotation(p, parameterType, annotations, annotation); if (annotationAction == null) { continue; } if (result != null) { throw parameterError( method, p, "Multiple Retrofit annotations found, only one allowed."); } result = annotationAction; } } if (result == null) { if (allowContinuation) { try { if (Utils.getRawType(parameterType) == Continuation.class) { isKotlinSuspendFunction = true; return null; } } catch (NoClassDefFoundError ignored) { // Ignored } } throw parameterError(method, p, "No Retrofit annotation found."); } return result; } @Nullable private ParameterHandler parseParameterAnnotation( int p, Type type, Annotation[] annotations, Annotation annotation) { if (annotation instanceof Url) { validateResolvableType(p, type); if (gotUrl) { throw parameterError(method, p, "Multiple @Url method annotations found."); } if (gotPath) { throw parameterError(method, p, "@Path parameters may not be used with @Url."); } if (gotQuery) { throw parameterError(method, p, "A @Url parameter must not come after a @Query."); } if (gotQueryName) { throw parameterError(method, p, "A @Url parameter must not come after a @QueryName."); } if (gotQueryMap) { throw parameterError(method, p, "A @Url parameter must not come after a @QueryMap."); } if (relativeUrl != null) { throw parameterError(method, p, "@Url cannot be used with @%s URL", httpMethod); } gotUrl = true; if (type == HttpUrl.class || type == String.class || type == URI.class || (type instanceof Class && "android.net.Uri".equals(((Class) type).getName()))) { return new ParameterHandler.RelativeUrl(method, p); } else { throw parameterError( method, p, "@Url must be okhttp3.HttpUrl, String, java.net.URI, or android.net.Uri type."); } } else if (annotation instanceof Path) { validateResolvableType(p, type); if (gotQuery) { throw parameterError(method, p, "A @Path parameter must not come after a @Query."); } if (gotQueryName) { throw parameterError(method, p, "A @Path parameter must not come after a @QueryName."); } if (gotQueryMap) { throw parameterError(method, p, "A @Path parameter must not come after a @QueryMap."); } if (gotUrl) { throw parameterError(method, p, "@Path parameters may not be used with @Url."); } if (relativeUrl == null) { throw parameterError( method, p, "@Path can only be used with relative url on @%s", httpMethod); } gotPath = true; Path path = (Path) annotation; String name = path.value(); validatePathName(p, name); Converter converter = retrofit.stringConverter(type, annotations); return new ParameterHandler.Path<>(method, p, name, converter, path.encoded()); } else if (annotation instanceof Query) { validateResolvableType(p, type); Query query = (Query) annotation; String name = query.value(); boolean encoded = query.encoded(); Class rawParameterType = Utils.getRawType(type); gotQuery = true; if (Iterable.class.isAssignableFrom(rawParameterType)) { if (!(type instanceof ParameterizedType)) { throw parameterError( method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + ")"); } ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); Converter converter = retrofit.stringConverter(iterableType, annotations); return new ParameterHandler.Query<>(name, converter, encoded).iterable(); } else if (rawParameterType.isArray()) { Class arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); Converter converter = retrofit.stringConverter(arrayComponentType, annotations); return new ParameterHandler.Query<>(name, converter, encoded).array(); } else { Converter converter = retrofit.stringConverter(type, annotations); return new ParameterHandler.Query<>(name, converter, encoded); } } else if (annotation instanceof QueryName) { validateResolvableType(p, type); QueryName query = (QueryName) annotation; boolean encoded = query.encoded(); Class rawParameterType = Utils.getRawType(type); gotQueryName = true; if (Iterable.class.isAssignableFrom(rawParameterType)) { if (!(type instanceof ParameterizedType)) { throw parameterError( method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + ")"); } ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); Converter converter = retrofit.stringConverter(iterableType, annotations); return new ParameterHandler.QueryName<>(converter, encoded).iterable(); } else if (rawParameterType.isArray()) { Class arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); Converter converter = retrofit.stringConverter(arrayComponentType, annotations); return new ParameterHandler.QueryName<>(converter, encoded).array(); } else { Converter converter = retrofit.stringConverter(type, annotations); return new ParameterHandler.QueryName<>(converter, encoded); } } else if (annotation instanceof QueryMap) { validateResolvableType(p, type); Class rawParameterType = Utils.getRawType(type); gotQueryMap = true; if (!Map.class.isAssignableFrom(rawParameterType)) { throw parameterError(method, p, "@QueryMap parameter type must be Map."); } Type mapType = Utils.getSupertype(type, rawParameterType, Map.class); if (!(mapType instanceof ParameterizedType)) { throw parameterError( method, p, "Map must include generic types (e.g., Map)"); } ParameterizedType parameterizedType = (ParameterizedType) mapType; Type keyType = Utils.getParameterUpperBound(0, parameterizedType); if (String.class != keyType) { throw parameterError(method, p, "@QueryMap keys must be of type String: " + keyType); } Type valueType = Utils.getParameterUpperBound(1, parameterizedType); Converter valueConverter = retrofit.stringConverter(valueType, annotations); return new ParameterHandler.QueryMap<>( method, p, valueConverter, ((QueryMap) annotation).encoded()); } else if (annotation instanceof Header) { validateResolvableType(p, type); Header header = (Header) annotation; String name = header.value(); Class rawParameterType = Utils.getRawType(type); if (Iterable.class.isAssignableFrom(rawParameterType)) { if (!(type instanceof ParameterizedType)) { throw parameterError( method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + ")"); } ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); Converter converter = retrofit.stringConverter(iterableType, annotations); return new ParameterHandler.Header<>(name, converter, header.allowUnsafeNonAsciiValues()) .iterable(); } else if (rawParameterType.isArray()) { Class arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); Converter converter = retrofit.stringConverter(arrayComponentType, annotations); return new ParameterHandler.Header<>(name, converter, header.allowUnsafeNonAsciiValues()) .array(); } else { Converter converter = retrofit.stringConverter(type, annotations); return new ParameterHandler.Header<>(name, converter, header.allowUnsafeNonAsciiValues()); } } else if (annotation instanceof HeaderMap) { if (type == Headers.class) { return new ParameterHandler.Headers(method, p); } validateResolvableType(p, type); Class rawParameterType = Utils.getRawType(type); if (!Map.class.isAssignableFrom(rawParameterType)) { throw parameterError(method, p, "@HeaderMap parameter type must be Map or Headers."); } Type mapType = Utils.getSupertype(type, rawParameterType, Map.class); if (!(mapType instanceof ParameterizedType)) { throw parameterError( method, p, "Map must include generic types (e.g., Map)"); } ParameterizedType parameterizedType = (ParameterizedType) mapType; Type keyType = Utils.getParameterUpperBound(0, parameterizedType); if (String.class != keyType) { throw parameterError(method, p, "@HeaderMap keys must be of type String: " + keyType); } Type valueType = Utils.getParameterUpperBound(1, parameterizedType); Converter valueConverter = retrofit.stringConverter(valueType, annotations); return new ParameterHandler.HeaderMap<>( method, p, valueConverter, ((HeaderMap) annotation).allowUnsafeNonAsciiValues()); } else if (annotation instanceof Field) { validateResolvableType(p, type); if (!isFormEncoded) { throw parameterError(method, p, "@Field parameters can only be used with form encoding."); } Field field = (Field) annotation; String name = field.value(); boolean encoded = field.encoded(); gotField = true; Class rawParameterType = Utils.getRawType(type); if (Iterable.class.isAssignableFrom(rawParameterType)) { if (!(type instanceof ParameterizedType)) { throw parameterError( method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + ")"); } ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); Converter converter = retrofit.stringConverter(iterableType, annotations); return new ParameterHandler.Field<>(name, converter, encoded).iterable(); } else if (rawParameterType.isArray()) { Class arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); Converter converter = retrofit.stringConverter(arrayComponentType, annotations); return new ParameterHandler.Field<>(name, converter, encoded).array(); } else { Converter converter = retrofit.stringConverter(type, annotations); return new ParameterHandler.Field<>(name, converter, encoded); } } else if (annotation instanceof FieldMap) { validateResolvableType(p, type); if (!isFormEncoded) { throw parameterError( method, p, "@FieldMap parameters can only be used with form encoding."); } Class rawParameterType = Utils.getRawType(type); if (!Map.class.isAssignableFrom(rawParameterType)) { throw parameterError(method, p, "@FieldMap parameter type must be Map."); } Type mapType = Utils.getSupertype(type, rawParameterType, Map.class); if (!(mapType instanceof ParameterizedType)) { throw parameterError( method, p, "Map must include generic types (e.g., Map)"); } ParameterizedType parameterizedType = (ParameterizedType) mapType; Type keyType = Utils.getParameterUpperBound(0, parameterizedType); if (String.class != keyType) { throw parameterError(method, p, "@FieldMap keys must be of type String: " + keyType); } Type valueType = Utils.getParameterUpperBound(1, parameterizedType); Converter valueConverter = retrofit.stringConverter(valueType, annotations); gotField = true; return new ParameterHandler.FieldMap<>( method, p, valueConverter, ((FieldMap) annotation).encoded()); } else if (annotation instanceof Part) { validateResolvableType(p, type); if (!isMultipart) { throw parameterError( method, p, "@Part parameters can only be used with multipart encoding."); } Part part = (Part) annotation; gotPart = true; String partName = part.value(); Class rawParameterType = Utils.getRawType(type); if (partName.isEmpty()) { if (Iterable.class.isAssignableFrom(rawParameterType)) { if (!(type instanceof ParameterizedType)) { throw parameterError( method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + ")"); } ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); if (!MultipartBody.Part.class.isAssignableFrom(Utils.getRawType(iterableType))) { throw parameterError( method, p, "@Part annotation must supply a name or use MultipartBody.Part parameter type."); } return ParameterHandler.RawPart.INSTANCE.iterable(); } else if (rawParameterType.isArray()) { Class arrayComponentType = rawParameterType.getComponentType(); if (!MultipartBody.Part.class.isAssignableFrom(arrayComponentType)) { throw parameterError( method, p, "@Part annotation must supply a name or use MultipartBody.Part parameter type."); } return ParameterHandler.RawPart.INSTANCE.array(); } else if (MultipartBody.Part.class.isAssignableFrom(rawParameterType)) { return ParameterHandler.RawPart.INSTANCE; } else { throw parameterError( method, p, "@Part annotation must supply a name or use MultipartBody.Part parameter type."); } } else { Headers headers = Headers.of( "Content-Disposition", "form-data; name=\"" + partName + "\"", "Content-Transfer-Encoding", part.encoding()); if (Iterable.class.isAssignableFrom(rawParameterType)) { if (!(type instanceof ParameterizedType)) { throw parameterError( method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + ")"); } ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); if (MultipartBody.Part.class.isAssignableFrom(Utils.getRawType(iterableType))) { throw parameterError( method, p, "@Part parameters using the MultipartBody.Part must not " + "include a part name in the annotation."); } Converter converter = retrofit.requestBodyConverter(iterableType, annotations, methodAnnotations); return new ParameterHandler.Part<>(method, p, headers, converter).iterable(); } else if (rawParameterType.isArray()) { Class arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); if (MultipartBody.Part.class.isAssignableFrom(arrayComponentType)) { throw parameterError( method, p, "@Part parameters using the MultipartBody.Part must not " + "include a part name in the annotation."); } Converter converter = retrofit.requestBodyConverter(arrayComponentType, annotations, methodAnnotations); return new ParameterHandler.Part<>(method, p, headers, converter).array(); } else if (MultipartBody.Part.class.isAssignableFrom(rawParameterType)) { throw parameterError( method, p, "@Part parameters using the MultipartBody.Part must not " + "include a part name in the annotation."); } else { Converter converter = retrofit.requestBodyConverter(type, annotations, methodAnnotations); return new ParameterHandler.Part<>(method, p, headers, converter); } } } else if (annotation instanceof PartMap) { validateResolvableType(p, type); if (!isMultipart) { throw parameterError( method, p, "@PartMap parameters can only be used with multipart encoding."); } gotPart = true; Class rawParameterType = Utils.getRawType(type); if (!Map.class.isAssignableFrom(rawParameterType)) { throw parameterError(method, p, "@PartMap parameter type must be Map."); } Type mapType = Utils.getSupertype(type, rawParameterType, Map.class); if (!(mapType instanceof ParameterizedType)) { throw parameterError( method, p, "Map must include generic types (e.g., Map)"); } ParameterizedType parameterizedType = (ParameterizedType) mapType; Type keyType = Utils.getParameterUpperBound(0, parameterizedType); if (String.class != keyType) { throw parameterError(method, p, "@PartMap keys must be of type String: " + keyType); } Type valueType = Utils.getParameterUpperBound(1, parameterizedType); if (MultipartBody.Part.class.isAssignableFrom(Utils.getRawType(valueType))) { throw parameterError( method, p, "@PartMap values cannot be MultipartBody.Part. " + "Use @Part List or a different value type instead."); } Converter valueConverter = retrofit.requestBodyConverter(valueType, annotations, methodAnnotations); PartMap partMap = (PartMap) annotation; return new ParameterHandler.PartMap<>(method, p, valueConverter, partMap.encoding()); } else if (annotation instanceof Body) { validateResolvableType(p, type); if (isFormEncoded || isMultipart) { throw parameterError( method, p, "@Body parameters cannot be used with form or multi-part encoding."); } if (gotBody) { throw parameterError(method, p, "Multiple @Body method annotations found."); } Converter converter; try { converter = retrofit.requestBodyConverter(type, annotations, methodAnnotations); } catch (RuntimeException e) { // Wide exception range because factories are user code. throw parameterError(method, e, p, "Unable to create @Body converter for %s", type); } gotBody = true; return new ParameterHandler.Body<>(method, p, converter); } else if (annotation instanceof Tag) { validateResolvableType(p, type); Class tagType = boxIfPrimitive(Utils.getRawType(type)); for (int i = p - 1; i >= 0; i--) { ParameterHandler otherHandler = parameterHandlers[i]; if (otherHandler instanceof ParameterHandler.Tag && ((ParameterHandler.Tag) otherHandler).cls.equals(tagType)) { throw parameterError( method, p, "@Tag type " + tagType.getName() + " is duplicate of " + Platform.reflection.describeMethodParameter(method, i) + " and would always overwrite its value."); } } return new ParameterHandler.Tag<>(tagType); } return null; // Not a Retrofit annotation. } private void validateResolvableType(int p, Type type) { if (Utils.hasUnresolvableType(type)) { throw parameterError( method, p, "Parameter type must not include a type variable or wildcard: %s", type); } } private void validatePathName(int p, String name) { if (!PARAM_NAME_REGEX.matcher(name).matches()) { throw parameterError( method, p, "@Path parameter name must match %s. Found: %s", PARAM_URL_REGEX.pattern(), name); } // Verify URL replacement name is actually present in the URL path. if (!relativeUrlParamNames.contains(name)) { throw parameterError(method, p, "URL \"%s\" does not contain \"{%s}\".", relativeUrl, name); } } /** * Gets the set of unique path parameters used in the given URI. If a parameter is used twice in * the URI, it will only show up once in the set. */ static Set parsePathParameters(String path) { Matcher m = PARAM_URL_REGEX.matcher(path); Set patterns = new LinkedHashSet<>(); while (m.find()) { patterns.add(m.group(1)); } return patterns; } private static Class boxIfPrimitive(Class type) { if (boolean.class == type) return Boolean.class; if (byte.class == type) return Byte.class; if (char.class == type) return Character.class; if (double.class == type) return Double.class; if (float.class == type) return Float.class; if (int.class == type) return Integer.class; if (long.class == type) return Long.class; if (short.class == type) return Short.class; return type; } } } ================================================ FILE: retrofit/src/main/java/retrofit2/Response.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.util.Objects; import javax.annotation.Nullable; import okhttp3.Headers; import okhttp3.Protocol; import okhttp3.Request; import okhttp3.ResponseBody; /** An HTTP response. */ public final class Response { /** Create a synthetic successful response with {@code body} as the deserialized body. */ public static Response success(@Nullable T body) { return success( body, new okhttp3.Response.Builder() // .code(200) .message("OK") .protocol(Protocol.HTTP_1_1) .request(new Request.Builder().url("http://localhost/").build()) .build()); } /** * Create a synthetic successful response with an HTTP status code of {@code code} and {@code * body} as the deserialized body. */ public static Response success(int code, @Nullable T body) { if (code < 200 || code >= 300) { throw new IllegalArgumentException("code < 200 or >= 300: " + code); } return success( body, new okhttp3.Response.Builder() // .code(code) .message("Response.success()") .protocol(Protocol.HTTP_1_1) .request(new Request.Builder().url("http://localhost/").build()) .build()); } /** * Create a synthetic successful response using {@code headers} with {@code body} as the * deserialized body. */ public static Response success(@Nullable T body, Headers headers) { Objects.requireNonNull(headers, "headers == null"); return success( body, new okhttp3.Response.Builder() // .code(200) .message("OK") .protocol(Protocol.HTTP_1_1) .headers(headers) .request(new Request.Builder().url("http://localhost/").build()) .build()); } /** * Create a successful response from {@code rawResponse} with {@code body} as the deserialized * body. */ public static Response success(@Nullable T body, okhttp3.Response rawResponse) { Objects.requireNonNull(rawResponse, "rawResponse == null"); if (!rawResponse.isSuccessful()) { throw new IllegalArgumentException("rawResponse must be successful response"); } return new Response<>(rawResponse, body, null); } /** * Create a synthetic error response with an HTTP status code of {@code code} and {@code body} as * the error body. */ public static Response error(int code, ResponseBody body) { Objects.requireNonNull(body, "body == null"); if (code < 400) throw new IllegalArgumentException("code < 400: " + code); return error( body, new okhttp3.Response.Builder() // .body(new OkHttpCall.NoContentResponseBody(body.contentType(), body.contentLength())) .code(code) .message("Response.error()") .protocol(Protocol.HTTP_1_1) .request(new Request.Builder().url("http://localhost/").build()) .build()); } /** Create an error response from {@code rawResponse} with {@code body} as the error body. */ public static Response error(ResponseBody body, okhttp3.Response rawResponse) { Objects.requireNonNull(body, "body == null"); Objects.requireNonNull(rawResponse, "rawResponse == null"); if (rawResponse.isSuccessful()) { throw new IllegalArgumentException("rawResponse should not be successful response"); } return new Response<>(rawResponse, null, body); } private final okhttp3.Response rawResponse; private final @Nullable T body; private final @Nullable ResponseBody errorBody; private Response( okhttp3.Response rawResponse, @Nullable T body, @Nullable ResponseBody errorBody) { this.rawResponse = rawResponse; this.body = body; this.errorBody = errorBody; } /** The raw response from the HTTP client. */ public okhttp3.Response raw() { return rawResponse; } /** HTTP status code. */ public int code() { return rawResponse.code(); } /** HTTP status message or null if unknown. */ public String message() { return rawResponse.message(); } /** HTTP headers. */ public Headers headers() { return rawResponse.headers(); } /** Returns true if {@link #code()} is in the range [200..300). */ public boolean isSuccessful() { return rawResponse.isSuccessful(); } /** The deserialized response body of a {@linkplain #isSuccessful() successful} response. */ public @Nullable T body() { return body; } /** The raw response body of an {@linkplain #isSuccessful() unsuccessful} response. */ public @Nullable ResponseBody errorBody() { return errorBody; } @Override public String toString() { return rawResponse.toString(); } } ================================================ FILE: retrofit/src/main/java/retrofit2/Retrofit.java ================================================ /* * Copyright (C) 2012 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static java.util.Collections.unmodifiableList; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.net.URL; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; import java.util.Deque; import java.util.List; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import javax.annotation.Nullable; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.http.GET; import retrofit2.http.HTTP; import retrofit2.http.Header; import retrofit2.http.Url; /** * Retrofit adapts a Java interface to HTTP calls by using annotations on the declared methods to * define how requests are made. Create instances using {@linkplain Builder the builder} and pass * your interface to {@link #create} to generate an implementation. * *

For example, * *


 * Retrofit retrofit = new Retrofit.Builder()
 *     .baseUrl("https://api.example.com/")
 *     .addConverterFactory(GsonConverterFactory.create())
 *     .build();
 *
 * MyApi api = retrofit.create(MyApi.class);
 * Response<User> user = api.getUser().execute();
 * 
* * @author Bob Lee (bob@squareup.com) * @author Jake Wharton (jw@squareup.com) */ public final class Retrofit { /** * Method associations in this map will be in one of three states, and may only progress forward * to higher-numbered states. *
    *
  1. No value - no one has started or completed parsing annotations for the method.
  2. *
  3. Lock object - a thread has started parsing annotations on the method. Once the lock is * available the map will have been updated with the parsed model.
  4. *
  5. {@code ServiceMethod} - annotations for the method have been fully parsed.
  6. *
* This map should only be accessed through {@link #loadServiceMethod} which contains the state * transition logic. */ private final ConcurrentHashMap serviceMethodCache = new ConcurrentHashMap<>(); final okhttp3.Call.Factory callFactory; final HttpUrl baseUrl; final List converterFactories; final int defaultConverterFactoriesSize; final List callAdapterFactories; final int defaultCallAdapterFactoriesSize; final @Nullable Executor callbackExecutor; final boolean validateEagerly; Retrofit( okhttp3.Call.Factory callFactory, HttpUrl baseUrl, List converterFactories, int defaultConverterFactoriesSize, List callAdapterFactories, int defaultCallAdapterFactoriesSize, @Nullable Executor callbackExecutor, boolean validateEagerly) { this.callFactory = callFactory; this.baseUrl = baseUrl; this.converterFactories = converterFactories; // Copy+unmodifiable at call site. this.defaultConverterFactoriesSize = defaultConverterFactoriesSize; this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site. this.defaultCallAdapterFactoriesSize = defaultCallAdapterFactoriesSize; this.callbackExecutor = callbackExecutor; this.validateEagerly = validateEagerly; } /** * Create an implementation of the API endpoints defined by the {@code service} interface. * *

The relative path for a given method is obtained from an annotation on the method describing * the request type. The built-in methods are {@link retrofit2.http.GET GET}, {@link * retrofit2.http.PUT PUT}, {@link retrofit2.http.POST POST}, {@link retrofit2.http.PATCH PATCH}, * {@link retrofit2.http.HEAD HEAD}, {@link retrofit2.http.DELETE DELETE} and {@link * retrofit2.http.OPTIONS OPTIONS}. You can use a custom HTTP method with {@link HTTP @HTTP}. For * a dynamic URL, omit the path on the annotation and annotate the first parameter with {@link * Url @Url}. * *

Method parameters can be used to replace parts of the URL by annotating them with {@link * retrofit2.http.Path @Path}. Replacement sections are denoted by an identifier surrounded by * curly braces (e.g., "{foo}"). To add items to the query string of a URL use {@link * retrofit2.http.Query @Query}. * *

The body of a request is denoted by the {@link retrofit2.http.Body @Body} annotation. The * object will be converted to request representation by one of the {@link Converter.Factory} * instances. A {@link RequestBody} can also be used for a raw representation. * *

Alternative request body formats are supported by method annotations and corresponding * parameter annotations: * *

    *
  • {@link retrofit2.http.FormUrlEncoded @FormUrlEncoded} - Form-encoded data with key-value * pairs specified by the {@link retrofit2.http.Field @Field} parameter annotation. *
  • {@link retrofit2.http.Multipart @Multipart} - RFC 2388-compliant multipart data with * parts specified by the {@link retrofit2.http.Part @Part} parameter annotation. *
* *

Additional static headers can be added for an endpoint using the {@link * retrofit2.http.Headers @Headers} method annotation. For per-request control over a header * annotate a parameter with {@link Header @Header}. * *

By default, methods return a {@link Call} which represents the HTTP request. The generic * parameter of the call is the response body type and will be converted by one of the {@link * Converter.Factory} instances. {@link ResponseBody} can also be used for a raw representation. * {@link Void} can be used if you do not care about the body contents. * *

For example: * *

   * public interface CategoryService {
   *   @POST("category/{cat}/")
   *   Call<List<Item>> categoryList(@Path("cat") String a, @Query("page") int b);
   * }
   * 
*/ @SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety. public T create(final Class service) { validateServiceInterface(service); return (T) Proxy.newProxyInstance( service.getClassLoader(), new Class[] {service}, new InvocationHandler() { private final Object[] emptyArgs = new Object[0]; @Override public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { // If the method is a method from Object then defer to normal invocation. if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } args = args != null ? args : emptyArgs; Reflection reflection = Platform.reflection; return reflection.isDefaultMethod(method) ? reflection.invokeDefaultMethod(method, service, proxy, args) : loadServiceMethod(service, method).invoke(proxy, args); } }); } private void validateServiceInterface(Class service) { if (!service.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces."); } Deque> check = new ArrayDeque<>(1); check.add(service); while (!check.isEmpty()) { Class candidate = check.removeFirst(); if (candidate.getTypeParameters().length != 0) { StringBuilder message = new StringBuilder("Type parameters are unsupported on ").append(candidate.getName()); if (candidate != service) { message.append(" which is an interface of ").append(service.getName()); } throw new IllegalArgumentException(message.toString()); } Collections.addAll(check, candidate.getInterfaces()); } if (validateEagerly) { Reflection reflection = Platform.reflection; for (Method method : service.getDeclaredMethods()) { if (!reflection.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers()) && !method.isSynthetic()) { loadServiceMethod(service, method); } } } } ServiceMethod loadServiceMethod(Class service, Method method) { while (true) { // Note: Once we are minSdk 24 this whole method can be replaced by computeIfAbsent. Object lookup = serviceMethodCache.get(method); if (lookup instanceof ServiceMethod) { // Happy path: method is already parsed into the model. return (ServiceMethod) lookup; } if (lookup == null) { // Map does not contain any value. Try to put in a lock for this method. We MUST synchronize // on the lock before it is visible to others via the map to signal we are doing the work. Object lock = new Object(); synchronized (lock) { lookup = serviceMethodCache.putIfAbsent(method, lock); if (lookup == null) { // On successful lock insertion, perform the work and update the map before releasing. // Other threads may be waiting on lock now and will expect the parsed model. ServiceMethod result; try { result = ServiceMethod.parseAnnotations(this, service, method); } catch (Throwable e) { // Remove the lock on failure. Any other locked threads will retry as a result. serviceMethodCache.remove(method); throw e; } serviceMethodCache.put(method, result); return result; } } } // Either the initial lookup or the attempt to put our lock in the map has returned someone // else's lock. This means they are doing the parsing, and will update the map before // releasing // the lock. Once we can take the lock, the map is guaranteed to contain the model or null. // Note: There's a chance that our effort to put a lock into the map has actually returned a // finished model instead of a lock. In that case this code will perform a pointless lock and // redundant lookup in the map of the same instance. This is rare, and ultimately harmless. synchronized (lookup) { Object result = serviceMethodCache.get(method); if (result == null) { // The other thread failed its parsing. We will retry (and probably also fail). continue; } return (ServiceMethod) result; } } } /** * The factory used to create {@linkplain okhttp3.Call OkHttp calls} for sending a HTTP requests. * Typically an instance of {@link OkHttpClient}. */ public okhttp3.Call.Factory callFactory() { return callFactory; } /** The API base URL. */ public HttpUrl baseUrl() { return baseUrl; } /** * Returns a list of the factories tried when creating a {@linkplain #callAdapter(Type, * Annotation[])} call adapter}. */ public List callAdapterFactories() { return callAdapterFactories; } /** * Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain * #callAdapterFactories() factories}. * * @throws IllegalArgumentException if no call adapter available for {@code type}. */ public CallAdapter callAdapter(Type returnType, Annotation[] annotations) { return nextCallAdapter(null, returnType, annotations); } /** * Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain * #callAdapterFactories() factories} except {@code skipPast}. * * @throws IllegalArgumentException if no call adapter available for {@code type}. */ public CallAdapter nextCallAdapter( @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { Objects.requireNonNull(returnType, "returnType == null"); Objects.requireNonNull(annotations, "annotations == null"); int start = callAdapterFactories.indexOf(skipPast) + 1; for (int i = start, count = callAdapterFactories.size(); i < count; i++) { CallAdapter adapter = callAdapterFactories.get(i).get(returnType, annotations, this); if (adapter != null) { return adapter; } } StringBuilder builder = new StringBuilder("Could not locate call adapter for ").append(returnType).append(".\n"); if (skipPast != null) { builder.append(" Skipped:"); for (int i = 0; i < start; i++) { builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName()); } builder.append('\n'); } builder.append(" Tried:"); for (int i = start, count = callAdapterFactories.size(); i < count; i++) { builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName()); } throw new IllegalArgumentException(builder.toString()); } /** * Returns an unmodifiable list of the factories tried when creating a {@linkplain * #requestBodyConverter(Type, Annotation[], Annotation[]) request body converter}, a {@linkplain * #responseBodyConverter(Type, Annotation[]) response body converter}, or a {@linkplain * #stringConverter(Type, Annotation[]) string converter}. */ public List converterFactories() { return converterFactories; } /** * Returns a {@link Converter} for {@code type} to {@link RequestBody} from the available * {@linkplain #converterFactories() factories}. * * @throws IllegalArgumentException if no converter available for {@code type}. */ public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations) { return nextRequestBodyConverter(null, type, parameterAnnotations, methodAnnotations); } /** * Returns a {@link Converter} for {@code type} to {@link RequestBody} from the available * {@linkplain #converterFactories() factories} except {@code skipPast}. * * @throws IllegalArgumentException if no converter available for {@code type}. */ public Converter nextRequestBodyConverter( @Nullable Converter.Factory skipPast, Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations) { Objects.requireNonNull(type, "type == null"); Objects.requireNonNull(parameterAnnotations, "parameterAnnotations == null"); Objects.requireNonNull(methodAnnotations, "methodAnnotations == null"); int start = converterFactories.indexOf(skipPast) + 1; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter.Factory factory = converterFactories.get(i); Converter converter = factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, this); if (converter != null) { //noinspection unchecked return (Converter) converter; } } StringBuilder builder = new StringBuilder("Could not locate RequestBody converter for ").append(type).append(".\n"); if (skipPast != null) { builder.append(" Skipped:"); for (int i = 0; i < start; i++) { builder.append("\n * ").append(converterFactories.get(i).getClass().getName()); } builder.append('\n'); } builder.append(" Tried:"); for (int i = start, count = converterFactories.size(); i < count; i++) { builder.append("\n * ").append(converterFactories.get(i).getClass().getName()); } throw new IllegalArgumentException(builder.toString()); } /** * Returns a {@link Converter} for {@link ResponseBody} to {@code type} from the available * {@linkplain #converterFactories() factories}. * * @throws IllegalArgumentException if no converter available for {@code type}. */ public Converter responseBodyConverter(Type type, Annotation[] annotations) { return nextResponseBodyConverter(null, type, annotations); } /** * Returns a {@link Converter} for {@link ResponseBody} to {@code type} from the available * {@linkplain #converterFactories() factories} except {@code skipPast}. * * @throws IllegalArgumentException if no converter available for {@code type}. */ public Converter nextResponseBodyConverter( @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) { Objects.requireNonNull(type, "type == null"); Objects.requireNonNull(annotations, "annotations == null"); int start = converterFactories.indexOf(skipPast) + 1; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter converter = converterFactories.get(i).responseBodyConverter(type, annotations, this); if (converter != null) { //noinspection unchecked return (Converter) converter; } } StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ") .append(type) .append(".\n"); if (skipPast != null) { builder.append(" Skipped:"); for (int i = 0; i < start; i++) { builder.append("\n * ").append(converterFactories.get(i).getClass().getName()); } builder.append('\n'); } builder.append(" Tried:"); for (int i = start, count = converterFactories.size(); i < count; i++) { builder.append("\n * ").append(converterFactories.get(i).getClass().getName()); } throw new IllegalArgumentException(builder.toString()); } /** * Returns a {@link Converter} for {@code type} to {@link String} from the available {@linkplain * #converterFactories() factories}. */ public Converter stringConverter(Type type, Annotation[] annotations) { Objects.requireNonNull(type, "type == null"); Objects.requireNonNull(annotations, "annotations == null"); for (int i = 0, count = converterFactories.size(); i < count; i++) { Converter converter = converterFactories.get(i).stringConverter(type, annotations, this); if (converter != null) { //noinspection unchecked return (Converter) converter; } } // Nothing matched. Resort to default converter which just calls toString(). //noinspection unchecked return (Converter) BuiltInConverters.ToStringConverter.INSTANCE; } /** * The executor used for {@link Callback} methods on a {@link Call}. This may be {@code null}, in * which case callbacks should be made synchronously on the background thread. */ public @Nullable Executor callbackExecutor() { return callbackExecutor; } public Builder newBuilder() { return new Builder(this); } /** * Build a new {@link Retrofit}. * *

Calling {@link #baseUrl} is required before calling {@link #build()}. All other methods are * optional. */ public static final class Builder { private @Nullable okhttp3.Call.Factory callFactory; private @Nullable HttpUrl baseUrl; private final List converterFactories = new ArrayList<>(); private final List callAdapterFactories = new ArrayList<>(); private @Nullable Executor callbackExecutor; private boolean validateEagerly; public Builder() {} Builder(Retrofit retrofit) { callFactory = retrofit.callFactory; baseUrl = retrofit.baseUrl; // Do not add the default BuiltIntConverters and platform-aware converters added by build(). for (int i = 1, size = retrofit.converterFactories.size() - retrofit.defaultConverterFactoriesSize; i < size; i++) { converterFactories.add(retrofit.converterFactories.get(i)); } // Do not add the default, platform-aware call adapters added by build(). for (int i = 0, size = retrofit.callAdapterFactories.size() - retrofit.defaultCallAdapterFactoriesSize; i < size; i++) { callAdapterFactories.add(retrofit.callAdapterFactories.get(i)); } callbackExecutor = retrofit.callbackExecutor; validateEagerly = retrofit.validateEagerly; } /** * The HTTP client used for requests. * *

This is a convenience method for calling {@link #callFactory}. */ public Builder client(OkHttpClient client) { return callFactory(Objects.requireNonNull(client, "client == null")); } /** * Specify a custom call factory for creating {@link Call} instances. * *

Note: Calling {@link #client} automatically sets this value. */ public Builder callFactory(okhttp3.Call.Factory factory) { this.callFactory = Objects.requireNonNull(factory, "factory == null"); return this; } /** * Set the API base URL. * * @see #baseUrl(HttpUrl) */ public Builder baseUrl(URL baseUrl) { Objects.requireNonNull(baseUrl, "baseUrl == null"); return baseUrl(HttpUrl.get(baseUrl.toString())); } /** * Set the API base URL. * * @see #baseUrl(HttpUrl) */ public Builder baseUrl(String baseUrl) { Objects.requireNonNull(baseUrl, "baseUrl == null"); return baseUrl(HttpUrl.get(baseUrl)); } /** * Set the API base URL. * *

The specified endpoint values (such as with {@link GET @GET}) are resolved against this * value using {@link HttpUrl#resolve(String)}. The behavior of this matches that of an {@code * } link on a website resolving on the current URL. * *

Base URLs should always end in {@code /}. * *

A trailing {@code /} ensures that endpoints values which are relative paths will correctly * append themselves to a base which has path components. * *

Correct:
* Base URL: http://example.com/api/
* Endpoint: foo/bar/
* Result: http://example.com/api/foo/bar/ * *

Incorrect:
* Base URL: http://example.com/api
* Endpoint: foo/bar/
* Result: http://example.com/foo/bar/ * *

This method enforces that {@code baseUrl} has a trailing {@code /}. * *

Endpoint values which contain a leading {@code /} are absolute. * *

Absolute values retain only the host from {@code baseUrl} and ignore any specified path * components. * *

Base URL: http://example.com/api/
* Endpoint: /foo/bar/
* Result: http://example.com/foo/bar/ * *

Base URL: http://example.com/
* Endpoint: /foo/bar/
* Result: http://example.com/foo/bar/ * *

Endpoint values may be a full URL. * *

Values which have a host replace the host of {@code baseUrl} and values also with a scheme * replace the scheme of {@code baseUrl}. * *

Base URL: http://example.com/
* Endpoint: https://github.com/square/retrofit/
* Result: https://github.com/square/retrofit/ * *

Base URL: http://example.com
* Endpoint: //github.com/square/retrofit/
* Result: http://github.com/square/retrofit/ (note the scheme stays 'http') */ public Builder baseUrl(HttpUrl baseUrl) { Objects.requireNonNull(baseUrl, "baseUrl == null"); List pathSegments = baseUrl.pathSegments(); if (!"".equals(pathSegments.get(pathSegments.size() - 1))) { throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl); } this.baseUrl = baseUrl; return this; } /** Add converter factory for serialization and deserialization of objects. */ public Builder addConverterFactory(Converter.Factory factory) { converterFactories.add(Objects.requireNonNull(factory, "factory == null")); return this; } /** * Add a call adapter factory for supporting service method return types other than {@link * Call}. */ public Builder addCallAdapterFactory(CallAdapter.Factory factory) { callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null")); return this; } /** * The executor on which {@link Callback} methods are invoked when returning {@link Call} from * your service method. * *

Note: {@code executor} is not used for {@linkplain #addCallAdapterFactory custom method * return types}. */ public Builder callbackExecutor(Executor executor) { this.callbackExecutor = Objects.requireNonNull(executor, "executor == null"); return this; } /** Returns a modifiable list of call adapter factories. */ public List callAdapterFactories() { return this.callAdapterFactories; } /** Returns a modifiable list of converter factories. */ public List converterFactories() { return this.converterFactories; } /** * When calling {@link #create} on the resulting {@link Retrofit} instance, eagerly validate the * configuration of all methods in the supplied interface. */ public Builder validateEagerly(boolean validateEagerly) { this.validateEagerly = validateEagerly; return this; } /** * Create the {@link Retrofit} instance using the configured values. * *

Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link * OkHttpClient} will be created and used. */ public Retrofit build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient(); } Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor == null) { callbackExecutor = Platform.callbackExecutor; } BuiltInFactories builtInFactories = Platform.builtInFactories; // Make a defensive copy of the adapters and add the default Call adapter. List callAdapterFactories = new ArrayList<>(this.callAdapterFactories); List defaultCallAdapterFactories = builtInFactories.createDefaultCallAdapterFactories(callbackExecutor); callAdapterFactories.addAll(defaultCallAdapterFactories); // Make a defensive copy of the converters. List defaultConverterFactories = builtInFactories.createDefaultConverterFactories(); int defaultConverterFactoriesSize = defaultConverterFactories.size(); List converterFactories = new ArrayList<>(1 + this.converterFactories.size() + defaultConverterFactoriesSize); // Add the built-in converter factory first. This prevents overriding its behavior but also // ensures correct behavior when using converters that consume all types. converterFactories.add(new BuiltInConverters()); converterFactories.addAll(this.converterFactories); converterFactories.addAll(defaultConverterFactories); return new Retrofit( callFactory, baseUrl, unmodifiableList(converterFactories), defaultConverterFactoriesSize, unmodifiableList(callAdapterFactories), defaultCallAdapterFactories.size(), callbackExecutor, validateEagerly); } } } ================================================ FILE: retrofit/src/main/java/retrofit2/ServiceMethod.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static retrofit2.Utils.methodError; import java.lang.reflect.Method; import java.lang.reflect.Type; import javax.annotation.Nullable; abstract class ServiceMethod { static ServiceMethod parseAnnotations(Retrofit retrofit, Class service, Method method) { RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, service, method); Type returnType = method.getGenericReturnType(); if (Utils.hasUnresolvableType(returnType)) { throw methodError( method, "Method return type must not include a type variable or wildcard: %s", returnType); } if (returnType == void.class) { throw methodError(method, "Service methods cannot return void."); } return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); } abstract @Nullable T invoke(Object instance, Object[] args); } ================================================ FILE: retrofit/src/main/java/retrofit2/SkipCallbackExecutor.java ================================================ /* * Copyright (C) 2019 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Type; /** * Change the behavior of a {@code Call} return type to not use the {@linkplain * Retrofit#callbackExecutor() callback executor} for invoking the {@link Callback#onResponse(Call, * Response) onResponse} or {@link Callback#onFailure(Call, Throwable) onFailure} methods. * *


 * @SkipCallbackExecutor
 * @GET("user/{id}/token")
 * Call<String> getToken(@Path("id") long id);
 * 
* * This annotation can also be used when a {@link CallAdapter.Factory} explicitly delegates * to the built-in factory for {@link Call} via {@link Retrofit#nextCallAdapter(CallAdapter.Factory, * Type, Annotation[])} in order for the returned {@link Call} to skip the executor. (Note: by * default, a {@link Call} supplied directly to a {@link CallAdapter} will already skip the callback * executor. The annotation is only useful when looking up the built-in adapter.) */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface SkipCallbackExecutor {} ================================================ FILE: retrofit/src/main/java/retrofit2/SkipCallbackExecutorImpl.java ================================================ /* * Copyright (C) 2019 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.lang.annotation.Annotation; // This class conforms to the annotation requirements documented on Annotation. final class SkipCallbackExecutorImpl implements SkipCallbackExecutor { private static final SkipCallbackExecutor INSTANCE = new SkipCallbackExecutorImpl(); static Annotation[] ensurePresent(Annotation[] annotations) { if (Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)) { return annotations; } Annotation[] newAnnotations = new Annotation[annotations.length + 1]; // Place the skip annotation first since we're guaranteed to check for it in the call adapter. newAnnotations[0] = SkipCallbackExecutorImpl.INSTANCE; System.arraycopy(annotations, 0, newAnnotations, 1, annotations.length); return newAnnotations; } @Override public Class annotationType() { return SkipCallbackExecutor.class; } @Override public boolean equals(Object obj) { return obj instanceof SkipCallbackExecutor; } @Override public int hashCode() { return 0; } @Override public String toString() { return "@" + SkipCallbackExecutor.class.getName() + "()"; } } ================================================ FILE: retrofit/src/main/java/retrofit2/Utils.java ================================================ /* * Copyright (C) 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.Arrays; import java.util.NoSuchElementException; import java.util.Objects; import javax.annotation.Nullable; import kotlin.Unit; import okhttp3.ResponseBody; import okio.Buffer; final class Utils { static final Type[] EMPTY_TYPE_ARRAY = new Type[0]; private Utils() { // No instances. } static RuntimeException methodError(Method method, String message, Object... args) { return methodError(method, null, message, args); } @SuppressWarnings("AnnotateFormatMethod") static RuntimeException methodError( Method method, @Nullable Throwable cause, String message, Object... args) { message = String.format(message, args); return new IllegalArgumentException( message + "\n for method " + method.getDeclaringClass().getSimpleName() + "." + method.getName(), cause); } static RuntimeException parameterError( Method method, Throwable cause, int p, String message, Object... args) { String paramDesc = Platform.reflection.describeMethodParameter(method, p); return methodError(method, cause, message + " (" + paramDesc + ")", args); } static RuntimeException parameterError(Method method, int p, String message, Object... args) { String paramDesc = Platform.reflection.describeMethodParameter(method, p); return methodError(method, message + " (" + paramDesc + ")", args); } static Class getRawType(Type type) { Objects.requireNonNull(type, "type == null"); if (type instanceof Class) { // Type is a normal class. return (Class) type; } if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; // I'm not exactly sure why getRawType() returns Type instead of Class. Neal isn't either but // suspects some pathological case related to nested classes exists. Type rawType = parameterizedType.getRawType(); if (!(rawType instanceof Class)) throw new IllegalArgumentException(); return (Class) rawType; } if (type instanceof GenericArrayType) { Type componentType = ((GenericArrayType) type).getGenericComponentType(); return Array.newInstance(getRawType(componentType), 0).getClass(); } if (type instanceof TypeVariable) { // We could use the variable's bounds, but that won't work if there are multiple. Having a raw // type that's more general than necessary is okay. return Object.class; } if (type instanceof WildcardType) { return getRawType(((WildcardType) type).getUpperBounds()[0]); } throw new IllegalArgumentException( "Expected a Class, ParameterizedType, or " + "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName()); } /** Returns true if {@code a} and {@code b} are equal. */ static boolean equals(Type a, Type b) { if (a == b) { return true; // Also handles (a == null && b == null). } else if (a instanceof Class) { return a.equals(b); // Class already specifies equals(). } else if (a instanceof ParameterizedType) { if (!(b instanceof ParameterizedType)) return false; ParameterizedType pa = (ParameterizedType) a; ParameterizedType pb = (ParameterizedType) b; Object ownerA = pa.getOwnerType(); Object ownerB = pb.getOwnerType(); boolean ownersAreEqual = ownerA == ownerB || (ownerA != null && ownerA.equals(ownerB)); boolean rawTypesAreEqual = pa.getRawType().equals(pb.getRawType()); boolean typeArgumentsAreEqual = Arrays.equals(pa.getActualTypeArguments(), pb.getActualTypeArguments()); return ownersAreEqual && rawTypesAreEqual && typeArgumentsAreEqual; } else if (a instanceof GenericArrayType) { if (!(b instanceof GenericArrayType)) return false; GenericArrayType ga = (GenericArrayType) a; GenericArrayType gb = (GenericArrayType) b; return equals(ga.getGenericComponentType(), gb.getGenericComponentType()); } else if (a instanceof WildcardType) { if (!(b instanceof WildcardType)) return false; WildcardType wa = (WildcardType) a; WildcardType wb = (WildcardType) b; return Arrays.equals(wa.getUpperBounds(), wb.getUpperBounds()) && Arrays.equals(wa.getLowerBounds(), wb.getLowerBounds()); } else if (a instanceof TypeVariable) { if (!(b instanceof TypeVariable)) return false; TypeVariable va = (TypeVariable) a; TypeVariable vb = (TypeVariable) b; return va.getGenericDeclaration() == vb.getGenericDeclaration() && va.getName().equals(vb.getName()); } else { return false; // This isn't a type we support! } } /** * Returns the generic supertype for {@code supertype}. For example, given a class {@code * IntegerSet}, the result for when supertype is {@code Set.class} is {@code Set} and the * result when the supertype is {@code Collection.class} is {@code Collection}. */ static Type getGenericSupertype(Type context, Class rawType, Class toResolve) { if (toResolve == rawType) return context; // We skip searching through interfaces if unknown is an interface. if (toResolve.isInterface()) { Class[] interfaces = rawType.getInterfaces(); for (int i = 0, length = interfaces.length; i < length; i++) { if (interfaces[i] == toResolve) { return rawType.getGenericInterfaces()[i]; } else if (toResolve.isAssignableFrom(interfaces[i])) { return getGenericSupertype(rawType.getGenericInterfaces()[i], interfaces[i], toResolve); } } } // Check our supertypes. if (!rawType.isInterface()) { while (rawType != Object.class) { Class rawSupertype = rawType.getSuperclass(); if (rawSupertype == toResolve) { return rawType.getGenericSuperclass(); } else if (toResolve.isAssignableFrom(rawSupertype)) { return getGenericSupertype(rawType.getGenericSuperclass(), rawSupertype, toResolve); } rawType = rawSupertype; } } // We can't resolve this further. return toResolve; } private static int indexOf(Object[] array, Object toFind) { for (int i = 0; i < array.length; i++) { if (toFind.equals(array[i])) return i; } throw new NoSuchElementException(); } static String typeToString(Type type) { return type instanceof Class ? ((Class) type).getName() : type.toString(); } /** * Returns the generic form of {@code supertype}. For example, if this is {@code * ArrayList}, this returns {@code Iterable} given the input {@code * Iterable.class}. * * @param supertype a superclass of, or interface implemented by, this. */ static Type getSupertype(Type context, Class contextRawType, Class supertype) { if (!supertype.isAssignableFrom(contextRawType)) throw new IllegalArgumentException(); return resolve( context, contextRawType, getGenericSupertype(context, contextRawType, supertype)); } static Type resolve(Type context, Class contextRawType, Type toResolve) { // This implementation is made a little more complicated in an attempt to avoid object-creation. while (true) { if (toResolve instanceof TypeVariable) { TypeVariable typeVariable = (TypeVariable) toResolve; toResolve = resolveTypeVariable(context, contextRawType, typeVariable); if (toResolve == typeVariable) { return toResolve; } } else if (toResolve instanceof Class && ((Class) toResolve).isArray()) { Class original = (Class) toResolve; Type componentType = original.getComponentType(); Type newComponentType = resolve(context, contextRawType, componentType); return componentType == newComponentType ? original : new GenericArrayTypeImpl(newComponentType); } else if (toResolve instanceof GenericArrayType) { GenericArrayType original = (GenericArrayType) toResolve; Type componentType = original.getGenericComponentType(); Type newComponentType = resolve(context, contextRawType, componentType); return componentType == newComponentType ? original : new GenericArrayTypeImpl(newComponentType); } else if (toResolve instanceof ParameterizedType) { ParameterizedType original = (ParameterizedType) toResolve; Type ownerType = original.getOwnerType(); Type newOwnerType = resolve(context, contextRawType, ownerType); boolean changed = newOwnerType != ownerType; Type[] args = original.getActualTypeArguments(); for (int t = 0, length = args.length; t < length; t++) { Type resolvedTypeArgument = resolve(context, contextRawType, args[t]); if (resolvedTypeArgument != args[t]) { if (!changed) { args = args.clone(); changed = true; } args[t] = resolvedTypeArgument; } } return changed ? new ParameterizedTypeImpl(newOwnerType, original.getRawType(), args) : original; } else if (toResolve instanceof WildcardType) { WildcardType original = (WildcardType) toResolve; Type[] originalLowerBound = original.getLowerBounds(); Type[] originalUpperBound = original.getUpperBounds(); if (originalLowerBound.length == 1) { Type lowerBound = resolve(context, contextRawType, originalLowerBound[0]); if (lowerBound != originalLowerBound[0]) { return new WildcardTypeImpl(new Type[] {Object.class}, new Type[] {lowerBound}); } } else if (originalUpperBound.length == 1) { Type upperBound = resolve(context, contextRawType, originalUpperBound[0]); if (upperBound != originalUpperBound[0]) { return new WildcardTypeImpl(new Type[] {upperBound}, EMPTY_TYPE_ARRAY); } } return original; } else { return toResolve; } } } private static Type resolveTypeVariable( Type context, Class contextRawType, TypeVariable unknown) { Class declaredByRaw = declaringClassOf(unknown); // We can't reduce this further. if (declaredByRaw == null) return unknown; Type declaredBy = getGenericSupertype(context, contextRawType, declaredByRaw); if (declaredBy instanceof ParameterizedType) { int index = indexOf(declaredByRaw.getTypeParameters(), unknown); return ((ParameterizedType) declaredBy).getActualTypeArguments()[index]; } return unknown; } /** * Returns the declaring class of {@code typeVariable}, or {@code null} if it was not declared by * a class. */ private static @Nullable Class declaringClassOf(TypeVariable typeVariable) { GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration(); return genericDeclaration instanceof Class ? (Class) genericDeclaration : null; } static void checkNotPrimitive(Type type) { if (type instanceof Class && ((Class) type).isPrimitive()) { throw new IllegalArgumentException(); } } /** Returns true if {@code annotations} contains an instance of {@code cls}. */ static boolean isAnnotationPresent(Annotation[] annotations, Class cls) { for (Annotation annotation : annotations) { if (cls.isInstance(annotation)) { return true; } } return false; } static ResponseBody buffer(final ResponseBody body) throws IOException { Buffer buffer = new Buffer(); body.source().readAll(buffer); return ResponseBody.create(body.contentType(), body.contentLength(), buffer); } static Type getParameterUpperBound(int index, ParameterizedType type) { Type[] types = type.getActualTypeArguments(); if (index < 0 || index >= types.length) { throw new IllegalArgumentException( "Index " + index + " not in range [0," + types.length + ") for " + type); } Type paramType = types[index]; if (paramType instanceof WildcardType) { return ((WildcardType) paramType).getUpperBounds()[0]; } return paramType; } static Type getParameterLowerBound(int index, ParameterizedType type) { Type paramType = type.getActualTypeArguments()[index]; if (paramType instanceof WildcardType) { return ((WildcardType) paramType).getLowerBounds()[0]; } return paramType; } static boolean hasUnresolvableType(@Nullable Type type) { if (type instanceof Class) { return false; } if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; for (Type typeArgument : parameterizedType.getActualTypeArguments()) { if (hasUnresolvableType(typeArgument)) { return true; } } return false; } if (type instanceof GenericArrayType) { return hasUnresolvableType(((GenericArrayType) type).getGenericComponentType()); } if (type instanceof TypeVariable) { return true; } if (type instanceof WildcardType) { return true; } String className = type == null ? "null" : type.getClass().getName(); throw new IllegalArgumentException( "Expected a Class, ParameterizedType, or " + "GenericArrayType, but <" + type + "> is of type " + className); } static final class ParameterizedTypeImpl implements ParameterizedType { private final @Nullable Type ownerType; private final Type rawType; private final Type[] typeArguments; ParameterizedTypeImpl(@Nullable Type ownerType, Type rawType, Type... typeArguments) { // Require an owner type if the raw type needs it. if (rawType instanceof Class && (ownerType == null) != (((Class) rawType).getEnclosingClass() == null)) { throw new IllegalArgumentException(); } for (Type typeArgument : typeArguments) { Objects.requireNonNull(typeArgument, "typeArgument == null"); checkNotPrimitive(typeArgument); } this.ownerType = ownerType; this.rawType = rawType; this.typeArguments = typeArguments.clone(); } @Override public Type[] getActualTypeArguments() { return typeArguments.clone(); } @Override public Type getRawType() { return rawType; } @Override public @Nullable Type getOwnerType() { return ownerType; } @Override public boolean equals(Object other) { return other instanceof ParameterizedType && Utils.equals(this, (ParameterizedType) other); } @Override public int hashCode() { return Arrays.hashCode(typeArguments) ^ rawType.hashCode() ^ (ownerType != null ? ownerType.hashCode() : 0); } @Override public String toString() { if (typeArguments.length == 0) return typeToString(rawType); StringBuilder result = new StringBuilder(30 * (typeArguments.length + 1)); result.append(typeToString(rawType)); result.append("<").append(typeToString(typeArguments[0])); for (int i = 1; i < typeArguments.length; i++) { result.append(", ").append(typeToString(typeArguments[i])); } return result.append(">").toString(); } } private static final class GenericArrayTypeImpl implements GenericArrayType { private final Type componentType; GenericArrayTypeImpl(Type componentType) { this.componentType = componentType; } @Override public Type getGenericComponentType() { return componentType; } @Override public boolean equals(Object o) { return o instanceof GenericArrayType && Utils.equals(this, (GenericArrayType) o); } @Override public int hashCode() { return componentType.hashCode(); } @Override public String toString() { return typeToString(componentType) + "[]"; } } /** * The WildcardType interface supports multiple upper bounds and multiple lower bounds. We only * support what the Java 6 language needs - at most one bound. If a lower bound is set, the upper * bound must be Object.class. */ private static final class WildcardTypeImpl implements WildcardType { private final Type upperBound; private final @Nullable Type lowerBound; WildcardTypeImpl(Type[] upperBounds, Type[] lowerBounds) { if (lowerBounds.length > 1) throw new IllegalArgumentException(); if (upperBounds.length != 1) throw new IllegalArgumentException(); if (lowerBounds.length == 1) { if (lowerBounds[0] == null) throw new NullPointerException(); checkNotPrimitive(lowerBounds[0]); if (upperBounds[0] != Object.class) throw new IllegalArgumentException(); this.lowerBound = lowerBounds[0]; this.upperBound = Object.class; } else { if (upperBounds[0] == null) throw new NullPointerException(); checkNotPrimitive(upperBounds[0]); this.lowerBound = null; this.upperBound = upperBounds[0]; } } @Override public Type[] getUpperBounds() { return new Type[] {upperBound}; } @Override public Type[] getLowerBounds() { return lowerBound != null ? new Type[] {lowerBound} : EMPTY_TYPE_ARRAY; } @Override public boolean equals(Object other) { return other instanceof WildcardType && Utils.equals(this, (WildcardType) other); } @Override public int hashCode() { // This equals Arrays.hashCode(getLowerBounds()) ^ Arrays.hashCode(getUpperBounds()). return (lowerBound != null ? 31 + lowerBound.hashCode() : 1) ^ (31 + upperBound.hashCode()); } @Override public String toString() { if (lowerBound != null) return "? super " + typeToString(lowerBound); if (upperBound == Object.class) return "?"; return "? extends " + typeToString(upperBound); } } // https://github.com/ReactiveX/RxJava/blob/6a44e5d0543a48f1c378dc833a155f3f71333bc2/ // src/main/java/io/reactivex/exceptions/Exceptions.java#L66 static void throwIfFatal(Throwable t) { if (t instanceof VirtualMachineError) { throw (VirtualMachineError) t; } else if (t instanceof ThreadDeath) { throw (ThreadDeath) t; } else if (t instanceof LinkageError) { throw (LinkageError) t; } } /** Not volatile because we don't mind multiple threads discovering this. */ private static boolean checkForKotlinUnit = true; static boolean isUnit(Type type) { if (checkForKotlinUnit) { try { return type == Unit.class; } catch (NoClassDefFoundError ignored) { checkForKotlinUnit = false; } } return false; } } ================================================ FILE: retrofit/src/main/java/retrofit2/http/Body.java ================================================ /* * Copyright (C) 2011 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import retrofit2.Converter; import retrofit2.Retrofit; /** * Use this annotation on a service method param when you want to directly control the request body * of a POST/PUT request (instead of sending in as request parameters or form-style request body). * The object will be serialized using the {@link Retrofit Retrofit} instance {@link Converter * Converter} and the result will be set directly as the request body. * *

Body parameters may not be {@code null}. */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface Body {} ================================================ FILE: retrofit/src/main/java/retrofit2/http/DELETE.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.HttpUrl; /** Make a DELETE request. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface DELETE { /** * A relative or absolute path, or full URL of the endpoint. This value is optional if the first * parameter of the method is annotated with {@link Url @Url}. * *

See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how * this is resolved against a base URL to create the full endpoint URL. */ String value() default ""; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/Field.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Type; import retrofit2.Retrofit; /** * Named pair for a form-encoded request. * *

Values are converted to strings using {@link Retrofit#stringConverter(Type, Annotation[])} (or * {@link Object#toString()}, if no matching string converter is installed) and then form URL * encoded. {@code null} values are ignored. Passing a {@link java.util.List List} or array will * result in a field pair for each non-{@code null} item. * *

Simple Example: * *


 * @FormUrlEncoded
 * @POST("/")
 * Call<ResponseBody> example(
 *     @Field("name") String name,
 *     @Field("occupation") String occupation);
 * 
* * Calling with {@code foo.example("Bob Smith", "President")} yields a request body of {@code * name=Bob+Smith&occupation=President}. * *

Array/Varargs Example: * *


 * @FormUrlEncoded
 * @POST("/list")
 * Call<ResponseBody> example(@Field("name") String... names);
 * 
* * Calling with {@code foo.example("Bob Smith", "Jane Doe")} yields a request body of {@code * name=Bob+Smith&name=Jane+Doe}. * * @see FormUrlEncoded * @see FieldMap */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface Field { String value(); /** Specifies whether the {@linkplain #value() name} and value are already URL encoded. */ boolean encoded() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/FieldMap.java ================================================ /* * Copyright (C) 2014 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Named key/value pairs for a form-encoded request. * *

Simple Example: * *


 * @FormUrlEncoded
 * @POST("/things")
 * Call<ResponseBody> things(@FieldMap Map<String, String> fields);
 * 
* * Calling with {@code foo.things(ImmutableMap.of("foo", "bar", "kit", "kat")} yields a request body * of {@code foo=bar&kit=kat}. * *

A {@code null} value for the map, as a key, or as a value is not allowed. * * @see FormUrlEncoded * @see Field */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface FieldMap { /** Specifies whether the names and values are already URL encoded. */ boolean encoded() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/FormUrlEncoded.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Denotes that the request body will use form URL encoding. Fields should be declared as parameters * and annotated with {@link Field @Field}. * *

Requests made with this annotation will have {@code application/x-www-form-urlencoded} MIME * type. Field names and values will be UTF-8 encoded before being URI-encoded in accordance to RFC-3986. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface FormUrlEncoded {} ================================================ FILE: retrofit/src/main/java/retrofit2/http/GET.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.HttpUrl; /** Make a GET request. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface GET { /** * A relative or absolute path, or full URL of the endpoint. This value is optional if the first * parameter of the method is annotated with {@link Url @Url}. * *

See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how * this is resolved against a base URL to create the full endpoint URL. */ String value() default ""; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/HEAD.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.HttpUrl; /** Make a HEAD request. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface HEAD { /** * A relative or absolute path, or full URL of the endpoint. This value is optional if the first * parameter of the method is annotated with {@link Url @Url}. * *

See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how * this is resolved against a base URL to create the full endpoint URL. */ String value() default ""; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/HTTP.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.HttpUrl; /** * Use a custom HTTP verb for a request. * *


 * interface Service {
 *   @HTTP(method = "CUSTOM", path = "custom/endpoint/")
 *   Call<ResponseBody> customEndpoint();
 * }
 * 
* * This annotation can also used for sending {@code DELETE} with a request body: * *

 * interface Service {
 *   @HTTP(method = "DELETE", path = "remove/", hasBody = true)
 *   Call<ResponseBody> deleteObject(@Body RequestBody object);
 * }
 * 
*/ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface HTTP { String method(); /** * A relative or absolute path, or full URL of the endpoint. This value is optional if the first * parameter of the method is annotated with {@link Url @Url}. * *

See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how * this is resolved against a base URL to create the full endpoint URL. */ String path() default ""; boolean hasBody() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/Header.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Replaces the header with the value of its target. * *


 * @GET("/")
 * Call<ResponseBody> foo(@Header("Accept-Language") String lang);
 * 
* * Header parameters may be {@code null} which will omit them from the request. Passing a {@link * java.util.List List} or array will result in a header for each non-{@code null} item. * *

Parameter keys and values only allows ascii values by default. Specify {@link * #allowUnsafeNonAsciiValues() allowUnsafeNonAsciiValues=true} to change this behavior. * *


 * @GET("/")
 * Call<ResponseBody> foo(@Header("Accept-Language", allowUnsafeNonAsciiValues=true) String lang);
 * 
* *

Note: Headers do not overwrite each other. All headers with the same name * will be included in the request. * * @see Headers * @see HeaderMap */ @Documented @Retention(RUNTIME) @Target(PARAMETER) public @interface Header { /** The query parameter name. */ String value(); /** * Specifies whether the parameter {@linkplain #value() name} and value are already URL encoded. */ boolean allowUnsafeNonAsciiValues() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/HeaderMap.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Type; import java.util.Map; import retrofit2.Retrofit; /** * Adds headers specified in the {@link Map} or {@link okhttp3.Headers}. * *

Values in the map are converted to strings using {@link Retrofit#stringConverter(Type, * Annotation[])} (or {@link Object#toString()}, if no matching string converter is installed). * *

Simple Example: * *

 * @GET("/search")
 * void list(@HeaderMap Map<String, String> headers);
 *
 * ...
 *
 * // The following call yields /search with headers
 * // Accept: text/plain and Accept-Charset: utf-8
 * foo.list(ImmutableMap.of("Accept", "text/plain", "Accept-Charset", "utf-8"));
 * 
* *

Map keys and values representing parameter values allow only ascii values by default. * Specify {@link #allowUnsafeNonAsciiValues() allowUnsafeNonAsciiValues=true} to change this behavior. * *

 * @GET("/search")
 * void list(@HeaderMap(allowUnsafeNonAsciiValues=true) Map<String, String> headers);
 * 
* * @see Header * @see Headers */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface HeaderMap { /** Specifies whether the parameter values are allowed with unsafe non ascii values. */ boolean allowUnsafeNonAsciiValues() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/Headers.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Adds headers literally supplied in the {@code value}. * *

 * @Headers("Cache-Control: max-age=640000")
 * @GET("/")
 * ...
 *
 * @Headers({
 *   "X-Foo: Bar",
 *   "X-Ping: Pong"
 * })
 * @GET("/")
 * ...
 * 
* *

Parameter keys and values only allows ascii values by default. Specify {@link * #allowUnsafeNonAsciiValues() allowUnsafeNonAsciiValues=true} to change this behavior. * *

@Headers({ "X-Foo: Bar", "X-Ping: Pong" }, allowUnsafeNonAsciiValues=true) @GET("/") * *

Note: Headers do not overwrite each other. All headers with the same name * will be included in the request. * * @see Header * @see HeaderMap */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface Headers { /** The query parameter name. */ String[] value(); /** * Specifies whether the parameter {@linkplain #value() name} and value are already URL encoded. */ boolean allowUnsafeNonAsciiValues() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/Multipart.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Denotes that the request body is multi-part. Parts should be declared as parameters and annotated * with {@link Part @Part}. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface Multipart {} ================================================ FILE: retrofit/src/main/java/retrofit2/http/OPTIONS.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.HttpUrl; /** Make an OPTIONS request. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface OPTIONS { /** * A relative or absolute path, or full URL of the endpoint. This value is optional if the first * parameter of the method is annotated with {@link Url @Url}. * *

See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how * this is resolved against a base URL to create the full endpoint URL. */ String value() default ""; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/PATCH.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.HttpUrl; /** Make a PATCH request. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface PATCH { /** * A relative or absolute path, or full URL of the endpoint. This value is optional if the first * parameter of the method is annotated with {@link Url @Url}. * *

See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how * this is resolved against a base URL to create the full endpoint URL. */ String value() default ""; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/POST.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.HttpUrl; /** Make a POST request. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface POST { /** * A relative or absolute path, or full URL of the endpoint. This value is optional if the first * parameter of the method is annotated with {@link Url @Url}. * *

See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how * this is resolved against a base URL to create the full endpoint URL. */ String value() default ""; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/PUT.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.HttpUrl; /** Make a PUT request. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface PUT { /** * A relative or absolute path, or full URL of the endpoint. This value is optional if the first * parameter of the method is annotated with {@link Url @Url}. * *

See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how * this is resolved against a base URL to create the full endpoint URL. */ String value() default ""; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/Part.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import retrofit2.Converter; /** * Denotes a single part of a multi-part request. * *

The parameter type on which this annotation exists will be processed in one of three ways: * *

    *
  • If the type is {@link okhttp3.MultipartBody.Part} the contents will be used directly. Omit * the name from the annotation (i.e., {@code @Part MultipartBody.Part part}). *
  • If the type is {@link okhttp3.RequestBody RequestBody} the value will be used directly with * its content type. Supply the part name in the annotation (e.g., {@code @Part("foo") * RequestBody foo}). *
  • Other object types will be converted to an appropriate representation by using {@linkplain * Converter a converter}. Supply the part name in the annotation (e.g., {@code @Part("foo") * Image photo}). *
* *

Values may be {@code null} which will omit them from the request body. * *

* *


 * @Multipart
 * @POST("/")
 * Call<ResponseBody> example(
 *     @Part("description") String description,
 *     @Part(value = "image", encoding = "8-bit") RequestBody image);
 * 
* *

Part parameters may not be {@code null}. */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface Part { /** * The name of the part. Required for all parameter types except {@link * okhttp3.MultipartBody.Part}. */ String value() default ""; /** The {@code Content-Transfer-Encoding} of this part. */ String encoding() default "binary"; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/PartMap.java ================================================ /* * Copyright (C) 2014 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import retrofit2.Converter; /** * Denotes name and value parts of a multi-part request. * *

Values of the map on which this annotation exists will be processed in one of two ways: * *

    *
  • If the type is {@link okhttp3.RequestBody RequestBody} the value will be used directly with * its content type. *
  • Other object types will be converted to an appropriate representation by using {@linkplain * Converter a converter}. *
* *

* *


 * @Multipart
 * @POST("/upload")
 * Call<ResponseBody> upload(
 *     @Part("file") RequestBody file,
 *     @PartMap Map<String, RequestBody> params);
 * 
* *

A {@code null} value for the map, as a key, or as a value is not allowed. * * @see Multipart * @see Part */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface PartMap { /** The {@code Content-Transfer-Encoding} of the parts. */ String encoding() default "binary"; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/Path.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Type; import retrofit2.Retrofit; /** * Named replacement in a URL path segment. Values are converted to strings using {@link * Retrofit#stringConverter(Type, Annotation[])} (or {@link Object#toString()}, if no matching * string converter is installed) and then URL encoded. * *

Simple example: * *


 * @GET("/image/{id}")
 * Call<ResponseBody> example(@Path("id") int id);
 * 
* * Calling with {@code foo.example(1)} yields {@code /image/1}. * *

Values are URL encoded by default. Disable with {@code encoded=true}. * *


 * @GET("/user/{name}")
 * Call<ResponseBody> encoded(@Path("name") String name);
 *
 * @GET("/user/{name}")
 * Call<ResponseBody> notEncoded(@Path(value="name", encoded=true) String name);
 * 
* * Calling {@code foo.encoded("John%Doe")} yields {@code /user/John%25Doe} whereas {@code * foo.notEncoded("John%Doe")} yields {@code /user/John%Doe}. * *

Path parameters may not be {@code null}. */ @Documented @Retention(RUNTIME) @Target(PARAMETER) public @interface Path { String value(); /** * Specifies whether the argument value to the annotated method parameter is already URL encoded. */ boolean encoded() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/Query.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Type; import retrofit2.Retrofit; /** * Query parameter appended to the URL. * *

Values are converted to strings using {@link Retrofit#stringConverter(Type, Annotation[])} (or * {@link Object#toString()}, if no matching string converter is installed) and then URL encoded. * {@code null} values are ignored. Passing a {@link java.util.List List} or array will result in a * query parameter for each non-{@code null} item. * *

Simple Example: * *


 * @GET("/friends")
 * Call<ResponseBody> friends(@Query("page") int page);
 * 
* * Calling with {@code foo.friends(1)} yields {@code /friends?page=1}. * *

Example with {@code null}: * *


 * @GET("/friends")
 * Call<ResponseBody> friends(@Query("group") String group);
 * 
* * Calling with {@code foo.friends(null)} yields {@code /friends}. * *

Array/Varargs Example: * *


 * @GET("/friends")
 * Call<ResponseBody> friends(@Query("group") String... groups);
 * 
* * Calling with {@code foo.friends("coworker", "bowling")} yields {@code * /friends?group=coworker&group=bowling}. * *

Parameter names and values are URL encoded by default. Specify {@link #encoded() encoded=true} * to change this behavior. * *


 * @GET("/friends")
 * Call<ResponseBody> friends(@Query(value="group", encoded=true) String group);
 * 
* * Calling with {@code foo.friends("foo+bar"))} yields {@code /friends?group=foo+bar}. * * @see QueryMap * @see QueryName */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface Query { /** The query parameter name. */ String value(); /** * Specifies whether the parameter {@linkplain #value() name} and value are already URL encoded. */ boolean encoded() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/QueryMap.java ================================================ /* * Copyright (C) 2014 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Type; import retrofit2.Retrofit; /** * Query parameter keys and values appended to the URL. * *

Values are converted to strings using {@link Retrofit#stringConverter(Type, Annotation[])} (or * {@link Object#toString()}, if no matching string converter is installed). * *

Simple Example: * *


 * @GET("/friends")
 * Call<ResponseBody> friends(@QueryMap Map<String, String> filters);
 * 
* * Calling with {@code foo.friends(ImmutableMap.of("group", "coworker", "age", "42"))} yields {@code * /friends?group=coworker&age=42}. * *

Map keys and values representing parameter values are URL encoded by default. Specify {@link * #encoded() encoded=true} to change this behavior. * *


 * @GET("/friends")
 * Call<ResponseBody> friends(@QueryMap(encoded=true) Map<String, String> filters);
 * 
* * Calling with {@code foo.list(ImmutableMap.of("group", "coworker+bowling"))} yields {@code * /friends?group=coworker+bowling}. * *

A {@code null} value for the map, as a key, or as a value is not allowed. * * @see Query * @see QueryName */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface QueryMap { /** Specifies whether parameter names and values are already URL encoded. */ boolean encoded() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/QueryName.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Query parameter appended to the URL that has no value. * *

Passing a {@link java.util.List List} or array will result in a query parameter for each * non-{@code null} item. * *

Simple Example: * *


 * @GET("/friends")
 * Call<ResponseBody> friends(@QueryName String filter);
 * 
* * Calling with {@code foo.friends("contains(Bob)")} yields {@code /friends?contains(Bob)}. * *

Array/Varargs Example: * *


 * @GET("/friends")
 * Call<ResponseBody> friends(@QueryName String... filters);
 * 
* * Calling with {@code foo.friends("contains(Bob)", "age(42)")} yields {@code * /friends?contains(Bob)&age(42)}. * *

Parameter names are URL encoded by default. Specify {@link #encoded() encoded=true} to change * this behavior. * *


 * @GET("/friends")
 * Call<ResponseBody> friends(@QueryName(encoded=true) String filter);
 * 
* * Calling with {@code foo.friends("name+age"))} yields {@code /friends?name+age}. * * @see Query * @see QueryMap */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface QueryName { /** Specifies whether the parameter is already URL encoded. */ boolean encoded() default false; } ================================================ FILE: retrofit/src/main/java/retrofit2/http/Streaming.java ================================================ /* * Copyright (C) 2014 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.ResponseBody; /** * Treat the response body on methods returning {@link ResponseBody ResponseBody} as is, i.e. * without converting the body to {@code byte[]}. */ @Documented @Target(METHOD) @Retention(RUNTIME) public @interface Streaming {} ================================================ FILE: retrofit/src/main/java/retrofit2/http/Tag.java ================================================ /* * Copyright (C) 2019 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Adds the argument instance as a request tag using the type as the key. * *

 * @GET("/")
 * Call<ResponseBody> foo(@Tag String tag);
 * 
* * Tag arguments may be {@code null} which will omit them from the request. Passing a parameterized * type will use the raw type as the key (e.g., {@code List} uses {@code List.class}). * Primitive types will be boxed and stored using the boxed type * (e.g., {@code long} uses {@code Long.class}). * Duplicate tag types are not allowed. */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface Tag {} ================================================ FILE: retrofit/src/main/java/retrofit2/http/Url.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.http; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import okhttp3.HttpUrl; import retrofit2.Retrofit; /** * URL resolved against the {@linkplain Retrofit#baseUrl() base URL}. * *

 * @GET
 * Call<ResponseBody> list(@Url String url);
 * 
* *

See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how the * value will be resolved against a base URL to create the full endpoint URL. */ @Documented @Target(PARAMETER) @Retention(RUNTIME) public @interface Url {} ================================================ FILE: retrofit/src/main/java/retrofit2/http/package-info.java ================================================ // Copyright 2014 Square, Inc. /** Annotations for interface methods to control the HTTP request behavior. */ package retrofit2.http; ================================================ FILE: retrofit/src/main/java/retrofit2/internal/EverythingIsNonNull.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.internal; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import javax.annotation.Nonnull; import javax.annotation.meta.TypeQualifierDefault; /** * Extends {@code ParametersAreNonnullByDefault} to also apply to Method results and fields. * * @see javax.annotation.ParametersAreNonnullByDefault */ @Documented @Nonnull @TypeQualifierDefault({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface EverythingIsNonNull {} ================================================ FILE: retrofit/src/main/java/retrofit2/package-info.java ================================================ // Copyright 2014 Square, Inc. /** * Retrofit turns your REST API into a Java interface. * *

 * public interface GitHubService {
 *   @GET("/users/{user}/repos")
 *   List<Repo> listRepos(@Path("user") String user);
 * }
 * 
*/ @retrofit2.internal.EverythingIsNonNull package retrofit2; ================================================ FILE: retrofit/src/main/java14/retrofit2/DefaultMethodSupport.java ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import javax.annotation.Nullable; /** * Java 14 allows a regular (i.e., non-trusted) lookup to succeed for invoking default methods. *

* https://bugs.openjdk.java.net/browse/JDK-8209005 */ final class DefaultMethodSupport { @Nullable static Object invoke( Method method, Class declaringClass, Object proxy, @Nullable Object[] args) throws Throwable { return MethodHandles.lookup() .unreflectSpecial(method, declaringClass) .bindTo(proxy) .invokeWithArguments(args); } private DefaultMethodSupport() {} } ================================================ FILE: retrofit/src/main/java16/retrofit2/DefaultMethodSupport.java ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import javax.annotation.Nullable; /** Java 16 finally has a public API for invoking default methods on a proxy. */ final class DefaultMethodSupport { @Nullable static Object invoke( Method method, Class declaringClass, Object proxy, @Nullable Object[] args) throws Throwable { return InvocationHandler.invokeDefault(proxy, method, args); } private DefaultMethodSupport() {} } ================================================ FILE: retrofit/src/main/resources/META-INF/proguard/retrofit2.pro ================================================ # Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and # EnclosingMethod is required to use InnerClasses. -keepattributes Signature, InnerClasses, EnclosingMethod # Retrofit does reflection on method and parameter annotations. -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations # Keep annotation default values (e.g., retrofit2.http.Field.encoded). -keepattributes AnnotationDefault # Retain service method parameters when optimizing. -keepclassmembers,allowshrinking,allowobfuscation interface * { @retrofit2.http.* ; } # Ignore annotation used for build tooling. -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement # Ignore JSR 305 annotations for embedding nullability information. -dontwarn javax.annotation.** # Guarded by a NoClassDefFoundError try/catch and only used when on the classpath. -dontwarn kotlin.Unit # Top-level functions that can only be used by Kotlin. -dontwarn retrofit2.KotlinExtensions -dontwarn retrofit2.KotlinExtensions$* # With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy # and replaces all potential values with null. Explicitly keeping the interfaces prevents this. -if interface * { @retrofit2.http.* ; } -keep,allowobfuscation interface <1> # Keep inherited services. -if interface * { @retrofit2.http.* ; } -keep,allowobfuscation interface * extends <1> # With R8 full mode generic signatures are stripped for classes that are not # kept. Suspend functions are wrapped in continuations where the type argument # is used. -keep,allowoptimization,allowshrinking,allowobfuscation class kotlin.coroutines.Continuation # R8 full mode strips generic signatures from return types if not kept. -if interface * { @retrofit2.http.* public *** *(...); } -keep,allowoptimization,allowshrinking,allowobfuscation class <3> # With R8 full mode generic signatures are stripped for classes that are not kept. -keep,allowoptimization,allowshrinking,allowobfuscation class retrofit2.Response ================================================ FILE: retrofit/test-helpers/build.gradle ================================================ apply plugin: 'java-library' dependencies { api projects.retrofit compileOnly libs.findBugsAnnotations } ================================================ FILE: retrofit/test-helpers/src/main/java/retrofit2/TestingUtils.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2; import java.lang.reflect.Method; import java.util.Arrays; import okhttp3.Request; import retrofit2.helpers.ToStringConverterFactory; final class TestingUtils { static Request buildRequest(Class cls, Retrofit.Builder builder, Object... args) { okhttp3.Call.Factory callFactory = request -> { throw new UnsupportedOperationException("Not implemented"); }; Retrofit retrofit = builder.callFactory(callFactory).build(); Method method = onlyMethod(cls); try { return RequestFactory.parseAnnotations(retrofit, cls, method).create(null, args); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new AssertionError(e); } } static Request buildRequest(Class cls, Object... args) { Retrofit.Builder retrofitBuilder = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(new ToStringConverterFactory()); return buildRequest(cls, retrofitBuilder, args); } static Method onlyMethod(Class c) { Method[] declaredMethods = c.getDeclaredMethods(); if (declaredMethods.length == 1) { return declaredMethods[0]; } throw new IllegalArgumentException("More than one method declared."); } static String repeat(char c, int times) { char[] cs = new char[times]; Arrays.fill(cs, c); return new String(cs); } } ================================================ FILE: retrofit/test-helpers/src/main/java/retrofit2/helpers/DelegatingCallAdapterFactory.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.helpers; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import retrofit2.CallAdapter; import retrofit2.Retrofit; public final class DelegatingCallAdapterFactory extends CallAdapter.Factory { public boolean called; @Override public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { called = true; return retrofit.nextCallAdapter(this, returnType, annotations); } } ================================================ FILE: retrofit/test-helpers/src/main/java/retrofit2/helpers/ExampleWithoutParameterNames.java ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.helpers; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.GET; /** This module is compiled without parameter names embedded in the class file. */ public interface ExampleWithoutParameterNames { @GET("/") Call method(String theFirstParameter); } ================================================ FILE: retrofit/test-helpers/src/main/java/retrofit2/helpers/NonMatchingCallAdapterFactory.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.helpers; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.CallAdapter; import retrofit2.Retrofit; public final class NonMatchingCallAdapterFactory extends CallAdapter.Factory { public boolean called; @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { called = true; return null; } } ================================================ FILE: retrofit/test-helpers/src/main/java/retrofit2/helpers/NonMatchingConverterFactory.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.helpers; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; public final class NonMatchingConverterFactory extends Converter.Factory { public boolean called; @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { called = true; return null; } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { called = true; return null; } @Override public @Nullable Converter stringConverter( Type type, Annotation[] annotations, Retrofit retrofit) { called = true; return null; } } ================================================ FILE: retrofit/test-helpers/src/main/java/retrofit2/helpers/NullObjectConverterFactory.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.helpers; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import retrofit2.Converter; import retrofit2.Retrofit; /** Always converts to null. */ public final class NullObjectConverterFactory extends Converter.Factory { @Override public Converter stringConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return new Converter() { @Override public String convert(Object value) throws IOException { return null; } }; } } ================================================ FILE: retrofit/test-helpers/src/main/java/retrofit2/helpers/ObjectInstanceConverterFactory.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.helpers; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; public final class ObjectInstanceConverterFactory extends Converter.Factory { public static final Object VALUE = new Object(); @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (type != Object.class) { return null; } return value -> VALUE; } } ================================================ FILE: retrofit/test-helpers/src/main/java/retrofit2/helpers/ToStringConverterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.helpers; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; public class ToStringConverterFactory extends Converter.Factory { static final MediaType MEDIA_TYPE = MediaType.get("text/plain"); @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (String.class.equals(type)) { return ResponseBody::string; } return null; } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (String.class.equals(type)) { return value -> RequestBody.create(MEDIA_TYPE, value); } return null; } } ================================================ FILE: retrofit-adapters/README.md ================================================ Retrofit Adapters ================= Retrofit ships with a default adapter for executing `Call` instances. The child modules contained herein are additional adapters for other popular execution mechanisms. To use, supply an instance of your desired adapter when building your `Retrofit` instance. ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com") .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); ``` ================================================ FILE: retrofit-adapters/guava/README.md ================================================ Guava Adapter ============== An `Adapter` for adapting [Guava][1] `ListenableFuture`. Usage ----- Add `GuavaCallAdapterFactory` as a `Call` adapter when building your `Retrofit` instance: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .addCallAdapterFactory(GuavaCallAdapterFactory.create()) .build(); ``` Your service methods can now use `ListenableFuture` as their return type. ```java interface MyService { @GET("/user") ListenableFuture getUser(); } ``` Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 adapter-guava latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:adapter-guava:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/google/guava [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=adapter-guava&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22adapter-guava%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-adapters/guava/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.guava compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.adapter.guava' } } ================================================ FILE: retrofit-adapters/guava/gradle.properties ================================================ POM_ARTIFACT_ID=adapter-guava POM_NAME=Adapter: Guava POM_DESCRIPTION=A Retrofit CallAdapter for Guava's ListenableFuture. ================================================ FILE: retrofit-adapters/guava/src/main/java/retrofit2/adapter/guava/GuavaCallAdapterFactory.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.guava; import com.google.common.util.concurrent.AbstractFuture; import com.google.common.util.concurrent.ListenableFuture; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; /** * A {@linkplain CallAdapter.Factory call adapter} which creates Guava futures. * *

Adding this class to {@link Retrofit} allows you to return {@link ListenableFuture} from * service methods. * *


 * interface MyService {
 *   @GET("user/me")
 *   ListenableFuture<User> getUser()
 * }
 * 
* * There are two configurations supported for the {@code ListenableFuture} type parameter: * *
    *
  • Direct body (e.g., {@code ListenableFuture}) returns the deserialized body for 2XX * responses, sets {@link retrofit2.HttpException HttpException} errors for non-2XX responses, * and sets {@link IOException} for network errors. *
  • Response wrapped body (e.g., {@code ListenableFuture>}) returns a {@link * Response} object for all HTTP responses and sets {@link IOException} for network errors *
*/ public final class GuavaCallAdapterFactory extends CallAdapter.Factory { public static GuavaCallAdapterFactory create() { return new GuavaCallAdapterFactory(); } private GuavaCallAdapterFactory() {} @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != ListenableFuture.class) { return null; } if (!(returnType instanceof ParameterizedType)) { throw new IllegalStateException( "ListenableFuture return type must be parameterized" + " as ListenableFuture or ListenableFuture"); } Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType); if (getRawType(innerType) != Response.class) { // Generic type is not Response. Use it for body-only adapter. return new BodyCallAdapter<>(innerType); } // Generic type is Response. Extract T and create the Response version of the adapter. if (!(innerType instanceof ParameterizedType)) { throw new IllegalStateException( "Response must be parameterized" + " as Response or Response"); } Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType); return new ResponseCallAdapter<>(responseType); } private static final class BodyCallAdapter implements CallAdapter> { private final Type responseType; BodyCallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public ListenableFuture adapt(final Call call) { CallCancelListenableFuture future = new CallCancelListenableFuture<>(call); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { future.set(response.body()); } else { future.setException(new HttpException(response)); } } @Override public void onFailure(Call call, Throwable t) { future.setException(t); } }); return future; } } private static final class ResponseCallAdapter implements CallAdapter>> { private final Type responseType; ResponseCallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public ListenableFuture> adapt(final Call call) { CallCancelListenableFuture> future = new CallCancelListenableFuture<>(call); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { future.set(response); } @Override public void onFailure(Call call, Throwable t) { future.setException(t); } }); return future; } } private static final class CallCancelListenableFuture extends AbstractFuture { private final Call call; CallCancelListenableFuture(Call call) { this.call = call; } @Override public boolean set(T value) { return super.set(value); } @Override public boolean setException(Throwable throwable) { return super.setException(throwable); } @Override protected void interruptTask() { call.cancel(); } } } ================================================ FILE: retrofit-adapters/guava/src/main/java/retrofit2/adapter/guava/HttpException.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.guava; import retrofit2.Response; /** @deprecated Use {@link retrofit2.HttpException}. */ @Deprecated public final class HttpException extends retrofit2.HttpException { public HttpException(Response response) { super(response); } } ================================================ FILE: retrofit-adapters/guava/src/main/java/retrofit2/adapter/guava/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.adapter.guava; ================================================ FILE: retrofit-adapters/guava/src/test/java/retrofit2/adapter/guava/GuavaCallAdapterFactoryTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.guava; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.reflect.TypeToken; import com.google.common.util.concurrent.ListenableFuture; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.CallAdapter; import retrofit2.Response; import retrofit2.Retrofit; public final class GuavaCallAdapterFactoryTest { private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; @Rule public final MockWebServer server = new MockWebServer(); private final CallAdapter.Factory factory = GuavaCallAdapterFactory.create(); private Retrofit retrofit; @Before public void setUp() { retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(factory) .build(); } @Test public void responseType() { Type bodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(bodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type bodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(bodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type bodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(bodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type responseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(responseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type responseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(responseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type resultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(resultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type resultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(resultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); } @Test public void nonListenableFutureReturnsNull() { CallAdapter adapter = factory.get(String.class, NO_ANNOTATIONS, retrofit); assertThat(adapter).isNull(); } @Test public void rawTypeThrows() { Type observableType = new TypeToken() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "ListenableFuture return type must be parameterized as ListenableFuture or ListenableFuture"); } } @Test public void rawResponseTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } } } ================================================ FILE: retrofit-adapters/guava/src/test/java/retrofit2/adapter/guava/ListenableFutureTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.guava; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import static org.junit.Assert.fail; import com.google.common.util.concurrent.ListenableFuture; import java.io.IOException; import java.util.concurrent.ExecutionException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class ListenableFutureTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") ListenableFuture body(); @GET("/") ListenableFuture> response(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(GuavaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() throws Exception { server.enqueue(new MockResponse().setBody("Hi")); ListenableFuture future = service.body(); assertThat(future.get()).isEqualTo("Hi"); } @Test public void bodySuccess404() throws Exception { server.enqueue(new MockResponse().setResponseCode(404)); ListenableFuture future = service.body(); try { future.get(); fail(); } catch (ExecutionException e) { Throwable cause = e.getCause(); assertThat(cause).isInstanceOf(HttpException.class); // Required for backwards compatibility. assertThat(cause).isInstanceOf(retrofit2.HttpException.class); assertThat(cause).hasMessageThat().isEqualTo("HTTP 404 Client Error"); } } @Test public void bodyFailure() throws Exception { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); ListenableFuture future = service.body(); try { future.get(); fail(); } catch (ExecutionException e) { assertThat(e).hasCauseThat().isInstanceOf(IOException.class); } } @Test public void responseSuccess200() throws Exception { server.enqueue(new MockResponse().setBody("Hi")); ListenableFuture> future = service.response(); Response response = future.get(); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isEqualTo("Hi"); } @Test public void responseSuccess404() throws Exception { server.enqueue(new MockResponse().setResponseCode(404).setBody("Hi")); ListenableFuture> future = service.response(); Response response = future.get(); assertThat(response.isSuccessful()).isFalse(); assertThat(response.errorBody().string()).isEqualTo("Hi"); } @Test public void responseFailure() throws Exception { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); ListenableFuture> future = service.response(); try { future.get(); fail(); } catch (ExecutionException e) { assertThat(e).hasCauseThat().isInstanceOf(IOException.class); } } } ================================================ FILE: retrofit-adapters/guava/src/test/java/retrofit2/adapter/guava/StringConverterFactory.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.guava; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; final class StringConverterFactory extends Converter.Factory { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return ResponseBody::string; } @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return value -> RequestBody.create(MediaType.get("text/plain"), value); } } ================================================ FILE: retrofit-adapters/java8/README.md ================================================ Java 8 Adapter (Deprecated) =========================== A call adapter [Java 8's `CompletableFuture`][1]. This adapter is no longer needed. Support for `CompletableFuture` is built-in to Retrofit and now works without configuration. [1]: http://www.oracle.com/technetwork/java/javase/jdk-8-readme-2095712.html ================================================ FILE: retrofit-adapters/java8/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.guava testImplementation libs.okhttp.mockwebserver } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.adapter.java8' } } ================================================ FILE: retrofit-adapters/java8/gradle.properties ================================================ POM_ARTIFACT_ID=adapter-java8 POM_NAME=Adapter: Java 8 POM_DESCRIPTION=A Retrofit CallAdapter for Java 8's CompletableFuture. ================================================ FILE: retrofit-adapters/java8/src/main/java/retrofit2/adapter/java8/HttpException.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.java8; import retrofit2.Response; /** @deprecated Use {@link retrofit2.HttpException}. */ @Deprecated public final class HttpException extends retrofit2.HttpException { public HttpException(Response response) { super(response); } } ================================================ FILE: retrofit-adapters/java8/src/main/java/retrofit2/adapter/java8/Java8CallAdapterFactory.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.java8; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.concurrent.CompletableFuture; import javax.annotation.Nullable; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; /** * @deprecated Retrofit includes support for CompletableFuture. This no longer needs to be added to * the Retrofit instance explicitly. *

A {@linkplain CallAdapter.Factory call adapter} which creates Java 8 futures. *

Adding this class to {@link Retrofit} allows you to return {@link CompletableFuture} from * service methods. *


 * interface MyService {
 *   @GET("user/me")
 *   CompletableFuture<User> getUser()
 * }
 * 
* There are two configurations supported for the {@code CompletableFuture} type parameter: *
    *
  • Direct body (e.g., {@code CompletableFuture}) returns the deserialized body for * 2XX responses, sets {@link retrofit2.HttpException HttpException} errors for non-2XX * responses, and sets {@link IOException} for network errors. *
  • Response wrapped body (e.g., {@code CompletableFuture>}) returns a * {@link Response} object for all HTTP responses and sets {@link IOException} for network * errors *
*/ @Deprecated public final class Java8CallAdapterFactory extends CallAdapter.Factory { public static Java8CallAdapterFactory create() { return new Java8CallAdapterFactory(); } private Java8CallAdapterFactory() {} @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != CompletableFuture.class) { return null; } if (!(returnType instanceof ParameterizedType)) { throw new IllegalStateException( "CompletableFuture return type must be parameterized" + " as CompletableFuture or CompletableFuture"); } Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType); if (getRawType(innerType) != Response.class) { // Generic type is not Response. Use it for body-only adapter. return new BodyCallAdapter<>(innerType); } // Generic type is Response. Extract T and create the Response version of the adapter. if (!(innerType instanceof ParameterizedType)) { throw new IllegalStateException( "Response must be parameterized" + " as Response or Response"); } Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType); return new ResponseCallAdapter<>(responseType); } private static final class BodyCallAdapter implements CallAdapter> { private final Type responseType; BodyCallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public CompletableFuture adapt(final Call call) { final CompletableFuture future = new CompletableFuture() { @Override public boolean cancel(boolean mayInterruptIfRunning) { if (mayInterruptIfRunning) { call.cancel(); } return super.cancel(mayInterruptIfRunning); } }; call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { future.complete(response.body()); } else { future.completeExceptionally(new HttpException(response)); } } @Override public void onFailure(Call call, Throwable t) { future.completeExceptionally(t); } }); return future; } } private static final class ResponseCallAdapter implements CallAdapter>> { private final Type responseType; ResponseCallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public CompletableFuture> adapt(final Call call) { final CompletableFuture> future = new CompletableFuture>() { @Override public boolean cancel(boolean mayInterruptIfRunning) { if (mayInterruptIfRunning) { call.cancel(); } return super.cancel(mayInterruptIfRunning); } }; call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { future.complete(response); } @Override public void onFailure(Call call, Throwable t) { future.completeExceptionally(t); } }); return future; } } } ================================================ FILE: retrofit-adapters/java8/src/main/java/retrofit2/adapter/java8/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.adapter.java8; ================================================ FILE: retrofit-adapters/java8/src/test/java/retrofit2/adapter/java8/CompletableFutureTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.java8; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import static org.junit.Assert.fail; import java.io.IOException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CompletableFutureTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") CompletableFuture body(); @GET("/") CompletableFuture> response(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(Java8CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() throws Exception { server.enqueue(new MockResponse().setBody("Hi")); CompletableFuture future = service.body(); assertThat(future.get()).isEqualTo("Hi"); } @Test public void bodySuccess404() throws Exception { server.enqueue(new MockResponse().setResponseCode(404)); CompletableFuture future = service.body(); try { future.get(); fail(); } catch (ExecutionException e) { Throwable cause = e.getCause(); assertThat(cause).isInstanceOf(HttpException.class); // Required for backwards compatibility. assertThat(cause).isInstanceOf(retrofit2.HttpException.class); assertThat(cause).hasMessageThat().isEqualTo("HTTP 404 Client Error"); } } @Test public void bodyFailure() throws Exception { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); CompletableFuture future = service.body(); try { future.get(); fail(); } catch (ExecutionException e) { assertThat(e).hasCauseThat().isInstanceOf(IOException.class); } } @Test public void responseSuccess200() throws Exception { server.enqueue(new MockResponse().setBody("Hi")); CompletableFuture> future = service.response(); Response response = future.get(); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isEqualTo("Hi"); } @Test public void responseSuccess404() throws Exception { server.enqueue(new MockResponse().setResponseCode(404).setBody("Hi")); CompletableFuture> future = service.response(); Response response = future.get(); assertThat(response.isSuccessful()).isFalse(); assertThat(response.errorBody().string()).isEqualTo("Hi"); } @Test public void responseFailure() throws Exception { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); CompletableFuture> future = service.response(); try { future.get(); fail(); } catch (ExecutionException e) { assertThat(e).hasCauseThat().isInstanceOf(IOException.class); } } } ================================================ FILE: retrofit-adapters/java8/src/test/java/retrofit2/adapter/java8/Java8CallAdapterFactoryTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.java8; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.reflect.TypeToken; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import java.util.concurrent.CompletableFuture; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.CallAdapter; import retrofit2.Response; import retrofit2.Retrofit; public final class Java8CallAdapterFactoryTest { private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; @Rule public final MockWebServer server = new MockWebServer(); private final CallAdapter.Factory factory = Java8CallAdapterFactory.create(); private Retrofit retrofit; @Before public void setUp() { retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(factory) .build(); } @Test public void responseType() { Type bodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(bodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type bodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(bodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type bodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(bodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type responseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(responseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type responseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(responseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type resultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(resultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type resultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(resultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); } @Test public void nonListenableFutureReturnsNull() { CallAdapter adapter = factory.get(String.class, NO_ANNOTATIONS, retrofit); assertThat(adapter).isNull(); } @Test public void rawTypeThrows() { Type observableType = new TypeToken() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "CompletableFuture return type must be parameterized as CompletableFuture or CompletableFuture"); } } @Test public void rawResponseTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } } } ================================================ FILE: retrofit-adapters/java8/src/test/java/retrofit2/adapter/java8/StringConverterFactory.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.java8; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; final class StringConverterFactory extends Converter.Factory { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return ResponseBody::string; } @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return value -> RequestBody.create(MediaType.get("text/plain"), value); } } ================================================ FILE: retrofit-adapters/rxjava/README.md ================================================ RxJava Adapter ============== An `Adapter` for adapting [RxJava 1.x][1] types. Available types: * `Observable`, `Observable>`, and `Observable>` where `T` is the body type. * `Single`, `Single>`, and `Single>` where `T` is the body type. * `Completable` where response bodies are discarded. Usage ----- Add `RxJavaCallAdapterFactory` as a `Call` adapter when building your `Retrofit` instance: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); ``` Your service methods can now use any of the above types as their return type. ```java interface MyService { @GET("/user") Observable getUser(); } ``` By default all reactive types execute their requests synchronously. There are multiple ways to control the threading on which a request occurs: * Call `subscribeOn` on the returned reactive type with a `Scheduler` of your choice. * Use `createAsync()` when creating the factory which will use OkHttp's internal thread pool. * Use `createWithScheduler(Scheduler)` to supply a default subscription `Scheduler`. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 adapter-rxjava latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:adapter-rxjava:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/ReactiveX/RxJava/tree/1.x [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=adapter-rxjava&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22adapter-rxjava%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-adapters/rxjava/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.rxjava compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.guava testImplementation libs.okhttp.mockwebserver } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.adapter.rxjava' } } ================================================ FILE: retrofit-adapters/rxjava/gradle.properties ================================================ POM_ARTIFACT_ID=adapter-rxjava POM_NAME=Adapter: RxJava POM_DESCRIPTION=A Retrofit CallAdapter for RxJava's stream types. ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/BodyOnSubscribe.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import retrofit2.Response; import rx.Observable.OnSubscribe; import rx.Subscriber; import rx.exceptions.CompositeException; import rx.exceptions.Exceptions; import rx.exceptions.OnCompletedFailedException; import rx.exceptions.OnErrorFailedException; import rx.exceptions.OnErrorNotImplementedException; import rx.plugins.RxJavaPlugins; final class BodyOnSubscribe implements OnSubscribe { private final OnSubscribe> upstream; BodyOnSubscribe(OnSubscribe> upstream) { this.upstream = upstream; } @Override public void call(Subscriber subscriber) { upstream.call(new BodySubscriber(subscriber)); } private static class BodySubscriber extends Subscriber> { private final Subscriber subscriber; /** Indicates whether a terminal event has been sent to {@link #subscriber}. */ private boolean subscriberTerminated; BodySubscriber(Subscriber subscriber) { super(subscriber); this.subscriber = subscriber; } @Override public void onNext(Response response) { if (response.isSuccessful()) { subscriber.onNext(response.body()); } else { subscriberTerminated = true; Throwable t = new HttpException(response); try { subscriber.onError(t); } catch (OnCompletedFailedException | OnErrorFailedException | OnErrorNotImplementedException e) { RxJavaPlugins.getInstance().getErrorHandler().handleError(e); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); CompositeException composite = new CompositeException(t, inner); RxJavaPlugins.getInstance().getErrorHandler().handleError(composite); } } } @Override public void onError(Throwable throwable) { if (!subscriberTerminated) { subscriber.onError(throwable); } else { // This should never happen! onNext handles and forwards errors automatically. Throwable broken = new AssertionError( "This should never happen! Report as a Retrofit bug with the full stacktrace."); //noinspection UnnecessaryInitCause Two-arg AssertionError constructor is 1.7+ only. broken.initCause(throwable); RxJavaPlugins.getInstance().getErrorHandler().handleError(broken); } } @Override public void onCompleted() { if (!subscriberTerminated) { subscriber.onCompleted(); } } } } ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/CallArbiter.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import java.util.concurrent.atomic.AtomicInteger; import retrofit2.Call; import retrofit2.Response; import rx.Producer; import rx.Subscriber; import rx.Subscription; import rx.exceptions.CompositeException; import rx.exceptions.Exceptions; import rx.exceptions.OnCompletedFailedException; import rx.exceptions.OnErrorFailedException; import rx.exceptions.OnErrorNotImplementedException; import rx.plugins.RxJavaPlugins; final class CallArbiter extends AtomicInteger implements Subscription, Producer { private static final int STATE_WAITING = 0; private static final int STATE_REQUESTED = 1; private static final int STATE_HAS_RESPONSE = 2; private static final int STATE_TERMINATED = 3; private final Call call; private final Subscriber> subscriber; private volatile boolean unsubscribed; private volatile Response response; CallArbiter(Call call, Subscriber> subscriber) { super(STATE_WAITING); this.call = call; this.subscriber = subscriber; } @Override public void unsubscribe() { unsubscribed = true; call.cancel(); } @Override public boolean isUnsubscribed() { return unsubscribed; } @Override public void request(long amount) { if (amount == 0) { return; } while (true) { int state = get(); switch (state) { case STATE_WAITING: if (compareAndSet(STATE_WAITING, STATE_REQUESTED)) { return; } break; // State transition failed. Try again. case STATE_HAS_RESPONSE: if (compareAndSet(STATE_HAS_RESPONSE, STATE_TERMINATED)) { deliverResponse(response); return; } break; // State transition failed. Try again. case STATE_REQUESTED: case STATE_TERMINATED: return; // Nothing to do. default: throw new IllegalStateException("Unknown state: " + state); } } } void emitResponse(Response response) { while (true) { int state = get(); switch (state) { case STATE_WAITING: this.response = response; if (compareAndSet(STATE_WAITING, STATE_HAS_RESPONSE)) { return; } break; // State transition failed. Try again. case STATE_REQUESTED: if (compareAndSet(STATE_REQUESTED, STATE_TERMINATED)) { deliverResponse(response); return; } break; // State transition failed. Try again. case STATE_HAS_RESPONSE: case STATE_TERMINATED: throw new AssertionError(); default: throw new IllegalStateException("Unknown state: " + state); } } } private void deliverResponse(Response response) { try { if (!isUnsubscribed()) { subscriber.onNext(response); } } catch (OnCompletedFailedException | OnErrorFailedException | OnErrorNotImplementedException e) { RxJavaPlugins.getInstance().getErrorHandler().handleError(e); return; } catch (Throwable t) { Exceptions.throwIfFatal(t); try { subscriber.onError(t); } catch (OnCompletedFailedException | OnErrorFailedException | OnErrorNotImplementedException e) { RxJavaPlugins.getInstance().getErrorHandler().handleError(e); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); CompositeException composite = new CompositeException(t, inner); RxJavaPlugins.getInstance().getErrorHandler().handleError(composite); } return; } try { if (!isUnsubscribed()) { subscriber.onCompleted(); } } catch (OnCompletedFailedException | OnErrorFailedException | OnErrorNotImplementedException e) { RxJavaPlugins.getInstance().getErrorHandler().handleError(e); } catch (Throwable t) { Exceptions.throwIfFatal(t); RxJavaPlugins.getInstance().getErrorHandler().handleError(t); } } void emitError(Throwable t) { set(STATE_TERMINATED); if (!isUnsubscribed()) { try { subscriber.onError(t); } catch (OnCompletedFailedException | OnErrorFailedException | OnErrorNotImplementedException e) { RxJavaPlugins.getInstance().getErrorHandler().handleError(e); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); CompositeException composite = new CompositeException(t, inner); RxJavaPlugins.getInstance().getErrorHandler().handleError(composite); } } } } ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/CallEnqueueOnSubscribe.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import rx.Observable.OnSubscribe; import rx.Subscriber; import rx.exceptions.Exceptions; final class CallEnqueueOnSubscribe implements OnSubscribe> { private final Call originalCall; CallEnqueueOnSubscribe(Call originalCall) { this.originalCall = originalCall; } @Override public void call(Subscriber> subscriber) { // Since Call is a one-shot type, clone it for each new subscriber. Call call = originalCall.clone(); final CallArbiter arbiter = new CallArbiter<>(call, subscriber); subscriber.add(arbiter); subscriber.setProducer(arbiter); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { arbiter.emitResponse(response); } @Override public void onFailure(Call call, Throwable t) { Exceptions.throwIfFatal(t); arbiter.emitError(t); } }); } } ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/CallExecuteOnSubscribe.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import retrofit2.Call; import retrofit2.Response; import rx.Observable.OnSubscribe; import rx.Subscriber; import rx.exceptions.Exceptions; final class CallExecuteOnSubscribe implements OnSubscribe> { private final Call originalCall; CallExecuteOnSubscribe(Call originalCall) { this.originalCall = originalCall; } @Override public void call(Subscriber> subscriber) { // Since Call is a one-shot type, clone it for each new subscriber. Call call = originalCall.clone(); CallArbiter arbiter = new CallArbiter<>(call, subscriber); subscriber.add(arbiter); subscriber.setProducer(arbiter); Response response; try { response = call.execute(); } catch (Throwable t) { Exceptions.throwIfFatal(t); arbiter.emitError(t); return; } arbiter.emitResponse(response); } } ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/HttpException.java ================================================ package retrofit2.adapter.rxjava; import retrofit2.Response; /** @deprecated Use {@link retrofit2.HttpException}. */ @Deprecated public final class HttpException extends retrofit2.HttpException { public HttpException(Response response) { super(response); } } ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/Result.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import java.io.IOException; import javax.annotation.Nullable; import retrofit2.Response; /** The result of executing an HTTP request. */ public final class Result { @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static Result error(Throwable error) { if (error == null) throw new NullPointerException("error == null"); return new Result<>(null, error); } @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static Result response(Response response) { if (response == null) throw new NullPointerException("response == null"); return new Result<>(response, null); } private final @Nullable Response response; private final @Nullable Throwable error; private Result(@Nullable Response response, @Nullable Throwable error) { this.response = response; this.error = error; } /** * The response received from executing an HTTP request. Only present when {@link #isError()} is * false, null otherwise. */ public @Nullable Response response() { return response; } /** * The error experienced while attempting to execute an HTTP request. Only present when {@link * #isError()} is true, null otherwise. * *

If the error is an {@link IOException} then there was a problem with the transport to the * remote server. Any other exception type indicates an unexpected failure and should be * considered fatal (configuration error, programming error, etc.). */ public @Nullable Throwable error() { return error; } /** {@code true} if the request resulted in an error. See {@link #error()} for the cause. */ public boolean isError() { return error != null; } @Override public String toString() { if (error != null) { return "Result{isError=true, error=\"" + error + "\"}"; } return "Result{isError=false, response=" + response + '}'; } } ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/ResultOnSubscribe.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import retrofit2.Response; import rx.Observable.OnSubscribe; import rx.Subscriber; import rx.exceptions.CompositeException; import rx.exceptions.Exceptions; import rx.exceptions.OnCompletedFailedException; import rx.exceptions.OnErrorFailedException; import rx.exceptions.OnErrorNotImplementedException; import rx.plugins.RxJavaPlugins; final class ResultOnSubscribe implements OnSubscribe> { private final OnSubscribe> upstream; ResultOnSubscribe(OnSubscribe> upstream) { this.upstream = upstream; } @Override public void call(Subscriber> subscriber) { upstream.call(new ResultSubscriber(subscriber)); } private static class ResultSubscriber extends Subscriber> { private final Subscriber> subscriber; ResultSubscriber(Subscriber> subscriber) { super(subscriber); this.subscriber = subscriber; } @Override public void onNext(Response response) { subscriber.onNext(Result.response(response)); } @Override public void onError(Throwable throwable) { try { subscriber.onNext(Result.error(throwable)); } catch (Throwable t) { try { subscriber.onError(t); } catch (OnCompletedFailedException | OnErrorFailedException | OnErrorNotImplementedException e) { RxJavaPlugins.getInstance().getErrorHandler().handleError(e); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); CompositeException composite = new CompositeException(t, inner); RxJavaPlugins.getInstance().getErrorHandler().handleError(composite); } return; } subscriber.onCompleted(); } @Override public void onCompleted() { subscriber.onCompleted(); } } } ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/RxJavaCallAdapter.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Response; import rx.Observable; import rx.Observable.OnSubscribe; import rx.Scheduler; final class RxJavaCallAdapter implements CallAdapter { private final Type responseType; private final @Nullable Scheduler scheduler; private final boolean isAsync; private final boolean isResult; private final boolean isBody; private final boolean isSingle; private final boolean isCompletable; RxJavaCallAdapter( Type responseType, @Nullable Scheduler scheduler, boolean isAsync, boolean isResult, boolean isBody, boolean isSingle, boolean isCompletable) { this.responseType = responseType; this.scheduler = scheduler; this.isAsync = isAsync; this.isResult = isResult; this.isBody = isBody; this.isSingle = isSingle; this.isCompletable = isCompletable; } @Override public Type responseType() { return responseType; } @Override public Object adapt(Call call) { OnSubscribe> callFunc = isAsync ? new CallEnqueueOnSubscribe<>(call) : new CallExecuteOnSubscribe<>(call); OnSubscribe func; if (isResult) { func = new ResultOnSubscribe<>(callFunc); } else if (isBody) { func = new BodyOnSubscribe<>(callFunc); } else { func = callFunc; } Observable observable = Observable.create(func); if (scheduler != null) { observable = observable.subscribeOn(scheduler); } if (isSingle) { return observable.toSingle(); } if (isCompletable) { return observable.toCompletable(); } return observable; } } ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/RxJavaCallAdapterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.CallAdapter; import retrofit2.HttpException; import retrofit2.Response; import retrofit2.Retrofit; import rx.Completable; import rx.Observable; import rx.Scheduler; import rx.Single; /** * A {@linkplain CallAdapter.Factory call adapter} which uses RxJava for creating observables. * *

Adding this class to {@link Retrofit} allows you to return an {@link Observable}, {@link * Single}, or {@link Completable} from service methods. * *


 * interface MyService {
 *   @GET("user/me")
 *   Observable<User> getUser()
 * }
 * 
* * There are three configurations supported for the {@code Observable} or {@code Single} type * parameter: * *
    *
  • Direct body (e.g., {@code Observable}) calls {@code onNext} with the deserialized * body for 2XX responses and calls {@code onError} with {@link HttpException} for non-2XX * responses and {@link IOException} for network errors. *
  • Response wrapped body (e.g., {@code Observable>}) calls {@code onNext} with * a {@link Response} object for all HTTP responses and calls {@code onError} with {@link * IOException} for network errors *
  • Result wrapped body (e.g., {@code Observable>}) calls {@code onNext} with a * {@link Result} object for all HTTP responses and errors. *
* *

Note: Support for {@link Single} and {@link Completable} is experimental and subject * to backwards-incompatible changes at any time since both of these types are not considered stable * by RxJava. */ public final class RxJavaCallAdapterFactory extends CallAdapter.Factory { /** * Returns an instance which creates synchronous observables that do not operate on any scheduler * by default. */ public static RxJavaCallAdapterFactory create() { return new RxJavaCallAdapterFactory(null, false); } /** Returns an instance which creates asynchronous observables. */ public static RxJavaCallAdapterFactory createAsync() { return new RxJavaCallAdapterFactory(null, true); } /** * Returns an instance which creates synchronous observables that {@linkplain * Observable#subscribeOn(Scheduler) subscribe on} {@code scheduler} by default. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static RxJavaCallAdapterFactory createWithScheduler(Scheduler scheduler) { if (scheduler == null) throw new NullPointerException("scheduler == null"); return new RxJavaCallAdapterFactory(scheduler, false); } private final @Nullable Scheduler scheduler; private final boolean isAsync; private RxJavaCallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) { this.scheduler = scheduler; this.isAsync = isAsync; } @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { Class rawType = getRawType(returnType); boolean isSingle = rawType == Single.class; boolean isCompletable = rawType == Completable.class; if (rawType != Observable.class && !isSingle && !isCompletable) { return null; } if (isCompletable) { return new RxJavaCallAdapter(Void.class, scheduler, isAsync, false, true, false, true); } boolean isResult = false; boolean isBody = false; Type responseType; if (!(returnType instanceof ParameterizedType)) { String name = isSingle ? "Single" : "Observable"; throw new IllegalStateException( name + " return type must be parameterized" + " as " + name + " or " + name + ""); } Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType); Class rawObservableType = getRawType(observableType); if (rawObservableType == Response.class) { if (!(observableType instanceof ParameterizedType)) { throw new IllegalStateException( "Response must be parameterized" + " as Response or Response"); } responseType = getParameterUpperBound(0, (ParameterizedType) observableType); } else if (rawObservableType == Result.class) { if (!(observableType instanceof ParameterizedType)) { throw new IllegalStateException( "Result must be parameterized" + " as Result or Result"); } responseType = getParameterUpperBound(0, (ParameterizedType) observableType); isResult = true; } else { responseType = observableType; isBody = true; } return new RxJavaCallAdapter( responseType, scheduler, isAsync, isResult, isBody, isSingle, false); } } ================================================ FILE: retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.adapter.rxjava; ================================================ FILE: retrofit-adapters/rxjava/src/main/resources/META-INF/proguard/retrofit2-rxjava-adapter.pro ================================================ # Keep generic signature of RxJava (R8 full mode strips signatures from non-kept items). # It's necessary to add the explicit rule for Result as it could be used as a nested return type like `Observable>` -keep,allowoptimization,allowshrinking,allowobfuscation class retrofit2.adapter.rxjava.Result ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/AsyncTest.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Completable; import rx.exceptions.CompositeException; import rx.exceptions.Exceptions; import rx.exceptions.OnErrorFailedException; import rx.observers.AsyncCompletableSubscriber; import rx.observers.TestSubscriber; import rx.plugins.RxJavaErrorHandler; import rx.plugins.RxJavaPlugins; public final class AsyncTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule pluginsReset = new RxJavaPluginsResetRule(); interface Service { @GET("/") Completable completable(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJavaCallAdapterFactory.createAsync()) .build(); service = retrofit.create(Service.class); } @Test public void success() throws InterruptedException { TestSubscriber subscriber = new TestSubscriber<>(); service.completable().subscribe(subscriber); assertFalse(subscriber.awaitValueCount(1, 1, SECONDS)); server.enqueue(new MockResponse()); subscriber.awaitTerminalEvent(1, SECONDS); subscriber.assertCompleted(); } @Test public void failure() throws InterruptedException { TestSubscriber subscriber = new TestSubscriber<>(); service.completable().subscribe(subscriber); assertFalse(subscriber.awaitValueCount(1, 1, SECONDS)); server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); subscriber.awaitTerminalEvent(1, SECONDS); subscriber.assertError(IOException.class); } @Test public void throwingInOnCompleteDeliveredToPlugin() throws InterruptedException { server.enqueue(new MockResponse()); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference errorRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } latch.countDown(); } }); final TestSubscriber subscriber = new TestSubscriber<>(); final RuntimeException e = new RuntimeException(); service .completable() .unsafeSubscribe( new AsyncCompletableSubscriber() { @Override public void onCompleted() { throw e; } @Override public void onError(Throwable t) { subscriber.onError(t); } }); latch.await(1, SECONDS); assertThat(errorRef.get()).isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() throws InterruptedException { server.enqueue(new MockResponse().setResponseCode(404)); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } latch.countDown(); } }); final TestSubscriber subscriber = new TestSubscriber<>(); final RuntimeException e = new RuntimeException(); final AtomicReference errorRef = new AtomicReference<>(); service .completable() .unsafeSubscribe( new AsyncCompletableSubscriber() { @Override public void onCompleted() { subscriber.onCompleted(); } @Override public void onError(Throwable t) { errorRef.set(t); throw e; } }); assertTrue(latch.await(1, SECONDS)); CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void bodyThrowingInOnSafeSubscriberErrorDeliveredToPlugin() throws InterruptedException { server.enqueue(new MockResponse().setResponseCode(404)); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (throwable instanceof OnErrorFailedException) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } latch.countDown(); } } }); final TestSubscriber subscriber = new TestSubscriber<>(); final RuntimeException e = new RuntimeException(); final AtomicReference errorRef = new AtomicReference<>(); service .completable() .subscribe( new AsyncCompletableSubscriber() { @Override public void onCompleted() { subscriber.onCompleted(); } @Override public void onError(Throwable t) { errorRef.set(t); throw e; } }); assertTrue(latch.await(1, SECONDS)); OnErrorFailedException failed = (OnErrorFailedException) pluginRef.get(); CompositeException composite = (CompositeException) failed.getCause(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/CancelDisposeTest.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.List; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Observable; import rx.Subscription; public final class CancelDisposeTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Observable go(); } private final OkHttpClient client = new OkHttpClient(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJavaCallAdapterFactory.createAsync()) .callFactory(client) .build(); service = retrofit.create(Service.class); } @Test public void disposeCancelsCall() { Subscription subscription = service.go().subscribe(); List calls = client.dispatcher().runningCalls(); assertEquals(1, calls.size()); subscription.unsubscribe(); assertTrue(calls.get(0).isCanceled()); } @Test public void cancelDoesNotDispose() { Subscription subscription = service.go().subscribe(); List calls = client.dispatcher().runningCalls(); assertEquals(1, calls.size()); calls.get(0).cancel(); assertFalse(subscription.isUnsubscribed()); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/CompletableTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Completable; public final class CompletableTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule pluginsReset = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Completable completable(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void completableSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.create(); service.completable().unsafeSubscribe(subscriber); subscriber.assertCompleted(); } @Test public void completableSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber subscriber = subscriberRule.create(); service.completable().unsafeSubscribe(subscriber); // Required for backwards compatibility. subscriber.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void completableFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber subscriber = subscriberRule.create(); service.completable().unsafeSubscribe(subscriber); subscriber.assertError(IOException.class); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Completable observable = service.completable(); RecordingSubscriber subscriber1 = subscriberRule.create(); observable.subscribe(subscriber1); subscriber1.assertCompleted(); RecordingSubscriber subscriber2 = subscriberRule.create(); observable.subscribe(subscriber2); subscriber2.assertCompleted(); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/CompletableThrowingSafeSubscriberTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Completable; import rx.CompletableSubscriber; import rx.Subscription; import rx.exceptions.CompositeException; import rx.exceptions.Exceptions; import rx.exceptions.OnCompletedFailedException; import rx.exceptions.OnErrorFailedException; import rx.plugins.RxJavaErrorHandler; import rx.plugins.RxJavaPlugins; public final class CompletableThrowingSafeSubscriberTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Completable completable(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void throwingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (throwable instanceof OnCompletedFailedException) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } } }); RecordingSubscriber observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onCompleted() { throw e; } }); assertThat(pluginRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (throwable instanceof OnErrorFailedException) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } } }); RecordingSubscriber observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); final AtomicReference errorRef = new AtomicReference<>(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onError(Throwable throwable) { errorRef.set(throwable); throw e; } }); CompositeException composite = (CompositeException) pluginRef.get().getCause(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } abstract static class ForwardingCompletableObserver implements CompletableSubscriber { private final RecordingSubscriber delegate; ForwardingCompletableObserver(RecordingSubscriber delegate) { this.delegate = delegate; } @Override public void onSubscribe(Subscription d) {} @Override public void onCompleted() { delegate.onCompleted(); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/CompletableThrowingTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Completable; import rx.CompletableSubscriber; import rx.Subscription; import rx.exceptions.CompositeException; import rx.exceptions.Exceptions; import rx.plugins.RxJavaErrorHandler; import rx.plugins.RxJavaPlugins; public final class CompletableThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Completable completable(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void throwingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .completable() .unsafeSubscribe( new ForwardingCompletableObserver(observer) { @Override public void onCompleted() { throw e; } }); assertThat(pluginRef.get()).isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); final AtomicReference errorRef = new AtomicReference<>(); service .completable() .unsafeSubscribe( new ForwardingCompletableObserver(observer) { @Override public void onError(Throwable throwable) { errorRef.set(throwable); throw e; } }); CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } abstract static class ForwardingCompletableObserver implements CompletableSubscriber { private final RecordingSubscriber delegate; ForwardingCompletableObserver(RecordingSubscriber delegate) { this.delegate = delegate; } @Override public void onSubscribe(Subscription d) {} @Override public void onCompleted() { delegate.onCompleted(); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/CompletableWithSchedulerTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Completable; import rx.schedulers.TestScheduler; public final class CompletableWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Completable completable(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void completableUsesScheduler() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.create(); service.completable().unsafeSubscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertCompleted(); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/ForwardingSubscriber.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import rx.Subscriber; abstract class ForwardingSubscriber extends Subscriber { private final Subscriber delegate; ForwardingSubscriber(Subscriber delegate) { this.delegate = delegate; } @Override public void onNext(T value) { delegate.onNext(value); } @Override public void onCompleted() { delegate.onCompleted(); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/ObservableTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Observable; public final class ObservableTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule pluginsReset = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.create(); service.body().unsafeSubscribe(subscriber); subscriber.assertValue("Hi").assertCompleted(); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber subscriber = subscriberRule.create(); service.body().unsafeSubscribe(subscriber); // Required for backwards compatibility. subscriber.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber subscriber = subscriberRule.create(); service.body().unsafeSubscribe(subscriber); subscriber.assertError(IOException.class); } @Test public void bodyRespectsBackpressure() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.createWithInitialRequest(0); service.body().unsafeSubscribe(subscriber); assertThat(server.getRequestCount()).isEqualTo(1); subscriber.assertNoEvents(); subscriber.requestMore(1); subscriber.assertAnyValue().assertCompleted(); subscriber.requestMore(Long.MAX_VALUE); // Subsequent requests do not trigger HTTP requests. assertThat(server.getRequestCount()).isEqualTo(1); } @Test public void responseSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().body()).isEqualTo("Hi"); subscriber.assertCompleted(); } @Test public void responseSuccess404() throws IOException { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().code()).isEqualTo(404); subscriber.assertCompleted(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().unsafeSubscribe(subscriber); subscriber.assertError(IOException.class); } @Test public void responseRespectsBackpressure() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.createWithInitialRequest(0); service.response().unsafeSubscribe(subscriber); assertThat(server.getRequestCount()).isEqualTo(1); subscriber.assertNoEvents(); subscriber.requestMore(1); subscriber.assertAnyValue().assertCompleted(); subscriber.requestMore(Long.MAX_VALUE); // Subsequent requests do not trigger HTTP requests. assertThat(server.getRequestCount()).isEqualTo(1); } @Test public void responseUnsubscribedDoesNotCallCompleted() throws InterruptedException { server.enqueue(new MockResponse().setBody("Hi")); final RecordingSubscriber> subscriber = subscriberRule.create(); service.response().doOnNext(response -> subscriber.unsubscribe()).subscribe(subscriber); assertThat(subscriber.takeValue().body()).isEqualTo("Hi"); } @Test public void resultSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().response().body()).isEqualTo("Hi"); subscriber.assertCompleted(); } @Test public void resultSuccess404() throws IOException { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().response().code()).isEqualTo(404); subscriber.assertCompleted(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().error()).isInstanceOf(IOException.class); subscriber.assertCompleted(); } @Test public void resultRespectsBackpressure() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.createWithInitialRequest(0); service.result().unsafeSubscribe(subscriber); assertThat(server.getRequestCount()).isEqualTo(1); subscriber.assertNoEvents(); subscriber.requestMore(1); subscriber.assertAnyValue().assertCompleted(); subscriber.requestMore(Long.MAX_VALUE); // Subsequent requests do not trigger HTTP requests. assertThat(server.getRequestCount()).isEqualTo(1); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Observable observable = service.body(); RecordingSubscriber subscriber1 = subscriberRule.create(); observable.subscribe(subscriber1); subscriber1.assertValue("Hi").assertCompleted(); RecordingSubscriber subscriber2 = subscriberRule.create(); observable.subscribe(subscriber2); subscriber2.assertValue("Hey").assertCompleted(); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/ObservableThrowingSafeSubscriberTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Observable; import rx.exceptions.CompositeException; import rx.exceptions.Exceptions; import rx.exceptions.OnCompletedFailedException; import rx.exceptions.OnErrorFailedException; import rx.plugins.RxJavaErrorHandler; import rx.plugins.RxJavaPlugins; public final class ObservableThrowingSafeSubscriberTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingSubscriber(observer) { @Override public void onNext(String value) { throw e; } }); observer.assertError(e); } @Test public void bodyThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (throwable instanceof OnCompletedFailedException) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } } }); RecordingSubscriber observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingSubscriber(observer) { @Override public void onCompleted() { throw e; } }); observer.assertAnyValue(); assertThat(pluginRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (throwable instanceof OnErrorFailedException) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } } }); RecordingSubscriber observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingSubscriber(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); CompositeException composite = (CompositeException) pluginRef.get().getCause(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingSubscriber>(observer) { @Override public void onNext(Response value) { throw e; } }); observer.assertError(e); } @Test public void responseThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (throwable instanceof OnCompletedFailedException) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } } }); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingSubscriber>(observer) { @Override public void onCompleted() { throw e; } }); observer.assertAnyValue(); assertThat(pluginRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (throwable instanceof OnErrorFailedException) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } } }); RecordingSubscriber> observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingSubscriber>(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); CompositeException composite = (CompositeException) pluginRef.get().getCause(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingSubscriber>(observer) { @Override public void onNext(Result value) { throw e; } }); observer.assertError(e); } @Test public void resultThrowingInOnCompletedDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (throwable instanceof OnCompletedFailedException) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } } }); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingSubscriber>(observer) { @Override public void onCompleted() { throw e; } }); observer.assertAnyValue(); assertThat(pluginRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (throwable instanceof OnErrorFailedException) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } } }); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .subscribe( new ForwardingSubscriber>(observer) { @Override public void onNext(Result value) { // The only way to trigger onError for a result is if onNext throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); CompositeException composite = (CompositeException) pluginRef.get().getCause(); assertThat(composite.getExceptions()).containsExactly(first, second); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/ObservableThrowingTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Observable; import rx.exceptions.CompositeException; import rx.exceptions.Exceptions; import rx.plugins.RxJavaErrorHandler; import rx.plugins.RxJavaPlugins; public final class ObservableThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .unsafeSubscribe( new ForwardingSubscriber(observer) { @Override public void onNext(String value) { throw e; } }); observer.assertError(e); } @Test public void bodyThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .unsafeSubscribe( new ForwardingSubscriber(observer) { @Override public void onCompleted() { throw e; } }); observer.assertAnyValue(); assertThat(pluginRef.get()).isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .unsafeSubscribe( new ForwardingSubscriber(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .unsafeSubscribe( new ForwardingSubscriber>(observer) { @Override public void onNext(Response value) { throw e; } }); observer.assertError(e); } @Test public void responseThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .unsafeSubscribe( new ForwardingSubscriber>(observer) { @Override public void onCompleted() { throw e; } }); observer.assertAnyValue(); assertThat(pluginRef.get()).isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber> observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .unsafeSubscribe( new ForwardingSubscriber>(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .unsafeSubscribe( new ForwardingSubscriber>(observer) { @Override public void onNext(Result value) { throw e; } }); observer.assertError(e); } @Test public void resultThrowingInOnCompletedDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .unsafeSubscribe( new ForwardingSubscriber>(observer) { @Override public void onCompleted() { throw e; } }); observer.assertAnyValue(); assertThat(pluginRef.get()).isSameInstanceAs(e); } @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .unsafeSubscribe( new ForwardingSubscriber>(observer) { @Override public void onNext(Result value) { // The only way to trigger onError for a result is if onNext throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/ObservableWithSchedulerTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Observable; import rx.schedulers.TestScheduler; public final class ObservableWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.create(); service.body().unsafeSubscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertCompleted(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().unsafeSubscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertCompleted(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().unsafeSubscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertCompleted(); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/RecordingSubscriber.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import rx.Notification; import rx.Subscriber; /** A test {@link Subscriber} and JUnit rule which guarantees all events are asserted. */ final class RecordingSubscriber extends Subscriber { private final long initialRequest; private final Deque> events = new ArrayDeque<>(); private RecordingSubscriber(long initialRequest) { this.initialRequest = initialRequest; } @Override public void onStart() { request(initialRequest); } @Override public void onNext(T value) { events.add(Notification.createOnNext(value)); } @Override public void onCompleted() { events.add(Notification.createOnCompleted()); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public T takeValue() { Notification notification = takeNotification(); assertWithMessage("Expected onNext event but was %s", notification) .that(notification.isOnNext()) .isTrue(); return notification.getValue(); } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was %s", notification) .that(notification.isOnError()) .isTrue(); return notification.getThrowable(); } public RecordingSubscriber assertAnyValue() { takeValue(); return this; } public RecordingSubscriber assertValue(T value) { assertThat(takeValue()).isEqualTo(value); return this; } public void assertCompleted() { Notification notification = takeNotification(); assertWithMessage("Expected onCompleted event but was %s", notification) .that(notification.isOnCompleted()) .isTrue(); assertNoEvents(); } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public void requestMore(long amount) { request(amount); } public static final class Rule implements TestRule { final List> subscribers = new ArrayList<>(); public RecordingSubscriber create() { return createWithInitialRequest(Long.MAX_VALUE); } public RecordingSubscriber createWithInitialRequest(long initialRequest) { RecordingSubscriber subscriber = new RecordingSubscriber<>(initialRequest); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingSubscriber subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/ResultTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import java.io.IOException; import org.junit.Test; import retrofit2.Response; public final class ResultTest { @Test public void response() { Response response = Response.success("Hi"); Result result = Result.response(response); assertThat(result.isError()).isFalse(); assertThat(result.error()).isNull(); assertThat(result.response()).isSameInstanceAs(response); } @Test public void nullResponseThrows() { try { Result.response(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("response == null"); } } @Test public void error() { Throwable error = new IOException(); Result result = Result.error(error); assertThat(result.isError()).isTrue(); assertThat(result.error()).isSameInstanceAs(error); assertThat(result.response()).isNull(); } @Test public void nullErrorThrows() { try { Result.error(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("error == null"); } } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/RxJavaCallAdapterFactoryTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.reflect.TypeToken; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import org.junit.Before; import org.junit.Test; import retrofit2.CallAdapter; import retrofit2.Response; import retrofit2.Retrofit; import rx.Observable; import rx.Single; public final class RxJavaCallAdapterFactoryTest { private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; private final CallAdapter.Factory factory = RxJavaCallAdapterFactory.create(); private Retrofit retrofit; @Before public void setUp() { retrofit = new Retrofit.Builder() .baseUrl("http://localhost:1") .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(factory) .build(); } @Test public void nullSchedulerThrows() { try { RxJavaCallAdapterFactory.createWithScheduler(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("scheduler == null"); } } @Test public void nonRxJavaTypeReturnsNull() { CallAdapter adapter = factory.get(String.class, NO_ANNOTATIONS, retrofit); assertThat(adapter).isNull(); } @Test public void responseTypes() { Type oBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(oBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(sBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(oBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(sBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(oBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type sBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(sBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type oResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(oResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(sResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(oResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(sResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(oResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(sResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(oResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(sResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); } @Test public void rawBodyTypeThrows() { Type observableType = new TypeToken() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Observable return type must be parameterized as Observable or Observable"); } Type singleType = new TypeToken() {}.getType(); try { factory.get(singleType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Single return type must be parameterized as Single or Single"); } } @Test public void rawResponseTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } Type singleType = new TypeToken>() {}.getType(); try { factory.get(singleType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } } @Test public void rawResultTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } Type singleType = new TypeToken>() {}.getType(); try { factory.get(singleType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/RxJavaPluginsResetRule.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import rx.plugins.RxJavaPlugins; /** A JUnit @Rule which resets RxJava's plugins before and after each test. */ final class RxJavaPluginsResetRule implements TestRule { @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { RxJavaPlugins.getInstance().reset(); try { base.evaluate(); } finally { RxJavaPlugins.getInstance().reset(); } } }; } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/SingleTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Single; public final class SingleTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule pluginsReset = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Single body(); @GET("/") Single> response(); @GET("/") Single> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.create(); service.body().unsafeSubscribe(subscriber); subscriber.assertValue("Hi").assertCompleted(); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber subscriber = subscriberRule.create(); service.body().unsafeSubscribe(subscriber); // Required for backwards compatibility. subscriber.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber subscriber = subscriberRule.create(); service.body().unsafeSubscribe(subscriber); subscriber.assertError(IOException.class); } @Test public void bodyThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .unsafeSubscribe( new ForwardingSubscriber(subscriber) { @Override public void onNext(String value) { throw e; } }); subscriber.assertError(e); } @Test public void responseSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().body()).isEqualTo("Hi"); subscriber.assertCompleted(); } @Test public void responseSuccess404() throws IOException { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().code()).isEqualTo(404); subscriber.assertCompleted(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().unsafeSubscribe(subscriber); subscriber.assertError(IOException.class); } @Test public void responseThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .unsafeSubscribe( new ForwardingSubscriber>(subscriber) { @Override public void onNext(Response value) { throw e; } }); subscriber.assertError(e); } @Test public void resultSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().response().body()).isEqualTo("Hi"); subscriber.assertCompleted(); } @Test public void resultSuccess404() throws IOException { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().response().code()).isEqualTo(404); subscriber.assertCompleted(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().unsafeSubscribe(subscriber); assertThat(subscriber.takeValue().error()).isInstanceOf(IOException.class); subscriber.assertCompleted(); } @Test public void resultThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .unsafeSubscribe( new ForwardingSubscriber>(subscriber) { @Override public void onNext(Result value) { throw e; } }); subscriber.assertError(e); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Single observable = service.body(); RecordingSubscriber subscriber1 = subscriberRule.create(); observable.subscribe(subscriber1); subscriber1.assertValue("Hi").assertCompleted(); RecordingSubscriber subscriber2 = subscriberRule.create(); observable.subscribe(subscriber2); subscriber2.assertValue("Hey").assertCompleted(); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/SingleThrowingTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Single; import rx.SingleSubscriber; import rx.Subscriber; import rx.exceptions.CompositeException; import rx.exceptions.Exceptions; import rx.plugins.RxJavaErrorHandler; import rx.plugins.RxJavaPlugins; public final class SingleThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Single body(); @GET("/") Single> response(); @GET("/") Single> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onSuccess(String value) { throw e; } }); assertThat(pluginRef.get()).isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Response value) { throw e; } }); assertThat(pluginRef.get()).isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber> observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { throw e; } }); assertThat(pluginRef.get()).isSameInstanceAs(e); } @Ignore("Single's contract is onNext|onError so we have no way of triggering this case") @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.getInstance() .registerErrorHandler( new RxJavaErrorHandler() { @Override public void handleError(Throwable throwable) { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } } }); RecordingSubscriber> observer = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { // The only way to trigger onError for Result is if onSuccess throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } private abstract static class ForwardingObserver extends SingleSubscriber { private final Subscriber delegate; ForwardingObserver(Subscriber delegate) { this.delegate = delegate; } @Override public void onSuccess(T value) { delegate.onNext(value); delegate.onCompleted(); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/SingleWithSchedulerTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; import rx.Single; import rx.schedulers.TestScheduler; public final class SingleWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Single body(); @GET("/") Single> response(); @GET("/") Single> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.create(); service.body().unsafeSubscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertCompleted(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().unsafeSubscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertCompleted(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().unsafeSubscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertCompleted(); } } ================================================ FILE: retrofit-adapters/rxjava/src/test/java/retrofit2/adapter/rxjava/StringConverterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; final class StringConverterFactory extends Converter.Factory { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return ResponseBody::string; } @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return value -> RequestBody.create(MediaType.get("text/plain"), value); } } ================================================ FILE: retrofit-adapters/rxjava2/README.md ================================================ RxJava2 Adapter ============== An `Adapter` for adapting [RxJava 2.x][1] types. Available types: * `Observable`, `Observable>`, and `Observable>` where `T` is the body type. * `Flowable`, `Flowable>` and `Flowable>` where `T` is the body type. * `Single`, `Single>`, and `Single>` where `T` is the body type. * `Maybe`, `Maybe>`, and `Maybe>` where `T` is the body type. * `Completable` where response bodies are discarded. Usage ----- Add `RxJava2CallAdapterFactory` as a `Call` adapter when building your `Retrofit` instance: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); ``` Your service methods can now use any of the above types as their return type. ```java interface MyService { @GET("/user") Observable getUser(); } ``` By default all reactive types execute their requests synchronously. There are multiple ways to control the threading on which a request occurs: * Call `subscribeOn` on the returned reactive type with a `Scheduler` of your choice. * Use `createAsync()` when creating the factory which will use OkHttp's internal thread pool. * Use `createWithScheduler(Scheduler)` to supply a default subscription `Scheduler`. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 adapter-rxjava2 latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:adapter-rxjava2:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/ReactiveX/RxJava/tree/2.x [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=adapter-rxjava2&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22adapter-rxjava2%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-adapters/rxjava2/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.rxjava2 api libs.reactiveStreams compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.guava testImplementation libs.okhttp.mockwebserver } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.adapter.rxjava2' } } ================================================ FILE: retrofit-adapters/rxjava2/gradle.properties ================================================ POM_ARTIFACT_ID=adapter-rxjava2 POM_NAME=Adapter: RxJava 2 POM_DESCRIPTION=A Retrofit CallAdapter for RxJava 2's stream types. ================================================ FILE: retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/BodyObservable.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; 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 retrofit2.Response; final class BodyObservable extends Observable { private final Observable> upstream; BodyObservable(Observable> upstream) { this.upstream = upstream; } @Override protected void subscribeActual(Observer observer) { upstream.subscribe(new BodyObserver(observer)); } private static class BodyObserver implements Observer> { private final Observer observer; private boolean terminated; BodyObserver(Observer observer) { this.observer = observer; } @Override public void onSubscribe(Disposable disposable) { observer.onSubscribe(disposable); } @Override public void onNext(Response response) { if (response.isSuccessful()) { observer.onNext(response.body()); } else { terminated = true; Throwable t = new HttpException(response); try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } } @Override public void onComplete() { if (!terminated) { observer.onComplete(); } } @Override public void onError(Throwable throwable) { if (!terminated) { observer.onError(throwable); } else { // This should never happen! onNext handles and forwards errors automatically. Throwable broken = new AssertionError( "This should never happen! Report as a bug with the full stacktrace."); //noinspection UnnecessaryInitCause Two-arg AssertionError constructor is 1.7+ only. broken.initCause(throwable); RxJavaPlugins.onError(broken); } } } } ================================================ FILE: retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/CallEnqueueObservable.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; 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 retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; final class CallEnqueueObservable extends Observable> { private final Call originalCall; CallEnqueueObservable(Call originalCall) { this.originalCall = originalCall; } @Override protected void subscribeActual(Observer> observer) { // Since Call is a one-shot type, clone it for each new observer. Call call = originalCall.clone(); CallCallback callback = new CallCallback<>(call, observer); observer.onSubscribe(callback); if (!callback.isDisposed()) { call.enqueue(callback); } } private static final class CallCallback implements Disposable, Callback { private final Call call; private final Observer> observer; private volatile boolean disposed; boolean terminated = false; CallCallback(Call call, Observer> observer) { this.call = call; this.observer = observer; } @Override public void onResponse(Call call, Response response) { if (disposed) return; try { observer.onNext(response); if (!disposed) { terminated = true; observer.onComplete(); } } catch (Throwable t) { Exceptions.throwIfFatal(t); if (terminated) { RxJavaPlugins.onError(t); } else if (!disposed) { try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } } } @Override public void onFailure(Call call, Throwable t) { if (call.isCanceled()) return; try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } @Override public void dispose() { disposed = true; call.cancel(); } @Override public boolean isDisposed() { return disposed; } } } ================================================ FILE: retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/CallExecuteObservable.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; 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 retrofit2.Call; import retrofit2.Response; final class CallExecuteObservable extends Observable> { private final Call originalCall; CallExecuteObservable(Call originalCall) { this.originalCall = originalCall; } @Override protected void subscribeActual(Observer> observer) { // Since Call is a one-shot type, clone it for each new observer. Call call = originalCall.clone(); CallDisposable disposable = new CallDisposable(call); observer.onSubscribe(disposable); if (disposable.isDisposed()) { return; } boolean terminated = false; try { Response response = call.execute(); if (!disposable.isDisposed()) { observer.onNext(response); } if (!disposable.isDisposed()) { terminated = true; observer.onComplete(); } } catch (Throwable t) { Exceptions.throwIfFatal(t); if (terminated) { RxJavaPlugins.onError(t); } else if (!disposable.isDisposed()) { try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } } } private static final class CallDisposable implements Disposable { private final Call call; private volatile boolean disposed; CallDisposable(Call call) { this.call = call; } @Override public void dispose() { disposed = true; call.cancel(); } @Override public boolean isDisposed() { return disposed; } } } ================================================ FILE: retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/HttpException.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import retrofit2.Response; /** @deprecated Use {@link retrofit2.HttpException}. */ @Deprecated public final class HttpException extends retrofit2.HttpException { public HttpException(Response response) { super(response); } } ================================================ FILE: retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/Result.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import java.io.IOException; import javax.annotation.Nullable; import retrofit2.Response; /** The result of executing an HTTP request. */ public final class Result { @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static Result error(Throwable error) { if (error == null) throw new NullPointerException("error == null"); return new Result<>(null, error); } @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static Result response(Response response) { if (response == null) throw new NullPointerException("response == null"); return new Result<>(response, null); } private final @Nullable Response response; private final @Nullable Throwable error; private Result(@Nullable Response response, @Nullable Throwable error) { this.response = response; this.error = error; } /** * The response received from executing an HTTP request. Only present when {@link #isError()} is * false, null otherwise. */ public @Nullable Response response() { return response; } /** * The error experienced while attempting to execute an HTTP request. Only present when {@link * #isError()} is true, null otherwise. * *

If the error is an {@link IOException} then there was a problem with the transport to the * remote server. Any other exception type indicates an unexpected failure and should be * considered fatal (configuration error, programming error, etc.). */ public @Nullable Throwable error() { return error; } /** {@code true} if the request resulted in an error. See {@link #error()} for the cause. */ public boolean isError() { return error != null; } } ================================================ FILE: retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/ResultObservable.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; 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 retrofit2.Response; final class ResultObservable extends Observable> { private final Observable> upstream; ResultObservable(Observable> upstream) { this.upstream = upstream; } @Override protected void subscribeActual(Observer> observer) { upstream.subscribe(new ResultObserver(observer)); } private static class ResultObserver implements Observer> { private final Observer> observer; ResultObserver(Observer> observer) { this.observer = observer; } @Override public void onSubscribe(Disposable disposable) { observer.onSubscribe(disposable); } @Override public void onNext(Response response) { observer.onNext(Result.response(response)); } @Override public void onError(Throwable throwable) { try { observer.onNext(Result.error(throwable)); } catch (Throwable t) { try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } return; } observer.onComplete(); } @Override public void onComplete() { observer.onComplete(); } } } ================================================ FILE: retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/RxJava2CallAdapter.java ================================================ /* * Copyright (C) 2016 Jake Wharton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import io.reactivex.BackpressureStrategy; import io.reactivex.Observable; import io.reactivex.Scheduler; import io.reactivex.plugins.RxJavaPlugins; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Response; final class RxJava2CallAdapter implements CallAdapter { private final Type responseType; private final @Nullable Scheduler scheduler; private final boolean isAsync; private final boolean isResult; private final boolean isBody; private final boolean isFlowable; private final boolean isSingle; private final boolean isMaybe; private final boolean isCompletable; RxJava2CallAdapter( Type responseType, @Nullable Scheduler scheduler, boolean isAsync, boolean isResult, boolean isBody, boolean isFlowable, boolean isSingle, boolean isMaybe, boolean isCompletable) { this.responseType = responseType; this.scheduler = scheduler; this.isAsync = isAsync; this.isResult = isResult; this.isBody = isBody; this.isFlowable = isFlowable; this.isSingle = isSingle; this.isMaybe = isMaybe; this.isCompletable = isCompletable; } @Override public Type responseType() { return responseType; } @Override public Object adapt(Call call) { Observable> responseObservable = isAsync ? new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call); Observable observable; if (isResult) { observable = new ResultObservable<>(responseObservable); } else if (isBody) { observable = new BodyObservable<>(responseObservable); } else { observable = responseObservable; } if (scheduler != null) { observable = observable.subscribeOn(scheduler); } if (isFlowable) { // We only ever deliver a single value, and the RS spec states that you MUST request at least // one element which means we never need to honor backpressure. return observable.toFlowable(BackpressureStrategy.MISSING); } if (isSingle) { return observable.singleOrError(); } if (isMaybe) { return observable.singleElement(); } if (isCompletable) { return observable.ignoreElements(); } return RxJavaPlugins.onAssembly(observable); } } ================================================ FILE: retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/RxJava2CallAdapterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import io.reactivex.Completable; import io.reactivex.Flowable; import io.reactivex.Maybe; import io.reactivex.Observable; import io.reactivex.Scheduler; import io.reactivex.Single; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.CallAdapter; import retrofit2.HttpException; import retrofit2.Response; import retrofit2.Retrofit; /** * A {@linkplain CallAdapter.Factory call adapter} which uses RxJava 2 for creating observables. * *

Adding this class to {@link Retrofit} allows you to return an {@link Observable}, {@link * Flowable}, {@link Single}, {@link Completable} or {@link Maybe} from service methods. * *


 * interface MyService {
 *   @GET("user/me")
 *   Observable<User> getUser()
 * }
 * 
* * There are three configurations supported for the {@code Observable}, {@code Flowable}, {@code * Single}, {@link Completable} and {@code Maybe} type parameter: * *
    *
  • Direct body (e.g., {@code Observable}) calls {@code onNext} with the deserialized * body for 2XX responses and calls {@code onError} with {@link HttpException} for non-2XX * responses and {@link IOException} for network errors. *
  • Response wrapped body (e.g., {@code Observable>}) calls {@code onNext} with * a {@link Response} object for all HTTP responses and calls {@code onError} with {@link * IOException} for network errors *
  • Result wrapped body (e.g., {@code Observable>}) calls {@code onNext} with a * {@link Result} object for all HTTP responses and errors. *
*/ public final class RxJava2CallAdapterFactory extends CallAdapter.Factory { /** * Returns an instance which creates synchronous observables that do not operate on any scheduler * by default. */ public static RxJava2CallAdapterFactory create() { return new RxJava2CallAdapterFactory(null, false); } /** Returns an instance which creates asynchronous observables. */ public static RxJava2CallAdapterFactory createAsync() { return new RxJava2CallAdapterFactory(null, true); } /** * Returns an instance which creates synchronous observables that {@linkplain * Observable#subscribeOn(Scheduler) subscribe on} {@code scheduler} by default. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static RxJava2CallAdapterFactory createWithScheduler(Scheduler scheduler) { if (scheduler == null) throw new NullPointerException("scheduler == null"); return new RxJava2CallAdapterFactory(scheduler, false); } private final @Nullable Scheduler scheduler; private final boolean isAsync; private RxJava2CallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) { this.scheduler = scheduler; this.isAsync = isAsync; } @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { Class rawType = getRawType(returnType); if (rawType == Completable.class) { // Completable is not parameterized (which is what the rest of this method deals with) so it // can only be created with a single configuration. return new RxJava2CallAdapter( Void.class, scheduler, isAsync, false, true, false, false, false, true); } boolean isFlowable = rawType == Flowable.class; boolean isSingle = rawType == Single.class; boolean isMaybe = rawType == Maybe.class; if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) { return null; } boolean isResult = false; boolean isBody = false; Type responseType; if (!(returnType instanceof ParameterizedType)) { String name = isFlowable ? "Flowable" : isSingle ? "Single" : isMaybe ? "Maybe" : "Observable"; throw new IllegalStateException( name + " return type must be parameterized" + " as " + name + " or " + name + ""); } Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType); Class rawObservableType = getRawType(observableType); if (rawObservableType == Response.class) { if (!(observableType instanceof ParameterizedType)) { throw new IllegalStateException( "Response must be parameterized" + " as Response or Response"); } responseType = getParameterUpperBound(0, (ParameterizedType) observableType); } else if (rawObservableType == Result.class) { if (!(observableType instanceof ParameterizedType)) { throw new IllegalStateException( "Result must be parameterized" + " as Result or Result"); } responseType = getParameterUpperBound(0, (ParameterizedType) observableType); isResult = true; } else { responseType = observableType; isBody = true; } return new RxJava2CallAdapter( responseType, scheduler, isAsync, isResult, isBody, isFlowable, isSingle, isMaybe, false); } } ================================================ FILE: retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.adapter.rxjava2; ================================================ FILE: retrofit-adapters/rxjava2/src/main/resources/META-INF/proguard/retrofit2-rxjava2-adapter.pro ================================================ # Keep generic signature of RxJava2 (R8 full mode strips signatures from non-kept items). # It's necessary to add the explicit rule for Result as it could be used as a nested return type like `Observable>` -keep,allowoptimization,allowshrinking,allowobfuscation class retrofit2.adapter.rxjava2.Result ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/AsyncTest.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import io.reactivex.Completable; import io.reactivex.exceptions.CompositeException; import io.reactivex.exceptions.Exceptions; import io.reactivex.exceptions.UndeliverableException; import io.reactivex.observers.TestObserver; import io.reactivex.plugins.RxJavaPlugins; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; import okhttp3.Dispatcher; import okhttp3.OkHttpClient; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.CompletableThrowingTest.ForwardingCompletableObserver; import retrofit2.http.GET; public final class AsyncTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Completable completable(); } private Service service; private final List uncaughtExceptions = new ArrayList<>(); @Before public void setUp() { ExecutorService executorService = Executors.newCachedThreadPool( r -> { Thread thread = new Thread(r); thread.setUncaughtExceptionHandler((t, e) -> uncaughtExceptions.add(e)); return thread; }); OkHttpClient client = new OkHttpClient.Builder().dispatcher(new Dispatcher(executorService)).build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .client(client) .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync()) .build(); service = retrofit.create(Service.class); } @After public void tearDown() { assertTrue("Uncaught exceptions: " + uncaughtExceptions, uncaughtExceptions.isEmpty()); } @Test public void success() throws InterruptedException { TestObserver observer = new TestObserver<>(); service.completable().subscribe(observer); assertFalse(observer.await(1, SECONDS)); server.enqueue(new MockResponse()); observer.awaitTerminalEvent(1, SECONDS); observer.assertComplete(); } @Test public void failure() throws InterruptedException { TestObserver observer = new TestObserver<>(); service.completable().subscribe(observer); assertFalse(observer.await(1, SECONDS)); server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); observer.awaitTerminalEvent(1, SECONDS); observer.assertError(IOException.class); } @Test public void throwingInOnCompleteDeliveredToPlugin() throws InterruptedException { server.enqueue(new MockResponse()); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference errorRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } latch.countDown(); }); TestObserver observer = new TestObserver<>(); final RuntimeException e = new RuntimeException(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onComplete() { throw e; } }); latch.await(1, SECONDS); Throwable error = errorRef.get(); assertThat(error).isInstanceOf(UndeliverableException.class); assertThat(error).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() throws InterruptedException { server.enqueue(new MockResponse().setResponseCode(404)); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } latch.countDown(); }); TestObserver observer = new TestObserver<>(); final RuntimeException e = new RuntimeException(); final AtomicReference errorRef = new AtomicReference<>(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onError(Throwable throwable) { errorRef.set(throwable); throw e; } }); latch.await(1, SECONDS); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void bodyThrowingFatalInOnErrorPropagates() throws InterruptedException { server.enqueue(new MockResponse().setResponseCode(404)); final CountDownLatch latch = new CountDownLatch(1); TestObserver observer = new TestObserver<>(); final Error e = new OutOfMemoryError("Not real"); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onError(Throwable throwable) { throw e; } }); latch.await(1, SECONDS); assertEquals(1, uncaughtExceptions.size()); assertSame(e, uncaughtExceptions.remove(0)); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/CancelDisposeTest.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import io.reactivex.Observable; import io.reactivex.disposables.Disposable; import java.util.List; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CancelDisposeTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Observable go(); } private final OkHttpClient client = new OkHttpClient(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync()) .callFactory(client) .build(); service = retrofit.create(Service.class); } @Test public void disposeCancelsCall() { Disposable disposable = service.go().subscribe(); List calls = client.dispatcher().runningCalls(); assertEquals(1, calls.size()); disposable.dispose(); assertTrue(calls.get(0).isCanceled()); } @SuppressWarnings("ResultOfMethodCallIgnored") @Test public void disposeBeforeEnqueueDoesNotEnqueue() { service.go().test(true); List calls = client.dispatcher().runningCalls(); assertEquals(0, calls.size()); } @Test public void cancelDoesNotDispose() { Disposable disposable = service.go().subscribe(); List calls = client.dispatcher().runningCalls(); assertEquals(1, calls.size()); calls.get(0).cancel(); assertFalse(disposable.isDisposed()); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/CancelDisposeTestSync.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static org.junit.Assert.assertEquals; import io.reactivex.Observable; import okhttp3.OkHttpClient; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CancelDisposeTestSync { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Observable go(); } private final OkHttpClient client = new OkHttpClient(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .callFactory(client) .build(); service = retrofit.create(Service.class); } @SuppressWarnings("ResultOfMethodCallIgnored") @Test public void disposeBeforeExecuteDoesNotEnqueue() { service.go().test(true); assertEquals(0, server.getRequestCount()); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/CompletableTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.Completable; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CompletableTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingCompletableObserver.Rule observerRule = new RecordingCompletableObserver.Rule(); interface Service { @GET("/") Completable completable(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void completableSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingCompletableObserver observer = observerRule.create(); service.completable().subscribe(observer); observer.assertComplete(); } @Test public void completableSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingCompletableObserver observer = observerRule.create(); service.completable().subscribe(observer); // Required for backwards compatibility. observer.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void completableFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingCompletableObserver observer = observerRule.create(); service.completable().subscribe(observer); observer.assertError(IOException.class); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Completable observable = service.completable(); RecordingCompletableObserver observer1 = observerRule.create(); observable.subscribe(observer1); observer1.assertComplete(); RecordingCompletableObserver observer2 = observerRule.create(); observable.subscribe(observer2); observer2.assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/CompletableThrowingTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import io.reactivex.Completable; import io.reactivex.CompletableObserver; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.CompositeException; import io.reactivex.exceptions.Exceptions; import io.reactivex.exceptions.UndeliverableException; import io.reactivex.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CompletableThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingCompletableObserver.Rule observerRule = new RecordingCompletableObserver.Rule(); interface Service { @GET("/") Completable completable(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void throwingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference errorRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } }); RecordingCompletableObserver observer = observerRule.create(); final RuntimeException e = new RuntimeException(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onComplete() { throw e; } }); Throwable error = errorRef.get(); assertThat(error).isInstanceOf(UndeliverableException.class); assertThat(error).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } }); RecordingCompletableObserver observer = observerRule.create(); final RuntimeException e = new RuntimeException(); final AtomicReference errorRef = new AtomicReference<>(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onError(Throwable throwable) { errorRef.set(throwable); throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } abstract static class ForwardingCompletableObserver implements CompletableObserver { private final CompletableObserver delegate; ForwardingCompletableObserver(CompletableObserver delegate) { this.delegate = delegate; } @Override public void onSubscribe(Disposable disposable) { delegate.onSubscribe(disposable); } @Override public void onComplete() { delegate.onComplete(); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/CompletableWithSchedulerTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import io.reactivex.Completable; import io.reactivex.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CompletableWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingCompletableObserver.Rule observerRule = new RecordingCompletableObserver.Rule(); interface Service { @GET("/") Completable completable(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void completableUsesScheduler() { server.enqueue(new MockResponse()); RecordingCompletableObserver observer = observerRule.create(); service.completable().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/FlowableTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.Flowable; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class FlowableTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Flowable body(); @GET("/") Flowable> response(); @GET("/") Flowable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.create(); service.body().subscribe(subscriber); subscriber.assertValue("Hi").assertComplete(); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber subscriber = subscriberRule.create(); service.body().subscribe(subscriber); // Required for backwards compatibility. subscriber.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber subscriber = subscriberRule.create(); service.body().subscribe(subscriber); subscriber.assertError(IOException.class); } @Test public void responseSuccess200() { server.enqueue(new MockResponse()); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().subscribe(subscriber); assertThat(subscriber.takeValue().isSuccessful()).isTrue(); subscriber.assertComplete(); } @Test public void responseSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().subscribe(subscriber); assertThat(subscriber.takeValue().isSuccessful()).isFalse(); subscriber.assertComplete(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().subscribe(subscriber); subscriber.assertError(IOException.class); } @Test public void resultSuccess200() { server.enqueue(new MockResponse()); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().subscribe(subscriber); Result result = subscriber.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isTrue(); subscriber.assertComplete(); } @Test public void resultSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().subscribe(subscriber); Result result = subscriber.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isFalse(); subscriber.assertComplete(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().subscribe(subscriber); Result result = subscriber.takeValue(); assertThat(result.isError()).isTrue(); assertThat(result.error()).isInstanceOf(IOException.class); subscriber.assertComplete(); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Flowable observable = service.body(); RecordingSubscriber subscriber1 = subscriberRule.create(); observable.subscribe(subscriber1); subscriber1.assertValue("Hi").assertComplete(); RecordingSubscriber subscriber2 = subscriberRule.create(); observable.subscribe(subscriber2); subscriber2.assertValue("Hey").assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/FlowableThrowingTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.Flowable; import io.reactivex.exceptions.CompositeException; import io.reactivex.exceptions.Exceptions; import io.reactivex.exceptions.UndeliverableException; import io.reactivex.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class FlowableThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Flowable body(); @GET("/") Flowable> response(); @GET("/") Flowable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .safeSubscribe( new ForwardingSubscriber(subscriber) { @Override public void onNext(String value) { throw e; } }); subscriber.assertError(e); } @Test public void bodyThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingSubscriber(subscriber) { @Override public void onComplete() { throw e; } }); subscriber.assertAnyValue(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber subscriber = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingSubscriber(subscriber) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .safeSubscribe( new ForwardingSubscriber>(subscriber) { @Override public void onNext(Response value) { throw e; } }); subscriber.assertError(e); } @Test public void responseThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingSubscriber>(subscriber) { @Override public void onComplete() { throw e; } }); subscriber.assertAnyValue(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber> subscriber = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingSubscriber>(subscriber) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .safeSubscribe( new ForwardingSubscriber>(subscriber) { @Override public void onNext(Result value) { throw e; } }); subscriber.assertError(e); } @Test public void resultThrowingInOnCompletedDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingSubscriber>(subscriber) { @Override public void onComplete() { throw e; } }); subscriber.assertAnyValue(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .safeSubscribe( new ForwardingSubscriber>(subscriber) { @Override public void onNext(Result value) { // The only way to trigger onError for a result is if onNext throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } private abstract static class ForwardingSubscriber implements Subscriber { private final Subscriber delegate; ForwardingSubscriber(Subscriber delegate) { this.delegate = delegate; } @Override public void onSubscribe(Subscription subscription) { delegate.onSubscribe(subscription); } @Override public void onNext(T value) { delegate.onNext(value); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } @Override public void onComplete() { delegate.onComplete(); } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/FlowableWithSchedulerTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import io.reactivex.Flowable; import io.reactivex.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class FlowableWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Flowable body(); @GET("/") Flowable> response(); @GET("/") Flowable> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse()); RecordingSubscriber subscriber = subscriberRule.create(); service.body().subscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertComplete(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse()); RecordingSubscriber subscriber = subscriberRule.create(); service.response().subscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertComplete(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse()); RecordingSubscriber subscriber = subscriberRule.create(); service.result().subscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/MaybeTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.Maybe; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class MaybeTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingMaybeObserver.Rule observerRule = new RecordingMaybeObserver.Rule(); interface Service { @GET("/") Maybe body(); @GET("/") Maybe> response(); @GET("/") Maybe> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingMaybeObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertValue("Hi"); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingMaybeObserver observer = observerRule.create(); service.body().subscribe(observer); // Required for backwards compatibility. observer.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingMaybeObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertError(IOException.class); } @Test public void responseSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingMaybeObserver> observer = observerRule.create(); service.response().subscribe(observer); Response response = observer.takeValue(); assertThat(response.isSuccessful()).isTrue(); } @Test public void responseSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingMaybeObserver> observer = observerRule.create(); service.response().subscribe(observer); assertThat(observer.takeValue().isSuccessful()).isFalse(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingMaybeObserver> observer = observerRule.create(); service.response().subscribe(observer); observer.assertError(IOException.class); } @Test public void resultSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingMaybeObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isTrue(); } @Test public void resultSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingMaybeObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isFalse(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingMaybeObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isTrue(); assertThat(result.error()).isInstanceOf(IOException.class); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Maybe observable = service.body(); RecordingMaybeObserver observer1 = observerRule.create(); observable.subscribe(observer1); observer1.assertValue("Hi"); RecordingMaybeObserver observer2 = observerRule.create(); observable.subscribe(observer2); observer2.assertValue("Hey"); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/MaybeThrowingTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.Maybe; import io.reactivex.MaybeObserver; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.CompositeException; import io.reactivex.exceptions.Exceptions; import io.reactivex.exceptions.UndeliverableException; import io.reactivex.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class MaybeThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingMaybeObserver.Rule subscriberRule = new RecordingMaybeObserver.Rule(); interface Service { @GET("/") Maybe body(); @GET("/") Maybe> response(); @GET("/") Maybe> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onSuccess(String value) { throw e; } }); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Response value) { throw e; } }); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver> observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { throw e; } }); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Ignore("Single's contract is onNext|onError so we have no way of triggering this case") @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver> observer = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { // The only way to trigger onError for Result is if onSuccess throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } private abstract static class ForwardingObserver implements MaybeObserver { private final MaybeObserver delegate; ForwardingObserver(MaybeObserver delegate) { this.delegate = delegate; } @Override public void onSubscribe(Disposable disposable) { delegate.onSubscribe(disposable); } @Override public void onSuccess(T value) { delegate.onSuccess(value); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } @Override public void onComplete() { delegate.onComplete(); } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/MaybeWithSchedulerTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import io.reactivex.Maybe; import io.reactivex.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class MaybeWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingMaybeObserver.Rule observerRule = new RecordingMaybeObserver.Rule(); interface Service { @GET("/") Maybe body(); @GET("/") Maybe> response(); @GET("/") Maybe> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse()); RecordingMaybeObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse()); RecordingMaybeObserver observer = observerRule.create(); service.response().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse()); RecordingMaybeObserver observer = observerRule.create(); service.result().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/ObservableTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.Observable; import io.reactivex.plugins.RxJavaPlugins; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class ObservableTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingObserver.Rule observerRule = new RecordingObserver.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertValue("Hi").assertComplete(); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingObserver observer = observerRule.create(); service.body().subscribe(observer); // Required for backwards compatibility. observer.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertError(IOException.class); } @Test public void responseSuccess200() { server.enqueue(new MockResponse()); RecordingObserver> observer = observerRule.create(); service.response().subscribe(observer); assertThat(observer.takeValue().isSuccessful()).isTrue(); observer.assertComplete(); } @Test public void responseSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingObserver> observer = observerRule.create(); service.response().subscribe(observer); assertThat(observer.takeValue().isSuccessful()).isFalse(); observer.assertComplete(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingObserver> observer = observerRule.create(); service.response().subscribe(observer); observer.assertError(IOException.class); } @Test public void resultSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isTrue(); observer.assertComplete(); } @Test public void resultSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isFalse(); observer.assertComplete(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isTrue(); assertThat(result.error()).isInstanceOf(IOException.class); observer.assertComplete(); } @Test public void observableAssembly() { try { final Observable justMe = Observable.just("me"); RxJavaPlugins.setOnObservableAssembly(f -> justMe); assertThat(service.body()).isEqualTo(justMe); } finally { RxJavaPlugins.reset(); } } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Observable observable = service.body(); RecordingObserver observer1 = observerRule.create(); observable.subscribe(observer1); observer1.assertValue("Hi").assertComplete(); RecordingObserver observer2 = observerRule.create(); observable.subscribe(observer2); observer2.assertValue("Hey").assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/ObservableThrowingTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; 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.exceptions.UndeliverableException; import io.reactivex.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class ObservableThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingObserver.Rule subscriberRule = new RecordingObserver.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingObserver observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onNext(String value) { throw e; } }); observer.assertError(e); } @Test public void bodyThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onComplete() { throw e; } }); observer.assertAnyValue(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onNext(Response value) { throw e; } }); observer.assertError(e); } @Test public void responseThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onComplete() { throw e; } }); observer.assertAnyValue(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver> observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onNext(Result value) { throw e; } }); observer.assertError(e); } @Test public void resultThrowingInOnCompletedDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onComplete() { throw e; } }); observer.assertAnyValue(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver> observer = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onNext(Result value) { // The only way to trigger onError for a result is if onNext throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } private abstract static class ForwardingObserver implements Observer { private final Observer delegate; ForwardingObserver(Observer delegate) { this.delegate = delegate; } @Override public void onSubscribe(Disposable disposable) { delegate.onSubscribe(disposable); } @Override public void onNext(T value) { delegate.onNext(value); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } @Override public void onComplete() { delegate.onComplete(); } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/ObservableWithSchedulerTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import io.reactivex.Observable; import io.reactivex.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class ObservableWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingObserver.Rule observerRule = new RecordingObserver.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse()); RecordingObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue().assertComplete(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse()); RecordingObserver observer = observerRule.create(); service.response().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue().assertComplete(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse()); RecordingObserver observer = observerRule.create(); service.result().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue().assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/RecordingCompletableObserver.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.CompletableObserver; import io.reactivex.Notification; import io.reactivex.disposables.Disposable; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** A test {@link CompletableObserver} and JUnit rule which guarantees all events are asserted. */ final class RecordingCompletableObserver implements CompletableObserver { private final Deque> events = new ArrayDeque<>(); private RecordingCompletableObserver() {} @Override public void onSubscribe(Disposable disposable) {} @Override public void onComplete() { events.add(Notification.createOnComplete()); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public void assertComplete() { Notification notification = takeNotification(); assertWithMessage("Expected onCompleted event but was " + notification) .that(notification.isOnComplete()) .isTrue(); assertNoEvents(); } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public static final class Rule implements TestRule { final List subscribers = new ArrayList<>(); public RecordingCompletableObserver create() { RecordingCompletableObserver subscriber = new RecordingCompletableObserver(); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingCompletableObserver subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/RecordingMaybeObserver.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.MaybeObserver; import io.reactivex.Notification; import io.reactivex.Observer; import io.reactivex.disposables.Disposable; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** A test {@link Observer} and JUnit rule which guarantees all events are asserted. */ final class RecordingMaybeObserver implements MaybeObserver { private final Deque> events = new ArrayDeque<>(); private RecordingMaybeObserver() {} @Override public void onSubscribe(Disposable disposable) {} @Override public void onSuccess(T value) { events.add(Notification.createOnNext(value)); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } @Override public void onComplete() { events.add(Notification.createOnComplete()); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public T takeValue() { Notification notification = takeNotification(); assertWithMessage("Expected onNext event but was " + notification) .that(notification.isOnNext()) .isTrue(); return notification.getValue(); } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public RecordingMaybeObserver assertAnyValue() { takeValue(); return this; } public RecordingMaybeObserver assertValue(T value) { assertThat(takeValue()).isEqualTo(value); return this; } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public static final class Rule implements TestRule { final List> subscribers = new ArrayList<>(); public RecordingMaybeObserver create() { RecordingMaybeObserver subscriber = new RecordingMaybeObserver<>(); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingMaybeObserver subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/RecordingObserver.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.Notification; import io.reactivex.Observer; import io.reactivex.disposables.Disposable; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** A test {@link Observer} and JUnit rule which guarantees all events are asserted. */ final class RecordingObserver implements Observer { private final Deque> events = new ArrayDeque<>(); private RecordingObserver() {} @Override public void onSubscribe(Disposable disposable) {} @Override public void onNext(T value) { events.add(Notification.createOnNext(value)); } @Override public void onComplete() { events.add(Notification.createOnComplete()); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public T takeValue() { Notification notification = takeNotification(); assertWithMessage("Expected onNext event but was " + notification) .that(notification.isOnNext()) .isTrue(); return notification.getValue(); } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public RecordingObserver assertAnyValue() { takeValue(); return this; } public RecordingObserver assertValue(T value) { assertThat(takeValue()).isEqualTo(value); return this; } public void assertComplete() { Notification notification = takeNotification(); assertWithMessage("Expected onCompleted event but was " + notification) .that(notification.isOnComplete()) .isTrue(); assertNoEvents(); } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public static final class Rule implements TestRule { final List> subscribers = new ArrayList<>(); public RecordingObserver create() { RecordingObserver subscriber = new RecordingObserver<>(); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingObserver subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/RecordingSingleObserver.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.Notification; import io.reactivex.Observer; import io.reactivex.SingleObserver; import io.reactivex.disposables.Disposable; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** A test {@link Observer} and JUnit rule which guarantees all events are asserted. */ final class RecordingSingleObserver implements SingleObserver { private final Deque> events = new ArrayDeque<>(); private RecordingSingleObserver() {} @Override public void onSubscribe(Disposable disposable) {} @Override public void onSuccess(T value) { events.add(Notification.createOnNext(value)); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public T takeValue() { Notification notification = takeNotification(); assertWithMessage("Expected onNext event but was " + notification) .that(notification.isOnNext()) .isTrue(); return notification.getValue(); } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public RecordingSingleObserver assertAnyValue() { takeValue(); return this; } public RecordingSingleObserver assertValue(T value) { assertThat(takeValue()).isEqualTo(value); return this; } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public static final class Rule implements TestRule { final List> subscribers = new ArrayList<>(); public RecordingSingleObserver create() { RecordingSingleObserver subscriber = new RecordingSingleObserver<>(); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingSingleObserver subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/RecordingSubscriber.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.Notification; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; /** A test {@link Subscriber} and JUnit rule which guarantees all events are asserted. */ final class RecordingSubscriber implements Subscriber { private final long initialRequest; private final Deque> events = new ArrayDeque<>(); private Subscription subscription; private RecordingSubscriber(long initialRequest) { this.initialRequest = initialRequest; } @Override public void onSubscribe(Subscription subscription) { this.subscription = subscription; subscription.request(initialRequest); } @Override public void onNext(T value) { events.add(Notification.createOnNext(value)); } @Override public void onComplete() { events.add(Notification.createOnComplete()); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public T takeValue() { Notification notification = takeNotification(); assertWithMessage("Expected onNext event but was " + notification) .that(notification.isOnNext()) .isTrue(); return notification.getValue(); } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public RecordingSubscriber assertAnyValue() { takeValue(); return this; } public RecordingSubscriber assertValue(T value) { assertThat(takeValue()).isEqualTo(value); return this; } public void assertComplete() { Notification notification = takeNotification(); assertWithMessage("Expected onCompleted event but was " + notification) .that(notification.isOnComplete()) .isTrue(); assertNoEvents(); } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public void request(long amount) { if (subscription == null) { throw new IllegalStateException("onSubscribe has not been called yet. Did you subscribe()?"); } subscription.request(amount); } public static final class Rule implements TestRule { final List> subscribers = new ArrayList<>(); public RecordingSubscriber create() { return createWithInitialRequest(Long.MAX_VALUE); } public RecordingSubscriber createWithInitialRequest(long initialRequest) { RecordingSubscriber subscriber = new RecordingSubscriber<>(initialRequest); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingSubscriber subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/ResultTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import java.io.IOException; import org.junit.Test; import retrofit2.Response; public final class ResultTest { @Test public void response() { Response response = Response.success("Hi"); Result result = Result.response(response); assertThat(result.isError()).isFalse(); assertThat(result.error()).isNull(); assertThat(result.response()).isSameInstanceAs(response); } @Test public void nullResponseThrows() { try { Result.response(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("response == null"); } } @Test public void error() { Throwable error = new IOException(); Result result = Result.error(error); assertThat(result.isError()).isTrue(); assertThat(result.error()).isSameInstanceAs(error); assertThat(result.response()).isNull(); } @Test public void nullErrorThrows() { try { Result.error(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("error == null"); } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/RxJava2CallAdapterFactoryTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.reflect.TypeToken; import io.reactivex.Flowable; import io.reactivex.Maybe; import io.reactivex.Observable; import io.reactivex.Single; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import org.junit.Before; import org.junit.Test; import retrofit2.CallAdapter; import retrofit2.Response; import retrofit2.Retrofit; public class RxJava2CallAdapterFactoryTest { private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; private final CallAdapter.Factory factory = RxJava2CallAdapterFactory.create(); private Retrofit retrofit; @Before public void setUp() { retrofit = new Retrofit.Builder() .baseUrl("http://localhost:1") .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(factory) .build(); } @Test public void nullSchedulerThrows() { try { RxJava2CallAdapterFactory.createWithScheduler(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("scheduler == null"); } } @Test public void nonRxJavaTypeReturnsNull() { CallAdapter adapter = factory.get(String.class, NO_ANNOTATIONS, retrofit); assertThat(adapter).isNull(); } @Test public void responseTypes() { Type oBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(oBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(sBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(mBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(fBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(oBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(sBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(mBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(fBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(oBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type sBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(sBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type mBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(mBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type fBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(fBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type oResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(oResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(sResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(mResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(fResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(oResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(sResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(mResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(fResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(oResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(sResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(mResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(fResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(oResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(sResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(mResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(fResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); } @Test public void rawBodyTypeThrows() { Type observableType = new TypeToken() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Observable return type must be parameterized as Observable or Observable"); } Type singleType = new TypeToken() {}.getType(); try { factory.get(singleType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Single return type must be parameterized as Single or Single"); } Type maybeType = new TypeToken() {}.getType(); try { factory.get(maybeType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Maybe return type must be parameterized as Maybe or Maybe"); } Type flowableType = new TypeToken() {}.getType(); try { factory.get(flowableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Flowable return type must be parameterized as Flowable or Flowable"); } } @Test public void rawResponseTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } Type singleType = new TypeToken>() {}.getType(); try { factory.get(singleType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } Type maybeType = new TypeToken>() {}.getType(); try { factory.get(maybeType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } Type flowableType = new TypeToken>() {}.getType(); try { factory.get(flowableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } } @Test public void rawResultTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } Type singleType = new TypeToken>() {}.getType(); try { factory.get(singleType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } Type maybeType = new TypeToken>() {}.getType(); try { factory.get(maybeType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } Type flowableType = new TypeToken>() {}.getType(); try { factory.get(flowableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/RxJavaPluginsResetRule.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import io.reactivex.plugins.RxJavaPlugins; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; final class RxJavaPluginsResetRule implements TestRule { @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { RxJavaPlugins.reset(); try { base.evaluate(); } finally { RxJavaPlugins.reset(); } } }; } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/SingleTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.Single; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class SingleTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSingleObserver.Rule observerRule = new RecordingSingleObserver.Rule(); interface Service { @GET("/") Single body(); @GET("/") Single> response(); @GET("/") Single> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSingleObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertValue("Hi"); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSingleObserver observer = observerRule.create(); service.body().subscribe(observer); // Required for backwards compatibility. observer.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSingleObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertError(IOException.class); } @Test public void responseSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSingleObserver> observer = observerRule.create(); service.response().subscribe(observer); Response response = observer.takeValue(); assertThat(response.isSuccessful()).isTrue(); } @Test public void responseSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSingleObserver> observer = observerRule.create(); service.response().subscribe(observer); assertThat(observer.takeValue().isSuccessful()).isFalse(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSingleObserver> observer = observerRule.create(); service.response().subscribe(observer); observer.assertError(IOException.class); } @Test public void resultSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSingleObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isTrue(); } @Test public void resultSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSingleObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isFalse(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSingleObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isTrue(); assertThat(result.error()).isInstanceOf(IOException.class); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Single observable = service.body(); RecordingSingleObserver observer1 = observerRule.create(); observable.subscribe(observer1); observer1.assertValue("Hi"); RecordingSingleObserver observer2 = observerRule.create(); observable.subscribe(observer2); observer2.assertValue("Hey"); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/SingleThrowingTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.Single; import io.reactivex.SingleObserver; import io.reactivex.disposables.Disposable; import io.reactivex.exceptions.CompositeException; import io.reactivex.exceptions.Exceptions; import io.reactivex.exceptions.UndeliverableException; import io.reactivex.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class SingleThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingSingleObserver.Rule subscriberRule = new RecordingSingleObserver.Rule(); interface Service { @GET("/") Single body(); @GET("/") Single> response(); @GET("/") Single> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onSuccess(String value) { throw e; } }); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Response value) { throw e; } }); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver> observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { throw e; } }); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(UndeliverableException.class); assertThat(throwable).hasCauseThat().isSameInstanceAs(e); } @Ignore("Single's contract is onNext|onError so we have no way of triggering this case") @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver> observer = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { // The only way to trigger onError for Result is if onSuccess throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } private abstract static class ForwardingObserver implements SingleObserver { private final SingleObserver delegate; ForwardingObserver(SingleObserver delegate) { this.delegate = delegate; } @Override public void onSubscribe(Disposable disposable) { delegate.onSubscribe(disposable); } @Override public void onSuccess(T value) { delegate.onSuccess(value); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/SingleWithSchedulerTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import io.reactivex.Single; import io.reactivex.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class SingleWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSingleObserver.Rule observerRule = new RecordingSingleObserver.Rule(); interface Service { @GET("/") Single body(); @GET("/") Single> response(); @GET("/") Single> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse()); RecordingSingleObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse()); RecordingSingleObserver observer = observerRule.create(); service.response().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse()); RecordingSingleObserver observer = observerRule.create(); service.result().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } } ================================================ FILE: retrofit-adapters/rxjava2/src/test/java/retrofit2/adapter/rxjava2/StringConverterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava2; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; final class StringConverterFactory extends Converter.Factory { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return ResponseBody::string; } @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return value -> RequestBody.create(MediaType.get("text/plain"), value); } } ================================================ FILE: retrofit-adapters/rxjava3/README.md ================================================ RxJava3 Adapter ============== An `Adapter` for adapting [RxJava 3.x][1] types. Available types: * `Observable`, `Observable>`, and `Observable>` where `T` is the body type. * `Flowable`, `Flowable>` and `Flowable>` where `T` is the body type. * `Single`, `Single>`, and `Single>` where `T` is the body type. * `Maybe`, `Maybe>`, and `Maybe>` where `T` is the body type. * `Completable` where response bodies are discarded. Usage ----- Add `RxJava3CallAdapterFactory` as a `Call` adapter when building your `Retrofit` instance: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); ``` Your service methods can now use any of the above types as their return type. ```java interface MyService { @GET("/user") Observable getUser(); } ``` By default, `create()` will produce reactive types which execute their HTTP requests asynchronously on a background thread. There are two other ways to control the threading on which a request occurs: * Use `createSynchronous()` and call `subscribeOn` on the returned reactive type with a `Scheduler` of your choice. * Use `createWithScheduler(Scheduler)` to supply a default subscription `Scheduler`. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 adapter-rxjava3 latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:adapter-rxjava3:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/ReactiveX/RxJava/tree/3.x [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=adapter-rxjava3&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22adapter-rxjava3%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-adapters/rxjava3/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.rxjava3 api libs.reactiveStreams compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.guava testImplementation libs.okhttp.mockwebserver } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.adapter.rxjava3' } } ================================================ FILE: retrofit-adapters/rxjava3/gradle.properties ================================================ POM_ARTIFACT_ID=adapter-rxjava3 POM_NAME=Adapter: RxJava 3 POM_DESCRIPTION=A Retrofit CallAdapter for RxJava 3's stream types. ================================================ FILE: retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/BodyObservable.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import retrofit2.Response; final class BodyObservable extends Observable { private final Observable> upstream; BodyObservable(Observable> upstream) { this.upstream = upstream; } @Override protected void subscribeActual(Observer observer) { upstream.subscribe(new BodyObserver<>(observer)); } private static class BodyObserver implements Observer> { private final Observer observer; private boolean terminated; BodyObserver(Observer observer) { this.observer = observer; } @Override public void onSubscribe(Disposable disposable) { observer.onSubscribe(disposable); } @Override public void onNext(Response response) { if (response.isSuccessful()) { observer.onNext(response.body()); } else { terminated = true; Throwable t = new HttpException(response); try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } } @Override public void onComplete() { if (!terminated) { observer.onComplete(); } } @Override public void onError(Throwable throwable) { if (!terminated) { observer.onError(throwable); } else { // This should never happen! onNext handles and forwards errors automatically. Throwable broken = new AssertionError( "This should never happen! Report as a bug with the full stacktrace."); //noinspection UnnecessaryInitCause Two-arg AssertionError constructor is 1.7+ only. broken.initCause(throwable); RxJavaPlugins.onError(broken); } } } } ================================================ FILE: retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/CallEnqueueObservable.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; final class CallEnqueueObservable extends Observable> { private final Call originalCall; CallEnqueueObservable(Call originalCall) { this.originalCall = originalCall; } @Override protected void subscribeActual(Observer> observer) { // Since Call is a one-shot type, clone it for each new observer. Call call = originalCall.clone(); CallCallback callback = new CallCallback<>(call, observer); observer.onSubscribe(callback); if (!callback.isDisposed()) { call.enqueue(callback); } } private static final class CallCallback implements Disposable, Callback { private final Call call; private final Observer> observer; private volatile boolean disposed; boolean terminated = false; CallCallback(Call call, Observer> observer) { this.call = call; this.observer = observer; } @Override public void onResponse(Call call, Response response) { if (disposed) return; try { observer.onNext(response); if (!disposed) { terminated = true; observer.onComplete(); } } catch (Throwable t) { Exceptions.throwIfFatal(t); if (terminated) { RxJavaPlugins.onError(t); } else if (!disposed) { try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } } } @Override public void onFailure(Call call, Throwable t) { if (call.isCanceled()) return; try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } @Override public void dispose() { disposed = true; call.cancel(); } @Override public boolean isDisposed() { return disposed; } } } ================================================ FILE: retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/CallExecuteObservable.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import retrofit2.Call; import retrofit2.Response; final class CallExecuteObservable extends Observable> { private final Call originalCall; CallExecuteObservable(Call originalCall) { this.originalCall = originalCall; } @Override protected void subscribeActual(Observer> observer) { // Since Call is a one-shot type, clone it for each new observer. Call call = originalCall.clone(); CallDisposable disposable = new CallDisposable(call); observer.onSubscribe(disposable); if (disposable.isDisposed()) { return; } boolean terminated = false; try { Response response = call.execute(); if (!disposable.isDisposed()) { observer.onNext(response); } if (!disposable.isDisposed()) { terminated = true; observer.onComplete(); } } catch (Throwable t) { Exceptions.throwIfFatal(t); if (terminated) { RxJavaPlugins.onError(t); } else if (!disposable.isDisposed()) { try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } } } } private static final class CallDisposable implements Disposable { private final Call call; private volatile boolean disposed; CallDisposable(Call call) { this.call = call; } @Override public void dispose() { disposed = true; call.cancel(); } @Override public boolean isDisposed() { return disposed; } } } ================================================ FILE: retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/HttpException.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import retrofit2.Response; /** @deprecated Use {@link retrofit2.HttpException}. */ @Deprecated public final class HttpException extends retrofit2.HttpException { public HttpException(Response response) { super(response); } } ================================================ FILE: retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/Result.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import java.io.IOException; import javax.annotation.Nullable; import retrofit2.Response; /** The result of executing an HTTP request. */ public final class Result { @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static Result error(Throwable error) { if (error == null) throw new NullPointerException("error == null"); return new Result<>(null, error); } @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static Result response(Response response) { if (response == null) throw new NullPointerException("response == null"); return new Result<>(response, null); } private final @Nullable Response response; private final @Nullable Throwable error; private Result(@Nullable Response response, @Nullable Throwable error) { this.response = response; this.error = error; } /** * The response received from executing an HTTP request. Only present when {@link #isError()} is * false, null otherwise. */ public @Nullable Response response() { return response; } /** * The error experienced while attempting to execute an HTTP request. Only present when {@link * #isError()} is true, null otherwise. * *

If the error is an {@link IOException} then there was a problem with the transport to the * remote server. Any other exception type indicates an unexpected failure and should be * considered fatal (configuration error, programming error, etc.). */ public @Nullable Throwable error() { return error; } /** {@code true} if the request resulted in an error. See {@link #error()} for the cause. */ public boolean isError() { return error != null; } } ================================================ FILE: retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/ResultObservable.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import retrofit2.Response; final class ResultObservable extends Observable> { private final Observable> upstream; ResultObservable(Observable> upstream) { this.upstream = upstream; } @Override protected void subscribeActual(Observer> observer) { upstream.subscribe(new ResultObserver<>(observer)); } private static class ResultObserver implements Observer> { private final Observer> observer; ResultObserver(Observer> observer) { this.observer = observer; } @Override public void onSubscribe(Disposable disposable) { observer.onSubscribe(disposable); } @Override public void onNext(Response response) { observer.onNext(Result.response(response)); } @Override public void onError(Throwable throwable) { try { observer.onNext(Result.error(throwable)); } catch (Throwable t) { try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner)); } return; } observer.onComplete(); } @Override public void onComplete() { observer.onComplete(); } } } ================================================ FILE: retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/RxJava3CallAdapter.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.BackpressureStrategy; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Scheduler; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Response; final class RxJava3CallAdapter implements CallAdapter { private final Type responseType; private final @Nullable Scheduler scheduler; private final boolean isAsync; private final boolean isResult; private final boolean isBody; private final boolean isFlowable; private final boolean isSingle; private final boolean isMaybe; private final boolean isCompletable; RxJava3CallAdapter( Type responseType, @Nullable Scheduler scheduler, boolean isAsync, boolean isResult, boolean isBody, boolean isFlowable, boolean isSingle, boolean isMaybe, boolean isCompletable) { this.responseType = responseType; this.scheduler = scheduler; this.isAsync = isAsync; this.isResult = isResult; this.isBody = isBody; this.isFlowable = isFlowable; this.isSingle = isSingle; this.isMaybe = isMaybe; this.isCompletable = isCompletable; } @Override public Type responseType() { return responseType; } @Override public Object adapt(Call call) { Observable> responseObservable = isAsync ? new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call); Observable observable; if (isResult) { observable = new ResultObservable<>(responseObservable); } else if (isBody) { observable = new BodyObservable<>(responseObservable); } else { observable = responseObservable; } if (scheduler != null) { observable = observable.subscribeOn(scheduler); } if (isFlowable) { // We only ever deliver a single value, and the RS spec states that you MUST request at least // one element which means we never need to honor backpressure. return observable.toFlowable(BackpressureStrategy.MISSING); } if (isSingle) { return observable.singleOrError(); } if (isMaybe) { return observable.singleElement(); } if (isCompletable) { return observable.ignoreElements(); } return RxJavaPlugins.onAssembly(observable); } } ================================================ FILE: retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/RxJava3CallAdapterFactory.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Maybe; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Scheduler; import io.reactivex.rxjava3.core.Single; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.CallAdapter; import retrofit2.HttpException; import retrofit2.Response; import retrofit2.Retrofit; /** * A {@linkplain CallAdapter.Factory call adapter} which uses RxJava 3 for creating observables. * *

Adding this class to {@link Retrofit} allows you to return an {@link Observable}, {@link * Flowable}, {@link Single}, {@link Completable} or {@link Maybe} from service methods. * *


 * interface MyService {
 *   @GET("user/me")
 *   Observable<User> getUser()
 * }
 * 
* * There are three configurations supported for the {@code Observable}, {@code Flowable}, {@code * Single}, {@link Completable} and {@code Maybe} type parameter: * *
    *
  • Direct body (e.g., {@code Observable}) calls {@code onNext} with the deserialized * body for 2XX responses and calls {@code onError} with {@link HttpException} for non-2XX * responses and {@link IOException} for network errors. *
  • Response wrapped body (e.g., {@code Observable>}) calls {@code onNext} with * a {@link Response} object for all HTTP responses and calls {@code onError} with {@link * IOException} for network errors *
  • Result wrapped body (e.g., {@code Observable>}) calls {@code onNext} with a * {@link Result} object for all HTTP responses and errors. *
*/ public final class RxJava3CallAdapterFactory extends CallAdapter.Factory { /** * Returns an instance which creates asynchronous observables that run on a background thread by * default. Applying {@code subscribeOn(..)} has no effect on instances created by the returned * factory. */ public static RxJava3CallAdapterFactory create() { return new RxJava3CallAdapterFactory(null, true); } /** * Returns an instance which creates synchronous observables that do not operate on any scheduler * by default. Applying {@code subscribeOn(..)} will change the scheduler on which the HTTP calls * are made. */ public static RxJava3CallAdapterFactory createSynchronous() { return new RxJava3CallAdapterFactory(null, false); } /** * Returns an instance which creates synchronous observables that {@code subscribeOn(..)} the * supplied {@code scheduler} by default. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static RxJava3CallAdapterFactory createWithScheduler(Scheduler scheduler) { if (scheduler == null) throw new NullPointerException("scheduler == null"); return new RxJava3CallAdapterFactory(scheduler, false); } private final @Nullable Scheduler scheduler; private final boolean isAsync; private RxJava3CallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) { this.scheduler = scheduler; this.isAsync = isAsync; } @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { Class rawType = getRawType(returnType); if (rawType == Completable.class) { // Completable is not parameterized (which is what the rest of this method deals with) so it // can only be created with a single configuration. return new RxJava3CallAdapter( Void.class, scheduler, isAsync, false, true, false, false, false, true); } boolean isFlowable = rawType == Flowable.class; boolean isSingle = rawType == Single.class; boolean isMaybe = rawType == Maybe.class; if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) { return null; } boolean isResult = false; boolean isBody = false; Type responseType; if (!(returnType instanceof ParameterizedType)) { String name = isFlowable ? "Flowable" : isSingle ? "Single" : isMaybe ? "Maybe" : "Observable"; throw new IllegalStateException( name + " return type must be parameterized" + " as " + name + " or " + name + ""); } Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType); Class rawObservableType = getRawType(observableType); if (rawObservableType == Response.class) { if (!(observableType instanceof ParameterizedType)) { throw new IllegalStateException( "Response must be parameterized" + " as Response or Response"); } responseType = getParameterUpperBound(0, (ParameterizedType) observableType); } else if (rawObservableType == Result.class) { if (!(observableType instanceof ParameterizedType)) { throw new IllegalStateException( "Result must be parameterized" + " as Result or Result"); } responseType = getParameterUpperBound(0, (ParameterizedType) observableType); isResult = true; } else { responseType = observableType; isBody = true; } return new RxJava3CallAdapter( responseType, scheduler, isAsync, isResult, isBody, isFlowable, isSingle, isMaybe, false); } } ================================================ FILE: retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.adapter.rxjava3; ================================================ FILE: retrofit-adapters/rxjava3/src/main/resources/META-INF/proguard/retrofit2-rxjava3-adapter.pro ================================================ # Keep generic signature of RxJava3 (R8 full mode strips signatures from non-kept items). # It's necessary to add the explicit rule for Result as it could be used as a nested return type like `Observable>` -keep,allowoptimization,allowshrinking,allowobfuscation class retrofit2.adapter.rxjava3.Result ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/AsyncTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.observers.TestObserver; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; import okhttp3.Dispatcher; import okhttp3.OkHttpClient; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.adapter.rxjava3.CompletableThrowingTest.ForwardingCompletableObserver; import retrofit2.http.GET; public final class AsyncTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Completable completable(); } private Service service; private final List uncaughtExceptions = new ArrayList<>(); @Before public void setUp() { ExecutorService executorService = Executors.newCachedThreadPool( r -> { Thread thread = new Thread(r); thread.setUncaughtExceptionHandler((t, e) -> uncaughtExceptions.add(e)); return thread; }); OkHttpClient client = new OkHttpClient.Builder().dispatcher(new Dispatcher(executorService)).build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .client(client) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @After public void tearDown() { assertTrue("Uncaught exceptions: " + uncaughtExceptions, uncaughtExceptions.isEmpty()); } @Test public void success() throws InterruptedException { TestObserver observer = new TestObserver<>(); service.completable().subscribe(observer); assertFalse(observer.await(1, SECONDS)); server.enqueue(new MockResponse()); observer.await(1, SECONDS); observer.assertComplete(); } @Test public void failure() throws InterruptedException { TestObserver observer = new TestObserver<>(); service.completable().subscribe(observer); assertFalse(observer.await(1, SECONDS)); server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); observer.await(1, SECONDS); observer.assertError(IOException.class); } @Test public void throwingInOnCompleteDeliveredToPlugin() throws InterruptedException { server.enqueue(new MockResponse()); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference errorRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } latch.countDown(); }); TestObserver observer = new TestObserver<>(); final RuntimeException e = new RuntimeException(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onComplete() { throw e; } }); latch.await(1, SECONDS); assertThat(errorRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() throws InterruptedException { server.enqueue(new MockResponse().setResponseCode(404)); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } latch.countDown(); }); TestObserver observer = new TestObserver<>(); final RuntimeException e = new RuntimeException(); final AtomicReference errorRef = new AtomicReference<>(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onError(Throwable throwable) { errorRef.set(throwable); throw e; } }); latch.await(1, SECONDS); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void bodyThrowingFatalInOnErrorPropagates() throws InterruptedException { server.enqueue(new MockResponse().setResponseCode(404)); final CountDownLatch latch = new CountDownLatch(1); TestObserver observer = new TestObserver<>(); final Error e = new OutOfMemoryError("Not real"); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onError(Throwable throwable) { throw e; } }); latch.await(1, SECONDS); assertEquals(1, uncaughtExceptions.size()); assertSame(e, uncaughtExceptions.remove(0)); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/CancelDisposeTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.disposables.Disposable; import java.util.List; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CancelDisposeTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Observable go(); } private final OkHttpClient client = new OkHttpClient(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .callFactory(client) .build(); service = retrofit.create(Service.class); } @Test public void disposeCancelsCall() { Disposable disposable = service.go().subscribe(); List calls = client.dispatcher().runningCalls(); assertEquals(1, calls.size()); disposable.dispose(); assertTrue(calls.get(0).isCanceled()); } @SuppressWarnings("ResultOfMethodCallIgnored") @Test public void disposeBeforeEnqueueDoesNotEnqueue() { service.go().test(true); List calls = client.dispatcher().runningCalls(); assertEquals(0, calls.size()); } @Test public void cancelDoesNotDispose() { Disposable disposable = service.go().subscribe(); List calls = client.dispatcher().runningCalls(); assertEquals(1, calls.size()); calls.get(0).cancel(); assertFalse(disposable.isDisposed()); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/CancelDisposeTestSync.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static org.junit.Assert.assertEquals; import io.reactivex.rxjava3.core.Observable; import okhttp3.OkHttpClient; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CancelDisposeTestSync { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Observable go(); } private final OkHttpClient client = new OkHttpClient(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .callFactory(client) .build(); service = retrofit.create(Service.class); } @SuppressWarnings("ResultOfMethodCallIgnored") @Test public void disposeBeforeExecuteDoesNotEnqueue() { service.go().test(true); assertEquals(0, server.getRequestCount()); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/CompletableTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.rxjava3.core.Completable; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CompletableTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingCompletableObserver.Rule observerRule = new RecordingCompletableObserver.Rule(); interface Service { @GET("/") Completable completable(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void completableSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingCompletableObserver observer = observerRule.create(); service.completable().subscribe(observer); observer.assertComplete(); } @Test public void completableSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingCompletableObserver observer = observerRule.create(); service.completable().subscribe(observer); // Required for backwards compatibility. observer.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void completableFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingCompletableObserver observer = observerRule.create(); service.completable().subscribe(observer); observer.assertError(IOException.class); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Completable observable = service.completable(); RecordingCompletableObserver observer1 = observerRule.create(); observable.subscribe(observer1); observer1.assertComplete(); RecordingCompletableObserver observer2 = observerRule.create(); observable.subscribe(observer2); observer2.assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/CompletableThrowingTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.CompletableObserver; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CompletableThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingCompletableObserver.Rule observerRule = new RecordingCompletableObserver.Rule(); interface Service { @GET("/") Completable completable(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void throwingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference errorRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } }); RecordingCompletableObserver observer = observerRule.create(); final RuntimeException e = new RuntimeException(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onComplete() { throw e; } }); assertThat(errorRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference pluginRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!pluginRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); // Don't swallow secondary errors! } }); RecordingCompletableObserver observer = observerRule.create(); final RuntimeException e = new RuntimeException(); final AtomicReference errorRef = new AtomicReference<>(); service .completable() .subscribe( new ForwardingCompletableObserver(observer) { @Override public void onError(Throwable throwable) { errorRef.set(throwable); throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) pluginRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } abstract static class ForwardingCompletableObserver implements CompletableObserver { private final CompletableObserver delegate; ForwardingCompletableObserver(CompletableObserver delegate) { this.delegate = delegate; } @Override public void onSubscribe(Disposable disposable) { delegate.onSubscribe(disposable); } @Override public void onComplete() { delegate.onComplete(); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/CompletableWithSchedulerTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Retrofit; import retrofit2.http.GET; public final class CompletableWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingCompletableObserver.Rule observerRule = new RecordingCompletableObserver.Rule(); interface Service { @GET("/") Completable completable(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addCallAdapterFactory(RxJava3CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void completableUsesScheduler() { server.enqueue(new MockResponse()); RecordingCompletableObserver observer = observerRule.create(); service.completable().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/FlowableTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.rxjava3.core.Flowable; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class FlowableTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Flowable body(); @GET("/") Flowable> response(); @GET("/") Flowable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSubscriber subscriber = subscriberRule.create(); service.body().subscribe(subscriber); subscriber.assertValue("Hi").assertComplete(); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber subscriber = subscriberRule.create(); service.body().subscribe(subscriber); // Required for backwards compatibility. subscriber.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber subscriber = subscriberRule.create(); service.body().subscribe(subscriber); subscriber.assertError(IOException.class); } @Test public void responseSuccess200() { server.enqueue(new MockResponse()); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().subscribe(subscriber); assertThat(subscriber.takeValue().isSuccessful()).isTrue(); subscriber.assertComplete(); } @Test public void responseSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().subscribe(subscriber); assertThat(subscriber.takeValue().isSuccessful()).isFalse(); subscriber.assertComplete(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber> subscriber = subscriberRule.create(); service.response().subscribe(subscriber); subscriber.assertError(IOException.class); } @Test public void resultSuccess200() { server.enqueue(new MockResponse()); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().subscribe(subscriber); Result result = subscriber.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isTrue(); subscriber.assertComplete(); } @Test public void resultSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().subscribe(subscriber); Result result = subscriber.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isFalse(); subscriber.assertComplete(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSubscriber> subscriber = subscriberRule.create(); service.result().subscribe(subscriber); Result result = subscriber.takeValue(); assertThat(result.isError()).isTrue(); assertThat(result.error()).isInstanceOf(IOException.class); subscriber.assertComplete(); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Flowable observable = service.body(); RecordingSubscriber subscriber1 = subscriberRule.create(); observable.subscribe(subscriber1); subscriber1.assertValue("Hi").assertComplete(); RecordingSubscriber subscriber2 = subscriberRule.create(); observable.subscribe(subscriber2); subscriber2.assertValue("Hey").assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/FlowableThrowingTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class FlowableThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Flowable body(); @GET("/") Flowable> response(); @GET("/") Flowable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .safeSubscribe( new ForwardingSubscriber(subscriber) { @Override public void onNext(String value) { throw e; } }); subscriber.assertError(e); } @Test public void bodyThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingSubscriber(subscriber) { @Override public void onComplete() { throw e; } }); subscriber.assertAnyValue(); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber subscriber = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingSubscriber(subscriber) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .safeSubscribe( new ForwardingSubscriber>(subscriber) { @Override public void onNext(Response value) { throw e; } }); subscriber.assertError(e); } @Test public void responseThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingSubscriber>(subscriber) { @Override public void onComplete() { throw e; } }); subscriber.assertAnyValue(); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber> subscriber = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingSubscriber>(subscriber) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .safeSubscribe( new ForwardingSubscriber>(subscriber) { @Override public void onNext(Result value) { throw e; } }); subscriber.assertError(e); } @Test public void resultThrowingInOnCompletedDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingSubscriber>(subscriber) { @Override public void onComplete() { throw e; } }); subscriber.assertAnyValue(); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSubscriber> subscriber = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .safeSubscribe( new ForwardingSubscriber>(subscriber) { @Override public void onNext(Result value) { // The only way to trigger onError for a result is if onNext throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } private abstract static class ForwardingSubscriber implements Subscriber { private final Subscriber delegate; ForwardingSubscriber(Subscriber delegate) { this.delegate = delegate; } @Override public void onSubscribe(Subscription subscription) { delegate.onSubscribe(subscription); } @Override public void onNext(T value) { delegate.onNext(value); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } @Override public void onComplete() { delegate.onComplete(); } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/FlowableWithSchedulerTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class FlowableWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSubscriber.Rule subscriberRule = new RecordingSubscriber.Rule(); interface Service { @GET("/") Flowable body(); @GET("/") Flowable> response(); @GET("/") Flowable> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse()); RecordingSubscriber subscriber = subscriberRule.create(); service.body().subscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertComplete(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse()); RecordingSubscriber subscriber = subscriberRule.create(); service.response().subscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertComplete(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse()); RecordingSubscriber subscriber = subscriberRule.create(); service.result().subscribe(subscriber); subscriber.assertNoEvents(); scheduler.triggerActions(); subscriber.assertAnyValue().assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/MaybeTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.rxjava3.core.Maybe; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class MaybeTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingMaybeObserver.Rule observerRule = new RecordingMaybeObserver.Rule(); interface Service { @GET("/") Maybe body(); @GET("/") Maybe> response(); @GET("/") Maybe> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingMaybeObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertValue("Hi"); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingMaybeObserver observer = observerRule.create(); service.body().subscribe(observer); // Required for backwards compatibility. observer.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingMaybeObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertError(IOException.class); } @Test public void responseSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingMaybeObserver> observer = observerRule.create(); service.response().subscribe(observer); Response response = observer.takeValue(); assertThat(response.isSuccessful()).isTrue(); } @Test public void responseSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingMaybeObserver> observer = observerRule.create(); service.response().subscribe(observer); assertThat(observer.takeValue().isSuccessful()).isFalse(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingMaybeObserver> observer = observerRule.create(); service.response().subscribe(observer); observer.assertError(IOException.class); } @Test public void resultSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingMaybeObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isTrue(); } @Test public void resultSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingMaybeObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isFalse(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingMaybeObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isTrue(); assertThat(result.error()).isInstanceOf(IOException.class); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Maybe observable = service.body(); RecordingMaybeObserver observer1 = observerRule.create(); observable.subscribe(observer1); observer1.assertValue("Hi"); RecordingMaybeObserver observer2 = observerRule.create(); observable.subscribe(observer2); observer2.assertValue("Hey"); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/MaybeThrowingTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.rxjava3.core.Maybe; import io.reactivex.rxjava3.core.MaybeObserver; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class MaybeThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingMaybeObserver.Rule subscriberRule = new RecordingMaybeObserver.Rule(); interface Service { @GET("/") Maybe body(); @GET("/") Maybe> response(); @GET("/") Maybe> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onSuccess(String value) { throw e; } }); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Response value) { throw e; } }); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver> observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { throw e; } }); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Ignore("Single's contract is onNext|onError so we have no way of triggering this case") @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingMaybeObserver> observer = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { // The only way to trigger onError for Result is if onSuccess throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } private abstract static class ForwardingObserver implements MaybeObserver { private final MaybeObserver delegate; ForwardingObserver(MaybeObserver delegate) { this.delegate = delegate; } @Override public void onSubscribe(Disposable disposable) { delegate.onSubscribe(disposable); } @Override public void onSuccess(T value) { delegate.onSuccess(value); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } @Override public void onComplete() { delegate.onComplete(); } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/MaybeWithSchedulerTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Maybe; import io.reactivex.rxjava3.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class MaybeWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingMaybeObserver.Rule observerRule = new RecordingMaybeObserver.Rule(); interface Service { @GET("/") Maybe body(); @GET("/") Maybe> response(); @GET("/") Maybe> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse()); RecordingMaybeObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse()); RecordingMaybeObserver observer = observerRule.create(); service.response().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse()); RecordingMaybeObserver observer = observerRule.create(); service.result().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/ObservableTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class ObservableTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingObserver.Rule observerRule = new RecordingObserver.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertValue("Hi").assertComplete(); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingObserver observer = observerRule.create(); service.body().subscribe(observer); // Required for backwards compatibility. observer.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertError(IOException.class); } @Test public void responseSuccess200() { server.enqueue(new MockResponse()); RecordingObserver> observer = observerRule.create(); service.response().subscribe(observer); assertThat(observer.takeValue().isSuccessful()).isTrue(); observer.assertComplete(); } @Test public void responseSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingObserver> observer = observerRule.create(); service.response().subscribe(observer); assertThat(observer.takeValue().isSuccessful()).isFalse(); observer.assertComplete(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingObserver> observer = observerRule.create(); service.response().subscribe(observer); observer.assertError(IOException.class); } @Test public void resultSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isTrue(); observer.assertComplete(); } @Test public void resultSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isFalse(); observer.assertComplete(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isTrue(); assertThat(result.error()).isInstanceOf(IOException.class); observer.assertComplete(); } @Test public void observableAssembly() { try { final Observable justMe = Observable.just("me"); RxJavaPlugins.setOnObservableAssembly(f -> justMe); assertThat(service.body()).isEqualTo(justMe); } finally { RxJavaPlugins.reset(); } } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Observable observable = service.body(); RecordingObserver observer1 = observerRule.create(); observable.subscribe(observer1); observer1.assertValue("Hi").assertComplete(); RecordingObserver observer2 = observerRule.create(); observable.subscribe(observer2); observer2.assertValue("Hey").assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/ObservableThrowingTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class ObservableThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingObserver.Rule subscriberRule = new RecordingObserver.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingObserver observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onNext(String value) { throw e; } }); observer.assertError(e); } @Test public void bodyThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onComplete() { throw e; } }); observer.assertAnyValue(); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onNext(Response value) { throw e; } }); observer.assertError(e); } @Test public void responseThrowingInOnCompleteDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onComplete() { throw e; } }); observer.assertAnyValue(); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver> observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnNextDeliveredToError() { server.enqueue(new MockResponse()); RecordingObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onNext(Result value) { throw e; } }); observer.assertError(e); } @Test public void resultThrowingInOnCompletedDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onComplete() { throw e; } }); observer.assertAnyValue(); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingObserver> observer = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onNext(Result value) { // The only way to trigger onError for a result is if onNext throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } private abstract static class ForwardingObserver implements Observer { private final Observer delegate; ForwardingObserver(Observer delegate) { this.delegate = delegate; } @Override public void onSubscribe(Disposable disposable) { delegate.onSubscribe(disposable); } @Override public void onNext(T value) { delegate.onNext(value); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } @Override public void onComplete() { delegate.onComplete(); } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/ObservableWithSchedulerTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class ObservableWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingObserver.Rule observerRule = new RecordingObserver.Rule(); interface Service { @GET("/") Observable body(); @GET("/") Observable> response(); @GET("/") Observable> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse()); RecordingObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue().assertComplete(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse()); RecordingObserver observer = observerRule.create(); service.response().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue().assertComplete(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse()); RecordingObserver observer = observerRule.create(); service.result().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue().assertComplete(); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/RecordingCompletableObserver.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.rxjava3.core.CompletableObserver; import io.reactivex.rxjava3.core.Notification; import io.reactivex.rxjava3.disposables.Disposable; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** A test {@link CompletableObserver} and JUnit rule which guarantees all events are asserted. */ final class RecordingCompletableObserver implements CompletableObserver { private final Deque> events = new ArrayDeque<>(); private RecordingCompletableObserver() {} @Override public void onSubscribe(Disposable disposable) {} @Override public void onComplete() { events.add(Notification.createOnComplete()); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public void assertComplete() { Notification notification = takeNotification(); assertWithMessage("Expected onCompleted event but was " + notification) .that(notification.isOnComplete()) .isTrue(); assertNoEvents(); } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public static final class Rule implements TestRule { final List subscribers = new ArrayList<>(); public RecordingCompletableObserver create() { RecordingCompletableObserver subscriber = new RecordingCompletableObserver(); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingCompletableObserver subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/RecordingMaybeObserver.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.rxjava3.core.MaybeObserver; import io.reactivex.rxjava3.core.Notification; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** A test {@link Observer} and JUnit rule which guarantees all events are asserted. */ final class RecordingMaybeObserver implements MaybeObserver { private final Deque> events = new ArrayDeque<>(); private RecordingMaybeObserver() {} @Override public void onSubscribe(Disposable disposable) {} @Override public void onSuccess(T value) { events.add(Notification.createOnNext(value)); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } @Override public void onComplete() { events.add(Notification.createOnComplete()); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public T takeValue() { Notification notification = takeNotification(); assertWithMessage("Expected onNext event but was " + notification) .that(notification.isOnNext()) .isTrue(); return notification.getValue(); } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public RecordingMaybeObserver assertAnyValue() { takeValue(); return this; } public RecordingMaybeObserver assertValue(T value) { assertThat(takeValue()).isEqualTo(value); return this; } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public static final class Rule implements TestRule { final List> subscribers = new ArrayList<>(); public RecordingMaybeObserver create() { RecordingMaybeObserver subscriber = new RecordingMaybeObserver<>(); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingMaybeObserver subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/RecordingObserver.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.rxjava3.core.Notification; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** A test {@link Observer} and JUnit rule which guarantees all events are asserted. */ final class RecordingObserver implements Observer { private final Deque> events = new ArrayDeque<>(); private RecordingObserver() {} @Override public void onSubscribe(Disposable disposable) {} @Override public void onNext(T value) { events.add(Notification.createOnNext(value)); } @Override public void onComplete() { events.add(Notification.createOnComplete()); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public T takeValue() { Notification notification = takeNotification(); assertWithMessage("Expected onNext event but was " + notification) .that(notification.isOnNext()) .isTrue(); return notification.getValue(); } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public RecordingObserver assertAnyValue() { takeValue(); return this; } public RecordingObserver assertValue(T value) { assertThat(takeValue()).isEqualTo(value); return this; } public void assertComplete() { Notification notification = takeNotification(); assertWithMessage("Expected onCompleted event but was " + notification) .that(notification.isOnComplete()) .isTrue(); assertNoEvents(); } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public static final class Rule implements TestRule { final List> subscribers = new ArrayList<>(); public RecordingObserver create() { RecordingObserver subscriber = new RecordingObserver<>(); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingObserver subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/RecordingSingleObserver.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.rxjava3.core.Notification; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.core.SingleObserver; import io.reactivex.rxjava3.disposables.Disposable; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** A test {@link Observer} and JUnit rule which guarantees all events are asserted. */ final class RecordingSingleObserver implements SingleObserver { private final Deque> events = new ArrayDeque<>(); private RecordingSingleObserver() {} @Override public void onSubscribe(Disposable disposable) {} @Override public void onSuccess(T value) { events.add(Notification.createOnNext(value)); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public T takeValue() { Notification notification = takeNotification(); assertWithMessage("Expected onNext event but was " + notification) .that(notification.isOnNext()) .isTrue(); return notification.getValue(); } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public RecordingSingleObserver assertAnyValue() { takeValue(); return this; } public RecordingSingleObserver assertValue(T value) { assertThat(takeValue()).isEqualTo(value); return this; } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public static final class Rule implements TestRule { final List> subscribers = new ArrayList<>(); public RecordingSingleObserver create() { RecordingSingleObserver subscriber = new RecordingSingleObserver<>(); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingSingleObserver subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/RecordingSubscriber.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import io.reactivex.rxjava3.core.FlowableSubscriber; import io.reactivex.rxjava3.core.Notification; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; /** A test {@link Subscriber} and JUnit rule which guarantees all events are asserted. */ final class RecordingSubscriber implements FlowableSubscriber { private final long initialRequest; private final Deque> events = new ArrayDeque<>(); private Subscription subscription; private RecordingSubscriber(long initialRequest) { this.initialRequest = initialRequest; } @Override public void onSubscribe(Subscription subscription) { this.subscription = subscription; subscription.request(initialRequest); } @Override public void onNext(T value) { events.add(Notification.createOnNext(value)); } @Override public void onComplete() { events.add(Notification.createOnComplete()); } @Override public void onError(Throwable e) { events.add(Notification.createOnError(e)); } private Notification takeNotification() { Notification notification = events.pollFirst(); if (notification == null) { throw new AssertionError("No event found!"); } return notification; } public T takeValue() { Notification notification = takeNotification(); assertWithMessage("Expected onNext event but was " + notification) .that(notification.isOnNext()) .isTrue(); return notification.getValue(); } public Throwable takeError() { Notification notification = takeNotification(); assertWithMessage("Expected onError event but was " + notification) .that(notification.isOnError()) .isTrue(); return notification.getError(); } public RecordingSubscriber assertAnyValue() { takeValue(); return this; } public RecordingSubscriber assertValue(T value) { assertThat(takeValue()).isEqualTo(value); return this; } public void assertComplete() { Notification notification = takeNotification(); assertWithMessage("Expected onCompleted event but was " + notification) .that(notification.isOnComplete()) .isTrue(); assertNoEvents(); } public void assertError(Throwable throwable) { assertThat(takeError()).isEqualTo(throwable); } public void assertError(Class errorClass) { assertError(errorClass, null); } public void assertError(Class errorClass, String message) { Throwable throwable = takeError(); assertThat(throwable).isInstanceOf(errorClass); if (message != null) { assertThat(throwable).hasMessageThat().isEqualTo(message); } assertNoEvents(); } public void assertNoEvents() { assertWithMessage("Unconsumed events found!").that(events).isEmpty(); } public void request(long amount) { if (subscription == null) { throw new IllegalStateException("onSubscribe has not been called yet. Did you subscribe()?"); } subscription.request(amount); } public static final class Rule implements TestRule { final List> subscribers = new ArrayList<>(); public RecordingSubscriber create() { return createWithInitialRequest(Long.MAX_VALUE); } public RecordingSubscriber createWithInitialRequest(long initialRequest) { RecordingSubscriber subscriber = new RecordingSubscriber<>(initialRequest); subscribers.add(subscriber); return subscriber; } @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { base.evaluate(); for (RecordingSubscriber subscriber : subscribers) { subscriber.assertNoEvents(); } } }; } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/ResultTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import java.io.IOException; import org.junit.Test; import retrofit2.Response; public final class ResultTest { @Test public void response() { Response response = Response.success("Hi"); Result result = Result.response(response); assertThat(result.isError()).isFalse(); assertThat(result.error()).isNull(); assertThat(result.response()).isSameInstanceAs(response); } @Test public void nullResponseThrows() { try { Result.response(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("response == null"); } } @Test public void error() { Throwable error = new IOException(); Result result = Result.error(error); assertThat(result.isError()).isTrue(); assertThat(result.error()).isSameInstanceAs(error); assertThat(result.response()).isNull(); } @Test public void nullErrorThrows() { try { Result.error(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("error == null"); } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/RxJava3CallAdapterFactoryTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.reflect.TypeToken; import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Maybe; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import org.junit.Before; import org.junit.Test; import retrofit2.CallAdapter; import retrofit2.Response; import retrofit2.Retrofit; public class RxJava3CallAdapterFactoryTest { private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; private final CallAdapter.Factory factory = RxJava3CallAdapterFactory.createSynchronous(); private Retrofit retrofit; @Before public void setUp() { retrofit = new Retrofit.Builder() .baseUrl("http://localhost:1") .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(factory) .build(); } @Test public void nullSchedulerThrows() { try { RxJava3CallAdapterFactory.createWithScheduler(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("scheduler == null"); } } @Test public void nonRxJavaTypeReturnsNull() { CallAdapter adapter = factory.get(String.class, NO_ANNOTATIONS, retrofit); assertThat(adapter).isNull(); } @Test public void responseTypes() { Type oBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(oBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(sBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(mBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fBodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(fBodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(oBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(sBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(mBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fBodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(fBodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(oBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type sBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(sBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type mBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(mBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type fBodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(fBodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type oResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(oResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(sResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(mResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fResponseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(fResponseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(oResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(sResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(mResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fResponseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(fResponseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(oResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(sResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(mResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fResultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(fResultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type oResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(oResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type sResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(sResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type mResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(mResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type fResultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(fResultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); } @Test public void rawBodyTypeThrows() { Type observableType = new TypeToken() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Observable return type must be parameterized as Observable or Observable"); } Type singleType = new TypeToken() {}.getType(); try { factory.get(singleType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Single return type must be parameterized as Single or Single"); } Type maybeType = new TypeToken() {}.getType(); try { factory.get(maybeType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Maybe return type must be parameterized as Maybe or Maybe"); } Type flowableType = new TypeToken() {}.getType(); try { factory.get(flowableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Flowable return type must be parameterized as Flowable or Flowable"); } } @Test public void rawResponseTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } Type singleType = new TypeToken>() {}.getType(); try { factory.get(singleType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } Type maybeType = new TypeToken>() {}.getType(); try { factory.get(maybeType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } Type flowableType = new TypeToken>() {}.getType(); try { factory.get(flowableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } } @Test public void rawResultTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } Type singleType = new TypeToken>() {}.getType(); try { factory.get(singleType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } Type maybeType = new TypeToken>() {}.getType(); try { factory.get(maybeType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } Type flowableType = new TypeToken>() {}.getType(); try { factory.get(flowableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Result must be parameterized as Result or Result"); } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/RxJavaPluginsResetRule.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; final class RxJavaPluginsResetRule implements TestRule { @Override public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { RxJavaPlugins.reset(); try { base.evaluate(); } finally { RxJavaPlugins.reset(); } } }; } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/SingleTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.rxjava3.core.Single; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class SingleTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSingleObserver.Rule observerRule = new RecordingSingleObserver.Rule(); interface Service { @GET("/") Single body(); @GET("/") Single> response(); @GET("/") Single> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSingleObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertValue("Hi"); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSingleObserver observer = observerRule.create(); service.body().subscribe(observer); // Required for backwards compatibility. observer.assertError(HttpException.class, "HTTP 404 Client Error"); } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSingleObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertError(IOException.class); } @Test public void responseSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSingleObserver> observer = observerRule.create(); service.response().subscribe(observer); Response response = observer.takeValue(); assertThat(response.isSuccessful()).isTrue(); } @Test public void responseSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSingleObserver> observer = observerRule.create(); service.response().subscribe(observer); assertThat(observer.takeValue().isSuccessful()).isFalse(); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSingleObserver> observer = observerRule.create(); service.response().subscribe(observer); observer.assertError(IOException.class); } @Test public void resultSuccess200() { server.enqueue(new MockResponse().setBody("Hi")); RecordingSingleObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isTrue(); } @Test public void resultSuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); RecordingSingleObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isFalse(); assertThat(result.response().isSuccessful()).isFalse(); } @Test public void resultFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); RecordingSingleObserver> observer = observerRule.create(); service.result().subscribe(observer); Result result = observer.takeValue(); assertThat(result.isError()).isTrue(); assertThat(result.error()).isInstanceOf(IOException.class); } @Test public void subscribeTwice() { server.enqueue(new MockResponse().setBody("Hi")); server.enqueue(new MockResponse().setBody("Hey")); Single observable = service.body(); RecordingSingleObserver observer1 = observerRule.create(); observable.subscribe(observer1); observer1.assertValue("Hi"); RecordingSingleObserver observer2 = observerRule.create(); observable.subscribe(observer2); observer2.assertValue("Hey"); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/SingleThrowingTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import static com.google.common.truth.Truth.assertThat; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.SingleObserver; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.exceptions.CompositeException; import io.reactivex.rxjava3.exceptions.Exceptions; import io.reactivex.rxjava3.plugins.RxJavaPlugins; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class SingleThrowingTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final TestRule resetRule = new RxJavaPluginsResetRule(); @Rule public final RecordingSingleObserver.Rule subscriberRule = new RecordingSingleObserver.Rule(); interface Service { @GET("/") Single body(); @GET("/") Single> response(); @GET("/") Single> result(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous()) .build(); service = retrofit.create(Service.class); } @Test public void bodyThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onSuccess(String value) { throw e; } }); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void bodyThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setResponseCode(404)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .body() .subscribe( new ForwardingObserver(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void responseThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Response value) { throw e; } }); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Test public void responseThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver> observer = subscriberRule.create(); final AtomicReference errorRef = new AtomicReference<>(); final RuntimeException e = new RuntimeException(); service .response() .subscribe( new ForwardingObserver>(observer) { @Override public void onError(Throwable throwable) { if (!errorRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } throw e; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(errorRef.get(), e); } @Test public void resultThrowingInOnSuccessDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver> observer = subscriberRule.create(); final RuntimeException e = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { throw e; } }); assertThat(throwableRef.get()).hasCauseThat().isSameInstanceAs(e); } @Ignore("Single's contract is onNext|onError so we have no way of triggering this case") @Test public void resultThrowingInOnErrorDeliveredToPlugin() { server.enqueue(new MockResponse()); final AtomicReference throwableRef = new AtomicReference<>(); RxJavaPlugins.setErrorHandler( throwable -> { if (!throwableRef.compareAndSet(null, throwable)) { throw Exceptions.propagate(throwable); } }); RecordingSingleObserver> observer = subscriberRule.create(); final RuntimeException first = new RuntimeException(); final RuntimeException second = new RuntimeException(); service .result() .subscribe( new ForwardingObserver>(observer) { @Override public void onSuccess(Result value) { // The only way to trigger onError for Result is if onSuccess throws. throw first; } @Override public void onError(Throwable throwable) { throw second; } }); //noinspection ThrowableResultOfMethodCallIgnored CompositeException composite = (CompositeException) throwableRef.get(); assertThat(composite.getExceptions()).containsExactly(first, second); } private abstract static class ForwardingObserver implements SingleObserver { private final SingleObserver delegate; ForwardingObserver(SingleObserver delegate) { this.delegate = delegate; } @Override public void onSubscribe(Disposable disposable) { delegate.onSubscribe(disposable); } @Override public void onSuccess(T value) { delegate.onSuccess(value); } @Override public void onError(Throwable throwable) { delegate.onError(throwable); } } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/SingleWithSchedulerTest.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.schedulers.TestScheduler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; public final class SingleWithSchedulerTest { @Rule public final MockWebServer server = new MockWebServer(); @Rule public final RecordingSingleObserver.Rule observerRule = new RecordingSingleObserver.Rule(); interface Service { @GET("/") Single body(); @GET("/") Single> response(); @GET("/") Single> result(); } private final TestScheduler scheduler = new TestScheduler(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.createWithScheduler(scheduler)) .build(); service = retrofit.create(Service.class); } @Test public void bodyUsesScheduler() { server.enqueue(new MockResponse()); RecordingSingleObserver observer = observerRule.create(); service.body().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } @Test public void responseUsesScheduler() { server.enqueue(new MockResponse()); RecordingSingleObserver observer = observerRule.create(); service.response().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } @Test public void resultUsesScheduler() { server.enqueue(new MockResponse()); RecordingSingleObserver observer = observerRule.create(); service.result().subscribe(observer); observer.assertNoEvents(); scheduler.triggerActions(); observer.assertAnyValue(); } } ================================================ FILE: retrofit-adapters/rxjava3/src/test/java/retrofit2/adapter/rxjava3/StringConverterFactory.java ================================================ /* * Copyright (C) 2020 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.rxjava3; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; final class StringConverterFactory extends Converter.Factory { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return ResponseBody::string; } @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return value -> RequestBody.create(MediaType.get("text/plain"), value); } } ================================================ FILE: retrofit-adapters/scala/README.md ================================================ Scala Adapter ============= An `Adapter` for adapting Scala `Future`. Usage ----- Add `ScalaCallAdapterFactory` as a `Call` adapter when building your `Retrofit` instance: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .addCallAdapterFactory(ScalaCallAdapterFactory.create()) .build(); ``` Your service methods can now use `Future` as their return type. ```java interface MyService { @GET("/user") Future getUser(); } ``` Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 adapter-scala latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:adapter-scala:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=adapter-scala&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22adapter-scala%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-adapters/scala/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.scalaLibrary compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.guava testImplementation libs.okhttp.mockwebserver } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.adapter.scala' } } ================================================ FILE: retrofit-adapters/scala/gradle.properties ================================================ POM_ARTIFACT_ID=adapter-scala POM_NAME=Adapter: Scala POM_DESCRIPTION=A Retrofit CallAdapter for Scala's Future. ================================================ FILE: retrofit-adapters/scala/src/main/java/retrofit2/adapter/scala/BodyCallAdapter.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.scala; import java.lang.reflect.Type; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Callback; import retrofit2.HttpException; import retrofit2.Response; import scala.concurrent.Future; import scala.concurrent.Promise; final class BodyCallAdapter implements CallAdapter> { private final Type responseType; BodyCallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public Future adapt(Call call) { Promise promise = Promise.apply(); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { if (response.isSuccessful()) { promise.success(response.body()); } else { promise.failure(new HttpException(response)); } } @Override public void onFailure(Call call, Throwable t) { promise.failure(t); } }); return promise.future(); } } ================================================ FILE: retrofit-adapters/scala/src/main/java/retrofit2/adapter/scala/ResponseCallAdapter.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.scala; import java.lang.reflect.Type; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Callback; import retrofit2.Response; import scala.concurrent.Future; import scala.concurrent.Promise; final class ResponseCallAdapter implements CallAdapter>> { private final Type responseType; ResponseCallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public Future> adapt(Call call) { Promise> promise = Promise.apply(); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { promise.success(response); } @Override public void onFailure(Call call, Throwable t) { promise.failure(t); } }); return promise.future(); } } ================================================ FILE: retrofit-adapters/scala/src/main/java/retrofit2/adapter/scala/ScalaCallAdapterFactory.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.scala; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.CallAdapter; import retrofit2.Response; import retrofit2.Retrofit; import scala.concurrent.Future; /** * A {@linkplain CallAdapter.Factory call adapter} which creates Scala futures. * *

Adding this class to {@link Retrofit} allows you to return {@link Future} from service * methods. * *


 * interface MyService {
 *   @GET("user/me")
 *   Future<User> getUser()
 * }
 * 
* * There are two configurations supported for the {@code Future} type parameter: * *
    *
  • Direct body (e.g., {@code Future}) returns the deserialized body for 2XX responses, * sets {@link retrofit2.HttpException HttpException} errors for non-2XX responses, and sets * {@link IOException} for network errors. *
  • Response wrapped body (e.g., {@code Future>}) returns a {@link Response} * object for all HTTP responses and sets {@link IOException} for network errors *
*/ public final class ScalaCallAdapterFactory extends CallAdapter.Factory { public static ScalaCallAdapterFactory create() { return new ScalaCallAdapterFactory(); } private ScalaCallAdapterFactory() {} @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != Future.class) { return null; } if (!(returnType instanceof ParameterizedType)) { throw new IllegalStateException( "Future return type must be parameterized as Future or Future"); } Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType); if (getRawType(innerType) != Response.class) { // Generic type is not Response. Use it for body-only adapter. return new BodyCallAdapter<>(innerType); } if (!(innerType instanceof ParameterizedType)) { throw new IllegalStateException( "Response must be parameterized as Response or Response"); } Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType); return new ResponseCallAdapter<>(responseType); } } ================================================ FILE: retrofit-adapters/scala/src/main/java/retrofit2/adapter/scala/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.adapter.scala; ================================================ FILE: retrofit-adapters/scala/src/test/java/retrofit2/adapter/scala/FutureTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.scala; import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.SECONDS; import static okhttp3.mockwebserver.SocketPolicy.DISCONNECT_AFTER_REQUEST; import static org.junit.Assert.fail; import java.io.IOException; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.HttpException; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; import scala.concurrent.Await; import scala.concurrent.Future; import scala.concurrent.duration.Duration; public final class FutureTest { @Rule public final MockWebServer server = new MockWebServer(); interface Service { @GET("/") Future body(); @GET("/") Future> response(); } private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(ScalaCallAdapterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void bodySuccess200() throws Exception { server.enqueue(new MockResponse().setBody("Hi")); Future future = service.body(); String result = Await.result(future, Duration.create(5, SECONDS)); assertThat(result).isEqualTo("Hi"); } @Test public void bodySuccess404() { server.enqueue(new MockResponse().setResponseCode(404)); Future future = service.body(); try { Await.result(future, Duration.create(5, SECONDS)); fail(); } catch (Exception e) { assertThat(e).isInstanceOf(HttpException.class); // Required for backwards compatibility. assertThat(e).isInstanceOf(retrofit2.HttpException.class); assertThat(e).hasMessageThat().isEqualTo("HTTP 404 Client Error"); } } @Test public void bodyFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); Future future = service.body(); try { Await.result(future, Duration.create(5, SECONDS)); fail(); } catch (Exception e) { assertThat(e).isInstanceOf(IOException.class); } } @Test public void responseSuccess200() throws Exception { server.enqueue(new MockResponse().setBody("Hi")); Future> future = service.response(); Response response = Await.result(future, Duration.create(5, SECONDS)); assertThat(response.isSuccessful()).isTrue(); assertThat(response.body()).isEqualTo("Hi"); } @Test public void responseSuccess404() throws Exception { server.enqueue(new MockResponse().setResponseCode(404).setBody("Hi")); Future> future = service.response(); Response response = Await.result(future, Duration.create(5, SECONDS)); assertThat(response.isSuccessful()).isFalse(); assertThat(response.errorBody().string()).isEqualTo("Hi"); } @Test public void responseFailure() { server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AFTER_REQUEST)); Future> future = service.response(); try { Await.result(future, Duration.create(5, SECONDS)); fail(); } catch (Exception e) { assertThat(e).isInstanceOf(IOException.class); } } } ================================================ FILE: retrofit-adapters/scala/src/test/java/retrofit2/adapter/scala/ScalaCallAdapterFactoryTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.scala; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.reflect.TypeToken; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.CallAdapter; import retrofit2.Response; import retrofit2.Retrofit; import scala.concurrent.Future; public final class ScalaCallAdapterFactoryTest { private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; @Rule public final MockWebServer server = new MockWebServer(); private final CallAdapter.Factory factory = ScalaCallAdapterFactory.create(); private Retrofit retrofit; @Before public void setUp() { retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new StringConverterFactory()) .addCallAdapterFactory(factory) .build(); } @Test public void responseType() { Type bodyClass = new TypeToken>() {}.getType(); assertThat(factory.get(bodyClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type bodyWildcard = new TypeToken>() {}.getType(); assertThat(factory.get(bodyWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type bodyGeneric = new TypeToken>>() {}.getType(); assertThat(factory.get(bodyGeneric, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(new TypeToken>() {}.getType()); Type responseClass = new TypeToken>>() {}.getType(); assertThat(factory.get(responseClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type responseWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(responseWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type resultClass = new TypeToken>>() {}.getType(); assertThat(factory.get(resultClass, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); Type resultWildcard = new TypeToken>>() {}.getType(); assertThat(factory.get(resultWildcard, NO_ANNOTATIONS, retrofit).responseType()) .isEqualTo(String.class); } @Test public void nonListenableFutureReturnsNull() { CallAdapter adapter = factory.get(String.class, NO_ANNOTATIONS, retrofit); assertThat(adapter).isNull(); } @Test public void rawTypeThrows() { Type observableType = new TypeToken() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo( "Future return type must be parameterized as Future or Future"); } } @Test public void rawResponseTypeThrows() { Type observableType = new TypeToken>() {}.getType(); try { factory.get(observableType, NO_ANNOTATIONS, retrofit); fail(); } catch (IllegalStateException e) { assertThat(e) .hasMessageThat() .isEqualTo("Response must be parameterized as Response or Response"); } } } ================================================ FILE: retrofit-adapters/scala/src/test/java/retrofit2/adapter/scala/StringConverterFactory.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.adapter.scala; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; final class StringConverterFactory extends Converter.Factory { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return ResponseBody::string; } @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return value -> RequestBody.create(MediaType.get("text/plain"), value); } } ================================================ FILE: retrofit-bom/build.gradle ================================================ import com.vanniktech.maven.publish.JavaPlatform apply plugin: 'java-platform' apply plugin: 'com.vanniktech.maven.publish' mavenPublishing { configure(new JavaPlatform()) } dependencies { constraints { rootProject.subprojects { subproject -> subproject.plugins.withId('com.vanniktech.maven.publish') { // Exclude self project from BOM. if (subproject != this.project) { api subproject } } } } } ================================================ FILE: retrofit-bom/gradle.properties ================================================ POM_ARTIFACT_ID=retrofit-bom POM_NAME=Retrofit BOM POM_DESCRIPTION=A BOM for managing Retrofit dependencies. ================================================ FILE: retrofit-converters/README.md ================================================ Retrofit Converters =================== Retrofit ships with support for OkHttp's `RequestBody` and `ResponseBody` types but the library is content-format agnostic. The child modules contained herein are additional converters for other popular formats. To use, supply an instance of your desired converter when building your `Retrofit` instance. ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com") .addConverterFactory(GsonConverterFactory.create()) .build(); ``` ================================================ FILE: retrofit-converters/gson/README.md ================================================ Gson Converter ============== A `Converter` which uses [Gson][1] for serialization to and from JSON. A default `Gson` instance will be created or one can be configured and passed to the `GsonConverterFactory` to further control the serialization. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-gson latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-gson:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/google/gson [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-gson&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-gson%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/gson/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.gson compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver testImplementation libs.testParameterInjector } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.gson' } } ================================================ FILE: retrofit-converters/gson/gradle.properties ================================================ POM_ARTIFACT_ID=converter-gson POM_NAME=Converter: Gson POM_DESCRIPTION=A Retrofit Converter which uses Gson for serialization. ================================================ FILE: retrofit-converters/gson/src/main/java/retrofit2/converter/gson/GsonConverterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.gson; import com.google.gson.Gson; import com.google.gson.TypeAdapter; import com.google.gson.reflect.TypeToken; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; /** * A {@linkplain Converter.Factory converter} which uses Gson for JSON. * *

Because Gson is so flexible in the types it supports, this converter assumes that it can * handle all types. If you are mixing JSON serialization with something else (such as protocol * buffers), you must {@linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this * instance} last to allow the other converters a chance to see their types. */ public final class GsonConverterFactory extends Converter.Factory { /** * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and * decoding from JSON (when no charset is specified by a header) will use UTF-8. */ public static GsonConverterFactory create() { return create(new Gson()); } /** * Create an instance using {@code gson} for conversion. Encoding to JSON and decoding from JSON * (when no charset is specified by a header) will use UTF-8. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static GsonConverterFactory create(Gson gson) { if (gson == null) throw new NullPointerException("gson == null"); return new GsonConverterFactory(gson, false); } private final Gson gson; private final boolean streaming; private GsonConverterFactory(Gson gson, boolean streaming) { this.gson = gson; this.streaming = streaming; } /** * Return a new factory which streams serialization of request messages to bytes on the HTTP thread * This is either the calling thread for {@link Call#execute()}, or one of OkHttp's background * threads for {@link Call#enqueue}. Response bytes are always converted to message instances on * one of OkHttp's background threads. */ public GsonConverterFactory withStreaming() { return new GsonConverterFactory(gson, true); } @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter adapter = gson.getAdapter(TypeToken.get(type)); return new GsonResponseBodyConverter<>(gson, adapter); } @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter adapter = gson.getAdapter(TypeToken.get(type)); return new GsonRequestBodyConverter<>(gson, adapter, streaming); } } ================================================ FILE: retrofit-converters/gson/src/main/java/retrofit2/converter/gson/GsonRequestBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.gson; import static java.nio.charset.StandardCharsets.UTF_8; 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 okhttp3.MediaType; import okhttp3.RequestBody; import okio.Buffer; import okio.BufferedSink; import retrofit2.Converter; final class GsonRequestBodyConverter implements Converter { static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8"); private final Gson gson; private final TypeAdapter adapter; private final boolean streaming; GsonRequestBodyConverter(Gson gson, TypeAdapter adapter, boolean streaming) { this.gson = gson; this.adapter = adapter; this.streaming = streaming; } @Override public RequestBody convert(T value) throws IOException { if (streaming) { return new GsonStreamingRequestBody<>(gson, adapter, value); } Buffer buffer = new Buffer(); writeJson(buffer, gson, adapter, value); return RequestBody.create(MEDIA_TYPE, buffer.readByteString()); } static void writeJson(BufferedSink sink, Gson gson, TypeAdapter adapter, T value) throws IOException { Writer writer = new OutputStreamWriter(sink.outputStream(), UTF_8); JsonWriter jsonWriter = gson.newJsonWriter(writer); adapter.write(jsonWriter, value); jsonWriter.close(); } } ================================================ FILE: retrofit-converters/gson/src/main/java/retrofit2/converter/gson/GsonResponseBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.gson; import com.google.gson.Gson; import com.google.gson.JsonIOException; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import java.io.IOException; import okhttp3.ResponseBody; import retrofit2.Converter; final class GsonResponseBodyConverter implements Converter { private final Gson gson; private final TypeAdapter adapter; GsonResponseBodyConverter(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 { T result = adapter.read(jsonReader); if (jsonReader.peek() != JsonToken.END_DOCUMENT) { throw new JsonIOException("JSON document was not fully consumed."); } return result; } finally { value.close(); } } } ================================================ FILE: retrofit-converters/gson/src/main/java/retrofit2/converter/gson/GsonStreamingRequestBody.java ================================================ /* * Copyright (C) 2025 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.gson; import static retrofit2.converter.gson.GsonRequestBodyConverter.MEDIA_TYPE; import static retrofit2.converter.gson.GsonRequestBodyConverter.writeJson; import com.google.gson.Gson; import com.google.gson.TypeAdapter; import java.io.IOException; import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; final class GsonStreamingRequestBody extends RequestBody { private final Gson gson; private final TypeAdapter adapter; private final T value; public GsonStreamingRequestBody(Gson gson, TypeAdapter adapter, T value) { this.gson = gson; this.adapter = adapter; this.value = value; } @Override public MediaType contentType() { return MEDIA_TYPE; } @Override public void writeTo(BufferedSink sink) throws IOException { writeJson(sink, gson, adapter, value); } } ================================================ FILE: retrofit-converters/gson/src/main/java/retrofit2/converter/gson/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.converter.gson; ================================================ FILE: retrofit-converters/gson/src/test/java/retrofit2/converter/gson/GsonConverterFactoryTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.gson; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonIOException; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import com.google.testing.junit.testparameterinjector.TestParameter; import com.google.testing.junit.testparameterinjector.TestParameterInjector; import java.io.EOFException; import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; @RunWith(TestParameterInjector.class) public final class GsonConverterFactoryTest { interface AnInterface { String getName(); } static class AnImplementation implements AnInterface { private final String theName; AnImplementation(String name) { theName = name; } @Override public String getName() { return theName; } } static final class ErroringValue { static final TypeAdapter BROKEN_ADAPTER = new TypeAdapter() { @Override public void write(JsonWriter out, ErroringValue value) throws IOException { throw new EOFException("oops!"); } @Override @SuppressWarnings("CheckReturnValue") public ErroringValue read(JsonReader reader) throws IOException { reader.beginObject(); reader.nextName(); String theName = reader.nextString(); return new ErroringValue(theName); } }; final String theName; ErroringValue(String theName) { this.theName = theName; } } static class AnInterfaceAdapter extends TypeAdapter { @Override public void write(JsonWriter jsonWriter, AnInterface anInterface) throws IOException { jsonWriter.beginObject(); jsonWriter.name("name").value(anInterface.getName()); jsonWriter.endObject(); } @Override public AnInterface read(JsonReader jsonReader) throws IOException { jsonReader.beginObject(); String name = null; while (jsonReader.peek() != JsonToken.END_OBJECT) { switch (jsonReader.nextName()) { case "name": name = jsonReader.nextString(); break; } } jsonReader.endObject(); return new AnImplementation(name); } } interface Service { @POST("/") Call anImplementation(@Body AnImplementation impl); @POST("/") Call anInterface(@Body AnInterface impl); @GET("/") Call readErroringValue(); @POST("/") Call writeErroringValue(@Body ErroringValue value); } @Rule public final MockWebServer server = new MockWebServer(); private final boolean streaming; private final Service service; public GsonConverterFactoryTest(@TestParameter boolean streaming) { this.streaming = streaming; Gson gson = new GsonBuilder() .registerTypeAdapter(AnInterface.class, new AnInterfaceAdapter()) .registerTypeAdapter(ErroringValue.class, ErroringValue.BROKEN_ADAPTER) .setLenient() .create(); GsonConverterFactory factory = GsonConverterFactory.create(gson); if (streaming) { factory = factory.withStreaming(); } Retrofit retrofit = new Retrofit.Builder() // .baseUrl(server.url("/")) // .addConverterFactory(factory) // .build(); service = retrofit.create(Service.class); } @Test public void anInterface() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{\"name\":\"value\"}")); Call call = service.anInterface(new AnImplementation("value")); Response response = call.execute(); AnInterface body = response.body(); assertThat(body.getName()).isEqualTo("value"); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readUtf8()).isEqualTo("{\"name\":\"value\"}"); assertThat(request.getHeader("Content-Type")).isEqualTo("application/json; charset=UTF-8"); } @Test public void anImplementation() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{\"theName\":\"value\"}")); Call call = service.anImplementation(new AnImplementation("value")); Response response = call.execute(); AnImplementation body = response.body(); assertThat(body.theName).isEqualTo("value"); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readUtf8()).isEqualTo("{\"theName\":\"value\"}"); assertThat(request.getHeader("Content-Type")).isEqualTo("application/json; charset=UTF-8"); } @Test public void serializeUsesConfiguration() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{}")); service.anImplementation(new AnImplementation(null)).execute(); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readUtf8()).isEqualTo("{}"); // Null value was not serialized. assertThat(request.getHeader("Content-Type")).isEqualTo("application/json; charset=UTF-8"); } @Test public void deserializeUsesConfiguration() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{/* a comment! */}")); Response response = service.anImplementation(new AnImplementation("value")).execute(); assertThat(response.body().getName()).isNull(); } @Test public void requireFullResponseDocumentConsumption() throws Exception { server.enqueue(new MockResponse().setBody("{\"theName\":\"value\"}")); Call call = service.readErroringValue(); try { call.execute(); fail(); } catch (JsonIOException e) { assertThat(e).hasMessageThat().isEqualTo("JSON document was not fully consumed."); } } @Test public void serializeIsStreamed() throws InterruptedException { assumeTrue(streaming); Call call = service.writeErroringValue(new ErroringValue("hi")); final AtomicReference throwableRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); // If streaming were broken, the call to enqueue would throw the exception synchronously. call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { throwableRef.set(t); latch.countDown(); } }); latch.await(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(EOFException.class); assertThat(throwable).hasMessageThat().isEqualTo("oops!"); } } ================================================ FILE: retrofit-converters/guava/README.md ================================================ Guava Converter =============== A `Converter` which supports [Guava][1]'s `Optional` by delegating to other converters for `T` and then wrapping it into `Optional`. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-guava latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-guava:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/google/guava [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-guava&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-guava%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/guava/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.guava compileOnly libs.findBugsAnnotations testImplementation libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.guava' } } ================================================ FILE: retrofit-converters/guava/gradle.properties ================================================ POM_ARTIFACT_ID=converter-guava POM_NAME=Converter: Guava POM_DESCRIPTION=A Retrofit Converter for Guava's Optional type. ================================================ FILE: retrofit-converters/guava/src/main/java/retrofit/converter/guava/GuavaOptionalConverterFactory.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit.converter.guava; import com.google.common.base.Optional; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; /** * A {@linkplain Converter.Factory converter} for {@code Optional} which delegates to another * converter to deserialize {@code T} and then wraps it into {@link Optional}. */ public final class GuavaOptionalConverterFactory extends Converter.Factory { public static GuavaOptionalConverterFactory create() { return new GuavaOptionalConverterFactory(); } private GuavaOptionalConverterFactory() {} @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (getRawType(type) != Optional.class) { return null; } Type innerType = getParameterUpperBound(0, (ParameterizedType) type); Converter delegate = retrofit.responseBodyConverter(innerType, annotations); return new OptionalConverter<>(delegate); } } ================================================ FILE: retrofit-converters/guava/src/main/java/retrofit/converter/guava/OptionalConverter.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit.converter.guava; import com.google.common.base.Optional; import java.io.IOException; import okhttp3.ResponseBody; import retrofit2.Converter; final class OptionalConverter implements Converter> { private final Converter delegate; OptionalConverter(Converter delegate) { this.delegate = delegate; } @Override public Optional convert(ResponseBody value) throws IOException { return Optional.fromNullable(delegate.convert(value)); } } ================================================ FILE: retrofit-converters/guava/src/main/java/retrofit/converter/guava/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit.converter.guava; ================================================ FILE: retrofit-converters/guava/src/main/resources/META-INF/proguard/retrofit2-guava-converter.pro ================================================ # Keep generic signature of Optional (R8 full mode strips signatures from non-kept items). -keep,allowoptimization,allowshrinking,allowobfuscation class com.google.common.base.Optional ================================================ FILE: retrofit-converters/guava/src/test/java/retrofit/converter/guava/AlwaysNullConverterFactory.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit.converter.guava; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; final class AlwaysNullConverterFactory extends Converter.Factory { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return value -> null; } } ================================================ FILE: retrofit-converters/guava/src/test/java/retrofit/converter/guava/GuavaOptionalConverterFactoryTest.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit.converter.guava; import static com.google.common.truth.Truth.assertThat; import com.google.common.base.Optional; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; import retrofit2.http.GET; public final class GuavaOptionalConverterFactoryTest { interface Service { @GET("/") Call> optional(); @GET("/") Call object(); } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(GuavaOptionalConverterFactory.create()) .addConverterFactory(new AlwaysNullConverterFactory()) .build(); service = retrofit.create(Service.class); } @Test public void optional() throws IOException { server.enqueue(new MockResponse()); Optional optional = service.optional().execute().body(); assertThat(optional).isNotNull(); assertThat(optional.isPresent()).isFalse(); } @Test public void onlyMatchesOptional() throws IOException { server.enqueue(new MockResponse()); Object body = service.object().execute().body(); assertThat(body).isNull(); } @Test public void delegates() throws IOException { final Object object = new Object(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new Converter.Factory() { @Nullable @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (getRawType(type) != Object.class) { return null; } return value -> object; } }) .addConverterFactory(GuavaOptionalConverterFactory.create()) .build(); server.enqueue(new MockResponse()); Service service = retrofit.create(Service.class); Optional optional = service.optional().execute().body(); assertThat(optional).isNotNull(); assertThat(optional.get()).isSameInstanceAs(object); } } ================================================ FILE: retrofit-converters/jackson/README.md ================================================ Jackson Converter ================= A `Converter` which uses [Jackson][1] for serialization. A default `ObjectMapper` instance will be created or one can be configured and passed to the `JacksonConverterFactory` construction to further control the serialization. Multi-Format Support -------------------- This converter is not limited to JSON. Jackson supports many data formats through its [dataformat modules][4], and this converter works with any of them by supplying the appropriate mapper and media type. ### XML ```java import com.fasterxml.jackson.dataformat.xml.XmlMapper; Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .addConverterFactory( JacksonConverterFactory.create( new XmlMapper(), MediaType.get("application/xml"))) .build(); ``` Requires the `jackson-dataformat-xml` dependency. ### CBOR ```java import com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper; Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .addConverterFactory( JacksonConverterFactory.create( new CBORMapper(), MediaType.get("application/cbor"))) .build(); ``` Requires the `jackson-dataformat-cbor` dependency. ### Other Formats The same pattern applies to other Jackson dataformat modules such as YAML, Smile, Ion, and more. Simply use the corresponding mapper (e.g., `YAMLMapper`, `SmileMapper`) and media type. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-jackson latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-jackson:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/FasterXML/jackson [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-jackson&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-jackson%22 [4]: https://github.com/FasterXML/jackson#data-format-modules [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/jackson/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.jacksonDatabind compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver testImplementation libs.testParameterInjector testImplementation libs.jacksonDataformatCbor } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.jackson' } } ================================================ FILE: retrofit-converters/jackson/gradle.properties ================================================ POM_ARTIFACT_ID=converter-jackson POM_NAME=Converter: Jackson POM_DESCRIPTION=A Retrofit Converter which uses Jackson for serialization. ================================================ FILE: retrofit-converters/jackson/src/main/java/retrofit2/converter/jackson/JacksonConverterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jackson; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; import com.fasterxml.jackson.databind.ObjectWriter; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; /** * A {@linkplain Converter.Factory converter} which uses Jackson. * *

Because Jackson is so flexible in the types it supports, this converter assumes that it can * handle all types. If you are mixing JSON serialization with something else (such as protocol * buffers), you must {@linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this * instance} last to allow the other converters a chance to see their types. */ public final class JacksonConverterFactory extends Converter.Factory { private static final MediaType DEFAULT_MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8"); /** Create an instance using a default {@link ObjectMapper} instance for conversion. */ public static JacksonConverterFactory create() { return new JacksonConverterFactory(new ObjectMapper(), DEFAULT_MEDIA_TYPE, false); } /** Create an instance using {@code mapper} for conversion. */ public static JacksonConverterFactory create(ObjectMapper mapper) { return create(mapper, DEFAULT_MEDIA_TYPE); } /** Create an instance using {@code mapper} and {@code mediaType} for conversion. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static JacksonConverterFactory create(ObjectMapper mapper, MediaType mediaType) { if (mapper == null) throw new NullPointerException("mapper == null"); if (mediaType == null) throw new NullPointerException("mediaType == null"); return new JacksonConverterFactory(mapper, mediaType, false); } private final ObjectMapper mapper; private final MediaType mediaType; private final boolean streaming; private JacksonConverterFactory(ObjectMapper mapper, MediaType mediaType, boolean streaming) { this.mapper = mapper; this.mediaType = mediaType; this.streaming = streaming; } /** * Return a new factory which streams serialization of request messages to bytes on the HTTP thread * This is either the calling thread for {@link Call#execute()}, or one of OkHttp's background * threads for {@link Call#enqueue}. Response bytes are always converted to message instances on * one of OkHttp's background threads. */ public JacksonConverterFactory withStreaming() { return new JacksonConverterFactory(mapper, mediaType, true); } @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { JavaType javaType = mapper.getTypeFactory().constructType(type); ObjectReader reader = mapper.readerFor(javaType); return new JacksonResponseBodyConverter<>(reader); } @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { JavaType javaType = mapper.getTypeFactory().constructType(type); ObjectWriter writer = mapper.writerFor(javaType); return new JacksonRequestBodyConverter<>(writer, mediaType, streaming); } } ================================================ FILE: retrofit-converters/jackson/src/main/java/retrofit2/converter/jackson/JacksonRequestBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jackson; import com.fasterxml.jackson.databind.ObjectWriter; import java.io.IOException; import okhttp3.MediaType; import okhttp3.RequestBody; import retrofit2.Converter; final class JacksonRequestBodyConverter implements Converter { private final ObjectWriter adapter; private final MediaType mediaType; private final boolean streaming; JacksonRequestBodyConverter(ObjectWriter adapter, MediaType mediaType, boolean streaming) { this.adapter = adapter; this.mediaType = mediaType; this.streaming = streaming; } @Override public RequestBody convert(T value) throws IOException { if (streaming) { return new JacksonStreamingRequestBody(adapter, value, mediaType); } byte[] bytes = adapter.writeValueAsBytes(value); return RequestBody.create(mediaType, bytes); } } ================================================ FILE: retrofit-converters/jackson/src/main/java/retrofit2/converter/jackson/JacksonResponseBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jackson; import com.fasterxml.jackson.databind.ObjectReader; import java.io.IOException; import okhttp3.ResponseBody; import retrofit2.Converter; final class JacksonResponseBodyConverter implements Converter { private final ObjectReader adapter; JacksonResponseBodyConverter(ObjectReader adapter) { this.adapter = adapter; } @Override public T convert(ResponseBody value) throws IOException { try { return adapter.readValue(value.byteStream()); } finally { value.close(); } } } ================================================ FILE: retrofit-converters/jackson/src/main/java/retrofit2/converter/jackson/JacksonStreamingRequestBody.java ================================================ /* * Copyright (C) 2025 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jackson; import com.fasterxml.jackson.databind.ObjectWriter; import java.io.IOException; import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; final class JacksonStreamingRequestBody extends RequestBody { private final ObjectWriter adapter; private final Object value; private final MediaType mediaType; public JacksonStreamingRequestBody(ObjectWriter adapter, Object value, MediaType mediaType) { this.adapter = adapter; this.value = value; this.mediaType = mediaType; } @Override public MediaType contentType() { return mediaType; } @Override public void writeTo(BufferedSink sink) throws IOException { adapter.writeValue(sink.outputStream(), value); } } ================================================ FILE: retrofit-converters/jackson/src/main/java/retrofit2/converter/jackson/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.converter.jackson; ================================================ FILE: retrofit-converters/jackson/src/test/java/retrofit2/converter/jackson/JacksonCborConverterFactoryTest.java ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jackson; import static com.google.common.truth.Truth.assertThat; import com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper; import java.io.IOException; import okhttp3.MediaType; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okio.Buffer; import okio.ByteString; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.POST; public class JacksonCborConverterFactoryTest { static class IntWrapper { public int value; public IntWrapper(int v) { value = v; } protected IntWrapper() {} } interface Service { @POST("/") Call post(@Body IntWrapper person); } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( JacksonConverterFactory.create(new CBORMapper(), MediaType.get("application/cbor"))) .build(); service = retrofit.create(Service.class); } @Test public void post() throws IOException, InterruptedException { server.enqueue( new MockResponse() .setBody(new Buffer().write(ByteString.decodeHex("bf6576616c7565182aff")))); Call call = service.post(new IntWrapper(12)); Response response = call.execute(); assertThat(response.body().value).isEqualTo(42); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readByteString()) .isEqualTo(ByteString.decodeHex("bf6576616c75650cff")); assertThat(request.getHeader("Content-Type")).isEqualTo("application/cbor"); } } ================================================ FILE: retrofit-converters/jackson/src/test/java/retrofit2/converter/jackson/JacksonConverterFactoryTest.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jackson; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assume.assumeTrue; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.google.testing.junit.testparameterinjector.TestParameter; import com.google.testing.junit.testparameterinjector.TestParameterInjector; import java.io.EOFException; import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.POST; @RunWith(TestParameterInjector.class) public final class JacksonConverterFactoryTest { interface AnInterface { String getName(); } static class AnImplementation implements AnInterface { private String theName; AnImplementation() {} AnImplementation(String name) { theName = name; } @Override public String getName() { return theName; } } static class AnInterfaceSerializer extends StdSerializer { AnInterfaceSerializer() { super(AnInterface.class); } @Override public void serialize( AnInterface anInterface, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeStartObject(); jsonGenerator.writeFieldName("name"); jsonGenerator.writeString(anInterface.getName()); jsonGenerator.writeEndObject(); } } static class AnInterfaceDeserializer extends StdDeserializer { AnInterfaceDeserializer() { super(AnInterface.class); } @Override public AnInterface deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { if (jp.getCurrentToken() != JsonToken.START_OBJECT) { throw new AssertionError("Expected start object."); } String name = null; while (jp.nextToken() != JsonToken.END_OBJECT) { switch (jp.getCurrentName()) { case "name": name = jp.getValueAsString(); break; } } return new AnImplementation(name); } } static final class ErroringValue { final String theName; ErroringValue(String theName) { this.theName = theName; } } static final class ErroringValueSerializer extends StdSerializer { ErroringValueSerializer() { super(ErroringValue.class); } @Override public void serialize( ErroringValue erroringValue, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { throw new EOFException("oops!"); } } interface Service { @POST("/") Call anImplementation(@Body AnImplementation impl); @POST("/") Call anInterface(@Body AnInterface impl); @POST("/") Call erroringValue(@Body ErroringValue value); } @Rule public final MockWebServer server = new MockWebServer(); private final Service service; private final boolean streaming; public JacksonConverterFactoryTest(@TestParameter boolean streaming) { this.streaming = streaming; SimpleModule module = new SimpleModule(); module.addSerializer(AnInterface.class, new AnInterfaceSerializer()); module.addSerializer(ErroringValue.class, new ErroringValueSerializer()); module.addDeserializer(AnInterface.class, new AnInterfaceDeserializer()); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(module); mapper.configure(MapperFeature.AUTO_DETECT_GETTERS, false); mapper.configure(MapperFeature.AUTO_DETECT_SETTERS, false); mapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, false); mapper.setVisibilityChecker( mapper .getSerializationConfig() .getDefaultVisibilityChecker() .withFieldVisibility(JsonAutoDetect.Visibility.ANY)); JacksonConverterFactory factory = JacksonConverterFactory.create(mapper); if (streaming) { factory = factory.withStreaming(); } Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(factory).build(); service = retrofit.create(Service.class); } @Test public void anInterface() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{\"name\":\"value\"}")); Call call = service.anInterface(new AnImplementation("value")); Response response = call.execute(); AnInterface body = response.body(); assertThat(body.getName()).isEqualTo("value"); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readUtf8()).isEqualTo("{\"name\":\"value\"}"); assertThat(request.getHeader("Content-Type")).isEqualTo("application/json; charset=UTF-8"); } @Test public void anImplementation() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{\"theName\":\"value\"}")); Call call = service.anImplementation(new AnImplementation("value")); Response response = call.execute(); AnImplementation body = response.body(); assertThat(body.theName).isEqualTo("value"); RecordedRequest request = server.takeRequest(); // TODO figure out how to get Jackson to stop using AnInterface's serializer here. assertThat(request.getBody().readUtf8()).isEqualTo("{\"name\":\"value\"}"); assertThat(request.getHeader("Content-Type")).isEqualTo("application/json; charset=UTF-8"); } @Test public void serializeIsStreamed() throws InterruptedException { assumeTrue(streaming); Call call = service.erroringValue(new ErroringValue("hi")); final AtomicReference throwableRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); // If streaming were broken, the call to enqueue would throw the exception synchronously. call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { throwableRef.set(t); latch.countDown(); } }); latch.await(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(EOFException.class); assertThat(throwable).hasMessageThat().isEqualTo("oops!"); } } ================================================ FILE: retrofit-converters/java8/README.md ================================================ Java 8 Converter (Deprecated) ============================= A `Converter` which supports Java 8's `Optional` by delegating to other converters for `T` and then wrapping it into `Optional`. This converter is no longer needed. Support for `Optional` is built-in to Retrofit and now works without configuration. ================================================ FILE: retrofit-converters/java8/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver testImplementation libs.findBugsAnnotations } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.java8' } } ================================================ FILE: retrofit-converters/java8/gradle.properties ================================================ POM_ARTIFACT_ID=converter-java8 POM_NAME=Converter: Java 8 POM_DESCRIPTION=A Retrofit Converter for Java 8's Optional type. ================================================ FILE: retrofit-converters/java8/src/main/java/retrofit/converter/java8/Java8OptionalConverterFactory.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit.converter.java8; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Optional; import javax.annotation.Nullable; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; /** * @deprecated Retrofit includes support for Optional. This no longer needs to be added to the * Retrofit instance explicitly. *

A {@linkplain Converter.Factory converter} for {@code Optional} which delegates to * another converter to deserialize {@code T} and then wraps it into {@link Optional}. */ @Deprecated public final class Java8OptionalConverterFactory extends Converter.Factory { public static Java8OptionalConverterFactory create() { return new Java8OptionalConverterFactory(); } private Java8OptionalConverterFactory() {} @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (getRawType(type) != Optional.class) { return null; } Type innerType = getParameterUpperBound(0, (ParameterizedType) type); Converter delegate = retrofit.responseBodyConverter(innerType, annotations); return new OptionalConverter<>(delegate); } } ================================================ FILE: retrofit-converters/java8/src/main/java/retrofit/converter/java8/OptionalConverter.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit.converter.java8; import java.io.IOException; import java.util.Optional; import okhttp3.ResponseBody; import retrofit2.Converter; final class OptionalConverter implements Converter> { private final Converter delegate; OptionalConverter(Converter delegate) { this.delegate = delegate; } @Override public Optional convert(ResponseBody value) throws IOException { return Optional.ofNullable(delegate.convert(value)); } } ================================================ FILE: retrofit-converters/java8/src/main/java/retrofit/converter/java8/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit.converter.java8; ================================================ FILE: retrofit-converters/java8/src/test/java/retrofit/converter/java8/AlwaysNullConverterFactory.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit.converter.java8; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; final class AlwaysNullConverterFactory extends Converter.Factory { @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { return value -> null; } } ================================================ FILE: retrofit-converters/java8/src/test/java/retrofit/converter/java8/Java8OptionalConverterFactoryTest.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit.converter.java8; import static com.google.common.truth.Truth.assertThat; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Optional; import javax.annotation.Nullable; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; import retrofit2.http.GET; public final class Java8OptionalConverterFactoryTest { interface Service { @GET("/") Call> optional(); @GET("/") Call object(); } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(Java8OptionalConverterFactory.create()) .addConverterFactory(new AlwaysNullConverterFactory()) .build(); service = retrofit.create(Service.class); } @Test public void optional() throws IOException { server.enqueue(new MockResponse()); Optional optional = service.optional().execute().body(); assertThat(optional).isNotNull(); assertThat(optional.isPresent()).isFalse(); } @Test public void onlyMatchesOptional() throws IOException { server.enqueue(new MockResponse()); Object body = service.object().execute().body(); assertThat(body).isNull(); } @Test public void delegates() throws IOException { Object object = new Object(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new Converter.Factory() { @Nullable @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (getRawType(type) != Object.class) { return null; } return value -> object; } }) .addConverterFactory(Java8OptionalConverterFactory.create()) .build(); server.enqueue(new MockResponse()); Service service = retrofit.create(Service.class); Optional optional = service.optional().execute().body(); assertThat(optional).isNotNull(); assertThat(optional.get()).isSameInstanceAs(object); } } ================================================ FILE: retrofit-converters/jaxb/README.md ================================================ JAXB Converter ============== A `Converter` which uses [JAXB][1] for serialization to and from XML. A default `JAXBContext` instance will be created or one can be configured and passed to `JaxbConverterFactory.create()` to further control the serialization. **Note that JAXB does not work on Android.** Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-jaxb latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-jaxb:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/eclipse-ee4j/jaxb-ri [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-jaxb&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-jaxb%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/jaxb/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.jaxbApi compileOnly libs.findBugsAnnotations testImplementation libs.jaxbImpl testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver testImplementation libs.findBugsAnnotations } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.jaxb' } } ================================================ FILE: retrofit-converters/jaxb/gradle.properties ================================================ POM_ARTIFACT_ID=converter-jaxb POM_NAME=Converter: JAXB POM_DESCRIPTION=A Retrofit Converter which uses JAXB for serialization. ================================================ FILE: retrofit-converters/jaxb/src/main/java/retrofit2/converter/jaxb/JaxbConverterFactory.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.annotation.XmlRootElement; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; /** * A {@linkplain Converter.Factory converter} which uses JAXB for XML. All validation events are * ignored. */ public final class JaxbConverterFactory extends Converter.Factory { static final MediaType XML = MediaType.get("application/xml; charset=utf-8"); /** Create an instance using a default {@link JAXBContext} instance for conversion. */ public static JaxbConverterFactory create() { return new JaxbConverterFactory(null); } /** Create an instance using {@code context} for conversion. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static JaxbConverterFactory create(JAXBContext context) { if (context == null) throw new NullPointerException("context == null"); return new JaxbConverterFactory(context); } /** If null, a new JAXB context will be created for each type to be converted. */ private final @Nullable JAXBContext context; private JaxbConverterFactory(@Nullable JAXBContext context) { this.context = context; } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (type instanceof Class && ((Class) type).isAnnotationPresent(XmlRootElement.class)) { return new JaxbRequestConverter<>(contextForType((Class) type), (Class) type); } return null; } @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (type instanceof Class && ((Class) type).isAnnotationPresent(XmlRootElement.class)) { return new JaxbResponseConverter<>(contextForType((Class) type), (Class) type); } return null; } private JAXBContext contextForType(Class type) { try { return context != null ? context : JAXBContext.newInstance(type); } catch (JAXBException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: retrofit-converters/jaxb/src/main/java/retrofit2/converter/jaxb/JaxbRequestConverter.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb; import java.io.IOException; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import okhttp3.RequestBody; import okio.Buffer; import retrofit2.Converter; final class JaxbRequestConverter implements Converter { final XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance(); final JAXBContext context; final Class type; JaxbRequestConverter(JAXBContext context, Class type) { this.context = context; this.type = type; } @Override public RequestBody convert(final T value) throws IOException { Buffer buffer = new Buffer(); try { Marshaller marshaller = context.createMarshaller(); XMLStreamWriter xmlWriter = xmlOutputFactory.createXMLStreamWriter( buffer.outputStream(), JaxbConverterFactory.XML.charset().name()); marshaller.marshal(value, xmlWriter); } catch (JAXBException | XMLStreamException e) { throw new RuntimeException(e); } return RequestBody.create(JaxbConverterFactory.XML, buffer.readByteString()); } } ================================================ FILE: retrofit-converters/jaxb/src/main/java/retrofit2/converter/jaxb/JaxbResponseConverter.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb; import java.io.IOException; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import okhttp3.ResponseBody; import retrofit2.Converter; final class JaxbResponseConverter implements Converter { final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); final JAXBContext context; final Class type; JaxbResponseConverter(JAXBContext context, Class type) { this.context = context; this.type = type; // Prevent XML External Entity attacks (XXE). xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); } @Override public T convert(ResponseBody value) throws IOException { try { Unmarshaller unmarshaller = context.createUnmarshaller(); XMLStreamReader streamReader = xmlInputFactory.createXMLStreamReader(value.charStream()); return unmarshaller.unmarshal(streamReader, type).getValue(); } catch (JAXBException | XMLStreamException e) { throw new RuntimeException(e); } finally { value.close(); } } } ================================================ FILE: retrofit-converters/jaxb/src/main/java/retrofit2/converter/jaxb/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.converter.jaxb; ================================================ FILE: retrofit-converters/jaxb/src/test/java/retrofit2/converter/jaxb/Contact.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "contact") final class Contact { @XmlElement(required = true) public final String name; @XmlElement(name = "phone_number") public final List phone_numbers; @SuppressWarnings("unused") // Used by JAXB. private Contact() { this("", new ArrayList()); } public Contact(String name, List phoneNumbers) { this.name = name; this.phone_numbers = phoneNumbers; } @Override public boolean equals(Object o) { return o instanceof Contact && ((Contact) o).name.equals(name) && ((Contact) o).phone_numbers.equals(phone_numbers); } @Override public int hashCode() { return Arrays.asList(name, phone_numbers).hashCode(); } } ================================================ FILE: retrofit-converters/jaxb/src/test/java/retrofit2/converter/jaxb/JaxbConverterFactoryTest.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb; import static com.google.common.truth.Truth.assertThat; import static junit.framework.TestCase.fail; import java.util.Collections; import javax.xml.bind.JAXBContext; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; public final class JaxbConverterFactoryTest { static final Contact SAMPLE_CONTACT = new Contact("Jenny", Collections.singletonList(new PhoneNumber("867-5309", Type.MOBILE))); static final String SAMPLE_CONTACT_XML = "" + "" + "" + "Jenny" + "" + "867-5309" + "" + ""; interface Service { @POST("/") Call postXml(@Body Contact contact); @GET("/") Call getXml(); } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { JaxbConverterFactory factory = JaxbConverterFactory.create(); Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(factory).build(); service = retrofit.create(Service.class); } @Test public void xmlRequestBody() throws Exception { server.enqueue(new MockResponse()); Call call = service.postXml(SAMPLE_CONTACT); call.execute(); RecordedRequest request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("application/xml; charset=utf-8"); assertThat(request.getBody().readUtf8()).isEqualTo(SAMPLE_CONTACT_XML); } @Test public void xmlResponseBody() throws Exception { server.enqueue(new MockResponse().setBody(SAMPLE_CONTACT_XML)); Call call = service.getXml(); Response response = call.execute(); assertThat(response.body()).isEqualTo(SAMPLE_CONTACT); } @Test public void characterEncoding() throws Exception { server.enqueue( new MockResponse() .setBody( "" + "" + "" + "Бронтозавр \uD83E\uDD95 ティラノサウルス・レックス 🦖" + "")); Call call = service.getXml(); Response response = call.execute(); assertThat(response.body().name) .isEqualTo("Бронтозавр \uD83E\uDD95 ティラノサウルス・レックス \uD83E\uDD96"); } @Test public void userSuppliedJaxbContext() throws Exception { JAXBContext context = JAXBContext.newInstance(Contact.class); JaxbConverterFactory factory = JaxbConverterFactory.create(context); Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(factory).build(); service = retrofit.create(Service.class); server.enqueue(new MockResponse()); Call call = service.postXml(SAMPLE_CONTACT); call.execute(); RecordedRequest request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("application/xml; charset=utf-8"); assertThat(request.getBody().readUtf8()).isEqualTo(SAMPLE_CONTACT_XML); } @Test public void malformedXml() throws Exception { server.enqueue(new MockResponse().setBody("This is not XML")); Call call = service.getXml(); try { call.execute(); fail(); } catch (RuntimeException expected) { assertThat(expected).hasMessageThat().contains("ParseError"); } } @Test public void unrecognizedField() throws Exception { server.enqueue( new MockResponse() .setBody( "" + "" + "" + "Jenny" + "21" + "" + "867-5309" + "" + "")); Call call = service.getXml(); Response response = call.execute(); assertThat(response.body().name).isEqualTo("Jenny"); } @Test public void externalEntity() throws Exception { server.enqueue( new MockResponse() .setBody( "" + "" + "" + "]>" + "" + "&secret;" + "")); server.enqueue(new MockResponse().setBody("hello")); Call call = service.getXml(); try { Response response = call.execute(); response.body(); fail(); } catch (RuntimeException expected) { assertThat(expected).hasMessageThat().contains("ParseError"); } assertThat(server.getRequestCount()).isEqualTo(1); } @Test public void externalDtd() throws Exception { server.enqueue( new MockResponse() .setBody( "" + "" + "" + "" + "&secret;" + "")); server.enqueue( new MockResponse() .setBody( "" + "\n" + "\n" + "")); Call call = service.getXml(); try { Response response = call.execute(); response.body(); fail(); } catch (RuntimeException expected) { assertThat(expected).hasMessageThat().contains("ParseError"); } assertThat(server.getRequestCount()).isEqualTo(1); } } ================================================ FILE: retrofit-converters/jaxb/src/test/java/retrofit2/converter/jaxb/PhoneNumber.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb; import java.util.Arrays; import javax.annotation.Nullable; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; final class PhoneNumber { @XmlElement(required = true) public final String number; @XmlAttribute public final Type type; @SuppressWarnings("unused") // Used by JAXB. private PhoneNumber() { this("", Type.OTHER); } PhoneNumber(String number, @Nullable Type type) { this.number = number; this.type = type; } @Override public boolean equals(Object o) { return o instanceof PhoneNumber && ((PhoneNumber) o).number.equals(number) && ((PhoneNumber) o).type.equals(type); } @Override public int hashCode() { return Arrays.asList(number, type).hashCode(); } } ================================================ FILE: retrofit-converters/jaxb/src/test/java/retrofit2/converter/jaxb/Type.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb; enum Type { OTHER, MOBILE } ================================================ FILE: retrofit-converters/jaxb3/README.md ================================================ JAXB Converter ============== A `Converter` which uses [JAXB][1] 3.x (`jakarta.xml.bind` package) for serialization to and from XML. A default `JAXBContext` instance will be created or one can be configured and passed to `JaxbConverterFactory.create()` to further control the serialization. **Note that JAXB does not work on Android.** Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-jaxb3 latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-jaxb3:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/eclipse-ee4j/jaxb-ri [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-jaxb3&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-jaxb%322 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/jaxb3/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.jaxb3Api compileOnly libs.findBugsAnnotations testImplementation libs.jaxb3Impl testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver testImplementation libs.findBugsAnnotations } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.jaxb3' } } ================================================ FILE: retrofit-converters/jaxb3/gradle.properties ================================================ POM_ARTIFACT_ID=converter-jaxb3 POM_NAME=Converter: JAXB3 POM_DESCRIPTION=A Retrofit Converter which uses JAXB 3 for serialization. ================================================ FILE: retrofit-converters/jaxb3/src/main/java/retrofit2/converter/jaxb3/JaxbConverterFactory.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb3; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.annotation.XmlRootElement; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; /** * A {@linkplain Converter.Factory converter} which uses JAXB for XML. All validation events are * ignored. */ public final class JaxbConverterFactory extends Converter.Factory { static final MediaType XML = MediaType.get("application/xml; charset=utf-8"); /** Create an instance using a default {@link JAXBContext} instance for conversion. */ public static JaxbConverterFactory create() { return new JaxbConverterFactory(null); } /** Create an instance using {@code context} for conversion. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static JaxbConverterFactory create(JAXBContext context) { if (context == null) throw new NullPointerException("context == null"); return new JaxbConverterFactory(context); } /** If null, a new JAXB context will be created for each type to be converted. */ private final @Nullable JAXBContext context; private JaxbConverterFactory(@Nullable JAXBContext context) { this.context = context; } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (type instanceof Class && ((Class) type).isAnnotationPresent(XmlRootElement.class)) { return new JaxbRequestConverter<>(contextForType((Class) type), (Class) type); } return null; } @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (type instanceof Class && ((Class) type).isAnnotationPresent(XmlRootElement.class)) { return new JaxbResponseConverter<>(contextForType((Class) type), (Class) type); } return null; } private JAXBContext contextForType(Class type) { try { return context != null ? context : JAXBContext.newInstance(type); } catch (JAXBException e) { throw new IllegalArgumentException(e); } } } ================================================ FILE: retrofit-converters/jaxb3/src/main/java/retrofit2/converter/jaxb3/JaxbRequestConverter.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb3; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.Marshaller; import java.io.IOException; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import okhttp3.RequestBody; import okio.Buffer; import retrofit2.Converter; final class JaxbRequestConverter implements Converter { final XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance(); final JAXBContext context; final Class type; JaxbRequestConverter(JAXBContext context, Class type) { this.context = context; this.type = type; } @Override public RequestBody convert(final T value) throws IOException { Buffer buffer = new Buffer(); try { Marshaller marshaller = context.createMarshaller(); XMLStreamWriter xmlWriter = xmlOutputFactory.createXMLStreamWriter( buffer.outputStream(), JaxbConverterFactory.XML.charset().name()); marshaller.marshal(value, xmlWriter); } catch (JAXBException | XMLStreamException e) { throw new RuntimeException(e); } return RequestBody.create(JaxbConverterFactory.XML, buffer.readByteString()); } } ================================================ FILE: retrofit-converters/jaxb3/src/main/java/retrofit2/converter/jaxb3/JaxbResponseConverter.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb3; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.Unmarshaller; import java.io.IOException; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import okhttp3.ResponseBody; import retrofit2.Converter; final class JaxbResponseConverter implements Converter { final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); final JAXBContext context; final Class type; JaxbResponseConverter(JAXBContext context, Class type) { this.context = context; this.type = type; // Prevent XML External Entity attacks (XXE). xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); } @Override public T convert(ResponseBody value) throws IOException { try { Unmarshaller unmarshaller = context.createUnmarshaller(); XMLStreamReader streamReader = xmlInputFactory.createXMLStreamReader(value.charStream()); return unmarshaller.unmarshal(streamReader, type).getValue(); } catch (JAXBException | XMLStreamException e) { throw new RuntimeException(e); } finally { value.close(); } } } ================================================ FILE: retrofit-converters/jaxb3/src/main/java/retrofit2/converter/jaxb3/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.converter.jaxb3; ================================================ FILE: retrofit-converters/jaxb3/src/test/java/retrofit2/converter/jaxb3/Contact.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb3; import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @XmlRootElement(name = "contact") final class Contact { @XmlElement(required = true) public final String name; @XmlElement(name = "phone_number") public final List phone_numbers; @SuppressWarnings("unused") // Used by JAXB. private Contact() { this("", new ArrayList()); } public Contact(String name, List phoneNumbers) { this.name = name; this.phone_numbers = phoneNumbers; } @Override public boolean equals(Object o) { return o instanceof Contact && ((Contact) o).name.equals(name) && ((Contact) o).phone_numbers.equals(phone_numbers); } @Override public int hashCode() { return Arrays.asList(name, phone_numbers).hashCode(); } } ================================================ FILE: retrofit-converters/jaxb3/src/test/java/retrofit2/converter/jaxb3/JaxbConverterFactoryTest.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb3; import static com.google.common.truth.Truth.assertThat; import static junit.framework.TestCase.fail; import jakarta.xml.bind.JAXBContext; import java.util.Collections; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; public final class JaxbConverterFactoryTest { static final Contact SAMPLE_CONTACT = new Contact("Jenny", Collections.singletonList(new PhoneNumber("867-5309", Type.MOBILE))); static final String SAMPLE_CONTACT_XML = "" + "" + "" + "Jenny" + "" + "867-5309" + "" + ""; interface Service { @POST("/") Call postXml(@Body Contact contact); @GET("/") Call getXml(); } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { JaxbConverterFactory factory = JaxbConverterFactory.create(); Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(factory).build(); service = retrofit.create(Service.class); } @Test public void xmlRequestBody() throws Exception { server.enqueue(new MockResponse()); Call call = service.postXml(SAMPLE_CONTACT); call.execute(); RecordedRequest request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("application/xml; charset=utf-8"); assertThat(request.getBody().readUtf8()).isEqualTo(SAMPLE_CONTACT_XML); } @Test public void xmlResponseBody() throws Exception { server.enqueue(new MockResponse().setBody(SAMPLE_CONTACT_XML)); Call call = service.getXml(); Response response = call.execute(); assertThat(response.body()).isEqualTo(SAMPLE_CONTACT); } @Test public void characterEncoding() throws Exception { server.enqueue( new MockResponse() .setBody( "" + "" + "" + "Бронтозавр \uD83E\uDD95 ティラノサウルス・レックス 🦖" + "")); Call call = service.getXml(); Response response = call.execute(); assertThat(response.body().name) .isEqualTo("Бронтозавр \uD83E\uDD95 ティラノサウルス・レックス \uD83E\uDD96"); } @Test public void userSuppliedJaxbContext() throws Exception { JAXBContext context = JAXBContext.newInstance(Contact.class); JaxbConverterFactory factory = JaxbConverterFactory.create(context); Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(factory).build(); service = retrofit.create(Service.class); server.enqueue(new MockResponse()); Call call = service.postXml(SAMPLE_CONTACT); call.execute(); RecordedRequest request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("application/xml; charset=utf-8"); assertThat(request.getBody().readUtf8()).isEqualTo(SAMPLE_CONTACT_XML); } @Test public void malformedXml() throws Exception { server.enqueue(new MockResponse().setBody("This is not XML")); Call call = service.getXml(); try { call.execute(); fail(); } catch (RuntimeException expected) { assertThat(expected).hasMessageThat().contains("ParseError"); } } @Test public void unrecognizedField() throws Exception { server.enqueue( new MockResponse() .setBody( "" + "" + "" + "Jenny" + "21" + "" + "867-5309" + "" + "")); Call call = service.getXml(); Response response = call.execute(); assertThat(response.body().name).isEqualTo("Jenny"); } @Test public void externalEntity() throws Exception { server.enqueue( new MockResponse() .setBody( "" + "" + "" + "]>" + "" + "&secret;" + "")); server.enqueue(new MockResponse().setBody("hello")); Call call = service.getXml(); try { Response response = call.execute(); response.body(); fail(); } catch (RuntimeException expected) { assertThat(expected).hasMessageThat().contains("ParseError"); } assertThat(server.getRequestCount()).isEqualTo(1); } @Test public void externalDtd() throws Exception { server.enqueue( new MockResponse() .setBody( "" + "" + "" + "" + "&secret;" + "")); server.enqueue( new MockResponse() .setBody( "" + "\n" + "\n" + "")); Call call = service.getXml(); try { Response response = call.execute(); response.body(); fail(); } catch (RuntimeException expected) { assertThat(expected).hasMessageThat().contains("ParseError"); } assertThat(server.getRequestCount()).isEqualTo(1); } } ================================================ FILE: retrofit-converters/jaxb3/src/test/java/retrofit2/converter/jaxb3/PhoneNumber.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb3; import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlElement; import java.util.Arrays; import javax.annotation.Nullable; final class PhoneNumber { @XmlElement(required = true) public final String number; @XmlAttribute public final Type type; @SuppressWarnings("unused") // Used by JAXB. private PhoneNumber() { this("", Type.OTHER); } PhoneNumber(String number, @Nullable Type type) { this.number = number; this.type = type; } @Override public boolean equals(Object o) { return o instanceof PhoneNumber && ((PhoneNumber) o).number.equals(number) && ((PhoneNumber) o).type.equals(type); } @Override public int hashCode() { return Arrays.asList(number, type).hashCode(); } } ================================================ FILE: retrofit-converters/jaxb3/src/test/java/retrofit2/converter/jaxb3/Type.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.jaxb3; enum Type { OTHER, MOBILE } ================================================ FILE: retrofit-converters/kotlinx-serialization/README.md ================================================ # kotlinx.serialization Converter A `Converter` which uses [kotlinx.serialization][1] for serialization. Given a `TextFormat` or `BinaryFormat`, call `asConverterFactory()` in order to create a `Converter.Factory`. You will need to supply a `MediaType` for use as the `Content-Type` header for request bodies. ```kotlin val retrofit = Retrofit.Builder() .baseUrl("https://example.com/") .addConverterFactory( Json.asConverterFactory( "application/json; charset=utf-8".toMediaType())) .build() ``` ## Download Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-kotlinx-serialization latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-kotlinx-serialization:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/Kotlin/kotlinx.serialization [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-kotlinx-serialization&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-kotlinx-serialization%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/kotlinx-serialization/build.gradle ================================================ apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'org.jetbrains.kotlin.plugin.serialization' apply plugin: 'com.vanniktech.maven.publish' apply plugin: 'org.jetbrains.dokka' dependencies { api projects.retrofit api libs.kotlinx.serialization.core testImplementation libs.junit testImplementation libs.okhttp.mockwebserver testImplementation libs.kotlinx.serialization.proto testImplementation libs.kotlinx.serialization.json } ================================================ FILE: retrofit-converters/kotlinx-serialization/gradle.properties ================================================ POM_ARTIFACT_ID=converter-kotlinx-serialization POM_NAME=Converter: kotlinx.serialization POM_DESCRIPTION=A Retrofit Converter which uses kotlinx.serialization for serialization. ================================================ FILE: retrofit-converters/kotlinx-serialization/src/main/java/retrofit2/converter/kotlinx/serialization/DeserializationStrategyConverter.kt ================================================ package retrofit2.converter.kotlinx.serialization import kotlinx.serialization.DeserializationStrategy import okhttp3.ResponseBody import retrofit2.Converter internal class DeserializationStrategyConverter( private val loader: DeserializationStrategy, private val serializer: Serializer ) : Converter { override fun convert(value: ResponseBody) = serializer.fromResponseBody(loader, value) } ================================================ FILE: retrofit-converters/kotlinx-serialization/src/main/java/retrofit2/converter/kotlinx/serialization/Factory.kt ================================================ @file:JvmName("KotlinSerializationConverterFactory") package retrofit2.converter.kotlinx.serialization import retrofit2.converter.kotlinx.serialization.Serializer.FromBytes import retrofit2.converter.kotlinx.serialization.Serializer.FromString import java.lang.reflect.Type import kotlinx.serialization.BinaryFormat import kotlinx.serialization.StringFormat import okhttp3.MediaType import okhttp3.RequestBody import okhttp3.ResponseBody import retrofit2.Converter import retrofit2.Retrofit internal class Factory( private val contentType: MediaType, private val serializer: Serializer ) : Converter.Factory() { @Suppress("RedundantNullableReturnType") // Retaining interface contract. override fun responseBodyConverter( type: Type, annotations: Array, retrofit: Retrofit ): Converter? { val loader = serializer.serializer(type) return DeserializationStrategyConverter(loader, serializer) } @Suppress("RedundantNullableReturnType") // Retaining interface contract. override fun requestBodyConverter( type: Type, parameterAnnotations: Array, methodAnnotations: Array, retrofit: Retrofit ): Converter<*, RequestBody>? { val saver = serializer.serializer(type) return SerializationStrategyConverter(contentType, saver, serializer) } } /** * Return a [Converter.Factory] which uses Kotlin serialization for string-based payloads. * * Because Kotlin serialization is so flexible in the types it supports, this converter assumes * that it can handle all types. If you are mixing this with something else, you must add this * instance last to allow the other converters a chance to see their types. */ @JvmName("create") fun StringFormat.asConverterFactory(contentType: MediaType): Converter.Factory { return Factory(contentType, FromString(this)) } /** * Return a [Converter.Factory] which uses Kotlin serialization for byte-based payloads. * * Because Kotlin serialization is so flexible in the types it supports, this converter assumes * that it can handle all types. If you are mixing this with something else, you must add this * instance last to allow the other converters a chance to see their types. */ @JvmName("create") fun BinaryFormat.asConverterFactory(contentType: MediaType): Converter.Factory { return Factory(contentType, FromBytes(this)) } ================================================ FILE: retrofit-converters/kotlinx-serialization/src/main/java/retrofit2/converter/kotlinx/serialization/SerializationStrategyConverter.kt ================================================ package retrofit2.converter.kotlinx.serialization import kotlinx.serialization.SerializationStrategy import okhttp3.MediaType import okhttp3.RequestBody import retrofit2.Converter internal class SerializationStrategyConverter( private val contentType: MediaType, private val saver: SerializationStrategy, private val serializer: Serializer ) : Converter { override fun convert(value: T) = serializer.toRequestBody(contentType, saver, value) } ================================================ FILE: retrofit-converters/kotlinx-serialization/src/main/java/retrofit2/converter/kotlinx/serialization/Serializer.kt ================================================ package retrofit2.converter.kotlinx.serialization import java.lang.reflect.Type import kotlinx.serialization.BinaryFormat import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialFormat import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.StringFormat import kotlinx.serialization.serializer import okhttp3.MediaType import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.ResponseBody internal sealed class Serializer { abstract fun fromResponseBody(loader: DeserializationStrategy, body: ResponseBody): T abstract fun toRequestBody(contentType: MediaType, saver: SerializationStrategy, value: T): RequestBody protected abstract val format: SerialFormat fun serializer(type: Type): KSerializer = format.serializersModule.serializer(type) class FromString(override val format: StringFormat) : Serializer() { override fun fromResponseBody(loader: DeserializationStrategy, body: ResponseBody): T { val string = body.string() return format.decodeFromString(loader, string) } override fun toRequestBody(contentType: MediaType, saver: SerializationStrategy, value: T): RequestBody { val string = format.encodeToString(saver, value) return string.toRequestBody(contentType) } } class FromBytes(override val format: BinaryFormat) : Serializer() { override fun fromResponseBody(loader: DeserializationStrategy, body: ResponseBody): T { val bytes = body.bytes() return format.decodeFromByteArray(loader, bytes) } override fun toRequestBody(contentType: MediaType, saver: SerializationStrategy, value: T): RequestBody { val bytes = format.encodeToByteArray(saver, value) return bytes.toRequestBody(contentType, 0, bytes.size) } } } ================================================ FILE: retrofit-converters/kotlinx-serialization/src/test/java/retrofit2/converter/kotlinx/serialization/KotlinSerializationConverterFactoryBytesTest.kt ================================================ package retrofit2.converter.kotlinx.serialization import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.Serializable import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoNumber import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaType import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import okio.Buffer import okio.ByteString import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test import retrofit2.Call import retrofit2.Retrofit import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST private val bobBytes = ByteString.of(0x0a, 0x03, 'B'.code.toByte(), 'o'.code.toByte(), 'b'.code.toByte()) @ExperimentalSerializationApi class KotlinSerializationConverterFactoryBytesTest { @get:Rule val server = MockWebServer() private lateinit var service: Service interface Service { @GET("/") fun deserialize(): Call @POST("/") fun serialize(@Body user: User): Call } @Serializable data class User(@ProtoNumber(1) val name: String) @Before fun setUp() { val contentType = "application/x-protobuf".toMediaType() val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ProtoBuf.asConverterFactory(contentType)) .build() service = retrofit.create(Service::class.java) } @Test fun deserialize() { server.enqueue(MockResponse().setBody(Buffer().write(bobBytes))) val user = service.deserialize().execute().body()!! assertEquals(User("Bob"), user) } @Test fun serialize() { server.enqueue(MockResponse()) service.serialize(User("Bob")).execute() val request = server.takeRequest() assertEquals(bobBytes, request.body.readByteString()) assertEquals("application/x-protobuf", request.headers["Content-Type"]) } } ================================================ FILE: retrofit-converters/kotlinx-serialization/src/test/java/retrofit2/converter/kotlinx/serialization/KotlinSerializationConverterFactoryStringTest.kt ================================================ package retrofit2.converter.kotlinx.serialization import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaType import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test import retrofit2.Call import retrofit2.Retrofit import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST class KotlinSerializationConverterFactoryStringTest { @get:Rule val server = MockWebServer() private lateinit var service: Service interface Service { @GET("/") fun deserialize(): Call @POST("/") fun serialize(@Body user: User): Call } @Serializable data class User(val name: String) @Before fun setUp() { val contentType = "application/json; charset=utf-8".toMediaType() val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(Json.asConverterFactory(contentType)) .build() service = retrofit.create(Service::class.java) } @Test fun deserialize() { server.enqueue(MockResponse().setBody("""{"name":"Bob"}""")) val user = service.deserialize().execute().body()!! assertEquals(User("Bob"), user) } @Test fun serialize() { server.enqueue(MockResponse()) service.serialize(User("Bob")).execute() val request = server.takeRequest() assertEquals("""{"name":"Bob"}""", request.body.readUtf8()) assertEquals("application/json; charset=utf-8", request.headers["Content-Type"]) } } ================================================ FILE: retrofit-converters/kotlinx-serialization/src/test/java/retrofit2/converter/kotlinx/serialization/KotlinxSerializationConverterFactoryContextualListTest.kt ================================================ package retrofit2.converter.kotlinx.serialization import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.contextual import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaType import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test import retrofit2.Call import retrofit2.Retrofit import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST class KotlinxSerializationConverterFactoryContextualListTest { @get:Rule val server = MockWebServer() private lateinit var service: Service interface Service { @GET("/") fun deserialize(): Call> @POST("/") fun serialize(@Body users: List): Call } data class User(val name: String) object UserSerializer : KSerializer { override val descriptor = PrimitiveSerialDescriptor("User", PrimitiveKind.STRING) override fun deserialize(decoder: Decoder): User = decoder.decodeSerializableValue(UserResponse.serializer()).run { User(name) } override fun serialize(encoder: Encoder, value: User): Unit = encoder.encodeSerializableValue(UserResponse.serializer(), UserResponse(value.name)) @Serializable private data class UserResponse(val name: String) } private val json = Json { serializersModule = SerializersModule { contextual(UserSerializer) } } @Before fun setUp() { val contentType = "application/json; charset=utf-8".toMediaType() val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(json.asConverterFactory(contentType)) .build() service = retrofit.create(Service::class.java) } @Test fun deserialize() { server.enqueue(MockResponse().setBody("""[{"name":"Bob"}]""")) val user = service.deserialize().execute().body()!! assertEquals(listOf(User("Bob")), user) } @Test fun serialize() { server.enqueue(MockResponse()) service.serialize(listOf(User("Bob"))).execute() val request = server.takeRequest() assertEquals("""[{"name":"Bob"}]""", request.body.readUtf8()) assertEquals("application/json; charset=utf-8", request.headers["Content-Type"]) } } ================================================ FILE: retrofit-converters/kotlinx-serialization/src/test/java/retrofit2/converter/kotlinx/serialization/KotlinxSerializationConverterFactoryContextualTest.kt ================================================ package retrofit2.converter.kotlinx.serialization import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.contextual import okhttp3.MediaType import okhttp3.MediaType.Companion.toMediaType import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test import retrofit2.Call import retrofit2.Retrofit import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST class KotlinxSerializationConverterFactoryContextualTest { @get:Rule val server = MockWebServer() private lateinit var service: Service interface Service { @GET("/") fun deserialize(): Call @POST("/") fun serialize(@Body user: User): Call } data class User(val name: String) object UserSerializer : KSerializer { override val descriptor = PrimitiveSerialDescriptor("User", PrimitiveKind.STRING) override fun deserialize(decoder: Decoder): User = decoder.decodeSerializableValue(UserResponse.serializer()).run { User(name) } override fun serialize(encoder: Encoder, value: User): Unit = encoder.encodeSerializableValue(UserResponse.serializer(), UserResponse(value.name)) @Serializable private data class UserResponse(val name: String) } private val json = Json { serializersModule = SerializersModule { contextual(UserSerializer) } } @Before fun setUp() { val contentType = "application/json; charset=utf-8".toMediaType() val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(json.asConverterFactory(contentType)) .build() service = retrofit.create(Service::class.java) } @Test fun deserialize() { server.enqueue(MockResponse().setBody("""{"name":"Bob"}""")) val user = service.deserialize().execute().body()!! assertEquals(User("Bob"), user) } @Test fun serialize() { server.enqueue(MockResponse()) service.serialize(User("Bob")).execute() val request = server.takeRequest() assertEquals("""{"name":"Bob"}""", request.body.readUtf8()) assertEquals("application/json; charset=utf-8", request.headers["Content-Type"]) } } ================================================ FILE: retrofit-converters/moshi/README.md ================================================ Moshi Converter =============== A `Converter` which uses [Moshi][1] for serialization to and from JSON. A default `Moshi` instance will be created or one can be configured and passed to `MoshiConverterFactory.create()` to further control the serialization. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-moshi latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-moshi:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/square/moshi [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-moshi&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-moshi%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/moshi/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.moshi compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver testImplementation libs.testParameterInjector } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.moshi' } } ================================================ FILE: retrofit-converters/moshi/gradle.properties ================================================ POM_ARTIFACT_ID=converter-moshi POM_NAME=Converter: Moshi POM_DESCRIPTION=A Retrofit Converter which uses Moshi for serialization. ================================================ FILE: retrofit-converters/moshi/src/main/java/retrofit2/converter/moshi/MoshiConverterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.moshi; import static java.util.Collections.unmodifiableSet; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.JsonQualifier; import com.squareup.moshi.Moshi; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; /** * A {@linkplain Converter.Factory converter} which uses Moshi for JSON. * *

Because Moshi is so flexible in the types it supports, this converter assumes that it can * handle all types. If you are mixing JSON serialization with something else (such as protocol * buffers), you must {@linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this * instance} last to allow the other converters a chance to see their types. * *

Any {@link JsonQualifier @JsonQualifier}-annotated annotations on the parameter will be used * when looking up a request body converter and those on the method will be used when looking up a * response body converter. */ public final class MoshiConverterFactory extends Converter.Factory { /** Create an instance using a default {@link Moshi} instance for conversion. */ public static MoshiConverterFactory create() { return create(new Moshi.Builder().build()); } /** Create an instance using {@code moshi} for conversion. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static MoshiConverterFactory create(Moshi moshi) { if (moshi == null) throw new NullPointerException("moshi == null"); return new MoshiConverterFactory(moshi, false, false, false, false); } private final Moshi moshi; private final boolean lenient; private final boolean failOnUnknown; private final boolean serializeNulls; private final boolean streaming; private MoshiConverterFactory( Moshi moshi, boolean lenient, boolean failOnUnknown, boolean serializeNulls, boolean streaming) { this.moshi = moshi; this.lenient = lenient; this.failOnUnknown = failOnUnknown; this.serializeNulls = serializeNulls; this.streaming = streaming; } /** Return a new factory which uses {@linkplain JsonAdapter#lenient() lenient} adapters. */ public MoshiConverterFactory asLenient() { return new MoshiConverterFactory(moshi, true, failOnUnknown, serializeNulls, streaming); } /** Return a new factory which uses {@link JsonAdapter#failOnUnknown()} adapters. */ public MoshiConverterFactory failOnUnknown() { return new MoshiConverterFactory(moshi, lenient, true, serializeNulls, streaming); } /** Return a new factory which includes null values into the serialized JSON. */ public MoshiConverterFactory withNullSerialization() { return new MoshiConverterFactory(moshi, lenient, failOnUnknown, true, streaming); } /** * Return a new factory which streams serialization of request messages to bytes on the HTTP thread * This is either the calling thread for {@link Call#execute()}, or one of OkHttp's background * threads for {@link Call#enqueue}. Response bytes are always converted to message instances on * one of OkHttp's background threads. */ public MoshiConverterFactory withStreaming() { return new MoshiConverterFactory(moshi, lenient, failOnUnknown, serializeNulls, true); } @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { JsonAdapter adapter = moshi.adapter(type, jsonAnnotations(annotations)); if (lenient) { adapter = adapter.lenient(); } if (failOnUnknown) { adapter = adapter.failOnUnknown(); } if (serializeNulls) { adapter = adapter.serializeNulls(); } return new MoshiResponseBodyConverter<>(adapter); } @Override public Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { JsonAdapter adapter = moshi.adapter(type, jsonAnnotations(parameterAnnotations)); if (lenient) { adapter = adapter.lenient(); } if (failOnUnknown) { adapter = adapter.failOnUnknown(); } if (serializeNulls) { adapter = adapter.serializeNulls(); } return new MoshiRequestBodyConverter<>(adapter, streaming); } private static Set jsonAnnotations(Annotation[] annotations) { Set result = null; for (Annotation annotation : annotations) { if (annotation.annotationType().isAnnotationPresent(JsonQualifier.class)) { if (result == null) result = new LinkedHashSet<>(); result.add(annotation); } } return result != null ? unmodifiableSet(result) : Collections.emptySet(); } } ================================================ FILE: retrofit-converters/moshi/src/main/java/retrofit2/converter/moshi/MoshiRequestBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.moshi; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.JsonWriter; import java.io.IOException; import okhttp3.MediaType; import okhttp3.RequestBody; import okio.Buffer; import retrofit2.Converter; final class MoshiRequestBodyConverter implements Converter { static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8"); private final JsonAdapter adapter; private final boolean streaming; MoshiRequestBodyConverter(JsonAdapter adapter, boolean streaming) { this.adapter = adapter; this.streaming = streaming; } @Override public RequestBody convert(T value) throws IOException { if (streaming) { return new MoshiStreamingRequestBody<>(adapter, value); } Buffer buffer = new Buffer(); JsonWriter writer = JsonWriter.of(buffer); adapter.toJson(writer, value); return RequestBody.create(MEDIA_TYPE, buffer.readByteString()); } } ================================================ FILE: retrofit-converters/moshi/src/main/java/retrofit2/converter/moshi/MoshiResponseBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.moshi; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.JsonDataException; import com.squareup.moshi.JsonReader; import java.io.IOException; import okhttp3.ResponseBody; import okio.BufferedSource; import okio.ByteString; import retrofit2.Converter; final class MoshiResponseBodyConverter implements Converter { private static final ByteString UTF8_BOM = ByteString.decodeHex("EFBBBF"); private final JsonAdapter adapter; MoshiResponseBodyConverter(JsonAdapter adapter) { this.adapter = adapter; } @Override public T convert(ResponseBody value) throws IOException { BufferedSource source = value.source(); try { // Moshi has no document-level API so the responsibility of BOM skipping falls to whatever // is delegating to it. Since it's a UTF-8-only library as well we only honor the UTF-8 BOM. if (source.rangeEquals(0, UTF8_BOM)) { source.skip(UTF8_BOM.size()); } JsonReader reader = JsonReader.of(source); T result = adapter.fromJson(reader); if (reader.peek() != JsonReader.Token.END_DOCUMENT) { throw new JsonDataException("JSON document was not fully consumed."); } return result; } finally { value.close(); } } } ================================================ FILE: retrofit-converters/moshi/src/main/java/retrofit2/converter/moshi/MoshiStreamingRequestBody.java ================================================ /* * Copyright (C) 2025 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.moshi; import static retrofit2.converter.moshi.MoshiRequestBodyConverter.MEDIA_TYPE; import com.squareup.moshi.JsonAdapter; import java.io.IOException; import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; final class MoshiStreamingRequestBody extends RequestBody { private final JsonAdapter adapter; private final T value; public MoshiStreamingRequestBody(JsonAdapter adapter, T value) { this.adapter = adapter; this.value = value; } @Override public MediaType contentType() { return MEDIA_TYPE; } @Override public void writeTo(BufferedSink sink) throws IOException { adapter.toJson(sink, value); } } ================================================ FILE: retrofit-converters/moshi/src/main/java/retrofit2/converter/moshi/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.converter.moshi; ================================================ FILE: retrofit-converters/moshi/src/test/java/retrofit2/converter/moshi/MoshiConverterFactoryTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.moshi; import static com.google.common.truth.Truth.assertThat; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; import com.google.testing.junit.testparameterinjector.TestParameter; import com.google.testing.junit.testparameterinjector.TestParameterInjector; import com.squareup.moshi.FromJson; import com.squareup.moshi.JsonDataException; import com.squareup.moshi.JsonQualifier; import com.squareup.moshi.JsonReader; import com.squareup.moshi.JsonWriter; import com.squareup.moshi.Moshi; import com.squareup.moshi.ToJson; import java.io.EOFException; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okio.Buffer; import okio.ByteString; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; @RunWith(TestParameterInjector.class) public final class MoshiConverterFactoryTest { @Retention(RUNTIME) @JsonQualifier @interface Qualifier {} @Retention(RUNTIME) @interface NonQualifer {} interface AnInterface { String getName(); } static class AnImplementation implements AnInterface { private final String theName; AnImplementation(String name) { theName = name; } @Override public String getName() { return theName; } } static final class ErroringValue { final String theName; ErroringValue(String theName) { this.theName = theName; } } static class Adapters { @ToJson public void write(JsonWriter jsonWriter, AnInterface anInterface) throws IOException { jsonWriter.beginObject(); jsonWriter.name("name").value(anInterface.getName()); jsonWriter.endObject(); } @FromJson public AnInterface read(JsonReader jsonReader) throws IOException { jsonReader.beginObject(); String name = null; while (jsonReader.hasNext()) { switch (jsonReader.nextName()) { case "name": name = jsonReader.nextString(); break; } } jsonReader.endObject(); return new AnImplementation(name); } @ToJson public void write(JsonWriter writer, @Qualifier String value) throws IOException { writer.value("qualified!"); } @FromJson @Qualifier public String readQualified(JsonReader reader) throws IOException { String string = reader.nextString(); if (string.equals("qualified!")) { return "it worked!"; } throw new AssertionError("Found: " + string); } @FromJson public ErroringValue readWithoutEndingObject(JsonReader reader) throws IOException { reader.beginObject(); reader.skipName(); String theName = reader.nextString(); return new ErroringValue(theName); } @ToJson public void write(JsonWriter writer, ErroringValue value) throws IOException { throw new EOFException("oops!"); } } interface Service { @POST("/") Call anImplementation(@Body AnImplementation impl); @POST("/") Call anInterface(@Body AnInterface impl); @GET("/") Call readErroringValue(); @POST("/") Call writeErroringValue(@Body ErroringValue value); @POST("/") @Qualifier @NonQualifer // Call annotations(@Body @Qualifier @NonQualifer String body); } @Rule public final MockWebServer server = new MockWebServer(); private final Service service; private final Service serviceLenient; private final Service serviceNulls; private final Service serviceFailOnUnknown; private final boolean streaming; public MoshiConverterFactoryTest(@TestParameter boolean streaming) { this.streaming = streaming; Moshi moshi = new Moshi.Builder() .add( (type, annotations, moshi1) -> { for (Annotation annotation : annotations) { if (!annotation.annotationType().isAnnotationPresent(JsonQualifier.class)) { throw new AssertionError("Non-@JsonQualifier annotation: " + annotation); } } return null; }) .add(new Adapters()) .build(); MoshiConverterFactory factory = MoshiConverterFactory.create(moshi); if (streaming) { factory = factory.withStreaming(); } MoshiConverterFactory factoryLenient = factory.asLenient(); MoshiConverterFactory factoryNulls = factory.withNullSerialization(); MoshiConverterFactory factoryFailOnUnknown = factory.failOnUnknown(); Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(factory).build(); Retrofit retrofitLenient = new Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(factoryLenient).build(); Retrofit retrofitNulls = new Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(factoryNulls).build(); Retrofit retrofitFailOnUnknown = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(factoryFailOnUnknown) .build(); service = retrofit.create(Service.class); serviceLenient = retrofitLenient.create(Service.class); serviceNulls = retrofitNulls.create(Service.class); serviceFailOnUnknown = retrofitFailOnUnknown.create(Service.class); } @Test public void anInterface() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{\"name\":\"value\"}")); Call call = service.anInterface(new AnImplementation("value")); Response response = call.execute(); AnInterface body = response.body(); assertThat(body.getName()).isEqualTo("value"); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readUtf8()).isEqualTo("{\"name\":\"value\"}"); assertThat(request.getHeader("Content-Type")).isEqualTo("application/json; charset=UTF-8"); } @Test public void anImplementation() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{\"theName\":\"value\"}")); Call call = service.anImplementation(new AnImplementation("value")); Response response = call.execute(); AnImplementation body = response.body(); assertThat(body.theName).isEqualTo("value"); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readUtf8()).isEqualTo("{\"theName\":\"value\"}"); assertThat(request.getHeader("Content-Type")).isEqualTo("application/json; charset=UTF-8"); } @Test public void annotations() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("\"qualified!\"")); Call call = service.annotations("value"); Response response = call.execute(); assertThat(response.body()).isEqualTo("it worked!"); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readUtf8()).isEqualTo("\"qualified!\""); assertThat(request.getHeader("Content-Type")).isEqualTo("application/json; charset=UTF-8"); } @Test public void asLenient() throws IOException, InterruptedException { MockResponse malformedResponse = new MockResponse().setBody("{\"theName\":value}"); server.enqueue(malformedResponse); server.enqueue(malformedResponse); Call call = service.anImplementation(new AnImplementation("value")); try { call.execute(); fail(); } catch (IOException e) { assertEquals( e.getMessage(), "Use JsonReader.setLenient(true) to accept malformed JSON at path $.theName"); } Call call2 = serviceLenient.anImplementation(new AnImplementation("value")); Response response = call2.execute(); AnImplementation body = response.body(); assertThat(body.theName).isEqualTo("value"); } @Test public void withNulls() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{}")); Call call = serviceNulls.anImplementation(new AnImplementation(null)); call.execute(); assertEquals("{\"theName\":null}", server.takeRequest().getBody().readUtf8()); } @Test public void failOnUnknown() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("{\"taco\":\"delicious\"}")); Call call = serviceFailOnUnknown.anImplementation(new AnImplementation(null)); try { call.execute(); fail(); } catch (JsonDataException e) { assertThat(e).hasMessageThat().isEqualTo("Cannot skip unexpected NAME at $.taco"); } } @Test public void utf8BomSkipped() throws IOException { Buffer responseBody = new Buffer().write(ByteString.decodeHex("EFBBBF")).writeUtf8("{\"theName\":\"value\"}"); MockResponse malformedResponse = new MockResponse().setBody(responseBody); server.enqueue(malformedResponse); Call call = service.anImplementation(new AnImplementation("value")); Response response = call.execute(); AnImplementation body = response.body(); assertThat(body.theName).isEqualTo("value"); } @Test public void nonUtf8BomIsNotSkipped() throws IOException { Buffer responseBody = new Buffer() .write(ByteString.decodeHex("FEFF")) .writeString("{\"theName\":\"value\"}", StandardCharsets.UTF_16); MockResponse malformedResponse = new MockResponse().setBody(responseBody); server.enqueue(malformedResponse); Call call = service.anImplementation(new AnImplementation("value")); try { call.execute(); fail(); } catch (IOException expected) { } } @Test public void requireFullResponseDocumentConsumption() throws Exception { server.enqueue(new MockResponse().setBody("{\"theName\":\"value\"}")); Call call = service.readErroringValue(); try { call.execute(); fail(); } catch (JsonDataException e) { assertThat(e).hasMessageThat().isEqualTo("JSON document was not fully consumed."); } } @Test public void serializeIsStreamed() throws InterruptedException { assumeTrue(streaming); Call call = service.writeErroringValue(new ErroringValue("hi")); final AtomicReference throwableRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); // If streaming were broken, the call to enqueue would throw the exception synchronously. call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { throwableRef.set(t); latch.countDown(); } }); latch.await(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(EOFException.class); assertThat(throwable).hasMessageThat().isEqualTo("oops!"); } } ================================================ FILE: retrofit-converters/protobuf/README.md ================================================ Google Protocol Buffer Converter ================================ A `Converter` which uses [Protocol Buffer][1] binary serialization. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-protobuf latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-protobuf:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://developers.google.com/protocol-buffers/ [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-protobuf&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-protobuf%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/protobuf/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.google.protobuf' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.protobuf compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver testImplementation libs.testParameterInjector } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.protobuf' } } protobuf { protoc { artifact = libs.protoc.get() } } ================================================ FILE: retrofit-converters/protobuf/gradle.properties ================================================ POM_ARTIFACT_ID=converter-protobuf POM_NAME=Converter: Protocol Buffers POM_DESCRIPTION=A Retrofit Converter which uses Protocol Buffers for serialization. ================================================ FILE: retrofit-converters/protobuf/src/main/java/retrofit2/converter/protobuf/ProtoConverterFactory.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.protobuf; import com.google.protobuf.ExtensionRegistryLite; import com.google.protobuf.MessageLite; import com.google.protobuf.Parser; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; /** * A {@linkplain Converter.Factory converter} which uses Protocol Buffers. * *

This converter only applies for types which extend from {@link MessageLite} (or one of its * subclasses). */ public final class ProtoConverterFactory extends Converter.Factory { public static ProtoConverterFactory create() { return new ProtoConverterFactory(null, false); } /** Create an instance which uses {@code registry} when deserializing. */ public static ProtoConverterFactory createWithRegistry(@Nullable ExtensionRegistryLite registry) { return new ProtoConverterFactory(registry, false); } private final @Nullable ExtensionRegistryLite registry; private final boolean streaming; private ProtoConverterFactory(@Nullable ExtensionRegistryLite registry, boolean streaming) { this.registry = registry; this.streaming = streaming; } /** * Return a new factory which streams serialization of request messages to bytes on the HTTP thread * This is either the calling thread for {@link Call#execute()}, or one of OkHttp's background * threads for {@link Call#enqueue}. Response bytes are always converted to message instances on * one of OkHttp's background threads. */ public ProtoConverterFactory withStreaming() { return new ProtoConverterFactory(registry, true); } @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (!(type instanceof Class)) { return null; } Class c = (Class) type; if (!MessageLite.class.isAssignableFrom(c)) { return null; } Parser parser; try { Method method = c.getDeclaredMethod("parser"); //noinspection unchecked parser = (Parser) method.invoke(null); } catch (InvocationTargetException e) { throw new RuntimeException(e.getCause()); } catch (NoSuchMethodException | IllegalAccessException ignored) { // If the method is missing, fall back to original static field for pre-3.0 support. try { Field field = c.getDeclaredField("PARSER"); //noinspection unchecked parser = (Parser) field.get(null); } catch (NoSuchFieldException | IllegalAccessException e) { throw new IllegalArgumentException( "Found a protobuf message but " + c.getName() + " had no parser() method or PARSER field.", e); } } return new ProtoResponseBodyConverter<>(parser, registry); } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (!(type instanceof Class)) { return null; } if (!MessageLite.class.isAssignableFrom((Class) type)) { return null; } return new ProtoRequestBodyConverter<>(streaming); } } ================================================ FILE: retrofit-converters/protobuf/src/main/java/retrofit2/converter/protobuf/ProtoRequestBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.protobuf; import com.google.protobuf.MessageLite; import okhttp3.MediaType; import okhttp3.RequestBody; import retrofit2.Converter; final class ProtoRequestBodyConverter implements Converter { static final MediaType MEDIA_TYPE = MediaType.get("application/x-protobuf"); private final boolean streaming; ProtoRequestBodyConverter(boolean streaming) { this.streaming = streaming; } @Override public RequestBody convert(T value) { if (streaming) { return new ProtoStreamingRequestBody(value); } byte[] bytes = value.toByteArray(); return RequestBody.create(MEDIA_TYPE, bytes); } } ================================================ FILE: retrofit-converters/protobuf/src/main/java/retrofit2/converter/protobuf/ProtoResponseBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.protobuf; import com.google.protobuf.ExtensionRegistryLite; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.MessageLite; import com.google.protobuf.Parser; import java.io.IOException; import javax.annotation.Nullable; import okhttp3.ResponseBody; import retrofit2.Converter; final class ProtoResponseBodyConverter implements Converter { private final Parser parser; private final @Nullable ExtensionRegistryLite registry; ProtoResponseBodyConverter(Parser parser, @Nullable ExtensionRegistryLite registry) { this.parser = parser; this.registry = registry; } @Override public T convert(ResponseBody value) throws IOException { try { return registry == null ? parser.parseFrom(value.byteStream()) : parser.parseFrom(value.byteStream(), registry); } catch (InvalidProtocolBufferException e) { throw new RuntimeException(e); // Despite extending IOException, this is data mismatch. } finally { value.close(); } } } ================================================ FILE: retrofit-converters/protobuf/src/main/java/retrofit2/converter/protobuf/ProtoStreamingRequestBody.java ================================================ /* * Copyright (C) 2025 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.protobuf; import static retrofit2.converter.protobuf.ProtoRequestBodyConverter.MEDIA_TYPE; import com.google.protobuf.MessageLite; import java.io.IOException; import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; final class ProtoStreamingRequestBody extends RequestBody { private final MessageLite value; public ProtoStreamingRequestBody(MessageLite value) { this.value = value; } @Override public MediaType contentType() { return MEDIA_TYPE; } @Override public void writeTo(BufferedSink sink) throws IOException { value.writeTo(sink.outputStream()); } } ================================================ FILE: retrofit-converters/protobuf/src/main/java/retrofit2/converter/protobuf/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.converter.protobuf; ================================================ FILE: retrofit-converters/protobuf/src/main/resources/META-INF/proguard/retrofit2-protobuf-converter.pro ================================================ # Parser looked up reflectively. -keepclassmembers class * implements com.google.protobuf.MessageLite { public static com.google.protobuf.Parser parser(); # Fallback for v2.x. public static com.google.protobuf.Parser PARSER; } ================================================ FILE: retrofit-converters/protobuf/src/test/java/retrofit2/converter/protobuf/FallbackParserFinderTest.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.protobuf; import static com.google.common.truth.Truth.assertThat; import com.google.protobuf.MessageLite; import com.google.protobuf.Parser; import java.lang.annotation.Annotation; import okhttp3.ResponseBody; import org.junit.Test; import retrofit2.Converter; import retrofit2.Retrofit; import retrofit2.converter.protobuf.PhoneProtos.Phone; public final class FallbackParserFinderTest { @Test public void converterFactoryFallsBackToParserField() { Retrofit retrofit = new Retrofit.Builder().baseUrl("http://localhost/").build(); ProtoConverterFactory factory = ProtoConverterFactory.create(); Converter converter = factory.responseBodyConverter(FakePhone.class, new Annotation[0], retrofit); assertThat(converter).isNotNull(); } @SuppressWarnings("unused") // Used reflectively. public abstract static class FakePhone implements MessageLite { public static final Parser PARSER = Phone.parser(); } } ================================================ FILE: retrofit-converters/protobuf/src/test/java/retrofit2/converter/protobuf/ProtoConverterFactoryTest.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.protobuf; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; import static retrofit2.converter.protobuf.PhoneProtos.Phone; import com.google.protobuf.AbstractMessageLite; import com.google.protobuf.CodedOutputStream; import com.google.protobuf.ExtensionRegistry; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.MessageLite; import com.google.protobuf.Parser; import com.google.testing.junit.testparameterinjector.TestParameter; import com.google.testing.junit.testparameterinjector.TestParameterInjector; import java.io.EOFException; import java.io.IOException; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okio.Buffer; import okio.ByteString; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; @RunWith(TestParameterInjector.class) public final class ProtoConverterFactoryTest { interface Service { @GET("/") Call get(); @POST("/") Call post(@Body MessageLite impl); @GET("/") Call wrongClass(); @GET("/") Call> wrongType(); } interface ServiceWithRegistry { @GET("/") Call get(); } @Rule public final MockWebServer server = new MockWebServer(); private final Service service; private final ServiceWithRegistry serviceWithRegistry; private final boolean streaming; public ProtoConverterFactoryTest(@TestParameter boolean streaming) { this.streaming = streaming; ExtensionRegistry registry = ExtensionRegistry.newInstance(); PhoneProtos.registerAllExtensions(registry); ProtoConverterFactory factory = ProtoConverterFactory.create(); ProtoConverterFactory factoryWithRegistry = ProtoConverterFactory.createWithRegistry(registry); if (streaming) { factory = factory.withStreaming(); factoryWithRegistry = factoryWithRegistry.withStreaming(); } Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(factory).build(); service = retrofit.create(Service.class); Retrofit retrofitWithRegistry = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(factoryWithRegistry) .build(); serviceWithRegistry = retrofitWithRegistry.create(ServiceWithRegistry.class); } @Test public void serializeAndDeserialize() throws IOException, InterruptedException { ByteString encoded = ByteString.decodeBase64("Cg4oNTE5KSA4NjctNTMwOQ=="); server.enqueue(new MockResponse().setBody(new Buffer().write(encoded))); Call call = service.post(Phone.newBuilder().setNumber("(519) 867-5309").build()); Response response = call.execute(); Phone body = response.body(); assertThat(body.getNumber()).isEqualTo("(519) 867-5309"); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readByteString()).isEqualTo(encoded); assertThat(request.getHeader("Content-Type")).isEqualTo("application/x-protobuf"); } @Test public void deserializeEmpty() throws IOException { server.enqueue(new MockResponse()); Call call = service.get(); Response response = call.execute(); Phone body = response.body(); assertThat(body.hasNumber()).isFalse(); } @Test public void deserializeUsesRegistry() throws IOException { ByteString encoded = ByteString.decodeBase64("Cg4oNTE5KSA4NjctNTMwORAB"); server.enqueue(new MockResponse().setBody(new Buffer().write(encoded))); Call call = serviceWithRegistry.get(); Response response = call.execute(); Phone body = response.body(); assertThat(body.getNumber()).isEqualTo("(519) 867-5309"); assertThat(body.getExtension(PhoneProtos.voicemail)).isEqualTo(true); } @Test public void deserializeWrongClass() throws IOException { ByteString encoded = ByteString.decodeBase64("Cg4oNTE5KSA4NjctNTMwOQ=="); server.enqueue(new MockResponse().setBody(new Buffer().write(encoded))); try { service.wrongClass(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Unable to create converter for class java.lang.String\n" + " for method Service.wrongClass"); assertThat(e.getCause()) .hasMessageThat() .isEqualTo( "" + "Could not locate ResponseBody converter for class java.lang.String.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.converter.protobuf.ProtoConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } } @Test public void deserializeWrongType() throws IOException { ByteString encoded = ByteString.decodeBase64("Cg4oNTE5KSA4NjctNTMwOQ=="); server.enqueue(new MockResponse().setBody(new Buffer().write(encoded))); try { service.wrongType(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Unable to create converter for java.util.List\n" + " for method Service.wrongType"); assertThat(e.getCause()) .hasMessageThat() .isEqualTo( "" + "Could not locate ResponseBody converter for java.util.List.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.converter.protobuf.ProtoConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } } @Test public void deserializeWrongValue() throws IOException { ByteString encoded = ByteString.decodeBase64("////"); server.enqueue(new MockResponse().setBody(new Buffer().write(encoded))); Call call = service.get(); try { call.execute(); fail(); } catch (RuntimeException e) { Throwable cause = e.getCause(); assertThat(cause).isInstanceOf(InvalidProtocolBufferException.class); assertThat(cause).hasMessageThat().contains("input ended unexpectedly"); } } @Test public void serializeIsStreamed() throws InterruptedException { assumeTrue(streaming); Call call = service.post(new ThrowingPhone(Phone.newBuilder().setNumber("(519) 867-5309").build())); final AtomicReference throwableRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); // If streaming were broken, the call to enqueue would throw the exception synchronously. call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { throwableRef.set(t); latch.countDown(); } }); latch.await(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(EOFException.class); assertThat(throwable).hasMessageThat().isEqualTo("oops!"); } private static final class ThrowingPhone extends AbstractMessageLite { private final Phone delegate; private ThrowingPhone(Phone delegate) { this.delegate = delegate; } @Override public void writeTo(CodedOutputStream output) throws IOException { throw new EOFException("oops!"); } @Override public int getSerializedSize() { return delegate.getSerializedSize(); } @Override public Parser getParserForType() { return delegate.getParserForType(); } @Override public MessageLite.Builder newBuilderForType() { return delegate.newBuilderForType(); } @Override public MessageLite.Builder toBuilder() { return delegate.toBuilder(); } @Override public MessageLite getDefaultInstanceForType() { return delegate.getDefaultInstanceForType(); } @Override public boolean isInitialized() { return delegate.isInitialized(); } } } ================================================ FILE: retrofit-converters/protobuf/src/test/proto/phone.proto ================================================ package retrofit2.converter.protobuf; option java_package = "retrofit2.converter.protobuf"; option java_outer_classname = "PhoneProtos"; message Phone { optional string number = 1; extensions 2; } extend Phone { optional bool voicemail = 2; } ================================================ FILE: retrofit-converters/scalars/README.md ================================================ Java Scalars Converter ====================== A `Converter` which supports converting strings and both primitives and their boxed types to `text/plain` bodies. Download -------- Download [the latest JAR][1] or grab via [Maven][2]: ```xml com.squareup.retrofit2 converter-scalars latest.version ``` or [Gradle][2]: ```groovy implementation 'com.squareup.retrofit2:converter-scalars:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-scalars&v=LATEST [2]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-scalars%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/scalars/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.scalars' } } ================================================ FILE: retrofit-converters/scalars/gradle.properties ================================================ POM_ARTIFACT_ID=converter-scalars POM_NAME=Converter: Scalars POM_DESCRIPTION=A Retrofit Converter for Java's scalar value types. ================================================ FILE: retrofit-converters/scalars/src/main/java/retrofit2/converter/scalars/ScalarRequestBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.scalars; import java.io.IOException; import okhttp3.MediaType; import okhttp3.RequestBody; import retrofit2.Converter; final class ScalarRequestBodyConverter implements Converter { static final ScalarRequestBodyConverter INSTANCE = new ScalarRequestBodyConverter<>(); private static final MediaType MEDIA_TYPE = MediaType.get("text/plain; charset=UTF-8"); private ScalarRequestBodyConverter() {} @Override public RequestBody convert(T value) throws IOException { return RequestBody.create(MEDIA_TYPE, String.valueOf(value)); } } ================================================ FILE: retrofit-converters/scalars/src/main/java/retrofit2/converter/scalars/ScalarResponseBodyConverters.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.scalars; import java.io.IOException; import okhttp3.ResponseBody; import retrofit2.Converter; final class ScalarResponseBodyConverters { private ScalarResponseBodyConverters() {} static final class StringResponseBodyConverter implements Converter { static final StringResponseBodyConverter INSTANCE = new StringResponseBodyConverter(); @Override public String convert(ResponseBody value) throws IOException { return value.string(); } } static final class BooleanResponseBodyConverter implements Converter { static final BooleanResponseBodyConverter INSTANCE = new BooleanResponseBodyConverter(); @Override public Boolean convert(ResponseBody value) throws IOException { return Boolean.valueOf(value.string()); } } static final class ByteResponseBodyConverter implements Converter { static final ByteResponseBodyConverter INSTANCE = new ByteResponseBodyConverter(); @Override public Byte convert(ResponseBody value) throws IOException { return Byte.valueOf(value.string()); } } static final class CharacterResponseBodyConverter implements Converter { static final CharacterResponseBodyConverter INSTANCE = new CharacterResponseBodyConverter(); @Override public Character convert(ResponseBody value) throws IOException { String body = value.string(); if (body.length() != 1) { throw new IOException( "Expected body of length 1 for Character conversion but was " + body.length()); } return body.charAt(0); } } static final class DoubleResponseBodyConverter implements Converter { static final DoubleResponseBodyConverter INSTANCE = new DoubleResponseBodyConverter(); @Override public Double convert(ResponseBody value) throws IOException { return Double.valueOf(value.string()); } } static final class FloatResponseBodyConverter implements Converter { static final FloatResponseBodyConverter INSTANCE = new FloatResponseBodyConverter(); @Override public Float convert(ResponseBody value) throws IOException { return Float.valueOf(value.string()); } } static final class IntegerResponseBodyConverter implements Converter { static final IntegerResponseBodyConverter INSTANCE = new IntegerResponseBodyConverter(); @Override public Integer convert(ResponseBody value) throws IOException { return Integer.valueOf(value.string()); } } static final class LongResponseBodyConverter implements Converter { static final LongResponseBodyConverter INSTANCE = new LongResponseBodyConverter(); @Override public Long convert(ResponseBody value) throws IOException { return Long.valueOf(value.string()); } } static final class ShortResponseBodyConverter implements Converter { static final ShortResponseBodyConverter INSTANCE = new ShortResponseBodyConverter(); @Override public Short convert(ResponseBody value) throws IOException { return Short.valueOf(value.string()); } } } ================================================ FILE: retrofit-converters/scalars/src/main/java/retrofit2/converter/scalars/ScalarsConverterFactory.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.scalars; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Converter; import retrofit2.Retrofit; import retrofit2.converter.scalars.ScalarResponseBodyConverters.BooleanResponseBodyConverter; import retrofit2.converter.scalars.ScalarResponseBodyConverters.ByteResponseBodyConverter; import retrofit2.converter.scalars.ScalarResponseBodyConverters.CharacterResponseBodyConverter; import retrofit2.converter.scalars.ScalarResponseBodyConverters.DoubleResponseBodyConverter; import retrofit2.converter.scalars.ScalarResponseBodyConverters.FloatResponseBodyConverter; import retrofit2.converter.scalars.ScalarResponseBodyConverters.IntegerResponseBodyConverter; import retrofit2.converter.scalars.ScalarResponseBodyConverters.LongResponseBodyConverter; import retrofit2.converter.scalars.ScalarResponseBodyConverters.ShortResponseBodyConverter; import retrofit2.converter.scalars.ScalarResponseBodyConverters.StringResponseBodyConverter; /** * A {@linkplain Converter.Factory converter} for strings and both primitives and their boxed types * to {@code text/plain} bodies. */ public final class ScalarsConverterFactory extends Converter.Factory { public static ScalarsConverterFactory create() { return new ScalarsConverterFactory(); } private ScalarsConverterFactory() {} @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (type == String.class || type == boolean.class || type == Boolean.class || type == byte.class || type == Byte.class || type == char.class || type == Character.class || type == double.class || type == Double.class || type == float.class || type == Float.class || type == int.class || type == Integer.class || type == long.class || type == Long.class || type == short.class || type == Short.class) { return ScalarRequestBodyConverter.INSTANCE; } return null; } @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (type == String.class) { return StringResponseBodyConverter.INSTANCE; } if (type == Boolean.class || type == boolean.class) { return BooleanResponseBodyConverter.INSTANCE; } if (type == Byte.class || type == byte.class) { return ByteResponseBodyConverter.INSTANCE; } if (type == Character.class || type == char.class) { return CharacterResponseBodyConverter.INSTANCE; } if (type == Double.class || type == double.class) { return DoubleResponseBodyConverter.INSTANCE; } if (type == Float.class || type == float.class) { return FloatResponseBodyConverter.INSTANCE; } if (type == Integer.class || type == int.class) { return IntegerResponseBodyConverter.INSTANCE; } if (type == Long.class || type == long.class) { return LongResponseBodyConverter.INSTANCE; } if (type == Short.class || type == short.class) { return ShortResponseBodyConverter.INSTANCE; } return null; } } ================================================ FILE: retrofit-converters/scalars/src/main/java/retrofit2/converter/scalars/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.converter.scalars; ================================================ FILE: retrofit-converters/scalars/src/test/java/retrofit2/converter/scalars/ScalarsConverterFactoryTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.scalars; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import java.io.IOException; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; public final class ScalarsConverterFactoryTest { interface Service { @POST("/") Call object(@Body Object body); @POST("/") Call stringObject(@Body String body); @POST("/") Call booleanPrimitive(@Body boolean body); @POST("/") Call booleanObject(@Body Boolean body); @POST("/") Call bytePrimitive(@Body byte body); @POST("/") Call byteObject(@Body Byte body); @POST("/") Call charPrimitive(@Body char body); @POST("/") Call charObject(@Body Character body); @POST("/") Call doublePrimitive(@Body double body); @POST("/") Call doubleObject(@Body Double body); @POST("/") Call floatPrimitive(@Body float body); @POST("/") Call floatObject(@Body Float body); @POST("/") Call integerPrimitive(@Body int body); @POST("/") Call integerObject(@Body Integer body); @POST("/") Call longPrimitive(@Body long body); @POST("/") Call longObject(@Body Long body); @POST("/") Call shortPrimitive(@Body short body); @POST("/") Call shortObject(@Body Short body); @GET("/") Call object(); @GET("/") Call stringObject(); @GET("/") Call booleanObject(); @GET("/") Call byteObject(); @GET("/") Call charObject(); @GET("/") Call doubleObject(); @GET("/") Call floatObject(); @GET("/") Call integerObject(); @GET("/") Call longObject(); @GET("/") Call shortObject(); } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ScalarsConverterFactory.create()) .build(); service = retrofit.create(Service.class); } @Test public void unsupportedRequestTypesNotMatched() { try { service.object(null); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Unable to create @Body converter for class java.lang.Object (parameter #1)\n" + " for method Service.object"); assertThat(e.getCause()) .hasMessageThat() .isEqualTo( "" + "Could not locate RequestBody converter for class java.lang.Object.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.converter.scalars.ScalarsConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } } @Test public void supportedRequestTypes() throws IOException, InterruptedException { RecordedRequest request; server.enqueue(new MockResponse()); service.stringObject("string").execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("6"); assertThat(request.getBody().readUtf8()).isEqualTo("string"); server.enqueue(new MockResponse()); service.booleanPrimitive(true).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("4"); assertThat(request.getBody().readUtf8()).isEqualTo("true"); server.enqueue(new MockResponse()); service.booleanObject(false).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("5"); assertThat(request.getBody().readUtf8()).isEqualTo("false"); server.enqueue(new MockResponse()); service.bytePrimitive((byte) 0).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("1"); assertThat(request.getBody().readUtf8()).isEqualTo("0"); server.enqueue(new MockResponse()); service.byteObject((byte) 1).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("1"); assertThat(request.getBody().readUtf8()).isEqualTo("1"); server.enqueue(new MockResponse()); service.charPrimitive('a').execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("1"); assertThat(request.getBody().readUtf8()).isEqualTo("a"); server.enqueue(new MockResponse()); service.charObject('b').execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("1"); assertThat(request.getBody().readUtf8()).isEqualTo("b"); server.enqueue(new MockResponse()); service.doublePrimitive(2.2d).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("3"); assertThat(request.getBody().readUtf8()).isEqualTo("2.2"); server.enqueue(new MockResponse()); service.doubleObject(3.3d).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("3"); assertThat(request.getBody().readUtf8()).isEqualTo("3.3"); server.enqueue(new MockResponse()); service.floatPrimitive(4.4f).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("3"); assertThat(request.getBody().readUtf8()).isEqualTo("4.4"); server.enqueue(new MockResponse()); service.floatObject(5.5f).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("3"); assertThat(request.getBody().readUtf8()).isEqualTo("5.5"); server.enqueue(new MockResponse()); service.integerPrimitive(6).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("1"); assertThat(request.getBody().readUtf8()).isEqualTo("6"); server.enqueue(new MockResponse()); service.integerObject(7).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("1"); assertThat(request.getBody().readUtf8()).isEqualTo("7"); server.enqueue(new MockResponse()); service.longPrimitive(8L).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("1"); assertThat(request.getBody().readUtf8()).isEqualTo("8"); server.enqueue(new MockResponse()); service.longObject(9L).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("1"); assertThat(request.getBody().readUtf8()).isEqualTo("9"); server.enqueue(new MockResponse()); service.shortPrimitive((short) 10).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("2"); assertThat(request.getBody().readUtf8()).isEqualTo("10"); server.enqueue(new MockResponse()); service.shortObject((short) 11).execute(); request = server.takeRequest(); assertThat(request.getHeader("Content-Type")).isEqualTo("text/plain; charset=UTF-8"); assertThat(request.getHeader("Content-Length")).isEqualTo("2"); assertThat(request.getBody().readUtf8()).isEqualTo("11"); } @Test public void unsupportedResponseTypesNotMatched() { try { service.object(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Unable to create converter for class java.lang.Object\n" + " for method Service.object"); assertThat(e.getCause()) .hasMessageThat() .isEqualTo( "" + "Could not locate ResponseBody converter for class java.lang.Object.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.converter.scalars.ScalarsConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } } @Test public void supportedResponseTypes() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("test")); Response stringResponse = service.stringObject().execute(); assertThat(stringResponse.body()).isEqualTo("test"); server.enqueue(new MockResponse().setBody("true")); Response booleanResponse = service.booleanObject().execute(); assertThat(booleanResponse.body()).isTrue(); server.enqueue(new MockResponse().setBody("5")); Response byteResponse = service.byteObject().execute(); assertThat(byteResponse.body()).isEqualTo((byte) 5); server.enqueue(new MockResponse().setBody("b")); Response characterResponse = service.charObject().execute(); assertThat(characterResponse.body()).isEqualTo('b'); server.enqueue(new MockResponse().setBody("")); try { service.charObject().execute(); fail(); } catch (IOException e) { assertThat(e) .hasMessageThat() .isEqualTo("Expected body of length 1 for Character conversion but was 0"); } server.enqueue(new MockResponse().setBody("bb")); try { service.charObject().execute(); fail(); } catch (IOException e) { assertThat(e) .hasMessageThat() .isEqualTo("Expected body of length 1 for Character conversion but was 2"); } server.enqueue(new MockResponse().setBody("13.13")); Response doubleResponse = service.doubleObject().execute(); assertThat(doubleResponse.body()).isEqualTo(13.13); server.enqueue(new MockResponse().setBody("13.13")); Response floatResponse = service.floatObject().execute(); assertThat(floatResponse.body()).isEqualTo(13.13f); server.enqueue(new MockResponse().setBody("13")); Response integerResponse = service.integerObject().execute(); assertThat(integerResponse.body()).isEqualTo(13); server.enqueue(new MockResponse().setBody("1347")); Response longResponse = service.longObject().execute(); assertThat(longResponse.body()).isEqualTo(1347L); server.enqueue(new MockResponse().setBody("134")); Response shortResponse = service.shortObject().execute(); assertThat(shortResponse.body()).isEqualTo((short) 134); } } ================================================ FILE: retrofit-converters/scalars/src/test/java/retrofit2/converter/scalars/ScalarsConverterPrimitivesFactoryTest.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.scalars; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Retrofit; import retrofit2.http.GET; public final class ScalarsConverterPrimitivesFactoryTest { interface Service { @GET("/") boolean booleanPrimitive(); @GET("/") byte bytePrimitive(); @GET("/") char charPrimitive(); @GET("/") double doublePrimitive(); @GET("/") float floatPrimitive(); @GET("/") int integerPrimitive(); @GET("/") long longPrimitive(); @GET("/") short shortPrimitive(); } static class DirectCallIOException extends RuntimeException { DirectCallIOException(String message, IOException e) { super(message, e); } } static class DirectCallAdapterFactory extends CallAdapter.Factory { @Override public CallAdapter get( final Type returnType, Annotation[] annotations, Retrofit retrofit) { return new CallAdapter() { @Override public Type responseType() { return returnType; } @Override public Object adapt(Call call) { try { return call.execute().body(); } catch (IOException e) { throw new DirectCallIOException(e.getMessage(), e); } } }; } } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(ScalarsConverterFactory.create()) .addCallAdapterFactory(new DirectCallAdapterFactory()) .build(); service = retrofit.create(Service.class); } @Test public void supportedResponseTypes() throws IOException, InterruptedException { server.enqueue(new MockResponse().setBody("true")); boolean booleanResponse = service.booleanPrimitive(); assertThat(booleanResponse).isTrue(); server.enqueue(new MockResponse().setBody("5")); byte byteResponse = service.bytePrimitive(); assertThat(byteResponse).isEqualTo((byte) 5); server.enqueue(new MockResponse().setBody("b")); char characterResponse = service.charPrimitive(); assertThat(characterResponse).isEqualTo('b'); server.enqueue(new MockResponse().setBody("")); try { service.charPrimitive(); fail(); } catch (DirectCallIOException e) { assertThat(e) .hasMessageThat() .isEqualTo("Expected body of length 1 for Character conversion but was 0"); } server.enqueue(new MockResponse().setBody("bb")); try { service.charPrimitive(); fail(); } catch (DirectCallIOException e) { assertThat(e) .hasMessageThat() .isEqualTo("Expected body of length 1 for Character conversion but was 2"); } server.enqueue(new MockResponse().setBody("13.13")); double doubleResponse = service.doublePrimitive(); assertThat(doubleResponse).isEqualTo(13.13); server.enqueue(new MockResponse().setBody("13.13")); float floatResponse = service.floatPrimitive(); assertThat(floatResponse).isEqualTo(13.13f); server.enqueue(new MockResponse().setBody("13")); int integerResponse = service.integerPrimitive(); assertThat(integerResponse).isEqualTo(13); server.enqueue(new MockResponse().setBody("1347")); long longResponse = service.longPrimitive(); assertThat(longResponse).isEqualTo(1347L); server.enqueue(new MockResponse().setBody("134")); short shortResponse = service.shortPrimitive(); assertThat(shortResponse).isEqualTo((short) 134); } } ================================================ FILE: retrofit-converters/simplexml/README.md ================================================ Simple XML Converter ==================== Deprecated – Please switch to the JAXB Converter ------------------------------------------------ The Simple XML project is no longer maintained. We recommend switching to the [JAXB converter](https://github.com/square/retrofit/tree/master/retrofit-converters/jaxb). ----- A `Converter` which uses [Simple][1] for XML serialization. A default `Serializer` instance will be created or one can be configured and passed to the `SimpleXMLConverter` construction to further control the serialization. Android ------- Simple depends on artifacts which are already provided by the Android platform. When specifying as a Maven or Gradle dependency, exclude the following transitive dependencies: `stax:stax-api`, `stax:stax`, and `xpp3:xpp3`. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-simplexml latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-simplexml:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: http://simple.sourceforge.net/ [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-simplexml&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-simplexml%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/simplexml/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api libs.simpleXml compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.simplexml' } } ================================================ FILE: retrofit-converters/simplexml/gradle.properties ================================================ POM_ARTIFACT_ID=converter-simplexml POM_NAME=Converter: SimpleXML POM_DESCRIPTION=A Retrofit Converter which uses Simple XML for serialization. ================================================ FILE: retrofit-converters/simplexml/src/main/java/retrofit2/converter/simplexml/SimpleXmlConverterFactory.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.simplexml; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.RequestBody; import okhttp3.ResponseBody; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import retrofit2.Converter; import retrofit2.Retrofit; /** * A {@linkplain Converter.Factory converter} which uses Simple Framework for XML. * *

This converter only applies for class types. Parameterized types (e.g., {@code List}) are * not handled. * * @deprecated we recommend switching to the JAXB converter. */ @Deprecated public final class SimpleXmlConverterFactory extends Converter.Factory { /** Create an instance using a default {@link Persister} instance for conversion. */ public static SimpleXmlConverterFactory create() { return create(new Persister()); } /** Create an instance using {@code serializer} for conversion. */ public static SimpleXmlConverterFactory create(Serializer serializer) { return new SimpleXmlConverterFactory(serializer, true); } /** Create an instance using a default {@link Persister} instance for non-strict conversion. */ public static SimpleXmlConverterFactory createNonStrict() { return createNonStrict(new Persister()); } /** Create an instance using {@code serializer} for non-strict conversion. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static SimpleXmlConverterFactory createNonStrict(Serializer serializer) { if (serializer == null) throw new NullPointerException("serializer == null"); return new SimpleXmlConverterFactory(serializer, false); } private final Serializer serializer; private final boolean strict; private SimpleXmlConverterFactory(Serializer serializer, boolean strict) { this.serializer = serializer; this.strict = strict; } public boolean isStrict() { return strict; } @Override public Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (!(type instanceof Class)) { return null; } Class cls = (Class) type; return new SimpleXmlResponseBodyConverter<>(cls, serializer, strict); } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (!(type instanceof Class)) { return null; } return new SimpleXmlRequestBodyConverter<>(serializer); } } ================================================ FILE: retrofit-converters/simplexml/src/main/java/retrofit2/converter/simplexml/SimpleXmlRequestBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.simplexml; import java.io.IOException; import java.io.OutputStreamWriter; import okhttp3.MediaType; import okhttp3.RequestBody; import okio.Buffer; import org.simpleframework.xml.Serializer; import retrofit2.Converter; final class SimpleXmlRequestBodyConverter implements Converter { private static final MediaType MEDIA_TYPE = MediaType.get("application/xml; charset=UTF-8"); private static final String CHARSET = "UTF-8"; private final Serializer serializer; SimpleXmlRequestBodyConverter(Serializer serializer) { this.serializer = serializer; } @Override public RequestBody convert(T value) throws IOException { Buffer buffer = new Buffer(); try { OutputStreamWriter osw = new OutputStreamWriter(buffer.outputStream(), CHARSET); serializer.write(value, osw); osw.flush(); } catch (RuntimeException | IOException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } return RequestBody.create(MEDIA_TYPE, buffer.readByteString()); } } ================================================ FILE: retrofit-converters/simplexml/src/main/java/retrofit2/converter/simplexml/SimpleXmlResponseBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.simplexml; import java.io.IOException; import okhttp3.ResponseBody; import org.simpleframework.xml.Serializer; import retrofit2.Converter; final class SimpleXmlResponseBodyConverter implements Converter { private final Class cls; private final Serializer serializer; private final boolean strict; SimpleXmlResponseBodyConverter(Class cls, Serializer serializer, boolean strict) { this.cls = cls; this.serializer = serializer; this.strict = strict; } @Override public T convert(ResponseBody value) throws IOException { try { T read = serializer.read(cls, value.charStream(), strict); if (read == null) { throw new IllegalStateException("Could not deserialize body as " + cls); } return read; } catch (RuntimeException | IOException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } finally { value.close(); } } } ================================================ FILE: retrofit-converters/simplexml/src/main/java/retrofit2/converter/simplexml/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.converter.simplexml; ================================================ FILE: retrofit-converters/simplexml/src/test/java/retrofit2/converter/simplexml/MyObject.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.simplexml; import org.simpleframework.xml.Default; import org.simpleframework.xml.DefaultType; import org.simpleframework.xml.Element; @Default(value = DefaultType.FIELD) final class MyObject { @Element private String message; @Element private int count; public MyObject() {} public MyObject(String message, int count) { this.message = message; this.count = count; } public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } public void setCount(int count) { this.count = count; } public int getCount() { return count; } @Override public int hashCode() { int result = 1; result = result * 31 + count; result = result * 31 + (message == null ? 0 : message.hashCode()); return result; } @Override public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof MyObject)) return false; MyObject other = (MyObject) obj; return count == other.count && (message == null ? other.message == null : message.equals(other.message)); } } ================================================ FILE: retrofit-converters/simplexml/src/test/java/retrofit2/converter/simplexml/SimpleXmlConverterFactoryTest.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.simplexml; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import java.io.IOException; import java.nio.charset.Charset; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okio.Buffer; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.simpleframework.xml.core.ElementException; import org.simpleframework.xml.core.Persister; import org.simpleframework.xml.stream.Format; import org.simpleframework.xml.stream.HyphenStyle; import org.simpleframework.xml.stream.Verbosity; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; public class SimpleXmlConverterFactoryTest { interface Service { @GET("/") Call get(); @POST("/") Call post(@Body MyObject impl); @GET("/") Call wrongClass(); } @Rule public final MockWebServer server = new MockWebServer(); private Service service; @Before public void setUp() { Format format = new Format(0, null, new HyphenStyle(), Verbosity.HIGH); Persister persister = new Persister(format); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(SimpleXmlConverterFactory.create(persister)) .build(); service = retrofit.create(Service.class); } @Test public void bodyWays() throws IOException, InterruptedException { server.enqueue( new MockResponse() .setBody("hello world10")); Call call = service.post(new MyObject("hello world", 10)); Response response = call.execute(); MyObject body = response.body(); assertThat(body.getMessage()).isEqualTo("hello world"); assertThat(body.getCount()).isEqualTo(10); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readUtf8()) .isAnyOf( "hello world10", "10hello world"); assertThat(request.getHeader("Content-Type")).isEqualTo("application/xml; charset=UTF-8"); } @Test public void honorsCharacterEncoding() throws IOException { Buffer buffer = new Buffer() .writeString( "你好,世界10", Charset.forName("GBK")); server.enqueue( new MockResponse().setBody(buffer).addHeader("Content-Type", "text/xml;charset=GBK")); Call call = service.get(); Response response = call.execute(); MyObject body = response.body(); assertThat(body.getMessage()).isEqualTo("你好,世界"); } @Test public void deserializeWrongValue() throws IOException { server.enqueue(new MockResponse().setBody("")); Call call = service.get(); try { call.execute(); fail(); } catch (RuntimeException e) { Throwable cause = e.getCause(); assertThat(cause).isInstanceOf(ElementException.class); assertThat(cause) .hasMessageThat() .startsWith( "Element 'foo' does not have a match in class retrofit2.converter.simplexml.MyObject"); } } @Test public void deserializeWrongClass() throws IOException { server.enqueue( new MockResponse() .setBody("hello world10")); Call call = service.wrongClass(); try { call.execute(); fail(); } catch (RuntimeException e) { assertThat(e) .hasMessageThat() .isEqualTo("Could not deserialize body as class java.lang.String"); } } } ================================================ FILE: retrofit-converters/wire/README.md ================================================ Wire Converter ============== A `Converter` which uses [Wire][1] for protocol buffer-compatible serialization. Download -------- Download [the latest JAR][2] or grab via [Maven][3]: ```xml com.squareup.retrofit2 converter-wire latest.version ``` or [Gradle][3]: ```groovy implementation 'com.squareup.retrofit2:converter-wire:latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://github.com/square/wire [2]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=converter-wire&v=LATEST [3]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-wire%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-converters/wire/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit api(libs.wireRuntime) { // Make sure OkHttp's transitive version wins (itself transitive from Retrofit). exclude group: 'com.squareup.okio', module: 'okio' } compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.okhttp.mockwebserver testImplementation libs.testParameterInjector } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.converter.wire' } } ================================================ FILE: retrofit-converters/wire/gradle.properties ================================================ POM_ARTIFACT_ID=converter-wire POM_NAME=Converter: Wire POM_DESCRIPTION=A Retrofit Converter which uses Wire for serialization. ================================================ FILE: retrofit-converters/wire/src/main/java/retrofit2/converter/wire/WireConverterFactory.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.wire; import com.squareup.wire.Message; import com.squareup.wire.ProtoAdapter; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; /** * A {@linkplain Converter.Factory converter} that uses Wire for protocol buffers. * *

This converter only applies for types which extend from {@link Message}. */ public final class WireConverterFactory extends Converter.Factory { /** * Create an instance which serializes request messages to bytes eagerly on the caller thread * when either {@link Call#execute()} or {@link Call#enqueue} is called. Response bytes are * always converted to message instances on one of OkHttp's background threads. */ public static WireConverterFactory create() { return new WireConverterFactory(false); } private final boolean streaming; private WireConverterFactory(boolean streaming) { this.streaming = streaming; } /** * Return a new factory which streams serialization of request messages to bytes on the HTTP thread * This is either the calling thread for {@link Call#execute()}, or one of OkHttp's background * threads for {@link Call#enqueue}. Response bytes are always converted to message instances on * one of OkHttp's background threads. */ public WireConverterFactory withStreaming() { return new WireConverterFactory(true); } @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (!(type instanceof Class)) { return null; } Class c = (Class) type; if (!Message.class.isAssignableFrom(c)) { return null; } //noinspection unchecked ProtoAdapter adapter = ProtoAdapter.get((Class) c); return new WireResponseBodyConverter<>(adapter); } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (!(type instanceof Class)) { return null; } Class c = (Class) type; if (!Message.class.isAssignableFrom(c)) { return null; } //noinspection unchecked ProtoAdapter adapter = ProtoAdapter.get((Class) c); return new WireRequestBodyConverter<>(adapter, streaming); } } ================================================ FILE: retrofit-converters/wire/src/main/java/retrofit2/converter/wire/WireRequestBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.wire; import com.squareup.wire.Message; import com.squareup.wire.ProtoAdapter; import java.io.IOException; import okhttp3.MediaType; import okhttp3.RequestBody; import okio.Buffer; import retrofit2.Converter; final class WireRequestBodyConverter> implements Converter { static final MediaType MEDIA_TYPE = MediaType.get("application/x-protobuf"); private final ProtoAdapter adapter; private final boolean streaming; WireRequestBodyConverter(ProtoAdapter adapter, boolean streaming) { this.adapter = adapter; this.streaming = streaming; } @Override public RequestBody convert(T value) throws IOException { if (streaming) { return new WireStreamingRequestBody<>(adapter, value); } Buffer buffer = new Buffer(); adapter.encode(buffer, value); return RequestBody.create(MEDIA_TYPE, buffer.snapshot()); } } ================================================ FILE: retrofit-converters/wire/src/main/java/retrofit2/converter/wire/WireResponseBodyConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.wire; import com.squareup.wire.Message; import com.squareup.wire.ProtoAdapter; import java.io.IOException; import okhttp3.ResponseBody; import retrofit2.Converter; final class WireResponseBodyConverter> implements Converter { private final ProtoAdapter adapter; WireResponseBodyConverter(ProtoAdapter adapter) { this.adapter = adapter; } @Override public T convert(ResponseBody value) throws IOException { try { return adapter.decode(value.source()); } finally { value.close(); } } } ================================================ FILE: retrofit-converters/wire/src/main/java/retrofit2/converter/wire/WireStreamingRequestBody.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.wire; import static retrofit2.converter.wire.WireRequestBodyConverter.MEDIA_TYPE; import com.squareup.wire.Message; import com.squareup.wire.ProtoAdapter; import java.io.IOException; import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; final class WireStreamingRequestBody> extends RequestBody { private final ProtoAdapter adapter; private final T value; WireStreamingRequestBody(ProtoAdapter adapter, T value) { this.adapter = adapter; this.value = value; } @Override public MediaType contentType() { return MEDIA_TYPE; } @Override public void writeTo(BufferedSink sink) throws IOException { adapter.encode(sink, value); } } ================================================ FILE: retrofit-converters/wire/src/main/java/retrofit2/converter/wire/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.converter.wire; ================================================ FILE: retrofit-converters/wire/src/main/resources/META-INF/proguard/retrofit2-wire-converter.pro ================================================ # ADAPTER field is looked up reflectively. -keepclassmembers class * extends com.squareup.wire.Message { public static com.squareup.wire.ProtoAdapter ADAPTER; } ================================================ FILE: retrofit-converters/wire/src/test/java/retrofit2/converter/wire/CrashingPhone.java ================================================ // Code generated by Wire protocol buffer compiler, do not edit. // Source file: phone.proto at 6:1 package retrofit2.converter.wire; import com.squareup.wire.FieldEncoding; import com.squareup.wire.Message; import com.squareup.wire.ProtoAdapter; import com.squareup.wire.ProtoReader; import com.squareup.wire.ProtoWriter; import com.squareup.wire.WireField; import com.squareup.wire.internal.Internal; import java.io.EOFException; import java.io.IOException; import okio.ByteString; public final class CrashingPhone extends Message { public static final ProtoAdapter ADAPTER = new ProtoAdapter_CrashingPhone(); private static final long serialVersionUID = 0L; public static final String DEFAULT_NUMBER = ""; @WireField(tag = 1, adapter = "com.squareup.wire.ProtoAdapter#STRING") public final String number; public CrashingPhone(String number) { this(number, ByteString.EMPTY); } public CrashingPhone(String number, ByteString unknownFields) { super(ADAPTER, unknownFields); this.number = number; } @Override public Builder newBuilder() { Builder builder = new Builder(); builder.number = number; builder.addUnknownFields(unknownFields()); return builder; } @Override public boolean equals(Object other) { if (other == this) return true; if (!(other instanceof CrashingPhone)) return false; CrashingPhone o = (CrashingPhone) other; return Internal.equals(unknownFields(), o.unknownFields()) && Internal.equals(number, o.number); } @Override public int hashCode() { int result = super.hashCode; if (result == 0) { result = unknownFields().hashCode(); result = result * 37 + (number != null ? number.hashCode() : 0); super.hashCode = result; } return result; } @Override public String toString() { StringBuilder builder = new StringBuilder(); if (number != null) builder.append(", number=").append(number); return builder.replace(0, 2, "Phone{").append('}').toString(); } public static final class Builder extends Message.Builder { public String number; public Builder() {} public Builder number(String number) { this.number = number; return this; } @Override public CrashingPhone build() { return new CrashingPhone(number, buildUnknownFields()); } } private static final class ProtoAdapter_CrashingPhone extends ProtoAdapter { ProtoAdapter_CrashingPhone() { super(FieldEncoding.LENGTH_DELIMITED, CrashingPhone.class); } @Override public int encodedSize(CrashingPhone value) { return (value.number != null ? ProtoAdapter.STRING.encodedSizeWithTag(1, value.number) : 0) + value.unknownFields().size(); } @Override public void encode(ProtoWriter writer, CrashingPhone value) throws IOException { throw new EOFException("oops!"); } @Override public CrashingPhone decode(ProtoReader reader) throws IOException { Builder builder = new Builder(); long token = reader.beginMessage(); for (int tag; (tag = reader.nextTag()) != -1; ) { switch (tag) { case 1: builder.number(ProtoAdapter.STRING.decode(reader)); break; default: { FieldEncoding fieldEncoding = reader.peekFieldEncoding(); Object value = fieldEncoding.rawProtoAdapter().decode(reader); builder.addUnknownField(tag, fieldEncoding, value); } } } reader.endMessage(token); return builder.build(); } @Override public CrashingPhone redact(CrashingPhone value) { Builder builder = value.newBuilder(); builder.clearUnknownFields(); return builder.build(); } } } ================================================ FILE: retrofit-converters/wire/src/test/java/retrofit2/converter/wire/Phone.java ================================================ // Code generated by Wire protocol buffer compiler, do not edit. // Source file: phone.proto at 6:1 package retrofit2.converter.wire; import com.squareup.wire.FieldEncoding; import com.squareup.wire.Message; import com.squareup.wire.ProtoAdapter; import com.squareup.wire.ProtoReader; import com.squareup.wire.ProtoWriter; import com.squareup.wire.WireField; import com.squareup.wire.internal.Internal; import java.io.IOException; import okio.ByteString; public final class Phone extends Message { public static final ProtoAdapter ADAPTER = new ProtoAdapter_Phone(); private static final long serialVersionUID = 0L; public static final String DEFAULT_NUMBER = ""; @WireField(tag = 1, adapter = "com.squareup.wire.ProtoAdapter#STRING") public final String number; public Phone(String number) { this(number, ByteString.EMPTY); } public Phone(String number, ByteString unknownFields) { super(ADAPTER, unknownFields); this.number = number; } @Override public Builder newBuilder() { Builder builder = new Builder(); builder.number = number; builder.addUnknownFields(unknownFields()); return builder; } @Override public boolean equals(Object other) { if (other == this) return true; if (!(other instanceof Phone)) return false; Phone o = (Phone) other; return Internal.equals(unknownFields(), o.unknownFields()) && Internal.equals(number, o.number); } @Override public int hashCode() { int result = super.hashCode; if (result == 0) { result = unknownFields().hashCode(); result = result * 37 + (number != null ? number.hashCode() : 0); super.hashCode = result; } return result; } @Override public String toString() { StringBuilder builder = new StringBuilder(); if (number != null) builder.append(", number=").append(number); return builder.replace(0, 2, "Phone{").append('}').toString(); } public static final class Builder extends Message.Builder { public String number; public Builder() {} public Builder number(String number) { this.number = number; return this; } @Override public Phone build() { return new Phone(number, buildUnknownFields()); } } private static final class ProtoAdapter_Phone extends ProtoAdapter { ProtoAdapter_Phone() { super(FieldEncoding.LENGTH_DELIMITED, Phone.class); } @Override public int encodedSize(Phone value) { return (value.number != null ? ProtoAdapter.STRING.encodedSizeWithTag(1, value.number) : 0) + value.unknownFields().size(); } @Override public void encode(ProtoWriter writer, Phone value) throws IOException { if (value.number != null) ProtoAdapter.STRING.encodeWithTag(writer, 1, value.number); writer.writeBytes(value.unknownFields()); } @Override public Phone decode(ProtoReader reader) throws IOException { Builder builder = new Builder(); long token = reader.beginMessage(); for (int tag; (tag = reader.nextTag()) != -1; ) { switch (tag) { case 1: builder.number(ProtoAdapter.STRING.decode(reader)); break; default: { FieldEncoding fieldEncoding = reader.peekFieldEncoding(); Object value = fieldEncoding.rawProtoAdapter().decode(reader); builder.addUnknownField(tag, fieldEncoding, value); } } } reader.endMessage(token); return builder.build(); } @Override public Phone redact(Phone value) { Builder builder = value.newBuilder(); builder.clearUnknownFields(); return builder.build(); } } } ================================================ FILE: retrofit-converters/wire/src/test/java/retrofit2/converter/wire/WireConverterFactoryTest.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.converter.wire; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; import com.google.testing.junit.testparameterinjector.TestParameter; import com.google.testing.junit.testparameterinjector.TestParameterInjector; import java.io.EOFException; import java.io.IOException; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okio.Buffer; import okio.ByteString; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; @RunWith(TestParameterInjector.class) public final class WireConverterFactoryTest { interface Service { @GET("/") Call get(); @POST("/") Call post(@Body Phone impl); @POST("/") Call postCrashing(@Body CrashingPhone impl); @GET("/") Call wrongClass(); @GET("/") Call> wrongType(); } @Rule public final MockWebServer server = new MockWebServer(); private final Service service; private final boolean streaming; public WireConverterFactoryTest(@TestParameter boolean streaming) { this.streaming = streaming; WireConverterFactory factory = WireConverterFactory.create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(streaming ? factory.withStreaming() : factory) .build(); service = retrofit.create(Service.class); } @Test public void serializeAndDeserialize() throws IOException, InterruptedException { ByteString encoded = ByteString.decodeBase64("Cg4oNTE5KSA4NjctNTMwOQ=="); server.enqueue(new MockResponse().setBody(new Buffer().write(encoded))); Call call = service.post(new Phone("(519) 867-5309")); Response response = call.execute(); Phone body = response.body(); assertThat(body.number).isEqualTo("(519) 867-5309"); RecordedRequest request = server.takeRequest(); assertThat(request.getBody().readByteString()).isEqualTo(encoded); assertThat(request.getHeader("Content-Type")).isEqualTo("application/x-protobuf"); } @Test public void serializeIsStreamed() throws IOException, InterruptedException { assumeTrue(streaming); Call call = service.postCrashing(new CrashingPhone("(519) 867-5309")); final AtomicReference throwableRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); // If streaming were broken, the call to enqueue would throw the exception synchronously. call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { throwableRef.set(t); latch.countDown(); } }); latch.await(); Throwable throwable = throwableRef.get(); assertThat(throwable).isInstanceOf(EOFException.class); assertThat(throwable).hasMessageThat().isEqualTo("oops!"); } @Test public void deserializeEmpty() throws IOException { server.enqueue(new MockResponse()); Call call = service.get(); Response response = call.execute(); Phone body = response.body(); assertThat(body.number).isNull(); } @Test public void deserializeWrongClass() throws IOException { ByteString encoded = ByteString.decodeBase64("Cg4oNTE5KSA4NjctNTMwOQ=="); server.enqueue(new MockResponse().setBody(new Buffer().write(encoded))); try { service.wrongClass(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Unable to create converter for class java.lang.String\n" + " for method Service.wrongClass"); assertThat(e.getCause()) .hasMessageThat() .isEqualTo( "" + "Could not locate ResponseBody converter for class java.lang.String.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.converter.wire.WireConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } } @Test public void deserializeWrongType() throws IOException { ByteString encoded = ByteString.decodeBase64("Cg4oNTE5KSA4NjctNTMwOQ=="); server.enqueue(new MockResponse().setBody(new Buffer().write(encoded))); try { service.wrongType(); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() .isEqualTo( "" + "Unable to create converter for java.util.List\n" + " for method Service.wrongType"); assertThat(e.getCause()) .hasMessageThat() .isEqualTo( "" + "Could not locate ResponseBody converter for java.util.List.\n" + " Tried:\n" + " * retrofit2.BuiltInConverters\n" + " * retrofit2.converter.wire.WireConverterFactory\n" + " * retrofit2.OptionalConverterFactory"); } } @Test public void deserializeWrongValue() throws IOException { ByteString encoded = ByteString.decodeBase64("////"); server.enqueue(new MockResponse().setBody(new Buffer().write(encoded))); Call call = service.get(); try { call.execute(); fail(); } catch (EOFException ignored) { } } } ================================================ FILE: retrofit-mock/README.md ================================================ Mock Web Server ============== A mock web server for mocking HTTP responses from a server, and simulating network behaviour. Download -------- Download [the latest JAR][1] or grab via [Maven][2]: ```xml com.squareup.retrofit2 retrofit-mock see.latest.version ``` or [Gradle][1]: ```groovy implementation 'com.squareup.retrofit2:retrofit-mock:see.latest.version' ``` Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. [1]: https://search.maven.org/remote_content?g=com.squareup.retrofit2&a=retrofit-mock&v=LATEST [2]: http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22retrofit-mock%22 [snap]: https://s01.oss.sonatype.org/content/repositories/snapshots/ ================================================ FILE: retrofit-mock/build.gradle ================================================ apply plugin: 'java-library' apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'com.vanniktech.maven.publish' dependencies { api projects.retrofit compileOnly libs.kotlin.stdLib compileOnly libs.findBugsAnnotations testImplementation libs.junit testImplementation libs.truth testImplementation libs.kotlin.stdLib testImplementation libs.kotlinx.coroutines } jar { manifest { attributes 'Automatic-Module-Name': 'retrofit2.mock' } } ================================================ FILE: retrofit-mock/gradle.properties ================================================ POM_ARTIFACT_ID=retrofit-mock POM_NAME=Retrofit Mock Adapter POM_DESCRIPTION=An add-on to Retrofit for implementing fake services. ================================================ FILE: retrofit-mock/src/main/java/retrofit2/mock/BehaviorCall.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock; import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; import okhttp3.Request; import okio.Timeout; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; final class BehaviorCall implements Call { final NetworkBehavior behavior; final ExecutorService backgroundExecutor; final Call delegate; private volatile @Nullable Future task; volatile boolean canceled; @GuardedBy("this") private boolean executed; BehaviorCall(NetworkBehavior behavior, ExecutorService backgroundExecutor, Call delegate) { this.behavior = behavior; this.backgroundExecutor = backgroundExecutor; this.delegate = delegate; } @SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state. @Override public Call clone() { return new BehaviorCall<>(behavior, backgroundExecutor, delegate.clone()); } @Override public Request request() { return delegate.request(); } @Override public Timeout timeout() { return delegate.timeout(); } @SuppressWarnings("ConstantConditions") // Guarding public API nullability. @Override public void enqueue(final Callback callback) { if (callback == null) throw new NullPointerException("callback == null"); synchronized (this) { if (executed) throw new IllegalStateException("Already executed"); executed = true; } task = backgroundExecutor.submit( new Runnable() { boolean delaySleep() { long sleepMs = behavior.calculateDelay(MILLISECONDS); if (sleepMs > 0) { try { Thread.sleep(sleepMs); } catch (InterruptedException e) { callback.onFailure(BehaviorCall.this, new IOException("canceled", e)); return false; } } return true; } @Override public void run() { if (canceled) { callback.onFailure(BehaviorCall.this, new IOException("canceled")); } else if (behavior.calculateIsFailure()) { if (delaySleep()) { callback.onFailure(BehaviorCall.this, behavior.failureException()); } } else if (behavior.calculateIsError()) { if (delaySleep()) { //noinspection unchecked An error response has no body. callback.onResponse( BehaviorCall.this, (Response) behavior.createErrorResponse()); } } else { delegate.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { if (delaySleep()) { callback.onResponse(call, response); } } @Override public void onFailure(Call call, Throwable t) { if (delaySleep()) { callback.onFailure(call, t); } } }); } } }); } @Override public synchronized boolean isExecuted() { return executed; } @Override public Response execute() throws IOException { final AtomicReference> responseRef = new AtomicReference<>(); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { responseRef.set(response); latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); latch.countDown(); } }); try { latch.await(); } catch (InterruptedException e) { throw new IOException("canceled", e); } Response response = responseRef.get(); if (response != null) return response; Throwable failure = failureRef.get(); if (failure instanceof RuntimeException) throw (RuntimeException) failure; if (failure instanceof IOException) throw (IOException) failure; throw new RuntimeException(failure); } @Override public void cancel() { canceled = true; Future task = this.task; if (task != null) { task.cancel(true); } } @Override public boolean isCanceled() { return canceled; } } ================================================ FILE: retrofit-mock/src/main/java/retrofit2/mock/BehaviorDelegate.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; import java.util.concurrent.ExecutorService; import javax.annotation.Nullable; import kotlin.coroutines.Continuation; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.KotlinExtensions; import retrofit2.Response; import retrofit2.Retrofit; /** * Applies {@linkplain NetworkBehavior behavior} to responses and adapts them into the appropriate * return type using the {@linkplain Retrofit#callAdapterFactories() call adapters} of {@link * Retrofit}. * * @see MockRetrofit#create(Class) */ public final class BehaviorDelegate { final Retrofit retrofit; private final NetworkBehavior behavior; private final ExecutorService executor; private final Class service; BehaviorDelegate( Retrofit retrofit, NetworkBehavior behavior, ExecutorService executor, Class service) { this.retrofit = retrofit; this.behavior = behavior; this.executor = executor; this.service = service; } public T returningResponse(@Nullable Object response) { return returning(Calls.response(response)); } @SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety. public T returning(Call call) { final Call behaviorCall = new BehaviorCall<>(behavior, executor, call); return (T) Proxy.newProxyInstance( service.getClassLoader(), new Class[] {service}, (proxy, method, args) -> { ServiceMethodAdapterInfo adapterInfo = parseServiceMethodAdapterInfo(method); Annotation[] methodAnnotations = method.getAnnotations(); CallAdapter callAdapter = (CallAdapter) retrofit.callAdapter(adapterInfo.responseType, methodAnnotations); T adapted = callAdapter.adapt(behaviorCall); if (!adapterInfo.isSuspend) { return adapted; } Call adaptedCall = (Call) adapted; Continuation continuation = (Continuation) args[args.length - 1]; try { return adapterInfo.wantsResponse ? KotlinExtensions.awaitResponse(adaptedCall, continuation) : KotlinExtensions.await(adaptedCall, continuation); } catch (Exception e) { return KotlinExtensions.suspendAndThrow(e, continuation); } }); } /** * Computes the adapter type of the method for lookup via {@link Retrofit#callAdapter} as well as * information on whether the method is a {@code suspend fun}. * *

In the case of a Kotlin {@code suspend fun}, the last parameter type is a {@code * Continuation} whose parameter carries the actual response type. In this case, we return {@code * Call} where {@code T} is the body type. */ private static ServiceMethodAdapterInfo parseServiceMethodAdapterInfo(Method method) { Type[] genericParameterTypes = method.getGenericParameterTypes(); if (genericParameterTypes.length != 0) { Type lastParameterType = genericParameterTypes[genericParameterTypes.length - 1]; if (lastParameterType instanceof ParameterizedType) { ParameterizedType parameterizedLastParameterType = (ParameterizedType) lastParameterType; try { if (parameterizedLastParameterType.getRawType() == Continuation.class) { Type resultType = parameterizedLastParameterType.getActualTypeArguments()[0]; if (resultType instanceof WildcardType) { resultType = ((WildcardType) resultType).getLowerBounds()[0]; } if (resultType instanceof ParameterizedType) { ParameterizedType parameterizedResultType = (ParameterizedType) resultType; if (parameterizedResultType.getRawType() == Response.class) { Type bodyType = parameterizedResultType.getActualTypeArguments()[0]; Type callType = new CallParameterizedTypeImpl(bodyType); return new ServiceMethodAdapterInfo(true, true, callType); } } Type callType = new CallParameterizedTypeImpl(resultType); return new ServiceMethodAdapterInfo(true, false, callType); } } catch (NoClassDefFoundError ignored) { // Not using coroutines. } } } return new ServiceMethodAdapterInfo(false, false, method.getGenericReturnType()); } static final class CallParameterizedTypeImpl implements ParameterizedType { private final Type bodyType; CallParameterizedTypeImpl(Type bodyType) { this.bodyType = bodyType; } @Override public Type[] getActualTypeArguments() { return new Type[] {bodyType}; } @Override public Type getRawType() { return Call.class; } @Override public @Nullable Type getOwnerType() { return null; } } static class ServiceMethodAdapterInfo { final boolean isSuspend; /** * Whether the suspend function return type was {@code Response}. Only meaningful if {@link * #isSuspend} is true. */ final boolean wantsResponse; final Type responseType; ServiceMethodAdapterInfo(boolean isSuspend, boolean wantsResponse, Type responseType) { this.isSuspend = isSuspend; this.wantsResponse = wantsResponse; this.responseType = responseType; } } } ================================================ FILE: retrofit-mock/src/main/java/retrofit2/mock/Calls.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock; import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.Nullable; import okhttp3.Request; import okio.Timeout; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; /** Factory methods for creating {@link Call} instances which immediately respond or fail. */ public final class Calls { /** * Invokes {@code callable} once for the returned {@link Call} and once for each instance that is * obtained from {@linkplain Call#clone() cloning} the returned {@link Call}. */ public static Call defer(Callable> callable) { return new DeferredCall<>(callable); } public static Call response(@Nullable T successValue) { return new FakeCall<>(Response.success(successValue), null); } public static Call response(Response response) { return new FakeCall<>(response, null); } /** Creates a failed {@link Call} from {@code failure}. */ public static Call failure(IOException failure) { // TODO delete this overload in Retrofit 3.0. return new FakeCall<>(null, failure); } /** * Creates a failed {@link Call} from {@code failure}. * *

Note: When invoking {@link Call#execute() execute()} on the returned {@link Call}, if {@code * failure} is a {@link RuntimeException}, {@link Error}, or {@link IOException} subtype it is * thrown directly. Otherwise it is "sneaky thrown" despite not being declared. */ public static Call failure(Throwable failure) { return new FakeCall<>(null, failure); } private Calls() { throw new AssertionError("No instances."); } static final class FakeCall implements Call { private final Response response; private final Throwable error; private final AtomicBoolean canceled = new AtomicBoolean(); private final AtomicBoolean executed = new AtomicBoolean(); FakeCall(@Nullable Response response, @Nullable Throwable error) { if ((response == null) == (error == null)) { throw new AssertionError("Only one of response or error can be set."); } this.response = response; this.error = error; } @Override public Response execute() throws IOException { if (!executed.compareAndSet(false, true)) { throw new IllegalStateException("Already executed"); } if (canceled.get()) { throw new IOException("canceled"); } if (response != null) { return response; } throw FakeCall.sneakyThrow(error); } // Intentionally abusing this feature. @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) private static T sneakyThrow(Throwable t) throws T { throw (T) t; } @SuppressWarnings("ConstantConditions") // Guarding public API nullability. @Override public void enqueue(Callback callback) { if (callback == null) { throw new NullPointerException("callback == null"); } if (!executed.compareAndSet(false, true)) { throw new IllegalStateException("Already executed"); } if (canceled.get()) { callback.onFailure(this, new IOException("canceled")); } else if (response != null) { callback.onResponse(this, response); } else { callback.onFailure(this, error); } } @Override public boolean isExecuted() { return executed.get(); } @Override public void cancel() { canceled.set(true); } @Override public boolean isCanceled() { return canceled.get(); } @Override public Call clone() { return new FakeCall<>(response, error); } @Override public Request request() { if (response != null) { return response.raw().request(); } return new Request.Builder().url("http://localhost").build(); } @Override public Timeout timeout() { return Timeout.NONE; } } static final class DeferredCall implements Call { private final Callable> callable; private @Nullable Call delegate; DeferredCall(Callable> callable) { this.callable = callable; } private synchronized Call getDelegate() { Call delegate = this.delegate; if (delegate == null) { try { delegate = callable.call(); } catch (Exception e) { delegate = failure(e); } this.delegate = delegate; } return delegate; } @Override public Response execute() throws IOException { return getDelegate().execute(); } @Override public void enqueue(Callback callback) { getDelegate().enqueue(callback); } @Override public boolean isExecuted() { return getDelegate().isExecuted(); } @Override public void cancel() { getDelegate().cancel(); } @Override public boolean isCanceled() { return getDelegate().isCanceled(); } @Override public Call clone() { return new DeferredCall<>(callable); } @Override public Request request() { return getDelegate().request(); } @Override public Timeout timeout() { return getDelegate().timeout(); } } } ================================================ FILE: retrofit-mock/src/main/java/retrofit2/mock/KotlinExtensions.kt ================================================ /* * Copyright (C) 2019 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock inline fun MockRetrofit.create(): BehaviorDelegate = create(T::class.java) ================================================ FILE: retrofit-mock/src/main/java/retrofit2/mock/MockRetrofit.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.annotation.Nullable; import retrofit2.Retrofit; public final class MockRetrofit { private final Retrofit retrofit; private final NetworkBehavior behavior; private final ExecutorService executor; MockRetrofit(Retrofit retrofit, NetworkBehavior behavior, ExecutorService executor) { this.retrofit = retrofit; this.behavior = behavior; this.executor = executor; } public Retrofit retrofit() { return retrofit; } public NetworkBehavior networkBehavior() { return behavior; } public Executor backgroundExecutor() { return executor; } @SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety. public BehaviorDelegate create(Class service) { return new BehaviorDelegate<>(retrofit, behavior, executor, service); } public static final class Builder { private final Retrofit retrofit; private @Nullable NetworkBehavior behavior; private @Nullable ExecutorService executor; @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public Builder(Retrofit retrofit) { if (retrofit == null) throw new NullPointerException("retrofit == null"); this.retrofit = retrofit; } @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public Builder networkBehavior(NetworkBehavior behavior) { if (behavior == null) throw new NullPointerException("behavior == null"); this.behavior = behavior; return this; } @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public Builder backgroundExecutor(ExecutorService executor) { if (executor == null) throw new NullPointerException("executor == null"); this.executor = executor; return this; } public MockRetrofit build() { if (behavior == null) behavior = NetworkBehavior.create(); if (executor == null) executor = Executors.newCachedThreadPool(); return new MockRetrofit(retrofit, behavior, executor); } } } ================================================ FILE: retrofit-mock/src/main/java/retrofit2/mock/MockRetrofitIOException.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock; import java.io.IOException; final class MockRetrofitIOException extends IOException { MockRetrofitIOException() { super("Failure triggered by MockRetrofit's NetworkBehavior"); } } ================================================ FILE: retrofit-mock/src/main/java/retrofit2/mock/NetworkBehavior.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock; import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.io.IOException; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import okhttp3.ResponseBody; import retrofit2.Response; /** * A simple emulation of the behavior of network calls. * *

This class models three properties of a network: * *

    *
  • Delay – the time it takes before a response is received (successful or otherwise). *
  • Variance – the amount of fluctuation of the delay to be faster or slower. *
  • Failure - the percentage of operations which fail (such as {@link IOException}). *
* * Behavior can be applied to a Retrofit interface with {@link MockRetrofit}. Behavior can also be * applied elsewhere using {@link #calculateDelay(TimeUnit)} and {@link #calculateIsFailure()}. * *

By default, instances of this class will use a 2 second delay with 40% variance. Failures will * occur 3% of the time. HTTP errors will occur 0% of the time. */ public final class NetworkBehavior { private static final int DEFAULT_DELAY_MS = 2000; // Network calls will take 2 seconds. private static final int DEFAULT_VARIANCE_PERCENT = 40; // Network delay varies by ±40%. private static final int DEFAULT_FAILURE_PERCENT = 3; // 3% of network calls will fail. private static final int DEFAULT_ERROR_PERCENT = 0; // 0% of network calls will return errors. /** Create an instance with default behavior. */ public static NetworkBehavior create() { return new NetworkBehavior(new Random()); } /** * Create an instance with default behavior which uses {@code random} to control variance and * failure calculation. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static NetworkBehavior create(Random random) { if (random == null) throw new NullPointerException("random == null"); return new NetworkBehavior(random); } private final Random random; private volatile long delayMs = DEFAULT_DELAY_MS; private volatile int variancePercent = DEFAULT_VARIANCE_PERCENT; private volatile int failurePercent = DEFAULT_FAILURE_PERCENT; private volatile Throwable failureException; private volatile int errorPercent = DEFAULT_ERROR_PERCENT; private volatile Callable> errorFactory = () -> Response.error(500, ResponseBody.create(null, new byte[0])); private NetworkBehavior(Random random) { this.random = random; failureException = new MockRetrofitIOException(); failureException.setStackTrace(new StackTraceElement[0]); } /** Set the network round trip delay. */ public void setDelay(long amount, TimeUnit unit) { if (amount < 0) { throw new IllegalArgumentException("Amount must be positive value."); } this.delayMs = unit.toMillis(amount); } /** The network round trip delay. */ public long delay(TimeUnit unit) { return MILLISECONDS.convert(delayMs, unit); } /** Set the plus-or-minus variance percentage of the network round trip delay. */ public void setVariancePercent(int variancePercent) { checkPercentageValidity(variancePercent, "Variance percentage must be between 0 and 100."); this.variancePercent = variancePercent; } /** The plus-or-minus variance percentage of the network round trip delay. */ public int variancePercent() { return variancePercent; } /** Set the percentage of calls to {@link #calculateIsFailure()} that return {@code true}. */ public void setFailurePercent(int failurePercent) { checkPercentageValidity(failurePercent, "Failure percentage must be between 0 and 100."); this.failurePercent = failurePercent; } /** The percentage of calls to {@link #calculateIsFailure()} that return {@code true}. */ public int failurePercent() { return failurePercent; } /** * Set the exception to be used when a failure is triggered. * *

It is a best practice to remove the stack trace from {@code exception} since it can * misleadingly point to code unrelated to this class. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public void setFailureException(Throwable exception) { if (exception == null) { throw new NullPointerException("exception == null"); } this.failureException = exception; } /** The exception to be used when a failure is triggered. */ public Throwable failureException() { return failureException; } /** The percentage of calls to {@link #calculateIsError()} that return {@code true}. */ public int errorPercent() { return errorPercent; } /** Set the percentage of calls to {@link #calculateIsError()} that return {@code true}. */ public void setErrorPercent(int errorPercent) { checkPercentageValidity(errorPercent, "Error percentage must be between 0 and 100."); this.errorPercent = errorPercent; } /** * Set the error response factory to be used when an error is triggered. This factory may only * return responses for which {@link Response#isSuccessful()} returns false. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public void setErrorFactory(Callable> errorFactory) { if (errorFactory == null) { throw new NullPointerException("errorFactory == null"); } this.errorFactory = errorFactory; } /** The HTTP error to be used when an error is triggered. */ public Response createErrorResponse() { Response call; try { call = errorFactory.call(); } catch (Exception e) { throw new IllegalStateException("Error factory threw an exception.", e); } if (call == null) { throw new IllegalStateException("Error factory returned null."); } if (call.isSuccessful()) { throw new IllegalStateException("Error factory returned successful response."); } return call; } /** * Randomly determine whether this call should result in a network failure in accordance with * configured behavior. When true, {@link #failureException()} should be thrown. */ public boolean calculateIsFailure() { return random.nextInt(100) < failurePercent; } /** * Randomly determine whether this call should result in an HTTP error in accordance with * configured behavior. When true, {@link #createErrorResponse()} should be returned. */ public boolean calculateIsError() { return random.nextInt(100) < errorPercent; } /** * Get the delay that should be used for delaying a response in accordance with configured * behavior. */ public long calculateDelay(TimeUnit unit) { float delta = variancePercent / 100f; // e.g., 20 / 100f == 0.2f float lowerBound = 1f - delta; // 0.2f --> 0.8f float upperBound = 1f + delta; // 0.2f --> 1.2f float bound = upperBound - lowerBound; // 1.2f - 0.8f == 0.4f float delayPercent = lowerBound + (random.nextFloat() * bound); // 0.8 + (rnd * 0.4) long callDelayMs = (long) (delayMs * delayPercent); return MILLISECONDS.convert(callDelayMs, unit); } private static void checkPercentageValidity(int percentage, String message) { if (percentage < 0 || percentage > 100) { throw new IllegalArgumentException(message); } } } ================================================ FILE: retrofit-mock/src/main/java/retrofit2/mock/package-info.java ================================================ @retrofit2.internal.EverythingIsNonNull package retrofit2.mock; ================================================ FILE: retrofit-mock/src/test/java/retrofit2/mock/BehaviorDelegateKotlinTest.kt ================================================ /* * Copyright (C) 2019 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock import com.google.common.truth.Truth.assertThat import java.io.IOException import java.util.Random import java.util.concurrent.TimeUnit.MILLISECONDS import java.util.concurrent.TimeUnit.NANOSECONDS import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Test import retrofit2.Response import retrofit2.Retrofit class BehaviorDelegateKotlinTest { internal interface DoWorkService { suspend fun body(): String suspend fun failure(): String suspend fun response(): Response suspend fun responseWildcard(): Response } private val mockFailure = IOException("Timeout!") private val behavior = NetworkBehavior.create(Random(2847)) private lateinit var service: DoWorkService @Before fun before() { val retrofit = Retrofit.Builder().baseUrl("http://example.com").build() val mockRetrofit = MockRetrofit.Builder(retrofit).networkBehavior(behavior).build() val delegate = mockRetrofit.create() service = object : DoWorkService { override suspend fun body(): String { return delegate.returning(Calls.response("Response!")).body() } override suspend fun failure(): String { val failure = Calls.failure(mockFailure) return delegate.returning(failure).failure() } override suspend fun response(): Response { val response = Calls.response("Response!") return delegate.returning(response).response() } override suspend fun responseWildcard() = response() } } @Test fun body() { behavior.setDelay(100, MILLISECONDS) behavior.setVariancePercent(0) behavior.setFailurePercent(0) val startNanos = System.nanoTime() val result = runBlocking { service.body() } val tookMs = NANOSECONDS.toMillis(System.nanoTime() - startNanos) assertThat(tookMs).isAtLeast(100L) assertThat(result).isEqualTo("Response!") } @Test fun bodyFailure() { behavior.setDelay(100, MILLISECONDS) behavior.setVariancePercent(0) behavior.setFailurePercent(100) val startNanos = System.nanoTime() val exception = runBlocking { try { throw AssertionError(service.body()) } catch (e: Exception) { e } } val tookMs = NANOSECONDS.toMillis(System.nanoTime() - startNanos) assertThat(tookMs).isAtLeast(100L) assertThat(exception).isSameInstanceAs(behavior.failureException()) } @Test fun failure() { behavior.setDelay(100, MILLISECONDS) behavior.setVariancePercent(0) behavior.setFailurePercent(0) val startNanos = System.nanoTime() val exception = runBlocking { try { throw AssertionError(service.failure()) } catch (e: Exception) { e } } val tookMs = NANOSECONDS.toMillis(System.nanoTime() - startNanos) assertThat(tookMs).isAtLeast(100L) // Coroutines break referential transparency on exceptions so compare type and message. assertThat(exception.javaClass).isEqualTo(mockFailure.javaClass) assertThat(exception).hasMessageThat().isEqualTo(mockFailure.message) } @Test fun response() { behavior.setDelay(100, MILLISECONDS) behavior.setVariancePercent(0) behavior.setFailurePercent(0) val startNanos = System.nanoTime() val result = runBlocking { service.response() } val tookMs = NANOSECONDS.toMillis(System.nanoTime() - startNanos) assertThat(tookMs).isAtLeast(100L) assertThat(result.body()).isEqualTo("Response!") } @Test fun responseFailure() { behavior.setDelay(100, MILLISECONDS) behavior.setVariancePercent(0) behavior.setFailurePercent(100) val startNanos = System.nanoTime() val exception = runBlocking { try { throw AssertionError(service.response()) } catch (e: Exception) { e } } val tookMs = NANOSECONDS.toMillis(System.nanoTime() - startNanos) assertThat(tookMs).isAtLeast(100L) assertThat(exception).isSameInstanceAs(behavior.failureException()) } @Test fun responseWildcard() { behavior.setDelay(100, MILLISECONDS) behavior.setVariancePercent(0) behavior.setFailurePercent(0) val startNanos = System.nanoTime() val result = runBlocking { service.responseWildcard() } val tookMs = NANOSECONDS.toMillis(System.nanoTime() - startNanos) assertThat(tookMs).isAtLeast(100L) assertThat(result.body()).isEqualTo("Response!") } } ================================================ FILE: retrofit-mock/src/test/java/retrofit2/mock/BehaviorDelegateTest.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock; import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import org.junit.Before; import org.junit.Test; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; public final class BehaviorDelegateTest { interface DoWorkService { Call response(); Call failure(); } private final IOException mockFailure = new IOException("Timeout!"); private final NetworkBehavior behavior = NetworkBehavior.create(new Random(2847)); private DoWorkService service; @Before public void setUp() { Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com").build(); MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).networkBehavior(behavior).build(); final BehaviorDelegate delegate = mockRetrofit.create(DoWorkService.class); service = new DoWorkService() { @Override public Call response() { Call response = Calls.response("Response!"); return delegate.returning(response).response(); } @Override public Call failure() { Call failure = Calls.failure(mockFailure); return delegate.returning(failure).failure(); } }; } @Test public void syncFailureThrowsAfterDelay() { behavior.setDelay(100, MILLISECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(100); Call call = service.response(); long startNanos = System.nanoTime(); try { call.execute(); fail(); } catch (IOException e) { long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos); assertThat(e).isSameInstanceAs(behavior.failureException()); assertThat(tookMs).isAtLeast(100); } } @Test public void asyncFailureTriggersFailureAfterDelay() throws InterruptedException { behavior.setDelay(100, MILLISECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(100); Call call = service.response(); final long startNanos = System.nanoTime(); final AtomicLong tookMs = new AtomicLong(); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { tookMs.set(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos)); failureRef.set(t); latch.countDown(); } }); assertTrue(latch.await(1, SECONDS)); assertThat(failureRef.get()).isSameInstanceAs(behavior.failureException()); assertThat(tookMs.get()).isAtLeast(100); } @Test public void syncSuccessReturnsAfterDelay() throws IOException { behavior.setDelay(100, MILLISECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(0); Call call = service.response(); long startNanos = System.nanoTime(); Response response = call.execute(); long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos); assertThat(response.body()).isEqualTo("Response!"); assertThat(tookMs).isAtLeast(100); } @Test public void asyncSuccessCalledAfterDelay() throws InterruptedException, IOException { behavior.setDelay(100, MILLISECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(0); Call call = service.response(); final long startNanos = System.nanoTime(); final AtomicLong tookMs = new AtomicLong(); final AtomicReference actual = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { tookMs.set(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos)); actual.set(response.body()); latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { throw new AssertionError(); } }); assertTrue(latch.await(1, SECONDS)); assertThat(actual.get()).isEqualTo("Response!"); assertThat(tookMs.get()).isAtLeast(100); } @Test public void syncFailureThrownAfterDelay() { behavior.setDelay(100, MILLISECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(0); Call call = service.failure(); long startNanos = System.nanoTime(); try { call.execute(); fail(); } catch (IOException e) { long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos); assertThat(tookMs).isAtLeast(100); assertThat(e).isSameInstanceAs(mockFailure); } } @Test public void asyncFailureCalledAfterDelay() throws InterruptedException { behavior.setDelay(100, MILLISECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(0); Call call = service.failure(); final AtomicLong tookMs = new AtomicLong(); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); final long startNanos = System.nanoTime(); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { throw new AssertionError(); } @Override public void onFailure(Call call, Throwable t) { tookMs.set(TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos)); failureRef.set(t); latch.countDown(); } }); assertTrue(latch.await(1, SECONDS)); assertThat(tookMs.get()).isAtLeast(100); assertThat(failureRef.get()).isSameInstanceAs(mockFailure); } @Test public void syncCanBeCanceled() throws IOException { behavior.setDelay(10, SECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(0); final Call call = service.response(); new Thread( () -> { try { Thread.sleep(100); call.cancel(); } catch (InterruptedException ignored) { } }) .start(); try { call.execute(); fail(); } catch (IOException e) { // Exact instance check as opposed to isInstanceOf's subtype checking. assertThat(e.getClass()).isEqualTo(IOException.class); assertThat(e).hasMessageThat().isEqualTo("canceled"); } } @Test public void asyncCanBeCanceled() throws InterruptedException { behavior.setDelay(10, SECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(0); final Call call = service.response(); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); latch.countDown(); } }); // TODO we shouldn't need to sleep Thread.sleep(100); // Ensure the task has started. call.cancel(); assertTrue(latch.await(1, SECONDS)); Throwable failure = failureRef.get(); // Exact instance check as opposed to isInstanceOf's subtype checking. assertThat(failure.getClass()).isEqualTo(IOException.class); assertThat(failure).hasMessageThat().isEqualTo("canceled"); } @Test public void syncCanceledBeforeStart() throws IOException { behavior.setDelay(100, MILLISECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(0); final Call call = service.response(); call.cancel(); try { call.execute(); fail(); } catch (IOException e) { // Exact instance check as opposed to isInstanceOf's subtype checking. assertThat(e.getClass()).isEqualTo(IOException.class); assertThat(e).hasMessageThat().isEqualTo("canceled"); } } @Test public void asyncCanBeCanceledBeforeStart() throws InterruptedException { behavior.setDelay(10, SECONDS); behavior.setVariancePercent(0); behavior.setFailurePercent(0); final Call call = service.response(); call.cancel(); final AtomicReference failureRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { latch.countDown(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); latch.countDown(); } }); assertTrue(latch.await(1, SECONDS)); Throwable failure = failureRef.get(); // Exact instance check as opposed to isInstanceOf's subtype checking. assertThat(failure.getClass()).isEqualTo(IOException.class); assertThat(failure).hasMessageThat().isEqualTo("canceled"); } } ================================================ FILE: retrofit-mock/src/test/java/retrofit2/mock/CallsTest.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.security.cert.CertificateException; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public final class CallsTest { @Test public void bodyExecute() throws IOException { Call taco = Calls.response("Taco"); assertEquals("Taco", taco.execute().body()); } @Test public void bodyEnqueue() throws IOException { Call taco = Calls.response("Taco"); final AtomicReference> responseRef = new AtomicReference<>(); taco.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { responseRef.set(response); } @Override public void onFailure(Call call, Throwable t) { fail(); } }); assertThat(responseRef.get().body()).isEqualTo("Taco"); } @Test public void responseExecute() throws IOException { Response response = Response.success("Taco"); Call taco = Calls.response(response); assertFalse(taco.isExecuted()); assertSame(response, taco.execute()); assertTrue(taco.isExecuted()); try { taco.execute(); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessageThat().isEqualTo("Already executed"); } } @Test public void responseEnqueue() { Response response = Response.success("Taco"); Call taco = Calls.response(response); assertFalse(taco.isExecuted()); final AtomicReference> responseRef = new AtomicReference<>(); taco.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { responseRef.set(response); } @Override public void onFailure(Call call, Throwable t) { fail(); } }); assertSame(response, responseRef.get()); assertTrue(taco.isExecuted()); try { taco.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { fail(); } @Override public void onFailure(Call call, Throwable t) { fail(); } }); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessageThat().isEqualTo("Already executed"); } } @Test public void enqueueNullThrows() { Call taco = Calls.response("Taco"); try { taco.enqueue(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("callback == null"); } } @Test public void responseCancelExecute() { Call taco = Calls.response(Response.success("Taco")); assertFalse(taco.isCanceled()); taco.cancel(); assertTrue(taco.isCanceled()); try { taco.execute(); fail(); } catch (IOException e) { assertThat(e).hasMessageThat().isEqualTo("canceled"); } } @Test public void responseCancelEnqueue() throws IOException { Call taco = Calls.response(Response.success("Taco")); assertFalse(taco.isCanceled()); taco.cancel(); assertTrue(taco.isCanceled()); final AtomicReference failureRef = new AtomicReference<>(); taco.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { fail(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); } }); Throwable failure = failureRef.get(); assertThat(failure).isInstanceOf(IOException.class); assertThat(failure).hasMessageThat().isEqualTo("canceled"); } @Test public void failureExecute() { IOException failure = new IOException("Hey"); Call taco = Calls.failure(failure); assertFalse(taco.isExecuted()); try { taco.execute(); fail(); } catch (IOException e) { assertSame(failure, e); } assertTrue(taco.isExecuted()); } @Test public void failureExecuteCheckedException() { CertificateException failure = new CertificateException("Hey"); Call taco = Calls.failure(failure); assertFalse(taco.isExecuted()); try { taco.execute(); fail(); } catch (Exception e) { assertSame(failure, e); } assertTrue(taco.isExecuted()); } @Test public void failureEnqueue() { IOException failure = new IOException("Hey"); Call taco = Calls.failure(failure); assertFalse(taco.isExecuted()); final AtomicReference failureRef = new AtomicReference<>(); taco.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { fail(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); } }); assertSame(failure, failureRef.get()); assertTrue(taco.isExecuted()); } @Test public void cloneHasOwnState() throws IOException { Call taco = Calls.response("Taco"); assertEquals("Taco", taco.execute().body()); Call anotherTaco = taco.clone(); assertFalse(anotherTaco.isExecuted()); assertEquals("Taco", anotherTaco.execute().body()); assertTrue(anotherTaco.isExecuted()); } @Test public void deferredReturnExecute() throws IOException { Call counts = Calls.defer( new Callable>() { private int count = 0; @Override public Call call() throws Exception { return Calls.response(++count); } }); Call a = counts.clone(); Call b = counts.clone(); assertEquals(1, b.execute().body().intValue()); assertEquals(2, a.execute().body().intValue()); } @Test public void deferredReturnEnqueue() { Call counts = Calls.defer( new Callable>() { private int count = 0; @Override public Call call() throws Exception { return Calls.response(++count); } }); Call a = counts.clone(); Call b = counts.clone(); final AtomicReference> responseRef = new AtomicReference<>(); Callback callback = new Callback() { @Override public void onResponse(Call call, Response response) { responseRef.set(response); } @Override public void onFailure(Call call, Throwable t) { fail(); } }; b.enqueue(callback); assertEquals(1, responseRef.get().body().intValue()); a.enqueue(callback); assertEquals(2, responseRef.get().body().intValue()); } @Test public void deferredThrowExecute() throws IOException { final IOException failure = new IOException("Hey"); Call failing = Calls.defer( () -> { throw failure; }); try { failing.execute(); fail(); } catch (IOException e) { assertSame(failure, e); } } @Test public void deferredThrowEnqueue() { final IOException failure = new IOException("Hey"); Call failing = Calls.defer( () -> { throw failure; }); final AtomicReference failureRef = new AtomicReference<>(); failing.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { fail(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); } }); assertSame(failure, failureRef.get()); } @Test public void deferredThrowUncheckedExceptionEnqueue() { final RuntimeException failure = new RuntimeException("Hey"); final AtomicReference failureRef = new AtomicReference<>(); Calls.failure(failure) .enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { fail(); } @Override public void onFailure(Call call, Throwable t) { failureRef.set(t); } }); assertSame(failure, failureRef.get()); } } ================================================ FILE: retrofit-mock/src/test/java/retrofit2/mock/MockRetrofitTest.java ================================================ package retrofit2.mock; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.Test; import retrofit2.Retrofit; public final class MockRetrofitTest { private final Retrofit retrofit = new Retrofit.Builder().baseUrl("http://example.com").build(); private final NetworkBehavior behavior = NetworkBehavior.create(); private final ExecutorService executor = Executors.newSingleThreadExecutor(); @Test public void retrofitNullThrows() { try { new MockRetrofit.Builder(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("retrofit == null"); } } @Test public void retrofitPropagated() { MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).build(); assertThat(mockRetrofit.retrofit()).isSameInstanceAs(retrofit); } @Test public void networkBehaviorNullThrows() { MockRetrofit.Builder builder = new MockRetrofit.Builder(retrofit); try { builder.networkBehavior(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("behavior == null"); } } @Test public void networkBehaviorDefault() { MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).build(); assertThat(mockRetrofit.networkBehavior()).isNotNull(); } @Test public void networkBehaviorPropagated() { MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).networkBehavior(behavior).build(); assertThat(mockRetrofit.networkBehavior()).isSameInstanceAs(behavior); } @Test public void backgroundExecutorNullThrows() { MockRetrofit.Builder builder = new MockRetrofit.Builder(retrofit); try { builder.backgroundExecutor(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("executor == null"); } } @Test public void backgroundExecutorDefault() { MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).build(); assertThat(mockRetrofit.backgroundExecutor()).isNotNull(); } @Test public void backgroundExecutorPropagated() { MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).backgroundExecutor(executor).build(); assertThat(mockRetrofit.backgroundExecutor()).isSameInstanceAs(executor); } } ================================================ FILE: retrofit-mock/src/test/java/retrofit2/mock/NetworkBehaviorTest.java ================================================ /* * Copyright (C) 2013 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.mock; import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.IOException; import java.util.Random; import java.util.concurrent.Callable; import okhttp3.ResponseBody; import org.junit.Test; import retrofit2.Response; public final class NetworkBehaviorTest { private final NetworkBehavior behavior = NetworkBehavior.create(new Random(2847)); @Test public void defaultThrowable() { Throwable t = behavior.failureException(); assertThat(t).isInstanceOf(IOException.class); // Exact instance check as opposed to isInstanceOf's subtype checking. assertThat(t.getClass()).isEqualTo(MockRetrofitIOException.class); assertThat(t.getStackTrace()).isEmpty(); } @Test public void delayMustBePositive() { try { behavior.setDelay(-1, SECONDS); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("Amount must be positive value."); } } @Test public void varianceRestrictsRange() { try { behavior.setVariancePercent(-13); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("Variance percentage must be between 0 and 100."); } try { behavior.setVariancePercent(174); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("Variance percentage must be between 0 and 100."); } } @Test public void failureRestrictsRange() { try { behavior.setFailurePercent(-13); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("Failure percentage must be between 0 and 100."); } try { behavior.setFailurePercent(174); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("Failure percentage must be between 0 and 100."); } } @Test public void failureExceptionIsNotNull() { try { behavior.setFailureException(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("exception == null"); } } @Test public void errorRestrictsRange() { try { behavior.setErrorPercent(-13); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("Error percentage must be between 0 and 100."); } try { behavior.setErrorPercent(174); fail(); } catch (IllegalArgumentException e) { assertThat(e).hasMessageThat().isEqualTo("Error percentage must be between 0 and 100."); } } @Test public void errorFactoryIsNotNull() { try { behavior.setErrorFactory(null); fail(); } catch (NullPointerException e) { assertThat(e).hasMessageThat().isEqualTo("errorFactory == null"); } } @Test public void errorFactoryCannotReturnNull() { behavior.setErrorFactory(() -> null); try { behavior.createErrorResponse(); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessageThat().isEqualTo("Error factory returned null."); } } @Test public void errorFactoryCannotThrow() { final RuntimeException broken = new RuntimeException("Broken"); behavior.setErrorFactory( () -> { throw broken; }); try { behavior.createErrorResponse(); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessageThat().isEqualTo("Error factory threw an exception."); assertThat(e).hasCauseThat().isSameInstanceAs(broken); } } @Test public void errorFactoryCannotReturnSuccess() { behavior.setErrorFactory(() -> Response.success("Taco")); try { behavior.createErrorResponse(); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessageThat().isEqualTo("Error factory returned successful response."); } } @Test public void errorFactoryCalledEachTime() { behavior.setErrorFactory( new Callable>() { private int code = 500; @Override public Response call() throws Exception { return Response.error(code++, ResponseBody.create(null, new byte[0])); } }); assertEquals(500, behavior.createErrorResponse().code()); assertEquals(501, behavior.createErrorResponse().code()); assertEquals(502, behavior.createErrorResponse().code()); } @Test public void failurePercentageIsAccurate() { behavior.setFailurePercent(0); for (int i = 0; i < 10000; i++) { assertThat(behavior.calculateIsFailure()).isFalse(); } behavior.setFailurePercent(3); int failures = 0; for (int i = 0; i < 100000; i++) { if (behavior.calculateIsFailure()) { failures += 1; } } assertThat(failures).isEqualTo(2964); // ~3% of 100k } @Test public void errorPercentageIsAccurate() { behavior.setErrorPercent(0); for (int i = 0; i < 10000; i++) { assertThat(behavior.calculateIsError()).isFalse(); } behavior.setErrorPercent(3); int errors = 0; for (int i = 0; i < 100000; i++) { if (behavior.calculateIsError()) { errors += 1; } } assertThat(errors).isEqualTo(2964); // ~3% of 100k } @Test public void delayVarianceIsAccurate() { behavior.setDelay(2, SECONDS); behavior.setVariancePercent(0); for (int i = 0; i < 100000; i++) { assertThat(behavior.calculateDelay(MILLISECONDS)).isEqualTo(2000); } behavior.setVariancePercent(40); long lowerBound = Integer.MAX_VALUE; long upperBound = Integer.MIN_VALUE; for (int i = 0; i < 100000; i++) { long delay = behavior.calculateDelay(MILLISECONDS); if (delay > upperBound) { upperBound = delay; } if (delay < lowerBound) { lowerBound = delay; } } assertThat(upperBound).isEqualTo(2799); // ~40% above 2000 assertThat(lowerBound).isEqualTo(1200); // ~40% below 2000 } } ================================================ FILE: retrofit-response-type-keeper/README.md ================================================ # Response Type Keeper Generates keep rules for types mentioned in generic parameter positions of Retrofit service methods. ## Problem Given a service method like ```java @GET("users/{id}") Call getUser( @Path("id") String id); ``` If you execute this request and do not actually use the returned `User` instance, R8 will remove it and replace the return type as `Call`. This fails Retrofit's runtime validation since a wildcard is not a valid type to pass to a converter. Note: this removal only occurs if the Retrofit's service method definition is the only reference to `User`. ## Solution This module contains an annotation processor which looks at each Retrofit method and generates explicit `-keep` rules for the types mentioned. Add it to Gradle Java projects with ```groovy annotationProcessor 'com.squareup.retrofit2:response-type-keeper:' ``` Or Gradle Kotlin projects with ```groovy kapt 'com.squareup.retrofit2:response-type-keeper:' ``` For other build systems, the `com.squareup.retrofit2:response-type-keeper` needs added to the Java compiler `-processor` classpath. For the example above, the annotation processor's generated file would contain ``` -keep com.example.User ``` This works for nested generics, such as `Call>`, which would produce: ``` -keep com.example.ApiResponse -keep com.example.User ``` It also works on Kotlin `suspend` functions which turn into a type like `Continuation` in the Java bytecode. ================================================ FILE: retrofit-response-type-keeper/build.gradle ================================================ apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'com.vanniktech.maven.publish' dependencies { testImplementation libs.junit testImplementation libs.compileTesting testImplementation libs.truth testImplementation projects.retrofit } ================================================ FILE: retrofit-response-type-keeper/gradle.properties ================================================ POM_ARTIFACT_ID=response-type-keeper POM_NAME=Response Type Keeper POM_DESCRIPTION=Annotation processor to generate R8 keep rules for types mentioned in generics. ================================================ FILE: retrofit-response-type-keeper/src/main/kotlin/retrofit2/keeper/RetrofitResponseTypeKeepProcessor.kt ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.keeper import javax.annotation.processing.AbstractProcessor import javax.annotation.processing.RoundEnvironment import javax.lang.model.SourceVersion import javax.lang.model.element.ExecutableElement import javax.lang.model.element.TypeElement import javax.lang.model.type.DeclaredType import javax.lang.model.type.TypeMirror import javax.lang.model.type.WildcardType import javax.tools.StandardLocation.CLASS_OUTPUT class RetrofitResponseTypeKeepProcessor : AbstractProcessor() { override fun getSupportedSourceVersion() = SourceVersion.latestSupported() override fun getSupportedAnnotationTypes() = setOf( "retrofit2.http.DELETE", "retrofit2.http.GET", "retrofit2.http.HEAD", "retrofit2.http.HTTP", "retrofit2.http.OPTIONS", "retrofit2.http.PATCH", "retrofit2.http.POST", "retrofit2.http.PUT", ) override fun process( annotations: Set, roundEnv: RoundEnvironment, ): Boolean { val elements = processingEnv.elementUtils val types = processingEnv.typeUtils val methods = supportedAnnotationTypes .mapNotNull(elements::getTypeElement) .flatMap(roundEnv::getElementsAnnotatedWith) val elementToReferencedTypes = mutableMapOf>() for (method in methods) { val executableElement = method as ExecutableElement val serviceType = method.enclosingElement as TypeElement val referenced = elementToReferencedTypes.getOrPut(serviceType, ::LinkedHashSet) val returnType = executableElement.returnType as DeclaredType returnType.recursiveParameterizedTypesTo(referenced) // Retrofit has special support for 'suspend fun' in Kotlin which manifests as a // final Continuation parameter whose generic type is the declared return type. executableElement.parameters .lastOrNull() ?.asType() ?.takeIf { types.erasure(it).toString() == "kotlin.coroutines.Continuation" } ?.let { (it as DeclaredType).typeArguments.single() } ?.recursiveParameterizedTypesTo(referenced) } for ((element, referencedTypes) in elementToReferencedTypes) { val typeName = element.qualifiedName.toString() val outputFile = "META-INF/proguard/retrofit-response-type-keeper-$typeName.pro" val rules = processingEnv.filer.createResource(CLASS_OUTPUT, "", outputFile, element) rules.openWriter().buffered().use { w -> w.write("# $typeName\n") for (referencedType in referencedTypes.sorted()) { w.write("-keep,allowoptimization,allowshrinking,allowobfuscation class $referencedType\n") } } } return false } private fun TypeMirror.recursiveParameterizedTypesTo(types: MutableSet) { when (this) { is WildcardType -> { extendsBound?.recursiveParameterizedTypesTo(types) superBound?.recursiveParameterizedTypesTo(types) } is DeclaredType -> { for (typeArgument in typeArguments) { typeArgument.recursiveParameterizedTypesTo(types) } types += (asElement() as TypeElement).qualifiedName.toString() } } } } ================================================ FILE: retrofit-response-type-keeper/src/main/resources/META-INF/gradle/incremental.annotation.processors ================================================ retrofit2.keeper.RetrofitResponseTypeKeepProcessor,ISOLATING ================================================ FILE: retrofit-response-type-keeper/src/main/resources/META-INF/services/javax.annotation.processing.Processor ================================================ retrofit2.keeper.RetrofitResponseTypeKeepProcessor ================================================ FILE: retrofit-response-type-keeper/src/test/kotlin/retrofit2/keeper/RetrofitResponseTypeKeepProcessorTest.kt ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package retrofit2.keeper import com.google.common.truth.Truth.assertAbout import com.google.testing.compile.JavaFileObjects import com.google.testing.compile.JavaSourceSubjectFactory.javaSource import java.nio.charset.StandardCharsets.UTF_8 import javax.tools.StandardLocation.CLASS_OUTPUT import org.junit.Test class RetrofitResponseTypeKeepProcessorTest { @Test fun allHttpMethods() { val service = JavaFileObjects.forSourceString( "test.Service", """ package test; import retrofit2.*; import retrofit2.http.*; class DeleteUser {} class GetUser {} class HeadUser {} class HttpUser {} class OptionsUser {} class PatchUser {} class PostUser {} class PutUser {} interface Service { @DELETE("/") Call delete(); @GET("/") Call get(); @HEAD("/") Call head(); @HTTP(method = "CUSTOM", path = "/") Call http(); @OPTIONS("/") Call options(); @PATCH("/") Call patch(); @POST("/") Call post(); @PUT("/") Call put(); } """.trimIndent(), ) assertAbout(javaSource()) .that(service) .processedWith(RetrofitResponseTypeKeepProcessor()) .compilesWithoutError() .and() .generatesFileNamed( CLASS_OUTPUT, "", "META-INF/proguard/retrofit-response-type-keeper-test.Service.pro", ).withStringContents( UTF_8, """ |# test.Service |-keep,allowoptimization,allowshrinking,allowobfuscation class retrofit2.Call |-keep,allowoptimization,allowshrinking,allowobfuscation class test.DeleteUser |-keep,allowoptimization,allowshrinking,allowobfuscation class test.GetUser |-keep,allowoptimization,allowshrinking,allowobfuscation class test.HeadUser |-keep,allowoptimization,allowshrinking,allowobfuscation class test.HttpUser |-keep,allowoptimization,allowshrinking,allowobfuscation class test.OptionsUser |-keep,allowoptimization,allowshrinking,allowobfuscation class test.PatchUser |-keep,allowoptimization,allowshrinking,allowobfuscation class test.PostUser |-keep,allowoptimization,allowshrinking,allowobfuscation class test.PutUser | """.trimMargin(), ) } @Test fun nesting() { val service = JavaFileObjects.forSourceString( "test.Service", """ package test; import retrofit2.*; import retrofit2.http.*; class One {} class Two {} class Three {} interface Service { @GET("/") Call>> get(); } """.trimIndent(), ) assertAbout(javaSource()) .that(service) .processedWith(RetrofitResponseTypeKeepProcessor()) .compilesWithoutError() .and() .generatesFileNamed( CLASS_OUTPUT, "", "META-INF/proguard/retrofit-response-type-keeper-test.Service.pro", ).withStringContents( UTF_8, """ |# test.Service |-keep,allowoptimization,allowshrinking,allowobfuscation class retrofit2.Call |-keep,allowoptimization,allowshrinking,allowobfuscation class test.One |-keep,allowoptimization,allowshrinking,allowobfuscation class test.Three |-keep,allowoptimization,allowshrinking,allowobfuscation class test.Two | """.trimMargin(), ) } @Test fun kotlinSuspend() { val service = JavaFileObjects.forSourceString( "test.Service", """ package test; import kotlin.coroutines.Continuation; import retrofit2.*; import retrofit2.http.*; class Body {} interface Service { @GET("/") Object get(Continuation c); } """.trimIndent(), ) assertAbout(javaSource()) .that(service) .processedWith(RetrofitResponseTypeKeepProcessor()) .compilesWithoutError() .and() .generatesFileNamed( CLASS_OUTPUT, "", "META-INF/proguard/retrofit-response-type-keeper-test.Service.pro", ).withStringContents( UTF_8, """ |# test.Service |-keep,allowoptimization,allowshrinking,allowobfuscation class java.lang.Object |-keep,allowoptimization,allowshrinking,allowobfuscation class test.Body | """.trimMargin(), ) } } ================================================ FILE: samples/build.gradle ================================================ apply plugin: 'org.jetbrains.kotlin.jvm' dependencies { implementation projects.retrofit implementation projects.retrofitMock implementation projects.retrofitConverters.moshi implementation projects.retrofitConverters.gson implementation projects.retrofitConverters.simplexml implementation projects.retrofitAdapters.rxjava implementation libs.okhttp.loggingInterceptor implementation libs.okhttp.mockwebserver implementation libs.kotlin.stdLib implementation libs.kotlinx.coroutines implementation libs.guava implementation libs.jsoup compileOnly libs.findBugsAnnotations } ================================================ FILE: samples/src/main/java/com/example/retrofit/AnnotatedConverters.java ================================================ /* * Copyright (C) 2017 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import static java.lang.annotation.RetentionPolicy.RUNTIME; import com.google.gson.GsonBuilder; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.reflect.Type; import java.util.LinkedHashMap; import java.util.Map; import javax.annotation.Nullable; import okhttp3.RequestBody; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Default; import org.simpleframework.xml.DefaultType; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.moshi.MoshiConverterFactory; import retrofit2.converter.simplexml.SimpleXmlConverterFactory; import retrofit2.http.GET; final class AnnotatedConverters { public static final class AnnotatedConverterFactory extends Converter.Factory { private final Map, Converter.Factory> factories; public static final class Builder { private final Map, Converter.Factory> factories = new LinkedHashMap<>(); public Builder add(Class cls, Converter.Factory factory) { if (cls == null) { throw new NullPointerException("cls == null"); } if (factory == null) { throw new NullPointerException("factory == null"); } factories.put(cls, factory); return this; } public AnnotatedConverterFactory build() { return new AnnotatedConverterFactory(factories); } } AnnotatedConverterFactory(Map, Converter.Factory> factories) { this.factories = new LinkedHashMap<>(factories); } @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { for (Annotation annotation : annotations) { Converter.Factory factory = factories.get(annotation.annotationType()); if (factory != null) { return factory.responseBodyConverter(type, annotations, retrofit); } } return null; } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { for (Annotation annotation : parameterAnnotations) { Converter.Factory factory = factories.get(annotation.annotationType()); if (factory != null) { return factory.requestBodyConverter( type, parameterAnnotations, methodAnnotations, retrofit); } } return null; } } @Retention(RUNTIME) public @interface Moshi {} @Retention(RUNTIME) public @interface Gson {} @Retention(RUNTIME) public @interface SimpleXml {} @Default(value = DefaultType.FIELD) static final class Library { @Attribute String name; } interface Service { @GET("/") @Moshi Call exampleMoshi(); @GET("/") @Gson Call exampleGson(); @GET("/") @SimpleXml Call exampleSimpleXml(); @GET("/") Call exampleDefault(); } public static void main(String... args) throws IOException { MockWebServer server = new MockWebServer(); server.start(); server.enqueue(new MockResponse().setBody("{\"name\": \"Moshi\"}")); server.enqueue(new MockResponse().setBody("{\"name\": \"Gson\"}")); server.enqueue(new MockResponse().setBody("")); server.enqueue(new MockResponse().setBody("{\"name\": \"Gson\"}")); com.squareup.moshi.Moshi moshi = new com.squareup.moshi.Moshi.Builder().build(); com.google.gson.Gson gson = new GsonBuilder().create(); MoshiConverterFactory moshiConverterFactory = MoshiConverterFactory.create(moshi); GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create(gson); SimpleXmlConverterFactory simpleXmlConverterFactory = SimpleXmlConverterFactory.create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new AnnotatedConverterFactory.Builder() .add(Moshi.class, moshiConverterFactory) .add(Gson.class, gsonConverterFactory) .add(SimpleXml.class, simpleXmlConverterFactory) .build()) .addConverterFactory(gsonConverterFactory) .build(); Service service = retrofit.create(Service.class); Library library1 = service.exampleMoshi().execute().body(); System.out.println("Library 1: " + library1.name); Library library2 = service.exampleGson().execute().body(); System.out.println("Library 2: " + library2.name); Library library3 = service.exampleSimpleXml().execute().body(); System.out.println("Library 3: " + library3.name); Library library4 = service.exampleDefault().execute().body(); System.out.println("Library 4: " + library4.name); server.shutdown(); } } ================================================ FILE: samples/src/main/java/com/example/retrofit/ChunkingConverter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okio.BufferedSink; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.http.Body; import retrofit2.http.POST; public final class ChunkingConverter { @Target(PARAMETER) @Retention(RUNTIME) @interface Chunked {} /** * A converter which removes known content lengths to force chunking when {@code @Chunked} is * present on {@code @Body} params. */ static class ChunkingConverterFactory extends Converter.Factory { @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { boolean isBody = false; boolean isChunked = false; for (Annotation annotation : parameterAnnotations) { isBody |= annotation instanceof Body; isChunked |= annotation instanceof Chunked; } if (!isBody || !isChunked) { return null; } // Look up the real converter to delegate to. final Converter delegate = retrofit.nextRequestBodyConverter(this, type, parameterAnnotations, methodAnnotations); // Wrap it in a Converter which removes the content length from the delegate's body. return value -> { final RequestBody realBody = delegate.convert(value); return new RequestBody() { @Override public MediaType contentType() { return realBody.contentType(); } @Override public void writeTo(BufferedSink sink) throws IOException { realBody.writeTo(sink); } }; }; } } static class Repo { final String owner; final String name; Repo(String owner, String name) { this.owner = owner; this.name = name; } } interface Service { @POST("/") Call sendNormal(@Body Repo repo); @POST("/") Call sendChunked(@Chunked @Body Repo repo); } public static void main(String... args) throws IOException, InterruptedException { MockWebServer server = new MockWebServer(); server.enqueue(new MockResponse()); server.enqueue(new MockResponse()); server.start(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new ChunkingConverterFactory()) .addConverterFactory(GsonConverterFactory.create()) .build(); Service service = retrofit.create(Service.class); Repo retrofitRepo = new Repo("square", "retrofit"); service.sendNormal(retrofitRepo).execute(); RecordedRequest normalRequest = server.takeRequest(); System.out.println( "Normal @Body Transfer-Encoding: " + normalRequest.getHeader("Transfer-Encoding")); service.sendChunked(retrofitRepo).execute(); RecordedRequest chunkedRequest = server.takeRequest(); System.out.println( "@Chunked @Body Transfer-Encoding: " + chunkedRequest.getHeader("Transfer-Encoding")); server.shutdown(); } } ================================================ FILE: samples/src/main/java/com/example/retrofit/ConditionalLoggingInterceptor.kt ================================================ /* * Copyright (C) 2024 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.Response import okhttp3.ResponseBody import okhttp3.logging.HttpLoggingInterceptor import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import retrofit2.Invocation import retrofit2.Retrofit import retrofit2.create import retrofit2.http.GET suspend fun main() { val server = MockWebServer() val client = OkHttpClient.Builder() .addInterceptor( ConditionalLoggingInterceptor( HttpLoggingInterceptor(::println).setLevel( HttpLoggingInterceptor.Level.BODY, ), ), ) .build() val retrofit = Retrofit.Builder() .baseUrl(server.url("/")) .client(client) .build() val exampleApi = retrofit.create() server.enqueue(MockResponse()) exampleApi.one() server.enqueue(MockResponse()) exampleApi.two() } private interface ExampleApi { @GET("one") suspend fun one(): ResponseBody @Log @GET("two") suspend fun two(): ResponseBody } /** * Retrofit service functions which are annotated with this class will have their HTTP calls * logged. You must add [ConditionalLoggingInterceptor] to your [OkHttpClient] for this to work. */ annotation class Log class ConditionalLoggingInterceptor( private val loggingInterceptor: HttpLoggingInterceptor, ) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() request.tag(Invocation::class.java)?.let { invocation -> if (invocation.method().isAnnotationPresent(Log::class.java)) { return loggingInterceptor.intercept(chain) } } return chain.proceed(request) } } ================================================ FILE: samples/src/main/java/com/example/retrofit/Crawler.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.Nullable; import okhttp3.ConnectionPool; import okhttp3.Dispatcher; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.ResponseBody; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Converter; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; import retrofit2.http.Url; /** A simple web crawler that uses a Retrofit service to turn URLs into webpages. */ public final class Crawler { private final Set fetchedUrls = Collections.synchronizedSet(new LinkedHashSet()); private final ConcurrentHashMap hostnames = new ConcurrentHashMap<>(); private final PageService pageService; public Crawler(PageService pageService) { this.pageService = pageService; } public void crawlPage(HttpUrl url) { // Skip hosts that we've visited many times. AtomicInteger hostnameCount = new AtomicInteger(); AtomicInteger previous = hostnames.putIfAbsent(url.host(), hostnameCount); if (previous != null) hostnameCount = previous; if (hostnameCount.incrementAndGet() > 100) return; // Asynchronously visit URL. pageService .get(url) .enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { if (!response.isSuccessful()) { System.out.println(call.request().url() + ": failed: " + response.code()); return; } // Print this page's URL and title. Page page = response.body(); HttpUrl base = response.raw().request().url(); System.out.println(base + ": " + page.title); // Enqueue its links for visiting. for (String link : page.links) { HttpUrl linkUrl = base.resolve(link); if (linkUrl != null && fetchedUrls.add(linkUrl)) { crawlPage(linkUrl); } } } @Override public void onFailure(Call call, Throwable t) { System.out.println(call.request().url() + ": failed: " + t); } }); } public static void main(String... args) throws Exception { Dispatcher dispatcher = new Dispatcher(Executors.newFixedThreadPool(20)); dispatcher.setMaxRequests(20); dispatcher.setMaxRequestsPerHost(1); OkHttpClient okHttpClient = new OkHttpClient.Builder() .dispatcher(dispatcher) .connectionPool(new ConnectionPool(100, 30, TimeUnit.SECONDS)) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(HttpUrl.get("https://example.com/")) .addConverterFactory(PageAdapter.FACTORY) .client(okHttpClient) .build(); PageService pageService = retrofit.create(PageService.class); Crawler crawler = new Crawler(pageService); crawler.crawlPage(HttpUrl.get(args[0])); } interface PageService { @GET Call get(@Url HttpUrl url); } static class Page { final String title; final List links; Page(String title, List links) { this.title = title; this.links = links; } } static final class PageAdapter implements Converter { static final Converter.Factory FACTORY = new Converter.Factory() { @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { if (type == Page.class) return new PageAdapter(); return null; } }; @Override public Page convert(ResponseBody responseBody) throws IOException { Document document = Jsoup.parse(responseBody.string()); List links = new ArrayList<>(); for (Element element : document.select("a[href]")) { links.add(element.attr("href")); } return new Page(document.title(), Collections.unmodifiableList(links)); } } } ================================================ FILE: samples/src/main/java/com/example/retrofit/DeserializeErrorBody.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import java.io.IOException; import java.lang.annotation.Annotation; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.http.GET; public final class DeserializeErrorBody { interface Service { @GET("/user") Call getUser(); } static class User { // normal fields... } static class ErrorBody { String message; } public static void main(String... args) throws IOException { // Create a local web server which response with a 404 and JSON body. MockWebServer server = new MockWebServer(); server.start(); server.enqueue( new MockResponse() .setResponseCode(404) .setBody("{\"message\":\"Unable to locate resource\"}")); // Create our Service instance with a Retrofit pointing at the local web server and Gson. Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(GsonConverterFactory.create()) .build(); Service service = retrofit.create(Service.class); Response response = service.getUser().execute(); // Normally you would check response.isSuccess() here before doing the following, but we know // this call will always fail. You could also use response.code() to determine whether to // convert the error body and/or which type to use for conversion. // Look up a converter for the Error type on the Retrofit instance. Converter errorConverter = retrofit.responseBodyConverter(ErrorBody.class, new Annotation[0]); // Convert the error body into our Error type. ErrorBody errorBody = errorConverter.convert(response.errorBody()); System.out.println("ERROR: " + errorBody.message); server.shutdown(); } } ================================================ FILE: samples/src/main/java/com/example/retrofit/DynamicBaseUrl.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import java.io.IOException; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.http.GET; /** * This example uses an OkHttp interceptor to change the target hostname dynamically at runtime. * Typically this would be used to implement client-side load balancing or to use the webserver * that's nearest geographically. */ public final class DynamicBaseUrl { public interface Pop { @GET("robots.txt") Call robots(); } static final class HostSelectionInterceptor implements Interceptor { private volatile String host; public void setHost(String host) { this.host = host; } @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request request = chain.request(); String host = this.host; if (host != null) { HttpUrl newUrl = request.url().newBuilder().host(host).build(); request = request.newBuilder().url(newUrl).build(); } return chain.proceed(request); } } public static void main(String... args) throws IOException { HostSelectionInterceptor hostSelectionInterceptor = new HostSelectionInterceptor(); OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(hostSelectionInterceptor).build(); Retrofit retrofit = new Retrofit.Builder().baseUrl("http://www.github.com/").callFactory(okHttpClient).build(); Pop pop = retrofit.create(Pop.class); Response response1 = pop.robots().execute(); System.out.println("Response from: " + response1.raw().request().url()); System.out.println(response1.body().string()); hostSelectionInterceptor.setHost("www.pepsi.com"); Response response2 = pop.robots().execute(); System.out.println("Response from: " + response2.raw().request().url()); System.out.println(response2.body().string()); } } ================================================ FILE: samples/src/main/java/com/example/retrofit/ErrorHandlingAdapter.java ================================================ /* * Copyright (C) 2015 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.concurrent.Executor; import javax.annotation.Nullable; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.http.GET; /** * A sample showing a custom {@link CallAdapter} which adapts the built-in {@link Call} to a custom * version whose callback has more granular methods. */ public final class ErrorHandlingAdapter { /** A callback which offers granular callbacks for various conditions. */ interface MyCallback { /** Called for [200, 300) responses. */ void success(Response response); /** Called for 401 responses. */ void unauthenticated(Response response); /** Called for [400, 500) responses, except 401. */ void clientError(Response response); /** Called for [500, 600) response. */ void serverError(Response response); /** Called for network errors while making the call. */ void networkError(IOException e); /** Called for unexpected errors while making the call. */ void unexpectedError(Throwable t); } interface MyCall { void cancel(); void enqueue(MyCallback callback); MyCall clone(); // Left as an exercise for the reader... // TODO MyResponse execute() throws MyHttpException; } public static class ErrorHandlingCallAdapterFactory extends CallAdapter.Factory { @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != MyCall.class) { return null; } if (!(returnType instanceof ParameterizedType)) { throw new IllegalStateException( "MyCall must have generic type (e.g., MyCall)"); } Type responseType = getParameterUpperBound(0, (ParameterizedType) returnType); Executor callbackExecutor = retrofit.callbackExecutor(); return new ErrorHandlingCallAdapter<>(responseType, callbackExecutor); } private static final class ErrorHandlingCallAdapter implements CallAdapter> { private final Type responseType; private final Executor callbackExecutor; ErrorHandlingCallAdapter(Type responseType, Executor callbackExecutor) { this.responseType = responseType; this.callbackExecutor = callbackExecutor; } @Override public Type responseType() { return responseType; } @Override public MyCall adapt(Call call) { return new MyCallAdapter<>(call, callbackExecutor); } } } /** Adapts a {@link Call} to {@link MyCall}. */ static class MyCallAdapter implements MyCall { private final Call call; private final Executor callbackExecutor; MyCallAdapter(Call call, Executor callbackExecutor) { this.call = call; this.callbackExecutor = callbackExecutor; } @Override public void cancel() { call.cancel(); } @Override public void enqueue(final MyCallback callback) { call.enqueue( new Callback() { @Override public void onResponse(Call call, Response response) { // TODO if 'callbackExecutor' is not null, the 'callback' methods should be executed // on that executor by submitting a Runnable. This is left as an exercise for the // reader. int code = response.code(); if (code >= 200 && code < 300) { callback.success(response); } else if (code == 401) { callback.unauthenticated(response); } else if (code >= 400 && code < 500) { callback.clientError(response); } else if (code >= 500 && code < 600) { callback.serverError(response); } else { callback.unexpectedError(new RuntimeException("Unexpected response " + response)); } } @Override public void onFailure(Call call, Throwable t) { // TODO if 'callbackExecutor' is not null, the 'callback' methods should be executed // on that executor by submitting a Runnable. This is left as an exercise for the // reader. if (t instanceof IOException) { callback.networkError((IOException) t); } else { callback.unexpectedError(t); } } }); } @Override public MyCall clone() { return new MyCallAdapter<>(call.clone(), callbackExecutor); } } interface HttpBinService { @GET("/ip") MyCall getIp(); } static class Ip { String origin; } public static void main(String... args) { Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://httpbin.org") .addCallAdapterFactory(new ErrorHandlingCallAdapterFactory()) .addConverterFactory(GsonConverterFactory.create()) .build(); HttpBinService service = retrofit.create(HttpBinService.class); MyCall ip = service.getIp(); ip.enqueue( new MyCallback() { @Override public void success(Response response) { System.out.println("SUCCESS! " + response.body().origin); } @Override public void unauthenticated(Response response) { System.out.println("UNAUTHENTICATED"); } @Override public void clientError(Response response) { System.out.println("CLIENT ERROR " + response.code() + " " + response.message()); } @Override public void serverError(Response response) { System.out.println("SERVER ERROR " + response.code() + " " + response.message()); } @Override public void networkError(IOException e) { System.err.println("NETWORK ERROR " + e.getMessage()); } @Override public void unexpectedError(Throwable t) { System.err.println("FATAL ERROR " + t.getMessage()); } }); } } ================================================ FILE: samples/src/main/java/com/example/retrofit/InvocationMetrics.java ================================================ /* * Copyright (C) 2018 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import java.io.IOException; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Invocation; import retrofit2.Retrofit; import retrofit2.http.GET; import retrofit2.http.Url; /** This example prints HTTP call metrics with the initiating method names and arguments. */ public final class InvocationMetrics { public interface Browse { @GET("/robots.txt") Call robots(); @GET("/favicon.ico") Call favicon(); @GET("/") Call home(); @GET Call page(@Url String path); } static final class InvocationLogger implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); long startNanos = System.nanoTime(); Response response = chain.proceed(request); long elapsedNanos = System.nanoTime() - startNanos; Invocation invocation = request.tag(Invocation.class); if (invocation != null) { System.out.printf( "%s.%s %s HTTP %s (%.0f ms)%n", invocation.service().getSimpleName(), invocation.method().getName(), invocation.arguments(), response.code(), elapsedNanos / 1_000_000.0); } return response; } } public static void main(String... args) throws IOException { InvocationLogger invocationLogger = new InvocationLogger(); OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(invocationLogger).build(); Retrofit retrofit = new Retrofit.Builder().baseUrl("https://square.com/").callFactory(okHttpClient).build(); Browse browse = retrofit.create(Browse.class); browse.robots().execute(); browse.favicon().execute(); browse.home().execute(); browse.page("sitemap.xml").execute(); browse.page("notfound").execute(); } } ================================================ FILE: samples/src/main/java/com/example/retrofit/JsonAndXmlConverters.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.RequestBody; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Default; import org.simpleframework.xml.DefaultType; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.simplexml.SimpleXmlConverterFactory; import retrofit2.http.GET; /** * Both the Gson converter and the Simple Framework converter accept all types. Because of this, you * cannot use both in a single service by default. In order to work around this, we can create * an @Json and @Xml annotation to declare which serialization format each endpoint should use and * then write our own Converter.Factory which delegates to either the Gson or Simple Framework * converter. */ public final class JsonAndXmlConverters { @Retention(RUNTIME) @interface Json {} @Retention(RUNTIME) @interface Xml {} static class QualifiedTypeConverterFactory extends Converter.Factory { private final Converter.Factory jsonFactory; private final Converter.Factory xmlFactory; QualifiedTypeConverterFactory(Converter.Factory jsonFactory, Converter.Factory xmlFactory) { this.jsonFactory = jsonFactory; this.xmlFactory = xmlFactory; } @Override public @Nullable Converter responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { for (Annotation annotation : annotations) { if (annotation instanceof Json) { return jsonFactory.responseBodyConverter(type, annotations, retrofit); } if (annotation instanceof Xml) { return xmlFactory.responseBodyConverter(type, annotations, retrofit); } } return null; } @Override public @Nullable Converter requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { for (Annotation annotation : parameterAnnotations) { if (annotation instanceof Json) { return jsonFactory.requestBodyConverter( type, parameterAnnotations, methodAnnotations, retrofit); } if (annotation instanceof Xml) { return xmlFactory.requestBodyConverter( type, parameterAnnotations, methodAnnotations, retrofit); } } return null; } } @Default(value = DefaultType.FIELD) static class User { @Attribute public String name; } interface Service { @GET("/") @Json Call exampleJson(); @GET("/") @Xml Call exampleXml(); } public static void main(String... args) throws IOException { MockWebServer server = new MockWebServer(); server.start(); server.enqueue(new MockResponse().setBody("{\"name\": \"Jason\"}")); server.enqueue(new MockResponse().setBody("")); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory( new QualifiedTypeConverterFactory( GsonConverterFactory.create(), SimpleXmlConverterFactory.create())) .build(); Service service = retrofit.create(Service.class); User user1 = service.exampleJson().execute().body(); System.out.println("User 1: " + user1.name); User user2 = service.exampleXml().execute().body(); System.out.println("User 2: " + user2.name); server.shutdown(); } } ================================================ FILE: samples/src/main/java/com/example/retrofit/JsonQueryParameters.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.reflect.Type; import javax.annotation.Nullable; import okhttp3.RequestBody; import okhttp3.ResponseBody; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import okio.Buffer; import retrofit2.Call; import retrofit2.Converter; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.http.GET; import retrofit2.http.Query; public final class JsonQueryParameters { @Retention(RUNTIME) @interface Json {} static class JsonStringConverterFactory extends Converter.Factory { private final Converter.Factory delegateFactory; JsonStringConverterFactory(Converter.Factory delegateFactory) { this.delegateFactory = delegateFactory; } @Override public @Nullable Converter stringConverter( Type type, Annotation[] annotations, Retrofit retrofit) { for (Annotation annotation : annotations) { if (annotation instanceof Json) { // NOTE: If you also have a JSON converter factory installed in addition to this factory, // you can call retrofit.requestBodyConverter(type, annotations) instead of having a // reference to it explicitly as a field. Converter delegate = delegateFactory.requestBodyConverter(type, annotations, new Annotation[0], retrofit); return new DelegateToStringConverter<>(delegate); } } return null; } static class DelegateToStringConverter implements Converter { private final Converter delegate; DelegateToStringConverter(Converter delegate) { this.delegate = delegate; } @Override public String convert(T value) throws IOException { Buffer buffer = new Buffer(); delegate.convert(value).writeTo(buffer); return buffer.readUtf8(); } } } static class Filter { final String userId; Filter(String userId) { this.userId = userId; } } interface Service { @GET("/filter") Call example(@Json @Query("value") Filter value); } @SuppressWarnings("UnusedVariable") public static void main(String... args) throws IOException, InterruptedException { MockWebServer server = new MockWebServer(); server.start(); server.enqueue(new MockResponse()); Retrofit retrofit = new Retrofit.Builder() .baseUrl(server.url("/")) .addConverterFactory(new JsonStringConverterFactory(GsonConverterFactory.create())) .build(); Service service = retrofit.create(Service.class); Call call = service.example(new Filter("123")); Response response = call.execute(); // TODO handle user response... // Print the request path that the server saw to show the JSON query param: RecordedRequest recordedRequest = server.takeRequest(); System.out.println(recordedRequest.getPath()); server.shutdown(); } } ================================================ FILE: samples/src/main/java/com/example/retrofit/RxJavaObserveOnMainThread.java ================================================ /* * Copyright (C) 2016 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import static rx.schedulers.Schedulers.io; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.annotation.Nullable; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Retrofit; import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; import rx.Observable; import rx.Scheduler; import rx.schedulers.Schedulers; public final class RxJavaObserveOnMainThread { @SuppressWarnings("UnusedVariable") public static void main(String... args) { Scheduler observeOn = Schedulers.computation(); // Or use mainThread() for Android. Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com") .addCallAdapterFactory(new ObserveOnMainCallAdapterFactory(observeOn)) .addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(io())) .build(); // Services created with this instance that use Observable will execute on the 'io' scheduler // and notify their observer on the 'computation' scheduler. } static final class ObserveOnMainCallAdapterFactory extends CallAdapter.Factory { final Scheduler scheduler; ObserveOnMainCallAdapterFactory(Scheduler scheduler) { this.scheduler = scheduler; } @Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != Observable.class) { return null; // Ignore non-Observable types. } // Look up the next call adapter which would otherwise be used if this one was not present. //noinspection unchecked returnType checked above to be Observable. final CallAdapter> delegate = (CallAdapter>) retrofit.nextCallAdapter(this, returnType, annotations); return new CallAdapter() { @Override public Object adapt(Call call) { // Delegate to get the normal Observable... Observable o = delegate.adapt(call); // ...and change it to send notifications to the observer on the specified scheduler. return o.observeOn(scheduler); } @Override public Type responseType() { return delegate.responseType(); } }; } } } ================================================ FILE: samples/src/main/java/com/example/retrofit/SimpleMockService.java ================================================ // Copyright 2013 Square, Inc. package com.example.retrofit; import com.example.retrofit.SimpleService.Contributor; import com.example.retrofit.SimpleService.GitHub; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import retrofit2.Call; import retrofit2.Retrofit; import retrofit2.mock.BehaviorDelegate; import retrofit2.mock.MockRetrofit; import retrofit2.mock.NetworkBehavior; /** * An example of using {@link MockRetrofit} to create a mock service implementation with fake data. * This re-uses the GitHub service from {@link SimpleService} for its mocking. */ public final class SimpleMockService { /** A mock implementation of the {@link GitHub} API interface. */ static final class MockGitHub implements GitHub { private final BehaviorDelegate delegate; private final Map>> ownerRepoContributors; MockGitHub(BehaviorDelegate delegate) { this.delegate = delegate; ownerRepoContributors = new LinkedHashMap<>(); // Seed some mock data. addContributor("square", "retrofit", "John Doe", 12); addContributor("square", "retrofit", "Bob Smith", 2); addContributor("square", "retrofit", "Big Bird", 40); addContributor("square", "picasso", "Proposition Joe", 39); addContributor("square", "picasso", "Keiser Soze", 152); } @Override public Call> contributors(String owner, String repo) { List response = Collections.emptyList(); Map> repoContributors = ownerRepoContributors.get(owner); if (repoContributors != null) { List contributors = repoContributors.get(repo); if (contributors != null) { response = contributors; } } return delegate.returningResponse(response).contributors(owner, repo); } void addContributor(String owner, String repo, String name, int contributions) { Map> repoContributors = ownerRepoContributors.get(owner); if (repoContributors == null) { repoContributors = new LinkedHashMap<>(); ownerRepoContributors.put(owner, repoContributors); } List contributors = repoContributors.get(repo); if (contributors == null) { contributors = new ArrayList<>(); repoContributors.put(repo, contributors); } contributors.add(new Contributor(name, contributions)); } } public static void main(String... args) throws IOException { // Create a very simple Retrofit adapter which points the GitHub API. Retrofit retrofit = new Retrofit.Builder().baseUrl(SimpleService.API_URL).build(); // Create a MockRetrofit object with a NetworkBehavior which manages the fake behavior of calls. NetworkBehavior behavior = NetworkBehavior.create(); MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).networkBehavior(behavior).build(); BehaviorDelegate delegate = mockRetrofit.create(GitHub.class); MockGitHub gitHub = new MockGitHub(delegate); // Query for some contributors for a few repositories. printContributors(gitHub, "square", "retrofit"); printContributors(gitHub, "square", "picasso"); // Using the mock-only methods, add some additional data. System.out.println("Adding more mock data...\n"); gitHub.addContributor("square", "retrofit", "Foo Bar", 61); gitHub.addContributor("square", "picasso", "Kit Kat", 53); // Reduce the delay to make the next calls complete faster. behavior.setDelay(500, TimeUnit.MILLISECONDS); // Query for the contributors again so we can see the mock data that was added. printContributors(gitHub, "square", "retrofit"); printContributors(gitHub, "square", "picasso"); } private static void printContributors(GitHub gitHub, String owner, String repo) throws IOException { System.out.println(String.format("== Contributors for %s/%s ==", owner, repo)); Call> contributors = gitHub.contributors(owner, repo); for (Contributor contributor : contributors.execute().body()) { System.out.println(contributor.login + " (" + contributor.contributions + ")"); } System.out.println(); } } ================================================ FILE: samples/src/main/java/com/example/retrofit/SimpleService.java ================================================ /* * Copyright (C) 2012 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.retrofit; import java.io.IOException; import java.util.List; import retrofit2.Call; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.http.GET; import retrofit2.http.Path; public final class SimpleService { public static final String API_URL = "https://api.github.com"; public static class Contributor { public final String login; public final int contributions; public Contributor(String login, int contributions) { this.login = login; this.contributions = contributions; } } public interface GitHub { @GET("/repos/{owner}/{repo}/contributors") Call> contributors(@Path("owner") String owner, @Path("repo") String repo); } public static void main(String... args) throws IOException { // Create a very simple REST adapter which points the GitHub API. Retrofit retrofit = new Retrofit.Builder() .baseUrl(API_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); // Create an instance of our GitHub API interface. GitHub github = retrofit.create(GitHub.class); // Create a call instance for looking up Retrofit contributors. Call> call = github.contributors("square", "retrofit"); // Fetch and print a list of the contributors to the library. List contributors = call.execute().body(); for (Contributor contributor : contributors) { System.out.println(contributor.login + " (" + contributor.contributions + ")"); } } } ================================================ FILE: samples/src/main/java/com/example/retrofit/package-info.java ================================================ @javax.annotation.ParametersAreNonnullByDefault package com.example.retrofit; ================================================ FILE: settings.gradle ================================================ plugins { id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' } dependencyResolutionManagement { repositories { mavenCentral() google() } } rootProject.name = 'retrofit-root' include ':retrofit' include ':retrofit-bom' include ':retrofit:android-test' include ':retrofit:java-test' include ':retrofit:kotlin-test' include ':retrofit:robovm-test' include ':retrofit:test-helpers' include ':retrofit-mock' include ':retrofit-response-type-keeper' include ':retrofit-adapters:guava' include ':retrofit-adapters:java8' include ':retrofit-adapters:rxjava' include ':retrofit-adapters:rxjava2' include ':retrofit-adapters:rxjava3' include ':retrofit-adapters:scala' include ':retrofit-converters:gson' include ':retrofit-converters:guava' include ':retrofit-converters:jackson' include ':retrofit-converters:java8' include ':retrofit-converters:jaxb' include ':retrofit-converters:jaxb3' include ':retrofit-converters:kotlinx-serialization' include ':retrofit-converters:moshi' include ':retrofit-converters:protobuf' include ':retrofit-converters:scalars' include ':retrofit-converters:simplexml' include ':retrofit-converters:wire' include ':samples' enableFeaturePreview('TYPESAFE_PROJECT_ACCESSORS') ================================================ FILE: website/.gitignore ================================================ dist/ .astro/ node_modules/ # Populated by ./gradlew copyWebsiteDocs public/3.x/ ================================================ FILE: website/README.md ================================================ # Website The documentation is [built with Starlight](https://starlight.astro.build). Common commands: * `npm install` – install deps (must do first or if `package.json` changes) * `npm run dev` – local, hot-reload server * `npm run build` – produce distribution in `dist/` * `npm run preview` – local server of the distribution folder * `npm run build -- --mode release` – remove "snapshot" banner ================================================ FILE: website/astro.config.mjs ================================================ // @ts-check import { readFileSync } from 'fs'; import { defineConfig, envField } from 'astro/config'; import starlight from '@astrojs/starlight'; import starlightLinksValidator from 'starlight-links-validator'; let retrofitProperties = readFileSync('../gradle.properties'); let retrofitVersion = /VERSION_NAME=(.*?)\n/.exec(retrofitProperties)[1]; export default defineConfig({ site: 'https://square.github.io', base: '/retrofit/latest', env: { schema: { VERSION: envField.string({ context: 'server', access: 'public', optional: true, default: retrofitVersion }), }, }, integrations: [ starlight({ title: 'Retrofit', customCss: [ './src/styles/theme.css', ], editLink: { baseUrl: 'https://github.com/square/retrofit/edit/trunk/website', }, social: [ { icon: 'stackOverflow', label: 'StackOverflow', href: 'https://stackoverflow.com/questions/tagged/retrofit?sort=active' }, { icon: 'github', label: 'GitHub', href: 'https://github.com/square/retrofit' }, ], sidebar: [ { label: 'Documentation', items: [ { slug: 'index' }, { slug: 'declarations' }, { slug: 'configuration' }, { slug: 'download' }, { slug: 'contributing' }, ] }, { label: 'Resources', items: [ { label: 'GitHub', link: 'https://github.com/square/retrofit' }, { label: 'Javadoc', collapsed: true, items: [ { label: 'retrofit', link: '/3.x/retrofit/' }, { label: 'retrofit-mock', link: '/3.x/retrofit-mock/' }, { label: 'converter-gson', link: '/3.x/converter-gson/' }, { label: 'converter-guava', link: '/3.x/converter-guava/' }, { label: 'converter-jackson', link: '/3.x/converter-jackson/' }, { label: 'converter-java8', link: '/3.x/converter-java8/' }, { label: 'converter-jaxb', link: '/3.x/converter-jaxb/' }, { label: 'converter-jaxb3', link: '/3.x/converter-jaxb3/' }, { label: 'converter-kotlinx-serialization', link: '/3.x/converter-kotlinx-serialization/' }, { label: 'converter-moshi', link: '/3.x/converter-moshi/' }, { label: 'converter-protobuf', link: '/3.x/converter-protobuf/' }, { label: 'converter-scalars', link: '/3.x/converter-scalars/' }, { label: 'converter-simplexml', link: '/3.x/converter-simplexml/' }, { label: 'converter-wire', link: '/3.x/converter-wire/' }, { label: 'adapter-guava', link: '/3.x/adapter-guava/' }, { label: 'adapter-java8', link: '/3.x/adapter-java8/' }, { label: 'adapter-rxjava', link: '/3.x/adapter-rxjava/' }, { label: 'adapter-rxjava2', link: '/3.x/adapter-rxjava2/' }, { label: 'adapter-rxjava3', link: '/3.x/adapter-rxjava3/' }, { label: 'adapter-scala', link: '/3.x/adapter-scala/' }, ], }, { label: 'Javadoc (2.x)', collapsed: true, items: [ { label: 'retrofit', link: '/2.x/retrofit/' }, { label: 'retrofit-mock', link: '/2.x/retrofit-mock/' }, { label: 'converter-gson', link: '/2.x/converter-gson/' }, { label: 'converter-guava', link: '/2.x/converter-guava/' }, { label: 'converter-jackson', link: '/2.x/converter-jackson/' }, { label: 'converter-java8', link: '/2.x/converter-java8/' }, { label: 'converter-jaxb', link: '/2.x/converter-jaxb/' }, { label: 'converter-jaxb3', link: '/2.x/converter-jaxb3/' }, { label: 'converter-kotlinx-serialization', link: '/2.x/converter-kotlinx-serialization/' }, { label: 'converter-moshi', link: '/2.x/converter-moshi/' }, { label: 'converter-protobuf', link: '/2.x/converter-protobuf/' }, { label: 'converter-scalars', link: '/2.x/converter-scalars/' }, { label: 'converter-simplexml', link: '/2.x/converter-simplexml/' }, { label: 'converter-wire', link: '/2.x/converter-wire/' }, { label: 'adapter-guava', link: '/2.x/adapter-guava/' }, { label: 'adapter-java8', link: '/2.x/adapter-java8/' }, { label: 'adapter-rxjava', link: '/2.x/adapter-rxjava/' }, { label: 'adapter-rxjava2', link: '/2.x/adapter-rxjava2/' }, { label: 'adapter-rxjava3', link: '/2.x/adapter-rxjava3/' }, { label: 'adapter-scala', link: '/2.x/adapter-scala/' }, ], }, { label: 'Javadoc (1.x)', collapsed: true, items: [ { label: 'retrofit', link: '/1.x/retrofit/' }, { label: 'retrofit-mock', link: '/1.x/retrofit-mock/' }, { label: 'converter-jackson', link: '/1.x/converter-jackson/' }, { label: 'converter-protobuf', link: '/1.x/converter-protobuf/' }, { label: 'converter-simplexml', link: '/1.x/converter-simplexml/' }, { label: 'converter-wire', link: '/1.x/converter-wire/' }, ], }, { label: 'StackOverflow', link: 'https://stackoverflow.com/questions/tagged/retrofit?sort=active' }, ], } ], plugins: [ starlightLinksValidator(), ], }), ], }); ================================================ FILE: website/package.json ================================================ { "name": "Retrofit Documentation", "type": "module", "version": "0.0.1", "scripts": { "dev": "astro dev", "build": "astro build", "preview": "astro preview", "astro": "astro" }, "dependencies": { "@astrojs/starlight": "^0.37.0", "astro": "^5.6.1", "sharp": "^0.34.0", "starlight-links-validator": "^0.19.0", "starlight-versions": "^0.7.0" } } ================================================ FILE: website/public/1.x/converter-jackson/allclasses-frame.html ================================================ All Classes (Converter: Jackson 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/converter-jackson/allclasses-noframe.html ================================================ All Classes (Converter: Jackson 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/converter-jackson/constant-values.html ================================================ Constant Field Values (Converter: Jackson 1.9.0 API)

Constant Field Values

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/deprecated-list.html ================================================ Deprecated List (Converter: Jackson 1.9.0 API)

Deprecated API

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/help-doc.html ================================================ API Help (Converter: Jackson 1.9.0 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Use

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/index-all.html ================================================ Index (Converter: Jackson 1.9.0 API)
F J R T 

F

fromBody(TypedInput, Type) - Method in class retrofit.converter.JacksonConverter
 

J

JacksonConverter - Class in retrofit.converter
A Converter which uses Jackson for reading and writing entities.
JacksonConverter() - Constructor for class retrofit.converter.JacksonConverter
 
JacksonConverter(ObjectMapper) - Constructor for class retrofit.converter.JacksonConverter
 

R

retrofit.converter - package retrofit.converter
 

T

toBody(Object) - Method in class retrofit.converter.JacksonConverter
 
F J R T 

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/index.html ================================================ Converter: Jackson 1.9.0 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit/converter/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/1.x/converter-jackson/overview-tree.html ================================================ Class Hierarchy (Converter: Jackson 1.9.0 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/package-list ================================================ retrofit.converter ================================================ FILE: website/public/1.x/converter-jackson/retrofit/converter/JacksonConverter.html ================================================ JacksonConverter (Converter: Jackson 1.9.0 API)
retrofit.converter

Class JacksonConverter

  • All Implemented Interfaces:
    Converter


    public class JacksonConverter
    extends Object
    implements Converter
    A Converter which uses Jackson for reading and writing entities.
    Author:
    Kai Waldron (kaiwaldron@gmail.com)

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/retrofit/converter/class-use/JacksonConverter.html ================================================ Uses of Class retrofit.converter.JacksonConverter (Converter: Jackson 1.9.0 API)

Uses of Class
retrofit.converter.JacksonConverter

No usage of retrofit.converter.JacksonConverter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/retrofit/converter/package-frame.html ================================================ retrofit.converter (Converter: Jackson 1.9.0 API)

retrofit.converter

================================================ FILE: website/public/1.x/converter-jackson/retrofit/converter/package-summary.html ================================================ retrofit.converter (Converter: Jackson 1.9.0 API)

Package retrofit.converter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/retrofit/converter/package-tree.html ================================================ retrofit.converter Class Hierarchy (Converter: Jackson 1.9.0 API)

Hierarchy For Package retrofit.converter

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/retrofit/converter/package-use.html ================================================ Uses of Package retrofit.converter (Converter: Jackson 1.9.0 API)

Uses of Package
retrofit.converter

No usage of retrofit.converter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-jackson/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/1.x/converter-jackson/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; width:100%; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/1.x/converter-jackson/version.txt ================================================ 1.9.0 ================================================ FILE: website/public/1.x/converter-protobuf/allclasses-frame.html ================================================ All Classes (Converter: Protocol Buffers 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/converter-protobuf/allclasses-noframe.html ================================================ All Classes (Converter: Protocol Buffers 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/converter-protobuf/constant-values.html ================================================ Constant Field Values (Converter: Protocol Buffers 1.9.0 API)

Constant Field Values

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/deprecated-list.html ================================================ Deprecated List (Converter: Protocol Buffers 1.9.0 API)

Deprecated API

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/help-doc.html ================================================ API Help (Converter: Protocol Buffers 1.9.0 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Use

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/index-all.html ================================================ Index (Converter: Protocol Buffers 1.9.0 API)
F P R T 

F

fromBody(TypedInput, Type) - Method in class retrofit.converter.ProtoConverter
 

P

ProtoConverter - Class in retrofit.converter
A Converter that reads and writes protocol buffers.
ProtoConverter() - Constructor for class retrofit.converter.ProtoConverter
 

R

retrofit.converter - package retrofit.converter
 

T

toBody(Object) - Method in class retrofit.converter.ProtoConverter
 
F P R T 

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/index.html ================================================ Converter: Protocol Buffers 1.9.0 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit/converter/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/1.x/converter-protobuf/overview-tree.html ================================================ Class Hierarchy (Converter: Protocol Buffers 1.9.0 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/package-list ================================================ retrofit.converter ================================================ FILE: website/public/1.x/converter-protobuf/retrofit/converter/ProtoConverter.html ================================================ ProtoConverter (Converter: Protocol Buffers 1.9.0 API)
retrofit.converter

Class ProtoConverter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/retrofit/converter/class-use/ProtoConverter.html ================================================ Uses of Class retrofit.converter.ProtoConverter (Converter: Protocol Buffers 1.9.0 API)

Uses of Class
retrofit.converter.ProtoConverter

No usage of retrofit.converter.ProtoConverter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/retrofit/converter/package-frame.html ================================================ retrofit.converter (Converter: Protocol Buffers 1.9.0 API)

retrofit.converter

Classes

================================================ FILE: website/public/1.x/converter-protobuf/retrofit/converter/package-summary.html ================================================ retrofit.converter (Converter: Protocol Buffers 1.9.0 API)

Package retrofit.converter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/retrofit/converter/package-tree.html ================================================ retrofit.converter Class Hierarchy (Converter: Protocol Buffers 1.9.0 API)

Hierarchy For Package retrofit.converter

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/retrofit/converter/package-use.html ================================================ Uses of Package retrofit.converter (Converter: Protocol Buffers 1.9.0 API)

Uses of Package
retrofit.converter

No usage of retrofit.converter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-protobuf/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/1.x/converter-protobuf/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; width:100%; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/1.x/converter-protobuf/version.txt ================================================ 1.9.0 ================================================ FILE: website/public/1.x/converter-simplexml/allclasses-frame.html ================================================ All Classes (Converter: SimpleXML 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/converter-simplexml/allclasses-noframe.html ================================================ All Classes (Converter: SimpleXML 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/converter-simplexml/constant-values.html ================================================ Constant Field Values (Converter: SimpleXML 1.9.0 API)

Constant Field Values

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/deprecated-list.html ================================================ Deprecated List (Converter: SimpleXML 1.9.0 API)

Deprecated API

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/help-doc.html ================================================ API Help (Converter: SimpleXML 1.9.0 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Use

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/index-all.html ================================================ Index (Converter: SimpleXML 1.9.0 API)
F I R S T 

F

fromBody(TypedInput, Type) - Method in class retrofit.converter.SimpleXMLConverter
 

I

isStrict() - Method in class retrofit.converter.SimpleXMLConverter
 

R

retrofit.converter - package retrofit.converter
 

S

SimpleXMLConverter - Class in retrofit.converter
A Converter which uses SimpleXML for reading and writing entities.
SimpleXMLConverter() - Constructor for class retrofit.converter.SimpleXMLConverter
 
SimpleXMLConverter(boolean) - Constructor for class retrofit.converter.SimpleXMLConverter
 
SimpleXMLConverter(Serializer) - Constructor for class retrofit.converter.SimpleXMLConverter
 
SimpleXMLConverter(Serializer, boolean) - Constructor for class retrofit.converter.SimpleXMLConverter
 

T

toBody(Object) - Method in class retrofit.converter.SimpleXMLConverter
 
F I R S T 

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/index.html ================================================ Converter: SimpleXML 1.9.0 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit/converter/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/1.x/converter-simplexml/overview-tree.html ================================================ Class Hierarchy (Converter: SimpleXML 1.9.0 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/package-list ================================================ retrofit.converter ================================================ FILE: website/public/1.x/converter-simplexml/retrofit/converter/SimpleXMLConverter.html ================================================ SimpleXMLConverter (Converter: SimpleXML 1.9.0 API)
retrofit.converter

Class SimpleXMLConverter

  • All Implemented Interfaces:
    Converter


    public class SimpleXMLConverter
    extends Object
    implements Converter
    A Converter which uses SimpleXML for reading and writing entities.
    Author:
    Fabien Ric (fabien.ric@gmail.com)
    • Constructor Detail

      • SimpleXMLConverter

        public SimpleXMLConverter()
      • SimpleXMLConverter

        public SimpleXMLConverter(boolean strict)
      • SimpleXMLConverter

        public SimpleXMLConverter(org.simpleframework.xml.Serializer serializer)
      • SimpleXMLConverter

        public SimpleXMLConverter(org.simpleframework.xml.Serializer serializer,
                                  boolean strict)

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/retrofit/converter/class-use/SimpleXMLConverter.html ================================================ Uses of Class retrofit.converter.SimpleXMLConverter (Converter: SimpleXML 1.9.0 API)

Uses of Class
retrofit.converter.SimpleXMLConverter

No usage of retrofit.converter.SimpleXMLConverter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/retrofit/converter/package-frame.html ================================================ retrofit.converter (Converter: SimpleXML 1.9.0 API)

retrofit.converter

================================================ FILE: website/public/1.x/converter-simplexml/retrofit/converter/package-summary.html ================================================ retrofit.converter (Converter: SimpleXML 1.9.0 API)

Package retrofit.converter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/retrofit/converter/package-tree.html ================================================ retrofit.converter Class Hierarchy (Converter: SimpleXML 1.9.0 API)

Hierarchy For Package retrofit.converter

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/retrofit/converter/package-use.html ================================================ Uses of Package retrofit.converter (Converter: SimpleXML 1.9.0 API)

Uses of Package
retrofit.converter

No usage of retrofit.converter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-simplexml/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/1.x/converter-simplexml/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; width:100%; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/1.x/converter-simplexml/version.txt ================================================ 1.9.0 ================================================ FILE: website/public/1.x/converter-wire/allclasses-frame.html ================================================ All Classes (Converter: Wire Protocol Buffers 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/converter-wire/allclasses-noframe.html ================================================ All Classes (Converter: Wire Protocol Buffers 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/converter-wire/constant-values.html ================================================ Constant Field Values (Converter: Wire Protocol Buffers 1.9.0 API)

Constant Field Values

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/deprecated-list.html ================================================ Deprecated List (Converter: Wire Protocol Buffers 1.9.0 API)

Deprecated API

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/help-doc.html ================================================ API Help (Converter: Wire Protocol Buffers 1.9.0 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Use

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/index-all.html ================================================ Index (Converter: Wire Protocol Buffers 1.9.0 API)
F R T W 

F

fromBody(TypedInput, Type) - Method in class retrofit.converter.WireConverter
 

R

retrofit.converter - package retrofit.converter
 

T

toBody(Object) - Method in class retrofit.converter.WireConverter
 

W

WireConverter - Class in retrofit.converter
A Converter that reads and writes protocol buffers using Wire.
WireConverter() - Constructor for class retrofit.converter.WireConverter
Create a converter with a default Wire instance.
WireConverter(Wire) - Constructor for class retrofit.converter.WireConverter
Create a converter using the supplied Wire instance.
F R T W 

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/index.html ================================================ Converter: Wire Protocol Buffers 1.9.0 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit/converter/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/1.x/converter-wire/overview-tree.html ================================================ Class Hierarchy (Converter: Wire Protocol Buffers 1.9.0 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/package-list ================================================ retrofit.converter ================================================ FILE: website/public/1.x/converter-wire/retrofit/converter/WireConverter.html ================================================ WireConverter (Converter: Wire Protocol Buffers 1.9.0 API)
retrofit.converter

Class WireConverter

  • All Implemented Interfaces:
    Converter


    public class WireConverter
    extends Object
    implements Converter
    A Converter that reads and writes protocol buffers using Wire.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/retrofit/converter/class-use/WireConverter.html ================================================ Uses of Class retrofit.converter.WireConverter (Converter: Wire Protocol Buffers 1.9.0 API)

Uses of Class
retrofit.converter.WireConverter

No usage of retrofit.converter.WireConverter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/retrofit/converter/package-frame.html ================================================ retrofit.converter (Converter: Wire Protocol Buffers 1.9.0 API)

retrofit.converter

Classes

================================================ FILE: website/public/1.x/converter-wire/retrofit/converter/package-summary.html ================================================ retrofit.converter (Converter: Wire Protocol Buffers 1.9.0 API)

Package retrofit.converter

  • Class Summary 
    Class Description
    WireConverter
    A Converter that reads and writes protocol buffers using Wire.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/retrofit/converter/package-tree.html ================================================ retrofit.converter Class Hierarchy (Converter: Wire Protocol Buffers 1.9.0 API)

Hierarchy For Package retrofit.converter

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/retrofit/converter/package-use.html ================================================ Uses of Package retrofit.converter (Converter: Wire Protocol Buffers 1.9.0 API)

Uses of Package
retrofit.converter

No usage of retrofit.converter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/converter-wire/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/1.x/converter-wire/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; width:100%; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/1.x/converter-wire/version.txt ================================================ 1.9.0 ================================================ FILE: website/public/1.x/retrofit/allclasses-frame.html ================================================ All Classes (Retrofit 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/retrofit/allclasses-noframe.html ================================================ All Classes (Retrofit 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/retrofit/constant-values.html ================================================ Constant Field Values (Retrofit 1.9.0 API)

Constant Field Values

Contents

retrofit.mime.*

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/deprecated-list.html ================================================ Deprecated List (Retrofit 1.9.0 API)

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/help-doc.html ================================================ API Help (Retrofit 1.9.0 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Overview

    The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.

  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Use

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/index-all.html ================================================ Index (Retrofit 1.9.0 API)
A B C D E F G H I L M N O P Q R S T U V W 

A

addEncodedPathParam(String, String) - Method in interface retrofit.RequestInterceptor.RequestFacade
Add a path parameter replacement without first URI encoding.
addEncodedQueryParam(String, String) - Method in interface retrofit.RequestInterceptor.RequestFacade
Add an additional query parameter without first URI encoding.
addField(String, String) - Method in class retrofit.mime.FormUrlEncodedTypedOutput
 
addField(String, boolean, String, boolean) - Method in class retrofit.mime.FormUrlEncodedTypedOutput
 
addHeader(String, String) - Method in interface retrofit.RequestInterceptor.RequestFacade
Add a header to the request.
addPart(String, TypedOutput) - Method in class retrofit.mime.MultipartTypedOutput
 
addPart(String, String, TypedOutput) - Method in class retrofit.mime.MultipartTypedOutput
 
addPathParam(String, String) - Method in interface retrofit.RequestInterceptor.RequestFacade
Add a path parameter replacement.
addQueryParam(String, String) - Method in interface retrofit.RequestInterceptor.RequestFacade
Add an additional query parameter.
afterCall(Profiler.RequestInformation, long, int, T) - Method in interface retrofit.Profiler
Invoked after an HTTP method completes.
AndroidApacheClient - Class in retrofit.android
Provides a Client which uses the Android-specific version of HttpClient, AndroidHttpClient.
AndroidApacheClient() - Constructor for class retrofit.android.AndroidApacheClient
 
AndroidLog - Class in retrofit.android
A logger for Android.
AndroidLog(String) - Constructor for class retrofit.android.AndroidLog
 
ApacheClient - Class in retrofit.client
A Client which uses an implementation of Apache's HttpClient.
ApacheClient() - Constructor for class retrofit.client.ApacheClient
Creates an instance backed by DefaultHttpClient.
ApacheClient(HttpClient) - Constructor for class retrofit.client.ApacheClient
 

B

beforeCall() - Method in interface retrofit.Profiler
Invoked before an HTTP method call.
Body - Annotation Type in retrofit.http
Use this annotation on a service method param when you want to directly control the request body of a POST/PUT request (instead of sending in as request parameters or form-style request body).
build() - Method in class retrofit.RestAdapter.Builder
Create the RestAdapter instances.
Builder() - Constructor for class retrofit.RestAdapter.Builder
 

C

Callback<T> - Interface in retrofit
Communicates responses from a server or offline requests.
Client - Interface in retrofit.client
Abstraction of an HTTP client which can execute Requests.
Client.Provider - Interface in retrofit.client
Deferred means of obtaining a Client.
conversionError(String, Response, Converter, Type, ConversionException) - Static method in exception retrofit.RetrofitError
 
ConversionException - Exception in retrofit.converter
Indicate that conversion was unable to complete successfully.
ConversionException(String) - Constructor for exception retrofit.converter.ConversionException
 
ConversionException(String, Throwable) - Constructor for exception retrofit.converter.ConversionException
 
ConversionException(Throwable) - Constructor for exception retrofit.converter.ConversionException
 
Converter - Interface in retrofit.converter
Arbiter for converting objects to and from their representation in HTTP.
create(Class<T>) - Method in class retrofit.RestAdapter
Create an implementation of the API defined by the specified service interface.

D

DEFAULT - Static variable in interface retrofit.ErrorHandler
An ErrorHandler which returns the original error.
DEFAULT_TRANSFER_ENCODING - Static variable in class retrofit.mime.MultipartTypedOutput
 
DELETE - Annotation Type in retrofit.http
Make a DELETE request to a REST path relative to base URL.

E

EncodedPath - Annotation Type in retrofit.http
Deprecated.
EncodedQuery - Annotation Type in retrofit.http
Deprecated.
EncodedQueryMap - Annotation Type in retrofit.http
Deprecated.
Endpoint - Interface in retrofit
Represents an API endpoint URL and associated name.
Endpoints - Class in retrofit
Static factory methods for creating Endpoint instances.
equals(Object) - Method in class retrofit.client.Header
 
equals(Object) - Method in class retrofit.mime.TypedByteArray
 
equals(Object) - Method in class retrofit.mime.TypedFile
 
ErrorHandler - Interface in retrofit
A hook allowing clients to customize response exceptions.
execute(Runnable) - Method in class retrofit.android.MainThreadExecutor
 
execute(Request) - Method in class retrofit.appengine.UrlFetchClient
 
execute(URLFetchService, HTTPRequest) - Method in class retrofit.appengine.UrlFetchClient
Execute the specified request using the provided urlFetchService.
execute(Request) - Method in class retrofit.client.ApacheClient
 
execute(HttpClient, HttpUriRequest) - Method in class retrofit.client.ApacheClient
Execute the specified request using the provided client.
execute(Request) - Method in interface retrofit.client.Client
Synchronously execute an HTTP represented by request and encapsulate all response data into a Response instance.
execute(Request) - Method in class retrofit.client.OkClient
 
execute(Request) - Method in class retrofit.client.UrlConnectionClient
 

F

failure(RetrofitError) - Method in interface retrofit.Callback
Unsuccessful HTTP response due to network failure, non-2XX status code, or unexpected exception.
Field - Annotation Type in retrofit.http
Named pair for a form-encoded request.
FieldMap - Annotation Type in retrofit.http
Named key/value pairs for a form-encoded request.
file() - Method in class retrofit.mime.TypedFile
Returns the file.
fileName() - Method in class retrofit.mime.FormUrlEncodedTypedOutput
 
fileName() - Method in class retrofit.mime.MultipartTypedOutput
 
fileName() - Method in class retrofit.mime.TypedByteArray
 
fileName() - Method in class retrofit.mime.TypedFile
 
fileName() - Method in interface retrofit.mime.TypedOutput
Original filename.
FormUrlEncoded - Annotation Type in retrofit.http
Denotes that the request body will use form URL encoding.
FormUrlEncodedTypedOutput - Class in retrofit.mime
 
FormUrlEncodedTypedOutput() - Constructor for class retrofit.mime.FormUrlEncodedTypedOutput
 
fromBody(TypedInput, Type) - Method in interface retrofit.converter.Converter
Convert an HTTP response body to a concrete object of the specified type.
fromBody(TypedInput, Type) - Method in class retrofit.converter.GsonConverter
 

G

get() - Method in interface retrofit.client.Client.Provider
Obtain an HTTP client.
GET - Annotation Type in retrofit.http
Make a GET request to a REST path relative to base URL.
getBaseUrl() - Method in class retrofit.Profiler.RequestInformation
Returns the URL to which the originating request was sent.
getBody() - Method in class retrofit.client.Request
Returns the request body or null.
getBody() - Method in class retrofit.client.Response
Response body.
getBody() - Method in exception retrofit.RetrofitError
HTTP response body converted to the type declared by either the interface method return type or the generic type of the supplied Callback parameter.
getBodyAs(Type) - Method in exception retrofit.RetrofitError
HTTP response body converted to specified type.
getBytes() - Method in class retrofit.mime.TypedByteArray
 
getContentLength() - Method in class retrofit.Profiler.RequestInformation
Returns the number of bytes in the originating request.
getContentType() - Method in class retrofit.Profiler.RequestInformation
Returns the content type header value of the originating request.
getHeaders() - Method in class retrofit.client.Request
Returns an unmodifiable list of headers, never null.
getHeaders() - Method in class retrofit.client.Response
An unmodifiable collection of headers.
getKind() - Method in exception retrofit.RetrofitError
The event kind which triggered this error.
getLogLevel() - Method in class retrofit.RestAdapter
The current logging level.
getMethod() - Method in class retrofit.client.Request
HTTP method verb.
getMethod() - Method in class retrofit.Profiler.RequestInformation
Returns the HTTP method of the originating request.
getName() - Method in class retrofit.client.Header
 
getName() - Method in interface retrofit.Endpoint
A name for differentiating between multiple API URLs.
getPartCount() - Method in class retrofit.mime.MultipartTypedOutput
 
getReason() - Method in class retrofit.client.Response
Status line reason phrase.
getRelativePath() - Method in class retrofit.Profiler.RequestInformation
Returns the path relative to the base URL to which the originating request was sent.
getResponse() - Method in exception retrofit.RetrofitError
Response object containing status code, headers, body, etc.
getStatus() - Method in class retrofit.client.Response
Status line code.
getSuccessType() - Method in exception retrofit.RetrofitError
The type declared by either the interface method return type or the generic type of the supplied Callback parameter.
getTag() - Method in class retrofit.android.AndroidLog
 
getUrl() - Method in class retrofit.client.Request
Target URL.
getUrl() - Method in class retrofit.client.Response
Request URL.
getUrl() - Method in interface retrofit.Endpoint
The base API URL.
getUrl() - Method in exception retrofit.RetrofitError
The request URL which produced the error.
getValue() - Method in class retrofit.client.Header
 
GsonConverter - Class in retrofit.converter
A Converter which uses GSON for serialization and deserialization of entities.
GsonConverter(Gson) - Constructor for class retrofit.converter.GsonConverter
Create an instance using the supplied Gson object for conversion.
GsonConverter(Gson, String) - Constructor for class retrofit.converter.GsonConverter
Create an instance using the supplied Gson object for conversion.

H

handleError(RetrofitError) - Method in interface retrofit.ErrorHandler
Return a custom exception to be thrown for a RetrofitError.
hashCode() - Method in class retrofit.client.Header
 
hashCode() - Method in class retrofit.mime.TypedByteArray
 
hashCode() - Method in class retrofit.mime.TypedFile
 
HEAD - Annotation Type in retrofit.http
Make a HEAD request to a REST path relative to base URL.
Header - Class in retrofit.client
Represents an HTTP header name/value pair.
Header(String, String) - Constructor for class retrofit.client.Header
 
Header - Annotation Type in retrofit.http
Replaces the header with the value of its target.
Headers - Annotation Type in retrofit.http
Adds headers literally supplied in the value.
httpError(String, Response, Converter, Type) - Static method in exception retrofit.RetrofitError
 

I

in() - Method in class retrofit.mime.TypedByteArray
 
in() - Method in class retrofit.mime.TypedFile
 
in() - Method in interface retrofit.mime.TypedInput
Read bytes as stream.
intercept(RequestInterceptor.RequestFacade) - Method in interface retrofit.RequestInterceptor
Called for every request.
isNetworkError() - Method in exception retrofit.RetrofitError
Deprecated.

L

length() - Method in class retrofit.mime.FormUrlEncodedTypedOutput
 
length() - Method in class retrofit.mime.MultipartTypedOutput
 
length() - Method in class retrofit.mime.TypedByteArray
 
length() - Method in class retrofit.mime.TypedFile
 
length() - Method in interface retrofit.mime.TypedInput
Length in bytes.
length() - Method in interface retrofit.mime.TypedOutput
Length in bytes or -1 if unknown.
log(String) - Method in class retrofit.android.AndroidLog
 
log(String) - Method in interface retrofit.RestAdapter.Log
Log a debug message to the appropriate console.
log() - Method in enum retrofit.RestAdapter.LogLevel
 
logChunk(String) - Method in class retrofit.android.AndroidLog
Called one or more times for each call to AndroidLog.log(String).

M

MainThreadExecutor - Class in retrofit.android
Executor that runs tasks on Android's main thread.
MainThreadExecutor() - Constructor for class retrofit.android.MainThreadExecutor
 
mimeType() - Method in class retrofit.mime.FormUrlEncodedTypedOutput
 
mimeType() - Method in class retrofit.mime.MultipartTypedOutput
 
mimeType() - Method in class retrofit.mime.TypedByteArray
 
mimeType() - Method in class retrofit.mime.TypedFile
 
mimeType() - Method in interface retrofit.mime.TypedInput
Returns the mime type.
mimeType() - Method in interface retrofit.mime.TypedOutput
Returns the mime type.
MimeUtil - Class in retrofit.mime
 
moveTo(TypedFile) - Method in class retrofit.mime.TypedFile
Atomically moves the contents of this file to a new location.
Multipart - Annotation Type in retrofit.http
Denotes that the request body is multi-part.
MultipartTypedOutput - Class in retrofit.mime
 
MultipartTypedOutput() - Constructor for class retrofit.mime.MultipartTypedOutput
 

N

networkError(String, IOException) - Static method in exception retrofit.RetrofitError
 
newFixedEndpoint(String) - Static method in class retrofit.Endpoints
Create a server with the provided URL.
newFixedEndpoint(String, String) - Static method in class retrofit.Endpoints
Create an endpoint with the provided URL and name.
NONE - Static variable in interface retrofit.RequestInterceptor
A RequestInterceptor which does no modification of requests.
NONE - Static variable in interface retrofit.RestAdapter.Log
A RestAdapter.Log implementation which does not log anything.

O

OkClient - Class in retrofit.client
Retrofit client that uses OkHttp for communication.
OkClient() - Constructor for class retrofit.client.OkClient
 
OkClient(OkHttpClient) - Constructor for class retrofit.client.OkClient
 
openConnection(Request) - Method in class retrofit.client.UrlConnectionClient
 

P

parseCharset(String) - Static method in class retrofit.mime.MimeUtil
parseCharset(String, String) - Static method in class retrofit.mime.MimeUtil
Parse the MIME type from a Content-Type header value.
Part - Annotation Type in retrofit.http
Denotes a single part of a multi-part request.
PartMap - Annotation Type in retrofit.http
Denotes name and value parts of a multi-part request
PATCH - Annotation Type in retrofit.http
Make a PATCH request to a REST path relative to base URL.
Path - Annotation Type in retrofit.http
Named replacement in the URL path.
POST - Annotation Type in retrofit.http
Make a POST request to a REST path relative to base URL.
Profiler<T> - Interface in retrofit
A hook allowing clients to log HTTP method times and response status codes.
Profiler.RequestInformation - Class in retrofit
Information about the HTTP request.
PUT - Annotation Type in retrofit.http
Make a PUT request to a REST path relative to base URL.

Q

Query - Annotation Type in retrofit.http
Query parameter appended to the URL.
QueryMap - Annotation Type in retrofit.http
Query parameter keys and values appended to the URL.

R

Request - Class in retrofit.client
Encapsulates all of the information necessary to make an HTTP request.
Request(String, String, List<Header>, TypedOutput) - Constructor for class retrofit.client.Request
 
RequestInformation(String, String, String, long, String) - Constructor for class retrofit.Profiler.RequestInformation
 
RequestInterceptor - Interface in retrofit
Intercept every request before it is executed in order to add additional data.
RequestInterceptor.RequestFacade - Interface in retrofit
 
Response - Class in retrofit.client
An HTTP response.
Response(String, int, String, List<Header>, TypedInput) - Constructor for class retrofit.client.Response
 
ResponseCallback - Class in retrofit
An extension of Callback which returns only Response object in Callback.success(Object, retrofit.client.Response) method.
ResponseCallback() - Constructor for class retrofit.ResponseCallback
 
RestAdapter - Class in retrofit
Adapts a Java interface to a REST API.
RestAdapter.Builder - Class in retrofit
Build a new RestAdapter.
RestAdapter.Log - Interface in retrofit
Simple logging abstraction for debug messages.
RestAdapter.LogLevel - Enum in retrofit
Controls the level of logging.
RestMethod - Annotation Type in retrofit.http
 
retrofit - package retrofit
Retrofit turns your REST API into a Java interface.
retrofit.android - package retrofit.android
 
retrofit.appengine - package retrofit.appengine
 
retrofit.client - package retrofit.client
 
retrofit.converter - package retrofit.converter
 
retrofit.http - package retrofit.http
Annotations for interface methods to control the HTTP request behavior.
retrofit.mime - package retrofit.mime
 
RetrofitError - Exception in retrofit
 
RetrofitError.Kind - Enum in retrofit
Identifies the event kind which triggered a RetrofitError.

S

setClient(Client) - Method in class retrofit.RestAdapter.Builder
The HTTP client used for requests.
setClient(Client.Provider) - Method in class retrofit.RestAdapter.Builder
The HTTP client used for requests.
setConverter(Converter) - Method in class retrofit.RestAdapter.Builder
The converter used for serialization and deserialization of objects.
setEndpoint(String) - Method in class retrofit.RestAdapter.Builder
API endpoint URL.
setEndpoint(Endpoint) - Method in class retrofit.RestAdapter.Builder
API endpoint.
setErrorHandler(ErrorHandler) - Method in class retrofit.RestAdapter.Builder
The error handler allows you to customize the type of exception thrown for errors on synchronous requests.
setExecutors(Executor, Executor) - Method in class retrofit.RestAdapter.Builder
Executors used for asynchronous HTTP client downloads and callbacks.
setLog(RestAdapter.Log) - Method in class retrofit.RestAdapter.Builder
Configure debug logging mechanism.
setLogLevel(RestAdapter.LogLevel) - Method in class retrofit.RestAdapter.Builder
Change the level of logging.
setLogLevel(RestAdapter.LogLevel) - Method in class retrofit.RestAdapter
Change the level of logging.
setProfiler(Profiler) - Method in class retrofit.RestAdapter.Builder
Set the profiler used to measure requests.
setRequestInterceptor(RequestInterceptor) - Method in class retrofit.RestAdapter.Builder
A request interceptor for adding data to every request.
Streaming - Annotation Type in retrofit.http
Treat the response body on methods returning Response as is, i.e.
success(T, Response) - Method in interface retrofit.Callback
Successful HTTP response.
success(Response, Response) - Method in class retrofit.ResponseCallback
 
success(Response) - Method in class retrofit.ResponseCallback
Successful HTTP response.

T

toBody(Object) - Method in interface retrofit.converter.Converter
Convert an object to an appropriate representation for HTTP transport.
toBody(Object) - Method in class retrofit.converter.GsonConverter
 
toString() - Method in class retrofit.client.Header
 
toString() - Method in class retrofit.mime.TypedByteArray
 
toString() - Method in class retrofit.mime.TypedFile
 
toString() - Method in class retrofit.mime.TypedString
 
TypedByteArray - Class in retrofit.mime
Byte array and its mime type.
TypedByteArray(String, byte[]) - Constructor for class retrofit.mime.TypedByteArray
Constructs a new typed byte array.
TypedFile - Class in retrofit.mime
File and its mime type.
TypedFile(String, File) - Constructor for class retrofit.mime.TypedFile
Constructs a new typed file.
TypedInput - Interface in retrofit.mime
Binary data with an associated mime type.
TypedOutput - Interface in retrofit.mime
Binary data with an associated mime type.
TypedString - Class in retrofit.mime
 
TypedString(String) - Constructor for class retrofit.mime.TypedString
 

U

unexpectedError(String, Throwable) - Static method in exception retrofit.RetrofitError
 
UrlConnectionClient - Class in retrofit.client
Retrofit client that uses HttpURLConnection for communication.
UrlConnectionClient() - Constructor for class retrofit.client.UrlConnectionClient
 
UrlFetchClient - Class in retrofit.appengine
A Client for Google AppEngine's which uses its URLFetchService.
UrlFetchClient() - Constructor for class retrofit.appengine.UrlFetchClient
 
UrlFetchClient(URLFetchService) - Constructor for class retrofit.appengine.UrlFetchClient
 

V

valueOf(String) - Static method in enum retrofit.RestAdapter.LogLevel
Returns the enum constant of this type with the specified name.
valueOf(String) - Static method in enum retrofit.RetrofitError.Kind
Returns the enum constant of this type with the specified name.
values() - Static method in enum retrofit.RestAdapter.LogLevel
Returns an array containing the constants of this enum type, in the order they are declared.
values() - Static method in enum retrofit.RetrofitError.Kind
Returns an array containing the constants of this enum type, in the order they are declared.

W

writeTo(OutputStream) - Method in class retrofit.mime.FormUrlEncodedTypedOutput
 
writeTo(OutputStream) - Method in class retrofit.mime.MultipartTypedOutput
 
writeTo(OutputStream) - Method in class retrofit.mime.TypedByteArray
 
writeTo(OutputStream) - Method in class retrofit.mime.TypedFile
 
writeTo(OutputStream) - Method in interface retrofit.mime.TypedOutput
Writes these bytes to the given output stream.
A B C D E F G H I L M N O P Q R S T U V W 

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/index.html ================================================ Retrofit 1.9.0 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="overview-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/1.x/retrofit/overview-frame.html ================================================ Overview List (Retrofit 1.9.0 API)

 

================================================ FILE: website/public/1.x/retrofit/overview-summary.html ================================================ Overview (Retrofit 1.9.0 API)

Retrofit 1.9.0 API

Packages 
Package Description
retrofit
Retrofit turns your REST API into a Java interface.
retrofit.android  
retrofit.appengine  
retrofit.client  
retrofit.converter  
retrofit.http
Annotations for interface methods to control the HTTP request behavior.
retrofit.mime  

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/overview-tree.html ================================================ Class Hierarchy (Retrofit 1.9.0 API)

Class Hierarchy

Interface Hierarchy

Annotation Type Hierarchy

Enum Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/package-list ================================================ retrofit retrofit.android retrofit.appengine retrofit.client retrofit.converter retrofit.http retrofit.mime ================================================ FILE: website/public/1.x/retrofit/retrofit/Callback.html ================================================ Callback (Retrofit 1.9.0 API)
retrofit

Interface Callback<T>

  • Type Parameters:
    T - expected response type
    All Known Implementing Classes:
    ResponseCallback


    public interface Callback<T>
    Communicates responses from a server or offline requests. One and only one method will be invoked in response to a given request.

    Callback methods are executed using the RestAdapter callback executor. When none is specified, the following defaults are used:

    • Android: Callbacks are executed on the application's main (UI) thread.
    • JVM: Callbacks are executed on the background thread which performed the request.
    See Also:
    RestAdapter.Builder.setExecutors(java.util.concurrent.Executor, java.util.concurrent.Executor)
    • Method Detail

      • success

        void success(T t,
                     Response response)
        Successful HTTP response.
      • failure

        void failure(RetrofitError error)
        Unsuccessful HTTP response due to network failure, non-2XX status code, or unexpected exception.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/Endpoint.html ================================================ Endpoint (Retrofit 1.9.0 API)
retrofit

Interface Endpoint



  • public interface Endpoint
    Represents an API endpoint URL and associated name. Callers should always consult the instance for the latest values rather than caching the returned values.
    Author:
    Matt Hickman (mhickman@palantir.com)
    • Method Detail

      • getUrl

        String getUrl()
        The base API URL.
      • getName

        String getName()
        A name for differentiating between multiple API URLs.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/Endpoints.html ================================================ Endpoints (Retrofit 1.9.0 API)
retrofit

Class Endpoints



  • public final class Endpoints
    extends Object
    Static factory methods for creating Endpoint instances.
    Author:
    Matt Hickman (mhickman@palantir.com)
    • Method Detail

      • newFixedEndpoint

        public static Endpoint newFixedEndpoint(String url)
        Create a server with the provided URL.
      • newFixedEndpoint

        public static Endpoint newFixedEndpoint(String url,
                                                String name)
        Create an endpoint with the provided URL and name.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/ErrorHandler.html ================================================ ErrorHandler (Retrofit 1.9.0 API)
retrofit

Interface ErrorHandler



  • public interface ErrorHandler
    A hook allowing clients to customize response exceptions.
    Author:
    Sam Beran sberan@gmail.com
    • Method Detail

      • handleError

        Throwable handleError(RetrofitError cause)
        Return a custom exception to be thrown for a RetrofitError. It is recommended that you pass the supplied error as the cause to any new exceptions.

        If the return exception is checked it must be declared to be thrown on the interface method.

        Example usage:

         class MyErrorHandler implements ErrorHandler {
           @Override public Throwable handleError(RetrofitError cause) {
             Response r = cause.getResponse();
             if (r != null && r.getStatus() == 401) {
               return new UnauthorizedException(cause);
             }
             return cause;
           }
         }
         
        Parameters:
        cause - the original RetrofitError exception
        Returns:
        Throwable an exception which will be thrown from a synchronous interface method or passed to an asynchronous error callback. Must not be null.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/Profiler.RequestInformation.html ================================================ Profiler.RequestInformation (Retrofit 1.9.0 API)
retrofit

Class Profiler.RequestInformation

  • Enclosing interface:
    Profiler<T>


    public static final class Profiler.RequestInformation
    extends Object
    Information about the HTTP request.
    • Constructor Detail

      • RequestInformation

        public RequestInformation(String method,
                                  String baseUrl,
                                  String relativePath,
                                  long contentLength,
                                  String contentType)
    • Method Detail

      • getMethod

        public String getMethod()
        Returns the HTTP method of the originating request.
      • getBaseUrl

        public String getBaseUrl()
        Returns the URL to which the originating request was sent.
      • getRelativePath

        public String getRelativePath()
        Returns the path relative to the base URL to which the originating request was sent.
      • getContentLength

        public long getContentLength()
        Returns the number of bytes in the originating request.
      • getContentType

        public String getContentType()
        Returns the content type header value of the originating request.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/Profiler.html ================================================ Profiler (Retrofit 1.9.0 API)
retrofit

Interface Profiler<T>



  • public interface Profiler<T>
    A hook allowing clients to log HTTP method times and response status codes.
    Author:
    Eric Burke (eric@squareup.com)
    • Method Detail

      • beforeCall

        T beforeCall()
        Invoked before an HTTP method call. The object returned by this method will be passed to afterCall(retrofit.Profiler.RequestInformation, long, int, T) when the call returns.

        This method gives implementers the opportunity to include information that may change during the server call in afterCall logic.

      • afterCall

        void afterCall(Profiler.RequestInformation requestInfo,
                       long elapsedTime,
                       int statusCode,
                       T beforeCallData)
        Invoked after an HTTP method completes. This is called from the RestAdapter's background thread.
        Parameters:
        requestInfo - information about the originating HTTP request.
        elapsedTime - time in milliseconds it took the HTTP request to complete.
        statusCode - response status code.
        beforeCallData - the data returned by the corresponding beforeCall().

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/RequestInterceptor.RequestFacade.html ================================================ RequestInterceptor.RequestFacade (Retrofit 1.9.0 API)
retrofit

Interface RequestInterceptor.RequestFacade

  • Enclosing interface:
    RequestInterceptor


    public static interface RequestInterceptor.RequestFacade
    • Method Detail

      • addHeader

        void addHeader(String name,
                       String value)
        Add a header to the request. This will not replace any existing headers.
      • addPathParam

        void addPathParam(String name,
                          String value)
        Add a path parameter replacement. This works exactly like a @Path-annotated method argument.
      • addEncodedPathParam

        void addEncodedPathParam(String name,
                                 String value)
        Add a path parameter replacement without first URI encoding. This works exactly like a @Path-annotated method argument with encode=false.
      • addQueryParam

        void addQueryParam(String name,
                           String value)
        Add an additional query parameter. This will not replace any existing query parameters.
      • addEncodedQueryParam

        void addEncodedQueryParam(String name,
                                  String value)
        Add an additional query parameter without first URI encoding. This will not replace any existing query parameters.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/RequestInterceptor.html ================================================ RequestInterceptor (Retrofit 1.9.0 API)
retrofit

Interface RequestInterceptor



  • public interface RequestInterceptor
    Intercept every request before it is executed in order to add additional data.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/ResponseCallback.html ================================================ ResponseCallback (Retrofit 1.9.0 API)
retrofit

Class ResponseCallback

    • Constructor Detail

      • ResponseCallback

        public ResponseCallback()
    • Method Detail

      • success

        public abstract void success(Response response)
        Successful HTTP response.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/RestAdapter.Builder.html ================================================ RestAdapter.Builder (Retrofit 1.9.0 API)
retrofit

Class RestAdapter.Builder

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/RestAdapter.Log.html ================================================ RestAdapter.Log (Retrofit 1.9.0 API)
retrofit

Interface RestAdapter.Log

  • All Known Implementing Classes:
    AndroidLog
    Enclosing class:
    RestAdapter


    public static interface RestAdapter.Log
    Simple logging abstraction for debug messages.
    • Method Detail

      • log

        void log(String message)
        Log a debug message to the appropriate console.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/RestAdapter.LogLevel.html ================================================ RestAdapter.LogLevel (Retrofit 1.9.0 API)
retrofit

Enum RestAdapter.LogLevel

    • Enum Constant Detail

      • BASIC

        public static final RestAdapter.LogLevel BASIC
        Log only the request method and URL and the response status code and execution time.
      • HEADERS

        public static final RestAdapter.LogLevel HEADERS
        Log the basic information along with request and response headers.
      • HEADERS_AND_ARGS

        public static final RestAdapter.LogLevel HEADERS_AND_ARGS
        Log the basic information along with request and response objects via toString().
      • FULL

        public static final RestAdapter.LogLevel FULL
        Log the headers, body, and metadata for both requests and responses.

        Note: This requires that the entire request and response body be buffered in memory!

    • Method Detail

      • values

        public static RestAdapter.LogLevel[] values()
        Returns an array containing the constants of this enum type, in the order they are declared. This method may be used to iterate over the constants as follows:
        for (RestAdapter.LogLevel c : RestAdapter.LogLevel.values())
            System.out.println(c);
        
        Returns:
        an array containing the constants of this enum type, in the order they are declared
      • valueOf

        public static RestAdapter.LogLevel valueOf(String name)
        Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)
        Parameters:
        name - the name of the enum constant to be returned.
        Returns:
        the enum constant with the specified name
        Throws:
        IllegalArgumentException - if this enum type has no constant with the specified name
        NullPointerException - if the argument is null
      • log

        public boolean log()

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/RestAdapter.html ================================================ RestAdapter (Retrofit 1.9.0 API)
retrofit

Class RestAdapter



  • public class RestAdapter
    extends Object
    Adapts a Java interface to a REST API.

    API endpoints are defined as methods on an interface with annotations providing metadata about the form in which the HTTP call should be made.

    The relative path for a given method is obtained from an annotation on the method describing the request type. The built-in methods are GET, PUT, POST, HEAD, and DELETE. You can define your own HTTP method by creating an annotation that takes a {code String} value and itself is annotated with @RestMethod.

    Method parameters can be used to replace parts of the URL by annotating them with @Path. Replacement sections are denoted by an identifier surrounded by curly braces (e.g., "{foo}"). To add items to the query string of a URL use @Query.

    HTTP requests happen in one of two ways:

    • On the provided HTTP Executor with callbacks marshaled to the callback Executor. The last method parameter should be of type Callback. The HTTP response will be converted to the callback's parameter type using the specified Converter. If the callback parameter type uses a wildcard, the lower bound will be used as the conversion type.
    • On the current thread returning the response or throwing a RetrofitError. The HTTP response will be converted to the method's return type using the specified Converter.

    The body of a request is denoted by the @Body annotation. The object will be converted to request representation by a call to toBody on the supplied Converter for this instance. The body can also be a TypedOutput where it will be used directly.

    Alternative request body formats are supported by method annotations and corresponding parameter annotations:

    • @FormUrlEncoded - Form-encoded data with key-value pairs specified by the @Field parameter annotation.
    • @Multipart - RFC 2387-compliant multi-part data with parts specified by the @Part parameter annotation.

    Additional static headers can be added for an endpoint using the @Headers method annotation. For per-request control over a header annotate a parameter with @Header.

    For example:

     public interface MyApi {
       @POST("/category/{cat}") // Asynchronous execution.
       void categoryList(@Path("cat") String a, @Query("page") int b,
                         Callback<List<Item>> cb);
       @POST("/category/{cat}") // Synchronous execution.
       List<Item> categoryList(@Path("cat") String a, @Query("page") int b);
     }
     

    Calling create(Class) with MyApi.class will validate and create a new implementation of the API.

    Author:
    Bob Lee (bob@squareup.com), Jake Wharton (jw@squareup.com)
    • Method Detail

      • setLogLevel

        public void setLogLevel(RestAdapter.LogLevel loglevel)
        Change the level of logging.
      • create

        public <T> T create(Class<T> service)
        Create an implementation of the API defined by the specified service interface.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/RetrofitError.Kind.html ================================================ RetrofitError.Kind (Retrofit 1.9.0 API)
retrofit

Enum RetrofitError.Kind

    • Enum Constant Detail

      • CONVERSION

        public static final RetrofitError.Kind CONVERSION
        An exception was thrown while (de)serializing a body.
      • HTTP

        public static final RetrofitError.Kind HTTP
        A non-200 HTTP status code was received from the server.
      • UNEXPECTED

        public static final RetrofitError.Kind UNEXPECTED
        An internal error occurred while attempting to execute a request. It is best practice to re-throw this exception so your application crashes.
    • Method Detail

      • values

        public static RetrofitError.Kind[] values()
        Returns an array containing the constants of this enum type, in the order they are declared. This method may be used to iterate over the constants as follows:
        for (RetrofitError.Kind c : RetrofitError.Kind.values())
            System.out.println(c);
        
        Returns:
        an array containing the constants of this enum type, in the order they are declared
      • valueOf

        public static RetrofitError.Kind valueOf(String name)
        Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)
        Parameters:
        name - the name of the enum constant to be returned.
        Returns:
        the enum constant with the specified name
        Throws:
        IllegalArgumentException - if this enum type has no constant with the specified name
        NullPointerException - if the argument is null

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/RetrofitError.html ================================================ RetrofitError (Retrofit 1.9.0 API)
retrofit

Class RetrofitError

    • Method Detail

      • getUrl

        public String getUrl()
        The request URL which produced the error.
      • getResponse

        public Response getResponse()
        Response object containing status code, headers, body, etc.
      • getKind

        public RetrofitError.Kind getKind()
        The event kind which triggered this error.
      • getBody

        public Object getBody()
        HTTP response body converted to the type declared by either the interface method return type or the generic type of the supplied Callback parameter. null if there is no response.
        Throws:
        RuntimeException - if unable to convert the body to the success type.
      • getSuccessType

        public Type getSuccessType()
        The type declared by either the interface method return type or the generic type of the supplied Callback parameter.
      • getBodyAs

        public Object getBodyAs(Type type)
        HTTP response body converted to specified type. null if there is no response.
        Throws:
        RuntimeException - if unable to convert the body to the specified type.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/android/AndroidApacheClient.html ================================================ AndroidApacheClient (Retrofit 1.9.0 API)
retrofit.android

Class AndroidApacheClient

  • All Implemented Interfaces:
    Client


    public final class AndroidApacheClient
    extends ApacheClient
    Provides a Client which uses the Android-specific version of HttpClient, AndroidHttpClient.

    If you need to provide a customized version of the AndroidHttpClient or a different HttpClient on Android use ApacheClient directly.

    • Constructor Detail

      • AndroidApacheClient

        public AndroidApacheClient()

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/android/AndroidLog.html ================================================ AndroidLog (Retrofit 1.9.0 API)
retrofit.android

Class AndroidLog

    • Constructor Detail

      • AndroidLog

        public AndroidLog(String tag)
    • Method Detail

      • log

        public final void log(String message)
        Description copied from interface: RestAdapter.Log
        Log a debug message to the appropriate console.
        Specified by:
        log in interface RestAdapter.Log
      • logChunk

        public void logChunk(String chunk)
        Called one or more times for each call to log(String). The length of chunk will be no more than 4000 characters to support Android's Log class.
      • getTag

        public String getTag()

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/android/MainThreadExecutor.html ================================================ MainThreadExecutor (Retrofit 1.9.0 API)
retrofit.android

Class MainThreadExecutor

  • All Implemented Interfaces:
    Executor


    public final class MainThreadExecutor
    extends Object
    implements Executor
    Executor that runs tasks on Android's main thread.
    • Constructor Detail

      • MainThreadExecutor

        public MainThreadExecutor()

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/android/class-use/AndroidApacheClient.html ================================================ Uses of Class retrofit.android.AndroidApacheClient (Retrofit 1.9.0 API)

Uses of Class
retrofit.android.AndroidApacheClient

No usage of retrofit.android.AndroidApacheClient

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/android/class-use/AndroidLog.html ================================================ Uses of Class retrofit.android.AndroidLog (Retrofit 1.9.0 API)

Uses of Class
retrofit.android.AndroidLog

No usage of retrofit.android.AndroidLog

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/android/class-use/MainThreadExecutor.html ================================================ Uses of Class retrofit.android.MainThreadExecutor (Retrofit 1.9.0 API)

Uses of Class
retrofit.android.MainThreadExecutor

No usage of retrofit.android.MainThreadExecutor

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/android/package-frame.html ================================================ retrofit.android (Retrofit 1.9.0 API)

retrofit.android

================================================ FILE: website/public/1.x/retrofit/retrofit/android/package-summary.html ================================================ retrofit.android (Retrofit 1.9.0 API)

Package retrofit.android

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/android/package-tree.html ================================================ retrofit.android Class Hierarchy (Retrofit 1.9.0 API)

Hierarchy For Package retrofit.android

Package Hierarchies:

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/android/package-use.html ================================================ Uses of Package retrofit.android (Retrofit 1.9.0 API)

Uses of Package
retrofit.android

No usage of retrofit.android

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/appengine/UrlFetchClient.html ================================================ UrlFetchClient (Retrofit 1.9.0 API)
retrofit.appengine

Class UrlFetchClient

  • All Implemented Interfaces:
    Client


    public class UrlFetchClient
    extends Object
    implements Client
    A Client for Google AppEngine's which uses its URLFetchService.
    • Constructor Detail

      • UrlFetchClient

        public UrlFetchClient()
      • UrlFetchClient

        public UrlFetchClient(com.google.appengine.api.urlfetch.URLFetchService urlFetchService)
    • Method Detail

      • execute

        public Response execute(Request request)
                         throws IOException
        Description copied from interface: Client
        Synchronously execute an HTTP represented by request and encapsulate all response data into a Response instance.

        Note: If the request has a body, its length and mime type will have already been added to the header list as Content-Length and Content-Type, respectively. Do NOT alter these values as they might have been set as a result of an application-level configuration.

        Specified by:
        execute in interface Client
        Throws:
        IOException
      • execute

        protected com.google.appengine.api.urlfetch.HTTPResponse execute(com.google.appengine.api.urlfetch.URLFetchService urlFetchService,
                                                                         com.google.appengine.api.urlfetch.HTTPRequest request)
                                                                  throws IOException
        Execute the specified request using the provided urlFetchService.
        Throws:
        IOException

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/appengine/class-use/UrlFetchClient.html ================================================ Uses of Class retrofit.appengine.UrlFetchClient (Retrofit 1.9.0 API)

Uses of Class
retrofit.appengine.UrlFetchClient

No usage of retrofit.appengine.UrlFetchClient

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/appengine/package-frame.html ================================================ retrofit.appengine (Retrofit 1.9.0 API)

retrofit.appengine

Classes

================================================ FILE: website/public/1.x/retrofit/retrofit/appengine/package-summary.html ================================================ retrofit.appengine (Retrofit 1.9.0 API)

Package retrofit.appengine

  • Class Summary 
    Class Description
    UrlFetchClient
    A Client for Google AppEngine's which uses its URLFetchService.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/appengine/package-tree.html ================================================ retrofit.appengine Class Hierarchy (Retrofit 1.9.0 API)

Hierarchy For Package retrofit.appengine

Package Hierarchies:

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/appengine/package-use.html ================================================ Uses of Package retrofit.appengine (Retrofit 1.9.0 API)

Uses of Package
retrofit.appengine

No usage of retrofit.appengine

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/Callback.html ================================================ Uses of Interface retrofit.Callback (Retrofit 1.9.0 API)

Uses of Interface
retrofit.Callback

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/Endpoint.html ================================================ Uses of Interface retrofit.Endpoint (Retrofit 1.9.0 API)

Uses of Interface
retrofit.Endpoint

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/Endpoints.html ================================================ Uses of Class retrofit.Endpoints (Retrofit 1.9.0 API)

Uses of Class
retrofit.Endpoints

No usage of retrofit.Endpoints

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/ErrorHandler.html ================================================ Uses of Interface retrofit.ErrorHandler (Retrofit 1.9.0 API)

Uses of Interface
retrofit.ErrorHandler

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/Profiler.RequestInformation.html ================================================ Uses of Class retrofit.Profiler.RequestInformation (Retrofit 1.9.0 API)

Uses of Class
retrofit.Profiler.RequestInformation

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/Profiler.html ================================================ Uses of Interface retrofit.Profiler (Retrofit 1.9.0 API)

Uses of Interface
retrofit.Profiler

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/RequestInterceptor.RequestFacade.html ================================================ Uses of Interface retrofit.RequestInterceptor.RequestFacade (Retrofit 1.9.0 API)

Uses of Interface
retrofit.RequestInterceptor.RequestFacade

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/RequestInterceptor.html ================================================ Uses of Interface retrofit.RequestInterceptor (Retrofit 1.9.0 API)

Uses of Interface
retrofit.RequestInterceptor

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/ResponseCallback.html ================================================ Uses of Class retrofit.ResponseCallback (Retrofit 1.9.0 API)

Uses of Class
retrofit.ResponseCallback

No usage of retrofit.ResponseCallback

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/RestAdapter.Builder.html ================================================ Uses of Class retrofit.RestAdapter.Builder (Retrofit 1.9.0 API)

Uses of Class
retrofit.RestAdapter.Builder

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/RestAdapter.Log.html ================================================ Uses of Interface retrofit.RestAdapter.Log (Retrofit 1.9.0 API)

Uses of Interface
retrofit.RestAdapter.Log

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/RestAdapter.LogLevel.html ================================================ Uses of Class retrofit.RestAdapter.LogLevel (Retrofit 1.9.0 API)

Uses of Class
retrofit.RestAdapter.LogLevel

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/RestAdapter.html ================================================ Uses of Class retrofit.RestAdapter (Retrofit 1.9.0 API)

Uses of Class
retrofit.RestAdapter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/RetrofitError.Kind.html ================================================ Uses of Class retrofit.RetrofitError.Kind (Retrofit 1.9.0 API)

Uses of Class
retrofit.RetrofitError.Kind

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/class-use/RetrofitError.html ================================================ Uses of Class retrofit.RetrofitError (Retrofit 1.9.0 API)

Uses of Class
retrofit.RetrofitError

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/ApacheClient.html ================================================ ApacheClient (Retrofit 1.9.0 API)
retrofit.client

Class ApacheClient

    • Constructor Detail

      • ApacheClient

        public ApacheClient()
        Creates an instance backed by DefaultHttpClient.
      • ApacheClient

        public ApacheClient(org.apache.http.client.HttpClient client)
    • Method Detail

      • execute

        public Response execute(Request request)
                         throws IOException
        Description copied from interface: Client
        Synchronously execute an HTTP represented by request and encapsulate all response data into a Response instance.

        Note: If the request has a body, its length and mime type will have already been added to the header list as Content-Length and Content-Type, respectively. Do NOT alter these values as they might have been set as a result of an application-level configuration.

        Specified by:
        execute in interface Client
        Throws:
        IOException
      • execute

        protected org.apache.http.HttpResponse execute(org.apache.http.client.HttpClient client,
                                                       org.apache.http.client.methods.HttpUriRequest request)
                                                throws IOException
        Execute the specified request using the provided client.
        Throws:
        IOException

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/Client.Provider.html ================================================ Client.Provider (Retrofit 1.9.0 API)
retrofit.client

Interface Client.Provider

  • Enclosing interface:
    Client


    public static interface Client.Provider
    Deferred means of obtaining a Client. For asynchronous requests this will always be called on a background thread.
    • Method Detail

      • get

        Client get()
        Obtain an HTTP client. Called once for each request.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/Client.html ================================================ Client (Retrofit 1.9.0 API)
retrofit.client

Interface Client

    • Method Detail

      • execute

        Response execute(Request request)
                  throws IOException
        Synchronously execute an HTTP represented by request and encapsulate all response data into a Response instance.

        Note: If the request has a body, its length and mime type will have already been added to the header list as Content-Length and Content-Type, respectively. Do NOT alter these values as they might have been set as a result of an application-level configuration.

        Throws:
        IOException

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/Header.html ================================================ Header (Retrofit 1.9.0 API)
retrofit.client

Class Header



  • public final class Header
    extends Object
    Represents an HTTP header name/value pair.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/OkClient.html ================================================ OkClient (Retrofit 1.9.0 API)
retrofit.client

Class OkClient

  • All Implemented Interfaces:
    Client


    public class OkClient
    extends Object
    implements Client
    Retrofit client that uses OkHttp for communication.
    • Constructor Detail

      • OkClient

        public OkClient()
      • OkClient

        public OkClient(com.squareup.okhttp.OkHttpClient client)
    • Method Detail

      • execute

        public Response execute(Request request)
                         throws IOException
        Description copied from interface: Client
        Synchronously execute an HTTP represented by request and encapsulate all response data into a Response instance.

        Note: If the request has a body, its length and mime type will have already been added to the header list as Content-Length and Content-Type, respectively. Do NOT alter these values as they might have been set as a result of an application-level configuration.

        Specified by:
        execute in interface Client
        Throws:
        IOException

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/Request.html ================================================ Request (Retrofit 1.9.0 API)
retrofit.client

Class Request



  • public final class Request
    extends Object
    Encapsulates all of the information necessary to make an HTTP request.
    • Method Detail

      • getMethod

        public String getMethod()
        HTTP method verb.
      • getUrl

        public String getUrl()
        Target URL.
      • getHeaders

        public List<Header> getHeaders()
        Returns an unmodifiable list of headers, never null.
      • getBody

        public TypedOutput getBody()
        Returns the request body or null.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/Response.html ================================================ Response (Retrofit 1.9.0 API)
retrofit.client

Class Response



  • public final class Response
    extends Object
    An HTTP response.

    When used directly as a data type for an interface method, the response body is buffered to a byte[]. Annotate the method with @Streaming for an unbuffered stream from the network.

    • Method Detail

      • getUrl

        public String getUrl()
        Request URL.
      • getStatus

        public int getStatus()
        Status line code.
      • getReason

        public String getReason()
        Status line reason phrase.
      • getHeaders

        public List<Header> getHeaders()
        An unmodifiable collection of headers.
      • getBody

        public TypedInput getBody()
        Response body. May be null.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/UrlConnectionClient.html ================================================ UrlConnectionClient (Retrofit 1.9.0 API)
retrofit.client

Class UrlConnectionClient

    • Constructor Detail

      • UrlConnectionClient

        public UrlConnectionClient()
    • Method Detail

      • execute

        public Response execute(Request request)
                         throws IOException
        Description copied from interface: Client
        Synchronously execute an HTTP represented by request and encapsulate all response data into a Response instance.

        Note: If the request has a body, its length and mime type will have already been added to the header list as Content-Length and Content-Type, respectively. Do NOT alter these values as they might have been set as a result of an application-level configuration.

        Specified by:
        execute in interface Client
        Throws:
        IOException

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/class-use/ApacheClient.html ================================================ Uses of Class retrofit.client.ApacheClient (Retrofit 1.9.0 API)

Uses of Class
retrofit.client.ApacheClient

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/class-use/Client.Provider.html ================================================ Uses of Interface retrofit.client.Client.Provider (Retrofit 1.9.0 API)

Uses of Interface
retrofit.client.Client.Provider

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/class-use/Client.html ================================================ Uses of Interface retrofit.client.Client (Retrofit 1.9.0 API)

Uses of Interface
retrofit.client.Client

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/class-use/Header.html ================================================ Uses of Class retrofit.client.Header (Retrofit 1.9.0 API)

Uses of Class
retrofit.client.Header

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/class-use/OkClient.html ================================================ Uses of Class retrofit.client.OkClient (Retrofit 1.9.0 API)

Uses of Class
retrofit.client.OkClient

No usage of retrofit.client.OkClient

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/class-use/Request.html ================================================ Uses of Class retrofit.client.Request (Retrofit 1.9.0 API)

Uses of Class
retrofit.client.Request

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/class-use/Response.html ================================================ Uses of Class retrofit.client.Response (Retrofit 1.9.0 API)

Uses of Class
retrofit.client.Response

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/class-use/UrlConnectionClient.html ================================================ Uses of Class retrofit.client.UrlConnectionClient (Retrofit 1.9.0 API)

Uses of Class
retrofit.client.UrlConnectionClient

No usage of retrofit.client.UrlConnectionClient

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/package-frame.html ================================================ retrofit.client (Retrofit 1.9.0 API)

retrofit.client

================================================ FILE: website/public/1.x/retrofit/retrofit/client/package-summary.html ================================================ retrofit.client (Retrofit 1.9.0 API)

Package retrofit.client

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/package-tree.html ================================================ retrofit.client Class Hierarchy (Retrofit 1.9.0 API)

Hierarchy For Package retrofit.client

Package Hierarchies:

Class Hierarchy

Interface Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/client/package-use.html ================================================ Uses of Package retrofit.client (Retrofit 1.9.0 API)

Uses of Package
retrofit.client

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/ConversionException.html ================================================ ConversionException (Retrofit 1.9.0 API)
retrofit.converter

Class ConversionException

  • All Implemented Interfaces:
    Serializable


    public class ConversionException
    extends Exception
    Indicate that conversion was unable to complete successfully.
    See Also:
    Serialized Form
    • Constructor Detail

      • ConversionException

        public ConversionException(String message)
      • ConversionException

        public ConversionException(String message,
                                   Throwable throwable)
      • ConversionException

        public ConversionException(Throwable throwable)

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/Converter.html ================================================ Converter (Retrofit 1.9.0 API)
retrofit.converter

Interface Converter

  • All Known Implementing Classes:
    GsonConverter


    public interface Converter
    Arbiter for converting objects to and from their representation in HTTP.
    Author:
    Jake Wharton (jw@squareup.com)
    • Method Detail

      • fromBody

        Object fromBody(TypedInput body,
                        Type type)
                 throws ConversionException
        Convert an HTTP response body to a concrete object of the specified type.
        Parameters:
        body - HTTP response body.
        type - Target object type.
        Returns:
        Instance of type which will be cast by the caller.
        Throws:
        ConversionException - if conversion was unable to complete. This will trigger a call to Callback.failure(retrofit.RetrofitError) or throw a RetrofitError. The exception message should report all necessary information about its cause as the response body will be set to null.
      • toBody

        TypedOutput toBody(Object object)
        Convert an object to an appropriate representation for HTTP transport.
        Parameters:
        object - Object instance to convert.
        Returns:
        Representation of the specified object as bytes.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/GsonConverter.html ================================================ GsonConverter (Retrofit 1.9.0 API)
retrofit.converter

Class GsonConverter

  • All Implemented Interfaces:
    Converter


    public class GsonConverter
    extends Object
    implements Converter
    A Converter which uses GSON for serialization and deserialization of entities.
    Author:
    Jake Wharton (jw@squareup.com)
    • Constructor Detail

      • GsonConverter

        public GsonConverter(com.google.gson.Gson gson)
        Create an instance using the supplied Gson object for conversion. Encoding to JSON and decoding from JSON (when no charset is specified by a header) will use UTF-8.
      • GsonConverter

        public GsonConverter(com.google.gson.Gson gson,
                             String charset)
        Create an instance using the supplied Gson object for conversion. Encoding to JSON and decoding from JSON (when no charset is specified by a header) will use the specified charset.
    • Method Detail

      • toBody

        public TypedOutput toBody(Object object)
        Description copied from interface: Converter
        Convert an object to an appropriate representation for HTTP transport.
        Specified by:
        toBody in interface Converter
        Parameters:
        object - Object instance to convert.
        Returns:
        Representation of the specified object as bytes.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/class-use/ConversionException.html ================================================ Uses of Class retrofit.converter.ConversionException (Retrofit 1.9.0 API)

Uses of Class
retrofit.converter.ConversionException

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/class-use/Converter.html ================================================ Uses of Interface retrofit.converter.Converter (Retrofit 1.9.0 API)

Uses of Interface
retrofit.converter.Converter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/class-use/GsonConverter.html ================================================ Uses of Class retrofit.converter.GsonConverter (Retrofit 1.9.0 API)

Uses of Class
retrofit.converter.GsonConverter

No usage of retrofit.converter.GsonConverter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/package-frame.html ================================================ retrofit.converter (Retrofit 1.9.0 API)

retrofit.converter

Interfaces

Classes

Exceptions

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/package-summary.html ================================================ retrofit.converter (Retrofit 1.9.0 API)

Package retrofit.converter

  • Interface Summary 
    Interface Description
    Converter
    Arbiter for converting objects to and from their representation in HTTP.
  • Class Summary 
    Class Description
    GsonConverter
    A Converter which uses GSON for serialization and deserialization of entities.
  • Exception Summary 
    Exception Description
    ConversionException
    Indicate that conversion was unable to complete successfully.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/package-tree.html ================================================ retrofit.converter Class Hierarchy (Retrofit 1.9.0 API)

Hierarchy For Package retrofit.converter

Package Hierarchies:

Class Hierarchy

Interface Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/converter/package-use.html ================================================ Uses of Package retrofit.converter (Retrofit 1.9.0 API)

Uses of Package
retrofit.converter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/Body.html ================================================ Body (Retrofit 1.9.0 API)
retrofit.http

Annotation Type Body



  • @Documented
     @Target(value=PARAMETER)
     @Retention(value=RUNTIME)
    public @interface Body
    Use this annotation on a service method param when you want to directly control the request body of a POST/PUT request (instead of sending in as request parameters or form-style request body). If the value of the parameter implements TypedOutput, the request body will be written exactly as specified by TypedOutput.writeTo(java.io.OutputStream). If the value does not implement TypedOutput, the object will be serialized using the RestAdapter's Converter and the result will be set directly as the request body.

    Body parameters may not be null.

    Author:
    Eric Denman (edenman@squareup.com)

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/DELETE.html ================================================ DELETE (Retrofit 1.9.0 API)
retrofit.http

Annotation Type DELETE

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Element Detail

      • value

        public abstract String value

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/EncodedPath.html ================================================ EncodedPath (Retrofit 1.9.0 API)
retrofit.http

Annotation Type EncodedPath

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value
      Deprecated. 
       
    • Element Detail

      • value

        public abstract String value
        Deprecated. 

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/EncodedQuery.html ================================================ EncodedQuery (Retrofit 1.9.0 API)
retrofit.http

Annotation Type EncodedQuery

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value
      Deprecated. 
       
    • Element Detail

      • value

        public abstract String value
        Deprecated. 

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/EncodedQueryMap.html ================================================ EncodedQueryMap (Retrofit 1.9.0 API)
retrofit.http

Annotation Type EncodedQueryMap

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/Field.html ================================================ Field (Retrofit 1.9.0 API)
retrofit.http

Annotation Type Field



  • @Documented
     @Target(value=PARAMETER)
     @Retention(value=RUNTIME)
    public @interface Field
    Named pair for a form-encoded request.

    Values are converted to strings using String.valueOf(Object) and then form URL encoded. null values are ignored. Passing a List or array will result in a field pair for each non-null item.

    Simple Example:

     @FormUrlEncoded
     @POST("/")
     void example(@Field("name") String name, @Field("occupation") String occupation);
     }
     
    Calling with foo.example("Bob Smith", "President") yields a request body of name=Bob+Smith&occupation=President.

    Array Example:

     @FormUrlEncoded
     @POST("/list")
     void example(@Field("name") String... names);
     
    Calling with foo.example("Bob Smith", "Jane Doe") yields a request body of name=Bob+Smith&name=Jane+Doe.
    See Also:
    FormUrlEncoded, FieldMap
    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element and Description
      boolean encodeName
      Specifies whether value() is URL encoded.
      boolean encodeValue
      Specifies whether the argument value to the annotated method parameter is URL encoded.
    • Element Detail

      • value

        public abstract String value
      • encodeName

        public abstract boolean encodeName
        Specifies whether value() is URL encoded.
        Default:
        true
      • encodeValue

        public abstract boolean encodeValue
        Specifies whether the argument value to the annotated method parameter is URL encoded.
        Default:
        true

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/FieldMap.html ================================================ FieldMap (Retrofit 1.9.0 API)
retrofit.http

Annotation Type FieldMap



  • @Documented
     @Target(value=PARAMETER)
     @Retention(value=RUNTIME)
    public @interface FieldMap
    Named key/value pairs for a form-encoded request.

    Field values may be null which will omit them from the request body.

    Simple Example:

     @FormUrlEncoded
     @POST("/things")
     void things(@FieldMap Map<String, String> fields);
     }
     
    Calling with foo.things(ImmutableMap.of("foo", "bar", "kit", "kat") yields a request body of foo=bar&kit=kat.
    See Also:
    FormUrlEncoded, Field
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element and Description
      boolean encodeNames
      Specifies whether parameter names (keys in the map) are URL encoded.
      boolean encodeValues
      Specifies whether parameter values (values in the map) are URL encoded.
    • Element Detail

      • encodeNames

        public abstract boolean encodeNames
        Specifies whether parameter names (keys in the map) are URL encoded.
        Default:
        true
      • encodeValues

        public abstract boolean encodeValues
        Specifies whether parameter values (values in the map) are URL encoded.
        Default:
        true

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/FormUrlEncoded.html ================================================ FormUrlEncoded (Retrofit 1.9.0 API)
retrofit.http

Annotation Type FormUrlEncoded



  • @Documented
     @Target(value=METHOD)
     @Retention(value=RUNTIME)
    public @interface FormUrlEncoded
    Denotes that the request body will use form URL encoding. Fields should be declared as parameters and annotated with @Field.

    Requests made with this annotation will have application/x-www-form-urlencoded MIME type. Field names and values will be UTF-8 encoded before being URI-encoded in accordance to RFC-3986.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/GET.html ================================================ GET (Retrofit 1.9.0 API)
retrofit.http

Annotation Type GET

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Element Detail

      • value

        public abstract String value

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/HEAD.html ================================================ HEAD (Retrofit 1.9.0 API)
retrofit.http

Annotation Type HEAD

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Element Detail

      • value

        public abstract String value

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/Header.html ================================================ Header (Retrofit 1.9.0 API)
retrofit.http

Annotation Type Header



  • @Documented
     @Retention(value=RUNTIME)
     @Target(value=PARAMETER)
    public @interface Header
    Replaces the header with the value of its target.

     @GET("/")
     void foo(@Header("Accept-Language") String lang, Callback<Response> cb);
     

    Header parameters may be null which will omit them from the request. Passing a List or array will result in a header for each non-null item.

    Note: Headers do not overwrite each other. All headers with the same name will be included in the request.

    Author:
    Adrian Cole (adrianc@netflix.com)
    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Element Detail

      • value

        public abstract String value

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/Headers.html ================================================ Headers (Retrofit 1.9.0 API)
retrofit.http

Annotation Type Headers



  • @Documented
     @Target(value=METHOD)
     @Retention(value=RUNTIME)
    public @interface Headers
    Adds headers literally supplied in the value.

     @Headers("Cache-Control: max-age=640000")
     @GET("/")
     ...
    
     @Headers({
       "X-Foo: Bar",
       "X-Ping: Pong"
     })
     @GET("/")
     ...
     

    Note: Headers do not overwrite each other. All headers with the same name will be included in the request.

    Author:
    Adrian Cole (adrianc@netflix.com)
    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String[] value 
    • Element Detail

      • value

        public abstract String[] value

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/Multipart.html ================================================ Multipart (Retrofit 1.9.0 API)
retrofit.http

Annotation Type Multipart

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/PATCH.html ================================================ PATCH (Retrofit 1.9.0 API)
retrofit.http

Annotation Type PATCH

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Element Detail

      • value

        public abstract String value

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/POST.html ================================================ POST (Retrofit 1.9.0 API)
retrofit.http

Annotation Type POST

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Element Detail

      • value

        public abstract String value

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/PUT.html ================================================ PUT (Retrofit 1.9.0 API)
retrofit.http

Annotation Type PUT

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Element Detail

      • value

        public abstract String value

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/Part.html ================================================ Part (Retrofit 1.9.0 API)
retrofit.http

Annotation Type Part



  • @Documented
     @Target(value=PARAMETER)
     @Retention(value=RUNTIME)
    public @interface Part
    Denotes a single part of a multi-part request.

    The parameter type on which this annotation exists will be processed in one of three ways:

    • If the type implements TypedOutput the headers and body will be used directly.
    • If the type is String the value will also be used directly with a text/plain content type.
    • Other object types will be converted to an appropriate representation by calling Converter.toBody(Object).

    Values may be null which will omit them from the request body.

     @Multipart
     @POST("/")
     void example(@Part("description") String description,
                  @Part("image") TypedFile image,
                  ...
     );
     

    Part parameters may not be null.

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element and Description
      String encoding
      The Content-Transfer-Encoding of this part.
    • Element Detail

      • value

        public abstract String value
      • encoding

        public abstract String encoding
        The Content-Transfer-Encoding of this part.
        Default:
        "binary"

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/PartMap.html ================================================ PartMap (Retrofit 1.9.0 API)
retrofit.http

Annotation Type PartMap



  • @Documented
     @Target(value=PARAMETER)
     @Retention(value=RUNTIME)
    public @interface PartMap
    Denotes name and value parts of a multi-part request

    Values of the map on which this annotation exists will be processed in one of three ways:

    • If the type implements TypedOutput the headers and body will be used directly.
    • If the type is String the value will also be used directly with a text/plain content type.
    • Other object types will be converted to an appropriate representation by calling Converter.toBody(Object).

     @Multipart
     @POST("/upload")
     void upload(@Part("file") TypedFile file, @PartMap Map<String, String> params);
     

    See Also:
    Multipart, Part
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element and Description
      String encoding
      The Content-Transfer-Encoding of this part.
    • Element Detail

      • encoding

        public abstract String encoding
        The Content-Transfer-Encoding of this part.
        Default:
        "binary"

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/Path.html ================================================ Path (Retrofit 1.9.0 API)
retrofit.http

Annotation Type Path



  • @Documented
     @Retention(value=RUNTIME)
     @Target(value=PARAMETER)
    public @interface Path
    Named replacement in the URL path. Values are converted to string using String.valueOf(Object) and URL encoded.

    Simple example:

     @GET("/image/{id}")
     void example(@Path("id") int id);
     
    Calling with foo.example(1) yields /image/1.

    Values are URL encoded by default. Disable with encode=false.

     @GET("/user/{name}")
     void encoded(@Path("name") String name);
    
     @GET("/user/{name}")
     void notEncoded(@Path(value="name", encode=false) String name);
     
    Calling foo.encoded("John+Doe") yields /user/John%2BDoe whereas foo.notEncoded("John+Doe") yields /user/John+Doe.

    Path parameters may not be null.

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element and Description
      boolean encode
      Specifies whether the argument value to the annotated method parameter is URL encoded.
    • Element Detail

      • value

        public abstract String value
      • encode

        public abstract boolean encode
        Specifies whether the argument value to the annotated method parameter is URL encoded.
        Default:
        true

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/Query.html ================================================ Query (Retrofit 1.9.0 API)
retrofit.http

Annotation Type Query



  • @Documented
     @Target(value=PARAMETER)
     @Retention(value=RUNTIME)
    public @interface Query
    Query parameter appended to the URL.

    Values are converted to strings using String.valueOf(Object) and then URL encoded. null values are ignored. Passing a List or array will result in a query parameter for each non-null item.

    Simple Example:

     @GET("/list")
     void list(@Query("page") int page);
     
    Calling with foo.list(1) yields /list?page=1.

    Example with null:

     @GET("/list")
     void list(@Query("category") String category);
     
    Calling with foo.list(null) yields /list.

    Array Example:

     @GET("/list")
     void list(@Query("category") String... categories);
     
    Calling with foo.list("bar", "baz") yields /list?category=foo&category=bar.

    Parameter names are not URL encoded. Specify encodeName=true to change this behavior.

     @GET("/search")
     void list(@Query(value="foo+bar", encodeName=true) String foobar);
     
    Calling with foo.list("baz") yields /search?foo%2Bbar=foo.

    Parameter values are URL encoded by default. Specify encodeValue=false to change this behavior.

     @GET("/search")
     void list(@Query(value="foo", encodeValue=false) String foo);
     
    Calling with foo.list("foo+foo")) yields /search?foo=foo+bar.
    See Also:
    QueryMap
    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value
      The query parameter name.
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element and Description
      boolean encodeName
      Specifies whether value() is URL encoded.
      boolean encodeValue
      Specifies whether the argument value to the annotated method parameter is URL encoded.
    • Element Detail

      • value

        public abstract String value
        The query parameter name.
      • encodeName

        public abstract boolean encodeName
        Specifies whether value() is URL encoded.
        Default:
        false
      • encodeValue

        public abstract boolean encodeValue
        Specifies whether the argument value to the annotated method parameter is URL encoded.
        Default:
        true

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/QueryMap.html ================================================ QueryMap (Retrofit 1.9.0 API)
retrofit.http

Annotation Type QueryMap



  • @Documented
     @Target(value=PARAMETER)
     @Retention(value=RUNTIME)
    public @interface QueryMap
    Query parameter keys and values appended to the URL.

    Both keys and values are converted to strings using String.valueOf(Object). Values are URL encoded and null will not include the query parameter in the URL. null keys are not allowed.

    Simple Example:

     @GET("/search")
     void list(@QueryMap Map<String, String> filters);
     
    Calling with foo.list(ImmutableMap.of("foo", "bar", "kit", "kat")) yields /search?foo=bar&kit=kat.

    Map keys representing the parameter names are not URL encoded. Specify encodeNames=true to change this behavior.

     @GET("/search")
     void list(@QueryMap(encodeNames=true) Map<String, String> filters);
     
    Calling with foo.list(ImmutableMap.of("foo+bar", "foo+bar")) yields /search?foo%2Bbar=foo.

    Map values representing parameter values are URL encoded by default. Specify encodeValues=false to change this behavior.

     @GET("/search")
     void list(@QueryMap(encodeValues=false) Map<String, String> filters);
     
    Calling with foo.list(ImmutableMap.of("foo", "foo+foo")) yields /search?foo=foo%2Bbar.
    See Also:
    Query
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element and Description
      boolean encodeNames
      Specifies whether parameter names (keys in the map) are URL encoded.
      boolean encodeValues
      Specifies whether parameter values (values in the map) are URL encoded.
    • Element Detail

      • encodeNames

        public abstract boolean encodeNames
        Specifies whether parameter names (keys in the map) are URL encoded.
        Default:
        false
      • encodeValues

        public abstract boolean encodeValues
        Specifies whether parameter values (values in the map) are URL encoded.
        Default:
        true

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/RestMethod.html ================================================ RestMethod (Retrofit 1.9.0 API)
retrofit.http

Annotation Type RestMethod

    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element and Description
      String value 
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element and Description
      boolean hasBody 
    • Element Detail

      • value

        public abstract String value
      • hasBody

        public abstract boolean hasBody
        Default:
        false

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/Streaming.html ================================================ Streaming (Retrofit 1.9.0 API)
retrofit.http

Annotation Type Streaming

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/Body.html ================================================ Uses of Class retrofit.http.Body (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.Body

No usage of retrofit.http.Body

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/DELETE.html ================================================ Uses of Class retrofit.http.DELETE (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.DELETE

No usage of retrofit.http.DELETE

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/EncodedPath.html ================================================ Uses of Class retrofit.http.EncodedPath (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.EncodedPath

No usage of retrofit.http.EncodedPath

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/EncodedQuery.html ================================================ Uses of Class retrofit.http.EncodedQuery (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.EncodedQuery

No usage of retrofit.http.EncodedQuery

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/EncodedQueryMap.html ================================================ Uses of Class retrofit.http.EncodedQueryMap (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.EncodedQueryMap

No usage of retrofit.http.EncodedQueryMap

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/Field.html ================================================ Uses of Class retrofit.http.Field (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.Field

No usage of retrofit.http.Field

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/FieldMap.html ================================================ Uses of Class retrofit.http.FieldMap (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.FieldMap

No usage of retrofit.http.FieldMap

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/FormUrlEncoded.html ================================================ Uses of Class retrofit.http.FormUrlEncoded (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.FormUrlEncoded

No usage of retrofit.http.FormUrlEncoded

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/GET.html ================================================ Uses of Class retrofit.http.GET (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.GET

No usage of retrofit.http.GET

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/HEAD.html ================================================ Uses of Class retrofit.http.HEAD (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.HEAD

No usage of retrofit.http.HEAD

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/Header.html ================================================ Uses of Class retrofit.http.Header (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.Header

No usage of retrofit.http.Header

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/Headers.html ================================================ Uses of Class retrofit.http.Headers (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.Headers

No usage of retrofit.http.Headers

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/Multipart.html ================================================ Uses of Class retrofit.http.Multipart (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.Multipart

No usage of retrofit.http.Multipart

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/PATCH.html ================================================ Uses of Class retrofit.http.PATCH (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.PATCH

No usage of retrofit.http.PATCH

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/POST.html ================================================ Uses of Class retrofit.http.POST (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.POST

No usage of retrofit.http.POST

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/PUT.html ================================================ Uses of Class retrofit.http.PUT (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.PUT

No usage of retrofit.http.PUT

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/Part.html ================================================ Uses of Class retrofit.http.Part (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.Part

No usage of retrofit.http.Part

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/PartMap.html ================================================ Uses of Class retrofit.http.PartMap (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.PartMap

No usage of retrofit.http.PartMap

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/Path.html ================================================ Uses of Class retrofit.http.Path (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.Path

No usage of retrofit.http.Path

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/Query.html ================================================ Uses of Class retrofit.http.Query (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.Query

No usage of retrofit.http.Query

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/QueryMap.html ================================================ Uses of Class retrofit.http.QueryMap (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.QueryMap

No usage of retrofit.http.QueryMap

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/RestMethod.html ================================================ Uses of Class retrofit.http.RestMethod (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.RestMethod

  • Packages that use RestMethod 
    Package Description
    retrofit.http
    Annotations for interface methods to control the HTTP request behavior.
    • Uses of RestMethod in retrofit.http

      Classes in retrofit.http with annotations of type RestMethod 
      Modifier and Type Class and Description
      interface  DELETE
      Make a DELETE request to a REST path relative to base URL.
      interface  GET
      Make a GET request to a REST path relative to base URL.
      interface  HEAD
      Make a HEAD request to a REST path relative to base URL.
      interface  PATCH
      Make a PATCH request to a REST path relative to base URL.
      interface  POST
      Make a POST request to a REST path relative to base URL.
      interface  PUT
      Make a PUT request to a REST path relative to base URL.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/class-use/Streaming.html ================================================ Uses of Class retrofit.http.Streaming (Retrofit 1.9.0 API)

Uses of Class
retrofit.http.Streaming

No usage of retrofit.http.Streaming

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/package-frame.html ================================================ retrofit.http (Retrofit 1.9.0 API)

retrofit.http

================================================ FILE: website/public/1.x/retrofit/retrofit/http/package-summary.html ================================================ retrofit.http (Retrofit 1.9.0 API)

Package retrofit.http

Annotations for interface methods to control the HTTP request behavior.

See: Description

  • Annotation Types Summary 
    Annotation Type Description
    Body
    Use this annotation on a service method param when you want to directly control the request body of a POST/PUT request (instead of sending in as request parameters or form-style request body).
    DELETE
    Make a DELETE request to a REST path relative to base URL.
    EncodedPath Deprecated
    EncodedQuery Deprecated
    EncodedQueryMap Deprecated
    Field
    Named pair for a form-encoded request.
    FieldMap
    Named key/value pairs for a form-encoded request.
    FormUrlEncoded
    Denotes that the request body will use form URL encoding.
    GET
    Make a GET request to a REST path relative to base URL.
    HEAD
    Make a HEAD request to a REST path relative to base URL.
    Header
    Replaces the header with the value of its target.
    Headers
    Adds headers literally supplied in the value.
    Multipart
    Denotes that the request body is multi-part.
    Part
    Denotes a single part of a multi-part request.
    PartMap
    Denotes name and value parts of a multi-part request
    PATCH
    Make a PATCH request to a REST path relative to base URL.
    Path
    Named replacement in the URL path.
    POST
    Make a POST request to a REST path relative to base URL.
    PUT
    Make a PUT request to a REST path relative to base URL.
    Query
    Query parameter appended to the URL.
    QueryMap
    Query parameter keys and values appended to the URL.
    RestMethod  
    Streaming
    Treat the response body on methods returning Response as is, i.e.

Package retrofit.http Description

Annotations for interface methods to control the HTTP request behavior.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/package-tree.html ================================================ retrofit.http Class Hierarchy (Retrofit 1.9.0 API)

Hierarchy For Package retrofit.http

Package Hierarchies:

Annotation Type Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/http/package-use.html ================================================ Uses of Package retrofit.http (Retrofit 1.9.0 API)

Uses of Package
retrofit.http

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/FormUrlEncodedTypedOutput.html ================================================ FormUrlEncodedTypedOutput (Retrofit 1.9.0 API)
retrofit.mime

Class FormUrlEncodedTypedOutput

    • Constructor Detail

      • FormUrlEncodedTypedOutput

        public FormUrlEncodedTypedOutput()

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/MimeUtil.html ================================================ MimeUtil (Retrofit 1.9.0 API)
retrofit.mime

Class MimeUtil



  • public final class MimeUtil
    extends Object
    • Method Detail

      • parseCharset

        public static String parseCharset(String mimeType,
                                          String defaultCharset)
        Parse the MIME type from a Content-Type header value.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/MultipartTypedOutput.html ================================================ MultipartTypedOutput (Retrofit 1.9.0 API)
retrofit.mime

Class MultipartTypedOutput

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/TypedByteArray.html ================================================ TypedByteArray (Retrofit 1.9.0 API)
retrofit.mime

Class TypedByteArray

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/TypedFile.html ================================================ TypedFile (Retrofit 1.9.0 API)
retrofit.mime

Class TypedFile

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/TypedInput.html ================================================ TypedInput (Retrofit 1.9.0 API)
retrofit.mime

Interface TypedInput

  • All Known Implementing Classes:
    TypedByteArray, TypedFile, TypedString


    public interface TypedInput
    Binary data with an associated mime type.
    Author:
    Jake Wharton (jw@squareup.com)
    • Method Detail

      • mimeType

        String mimeType()
        Returns the mime type.
      • length

        long length()
        Length in bytes. Returns -1 if length is unknown.
      • in

        InputStream in()
                throws IOException
        Read bytes as stream. Unless otherwise specified, this method may only be called once. It is the responsibility of the caller to close the stream.
        Throws:
        IOException

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/TypedOutput.html ================================================ TypedOutput (Retrofit 1.9.0 API)
retrofit.mime

Interface TypedOutput

    • Method Detail

      • fileName

        String fileName()
        Original filename. Used only for multipart requests, may be null.
      • mimeType

        String mimeType()
        Returns the mime type.
      • length

        long length()
        Length in bytes or -1 if unknown.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/TypedString.html ================================================ TypedString (Retrofit 1.9.0 API)
retrofit.mime

Class TypedString

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/class-use/FormUrlEncodedTypedOutput.html ================================================ Uses of Class retrofit.mime.FormUrlEncodedTypedOutput (Retrofit 1.9.0 API)

Uses of Class
retrofit.mime.FormUrlEncodedTypedOutput

No usage of retrofit.mime.FormUrlEncodedTypedOutput

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/class-use/MimeUtil.html ================================================ Uses of Class retrofit.mime.MimeUtil (Retrofit 1.9.0 API)

Uses of Class
retrofit.mime.MimeUtil

No usage of retrofit.mime.MimeUtil

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/class-use/MultipartTypedOutput.html ================================================ Uses of Class retrofit.mime.MultipartTypedOutput (Retrofit 1.9.0 API)

Uses of Class
retrofit.mime.MultipartTypedOutput

No usage of retrofit.mime.MultipartTypedOutput

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/class-use/TypedByteArray.html ================================================ Uses of Class retrofit.mime.TypedByteArray (Retrofit 1.9.0 API)

Uses of Class
retrofit.mime.TypedByteArray

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/class-use/TypedFile.html ================================================ Uses of Class retrofit.mime.TypedFile (Retrofit 1.9.0 API)

Uses of Class
retrofit.mime.TypedFile

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/class-use/TypedInput.html ================================================ Uses of Interface retrofit.mime.TypedInput (Retrofit 1.9.0 API)

Uses of Interface
retrofit.mime.TypedInput

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/class-use/TypedOutput.html ================================================ Uses of Interface retrofit.mime.TypedOutput (Retrofit 1.9.0 API)

Uses of Interface
retrofit.mime.TypedOutput

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/class-use/TypedString.html ================================================ Uses of Class retrofit.mime.TypedString (Retrofit 1.9.0 API)

Uses of Class
retrofit.mime.TypedString

No usage of retrofit.mime.TypedString

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/package-frame.html ================================================ retrofit.mime (Retrofit 1.9.0 API)

retrofit.mime

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/package-summary.html ================================================ retrofit.mime (Retrofit 1.9.0 API)

Package retrofit.mime

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/package-tree.html ================================================ retrofit.mime Class Hierarchy (Retrofit 1.9.0 API)

Hierarchy For Package retrofit.mime

Package Hierarchies:

Class Hierarchy

Interface Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/mime/package-use.html ================================================ Uses of Package retrofit.mime (Retrofit 1.9.0 API)

Uses of Package
retrofit.mime

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/package-frame.html ================================================ retrofit (Retrofit 1.9.0 API)

retrofit

================================================ FILE: website/public/1.x/retrofit/retrofit/package-summary.html ================================================ retrofit (Retrofit 1.9.0 API)

Package retrofit

Retrofit turns your REST API into a Java interface.

See: Description

Package retrofit Description

Retrofit turns your REST API into a Java interface.
 public interface GitHubService {
   @GET("/users/{user}/repos")
   List<Repo> listRepos(@Path("user") String user);
 }
 

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/package-tree.html ================================================ retrofit Class Hierarchy (Retrofit 1.9.0 API)

Hierarchy For Package retrofit

Package Hierarchies:

Class Hierarchy

Interface Hierarchy

Enum Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/retrofit/package-use.html ================================================ Uses of Package retrofit (Retrofit 1.9.0 API)

Uses of Package
retrofit

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/1.x/retrofit/serialized-form.html ================================================ Serialized Form (Retrofit 1.9.0 API)

Serialized Form

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; width:100%; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/1.x/retrofit/version.txt ================================================ 1.9.0 ================================================ FILE: website/public/1.x/retrofit-mock/allclasses-frame.html ================================================ All Classes (Retrofit Mock Adapter 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/retrofit-mock/allclasses-noframe.html ================================================ All Classes (Retrofit Mock Adapter 1.9.0 API)

All Classes

================================================ FILE: website/public/1.x/retrofit-mock/constant-values.html ================================================ Constant Field Values (Retrofit Mock Adapter 1.9.0 API)

Constant Field Values

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/deprecated-list.html ================================================ Deprecated List (Retrofit Mock Adapter 1.9.0 API)

Deprecated API

Contents

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/help-doc.html ================================================ API Help (Retrofit Mock Adapter 1.9.0 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Overview

    The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.

  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Use

    Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/index-all.html ================================================ Index (Retrofit Mock Adapter 1.9.0 API)
A C E F G I M N O R S W 

A

AndroidMockValuePersistence - Class in retrofit.android
A value change listener for MockRestAdapter which stores any customized behavior values into shared preferences.

C

calculateDelayForCall() - Method in class retrofit.MockRestAdapter
Get the delay (in milliseconds) that should be used for delaying a network call response.
calculateDelayForError() - Method in class retrofit.MockRestAdapter
Get the delay (in milliseconds) that should be used for triggering a network error.
calculateIsFailure() - Method in class retrofit.MockRestAdapter
Randomly determine whether this call should result in a network failure.
create(Class<T>, T) - Method in class retrofit.MockRestAdapter
Wrap the supplied mock implementation of a service so that it exhibits the delay and error characteristics of a real network.

E

EMPTY - Static variable in interface retrofit.MockRestAdapter.ValueChangeListener
 

F

from(RestAdapter) - Static method in class retrofit.MockRestAdapter
Create a new MockRestAdapter which will act as a factory for mock services.

G

getDelay() - Method in class retrofit.MockRestAdapter
The network round trip delay, in milliseconds
getErrorPercentage() - Method in class retrofit.MockRestAdapter
The percentage of calls to MockRestAdapter.calculateIsFailure() that return true.
getVariancePercentage() - Method in class retrofit.MockRestAdapter
The plus-or-minus variance percentage of the network round trip delay.

I

install(MockRestAdapter, SharedPreferences) - Static method in class retrofit.android.AndroidMockValuePersistence
Install a value change listener on the supplied MockRestAdapter using the SharedPreferences for storing customized behavior values.

M

MockHttpException - Exception in retrofit
An exception used to trigger the simulation of an HTTP error for mock services.
MockHttpException(int, String, Object) - Constructor for exception retrofit.MockHttpException
Create a new HTTP exception.
MockRestAdapter - Class in retrofit
Wraps mock implementations of API interfaces so that they exhibit the delay and error characteristics of a real network.
MockRestAdapter.ValueChangeListener - Interface in retrofit
A listener invoked when the network behavior values for a MockRestAdapter change.

N

newBadRequest(Object) - Static method in exception retrofit.MockHttpException
Create a new MockHttpException for HTTP 400 Bad Request.
newForbidden(Object) - Static method in exception retrofit.MockHttpException
Create a new MockHttpException for HTTP 403 Forbidden.
newInternalError(Object) - Static method in exception retrofit.MockHttpException
Create a new MockHttpException for HTTP 500 Internal Server Error.
newMovedPermanentely(String, Object) - Static method in exception retrofit.MockHttpException
Create a new MockHttpException for HTTP 301 Moved Permanently.
newMovedTemporarily(String, Object) - Static method in exception retrofit.MockHttpException
Create a new MockHttpException for HTTP 302 Moved Temporarily.
newNotFound(Object) - Static method in exception retrofit.MockHttpException
Create a new MockHttpException for HTTP 404 Not Found.
newUnauthorized(Object) - Static method in exception retrofit.MockHttpException
Create a new MockHttpException for HTTP 401 Unauthorized.

O

onMockValuesChanged(long, int, int) - Method in class retrofit.android.AndroidMockValuePersistence
 
onMockValuesChanged(long, int, int) - Method in interface retrofit.MockRestAdapter.ValueChangeListener
 

R

retrofit - package retrofit
 
retrofit.android - package retrofit.android
 

S

setDelay(long) - Method in class retrofit.MockRestAdapter
Set the network round trip delay, in milliseconds.
setErrorPercentage(int) - Method in class retrofit.MockRestAdapter
Set the percentage of calls to MockRestAdapter.calculateIsFailure() that return true.
setValueChangeListener(MockRestAdapter.ValueChangeListener) - Method in class retrofit.MockRestAdapter
Set a listener to be notified when any mock value changes.
setVariancePercentage(int) - Method in class retrofit.MockRestAdapter
Set the plus-or-minus variance percentage of the network round trip delay.

W

withHeader(String, String) - Method in exception retrofit.MockHttpException
Add a header to the response.
A C E F G I M N O R S W 

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/index.html ================================================ Retrofit Mock Adapter 1.9.0 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="overview-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/1.x/retrofit-mock/overview-frame.html ================================================ Overview List (Retrofit Mock Adapter 1.9.0 API)

 

================================================ FILE: website/public/1.x/retrofit-mock/overview-summary.html ================================================ Overview (Retrofit Mock Adapter 1.9.0 API)

Retrofit Mock Adapter 1.9.0 API

Packages 
Package Description
retrofit  
retrofit.android  

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/overview-tree.html ================================================ Class Hierarchy (Retrofit Mock Adapter 1.9.0 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

Interface Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/package-list ================================================ retrofit retrofit.android ================================================ FILE: website/public/1.x/retrofit-mock/retrofit/MockHttpException.html ================================================ MockHttpException (Retrofit Mock Adapter 1.9.0 API)
retrofit

Class MockHttpException

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/MockRestAdapter.ValueChangeListener.html ================================================ MockRestAdapter.ValueChangeListener (Retrofit Mock Adapter 1.9.0 API)
retrofit

Interface MockRestAdapter.ValueChangeListener

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/MockRestAdapter.html ================================================ MockRestAdapter (Retrofit Mock Adapter 1.9.0 API)
retrofit

Class MockRestAdapter



  • public final class MockRestAdapter
    extends Object
    Wraps mock implementations of API interfaces so that they exhibit the delay and error characteristics of a real network.

    Because APIs are defined as interfaces, versions of the API that use mock data can be created by simply implementing the API interface on a class. These mock implementations execute synchronously which is a large deviation from the behavior of those backed by an API call over the network. By wrapping the mock instances using this class, the interface will still use mock data but exhibit the delays and errors that a real network would face.

    Create an API interface and a mock implementation of it.

       public interface UserService {
         @GET("/user/{id}")
         User getUser(@Path("id") String userId);
       }
       public class MockUserService implements UserService {
         @Override public User getUser(String userId) {
           return new User("Jake");
         }
       }
     
    Given a RestAdapter an instance of this class can be created by calling from(retrofit.RestAdapter).
       MockRestAdapter mockRestAdapter = MockRestAdapter.from(restAdapter);
     
    Instances of this class should be used as a singleton so that the behavior of every mock service is consistent.

    Rather than using the MockUserService directly, pass it through the create method.

       UserService service = mockRestAdapter.create(UserService.class, new MockUserService());
     
    The returned UserService instance will now behave like it is happening over the network while allowing the mock implementation to be written synchronously.

    HTTP errors can be simulated in your mock services by throwing an instance of MockHttpException. This should be done for both synchronous and asynchronous methods. Do not call the failure() method of a callback.

    • Method Detail

      • setDelay

        public void setDelay(long delayMs)
        Set the network round trip delay, in milliseconds.
      • getDelay

        public long getDelay()
        The network round trip delay, in milliseconds
      • setVariancePercentage

        public void setVariancePercentage(int variancePct)
        Set the plus-or-minus variance percentage of the network round trip delay.
      • getVariancePercentage

        public int getVariancePercentage()
        The plus-or-minus variance percentage of the network round trip delay.
      • setErrorPercentage

        public void setErrorPercentage(int errorPct)
        Set the percentage of calls to calculateIsFailure() that return true.
      • getErrorPercentage

        public int getErrorPercentage()
        The percentage of calls to calculateIsFailure() that return true.
      • calculateIsFailure

        public boolean calculateIsFailure()
        Randomly determine whether this call should result in a network failure.

        This method is exposed for implementing other, non-Retrofit services which exhibit similar network behavior. Retrofit services automatically will exhibit network behavior when wrapped using create(Class, Object).

      • calculateDelayForError

        public int calculateDelayForError()
        Get the delay (in milliseconds) that should be used for triggering a network error.

        Because we are triggering an error, use a random delay between 0 and three times the normal network delay to simulate a flaky connection failing anywhere from quickly to slowly.

        This method is exposed for implementing other, non-Retrofit services which exhibit similar network behavior. Retrofit services automatically will exhibit network behavior when wrapped using create(Class, Object).

      • calculateDelayForCall

        public int calculateDelayForCall()
        Get the delay (in milliseconds) that should be used for delaying a network call response.

        This method is exposed for implementing other, non-Retrofit services which exhibit similar network behavior. Retrofit services automatically will exhibit network behavior when wrapped using create(Class, Object).

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/android/AndroidMockValuePersistence.html ================================================ AndroidMockValuePersistence (Retrofit Mock Adapter 1.9.0 API)
retrofit.android

Class AndroidMockValuePersistence

    • Method Detail

      • install

        public static void install(MockRestAdapter mockRestAdapter,
                                   android.content.SharedPreferences preferences)
        Install a value change listener on the supplied MockRestAdapter using the SharedPreferences for storing customized behavior values. Invoking this will load any existing stored values for the mock adapter's behavior.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/android/class-use/AndroidMockValuePersistence.html ================================================ Uses of Class retrofit.android.AndroidMockValuePersistence (Retrofit Mock Adapter 1.9.0 API)

Uses of Class
retrofit.android.AndroidMockValuePersistence

No usage of retrofit.android.AndroidMockValuePersistence

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/android/package-frame.html ================================================ retrofit.android (Retrofit Mock Adapter 1.9.0 API)

retrofit.android

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/android/package-summary.html ================================================ retrofit.android (Retrofit Mock Adapter 1.9.0 API)

Package retrofit.android

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/android/package-tree.html ================================================ retrofit.android Class Hierarchy (Retrofit Mock Adapter 1.9.0 API)

Hierarchy For Package retrofit.android

Package Hierarchies:

Class Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/android/package-use.html ================================================ Uses of Package retrofit.android (Retrofit Mock Adapter 1.9.0 API)

Uses of Package
retrofit.android

No usage of retrofit.android

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/class-use/MockHttpException.html ================================================ Uses of Class retrofit.MockHttpException (Retrofit Mock Adapter 1.9.0 API)

Uses of Class
retrofit.MockHttpException

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/class-use/MockRestAdapter.ValueChangeListener.html ================================================ Uses of Interface retrofit.MockRestAdapter.ValueChangeListener (Retrofit Mock Adapter 1.9.0 API)

Uses of Interface
retrofit.MockRestAdapter.ValueChangeListener

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/class-use/MockRestAdapter.html ================================================ Uses of Class retrofit.MockRestAdapter (Retrofit Mock Adapter 1.9.0 API)

Uses of Class
retrofit.MockRestAdapter

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/package-frame.html ================================================ retrofit (Retrofit Mock Adapter 1.9.0 API)

retrofit

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/package-summary.html ================================================ retrofit (Retrofit Mock Adapter 1.9.0 API)

Package retrofit

  • Interface Summary 
    Interface Description
    MockRestAdapter.ValueChangeListener
    A listener invoked when the network behavior values for a MockRestAdapter change.
  • Class Summary 
    Class Description
    MockRestAdapter
    Wraps mock implementations of API interfaces so that they exhibit the delay and error characteristics of a real network.
  • Exception Summary 
    Exception Description
    MockHttpException
    An exception used to trigger the simulation of an HTTP error for mock services.

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/package-tree.html ================================================ retrofit Class Hierarchy (Retrofit Mock Adapter 1.9.0 API)

Hierarchy For Package retrofit

Package Hierarchies:

Class Hierarchy

Interface Hierarchy

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/retrofit/package-use.html ================================================ Uses of Package retrofit (Retrofit Mock Adapter 1.9.0 API)

Uses of Package
retrofit

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/1.x/retrofit-mock/serialized-form.html ================================================ Serialized Form (Retrofit Mock Adapter 1.9.0 API)

Serialized Form

Copyright © 2015 Square, Inc.. All Rights Reserved.

================================================ FILE: website/public/1.x/retrofit-mock/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; width:100%; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/1.x/retrofit-mock/version.txt ================================================ 1.9.0 ================================================ FILE: website/public/2.x/adapter-guava/allclasses-frame.html ================================================ All Classes (guava API)

All Classes

================================================ FILE: website/public/2.x/adapter-guava/allclasses-noframe.html ================================================ All Classes (guava API)

All Classes

================================================ FILE: website/public/2.x/adapter-guava/constant-values.html ================================================ Constant Field Values (guava API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/adapter-guava/deprecated-list.html ================================================ Deprecated List (guava API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/adapter-guava/help-doc.html ================================================ API Help (guava API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/adapter-guava/index-all.html ================================================ Index (guava API)
C G H R 

C

create() - Static method in class retrofit2.adapter.guava.GuavaCallAdapterFactory
 

G

get(Type, Annotation[], Retrofit) - Method in class retrofit2.adapter.guava.GuavaCallAdapterFactory
 
GuavaCallAdapterFactory - Class in retrofit2.adapter.guava
A call adapter which creates Guava futures.

H

HttpException - Exception in retrofit2.adapter.guava
Deprecated.
Use HttpException.
HttpException(Response<?>) - Constructor for exception retrofit2.adapter.guava.HttpException
Deprecated.
 

R

retrofit2.adapter.guava - package retrofit2.adapter.guava
 
C G H R 
================================================ FILE: website/public/2.x/adapter-guava/index.html ================================================ guava API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/adapter/guava/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/adapter-guava/overview-tree.html ================================================ Class Hierarchy (guava API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
================================================ FILE: website/public/2.x/adapter-guava/package-list ================================================ retrofit2.adapter.guava ================================================ FILE: website/public/2.x/adapter-guava/retrofit2/adapter/guava/GuavaCallAdapterFactory.html ================================================ GuavaCallAdapterFactory (guava API)
retrofit2.adapter.guava

Class GuavaCallAdapterFactory

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
      • retrofit2.adapter.guava.GuavaCallAdapterFactory


  • public final class GuavaCallAdapterFactory
    extends retrofit2.CallAdapter.Factory
    A call adapter which creates Guava futures.

    Adding this class to Retrofit allows you to return ListenableFuture from service methods.

    
     interface MyService {
       @GET("user/me")
       ListenableFuture<User> getUser()
     }
     
    There are two configurations supported for the ListenableFuture type parameter:
    • Direct body (e.g., ListenableFuture<User>) returns the deserialized body for 2XX responses, sets HttpException errors for non-2XX responses, and sets IOException for network errors.
    • Response wrapped body (e.g., ListenableFuture<Response<User>>) returns a Response object for all HTTP responses and sets IOException for network errors
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static GuavaCallAdapterFactory create() 
      retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      • Methods inherited from class retrofit2.CallAdapter.Factory

        getParameterUpperBound, getRawType
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • get

        @Nullable
        public retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType,
                                                        java.lang.annotation.Annotation[] annotations,
                                                        retrofit2.Retrofit retrofit)
        Specified by:
        get in class retrofit2.CallAdapter.Factory
================================================ FILE: website/public/2.x/adapter-guava/retrofit2/adapter/guava/HttpException.html ================================================ HttpException (guava API)
retrofit2.adapter.guava

Class HttpException

  • java.lang.Object
    • java.lang.Throwable
      • java.lang.Exception
        • java.lang.RuntimeException
          • retrofit2.HttpException
            • retrofit2.adapter.guava.HttpException
  • All Implemented Interfaces:
    java.io.Serializable

    Deprecated. 
    Use HttpException.

    @Deprecated
    public final class HttpException
    extends retrofit2.HttpException
    See Also:
    Serialized Form
    • Constructor Summary

      Constructors 
      Constructor and Description
      HttpException(retrofit2.Response<?> response)
      Deprecated. 
       
    • Method Summary

      • Methods inherited from class retrofit2.HttpException

        code, message, response
      • Methods inherited from class java.lang.Throwable

        addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • HttpException

        public HttpException(retrofit2.Response<?> response)
        Deprecated. 
================================================ FILE: website/public/2.x/adapter-guava/retrofit2/adapter/guava/package-frame.html ================================================ retrofit2.adapter.guava (guava API)

retrofit2.adapter.guava

================================================ FILE: website/public/2.x/adapter-guava/retrofit2/adapter/guava/package-summary.html ================================================ retrofit2.adapter.guava (guava API)

@EverythingIsNonNull

Package retrofit2.adapter.guava

  • Class Summary 
    Class Description
    GuavaCallAdapterFactory
    A call adapter which creates Guava futures.
  • Exception Summary 
    Exception Description
    HttpException Deprecated
    Use HttpException.
================================================ FILE: website/public/2.x/adapter-guava/retrofit2/adapter/guava/package-tree.html ================================================ retrofit2.adapter.guava Class Hierarchy (guava API)

Hierarchy For Package retrofit2.adapter.guava

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
================================================ FILE: website/public/2.x/adapter-guava/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/adapter-guava/serialized-form.html ================================================ Serialized Form (guava API)

Serialized Form

================================================ FILE: website/public/2.x/adapter-guava/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/adapter-java8/allclasses-frame.html ================================================ All Classes (java8 API)

All Classes

================================================ FILE: website/public/2.x/adapter-java8/allclasses-noframe.html ================================================ All Classes (java8 API)

All Classes

================================================ FILE: website/public/2.x/adapter-java8/constant-values.html ================================================ Constant Field Values (java8 API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/adapter-java8/deprecated-list.html ================================================ Deprecated List (java8 API)

Deprecated API

Contents

  • Deprecated Classes 
    Class and Description
    retrofit2.adapter.java8.Java8CallAdapterFactory
    Retrofit includes support for CompletableFuture. This no longer needs to be added to the Retrofit instance explicitly.

    A call adapter which creates Java 8 futures.

    Adding this class to Retrofit allows you to return CompletableFuture from service methods.

    
     interface MyService {
       @GET("user/me")
       CompletableFuture<User> getUser()
     }
     
    There are two configurations supported for the CompletableFuture type parameter:
    • Direct body (e.g., CompletableFuture<User>) returns the deserialized body for 2XX responses, sets HttpException errors for non-2XX responses, and sets IOException for network errors.
    • Response wrapped body (e.g., CompletableFuture<Response<User>>) returns a Response object for all HTTP responses and sets IOException for network errors
================================================ FILE: website/public/2.x/adapter-java8/help-doc.html ================================================ API Help (java8 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/adapter-java8/index-all.html ================================================ Index (java8 API)
C G H J R 

C

create() - Static method in class retrofit2.adapter.java8.Java8CallAdapterFactory
Deprecated.
 

G

get(Type, Annotation[], Retrofit) - Method in class retrofit2.adapter.java8.Java8CallAdapterFactory
Deprecated.
 

H

HttpException - Exception in retrofit2.adapter.java8
Deprecated.
Use HttpException.
HttpException(Response<?>) - Constructor for exception retrofit2.adapter.java8.HttpException
Deprecated.
 

J

Java8CallAdapterFactory - Class in retrofit2.adapter.java8
Deprecated.
Retrofit includes support for CompletableFuture. This no longer needs to be added to the Retrofit instance explicitly.

A call adapter which creates Java 8 futures.

Adding this class to Retrofit allows you to return CompletableFuture from service methods.


 interface MyService {
   @GET("user/me")
   CompletableFuture<User> getUser()
 }
 
There are two configurations supported for the CompletableFuture type parameter:
  • Direct body (e.g., CompletableFuture<User>) returns the deserialized body for 2XX responses, sets HttpException errors for non-2XX responses, and sets IOException for network errors.
  • Response wrapped body (e.g., CompletableFuture<Response<User>>) returns a Response object for all HTTP responses and sets IOException for network errors

R

retrofit2.adapter.java8 - package retrofit2.adapter.java8
 
C G H J R 
================================================ FILE: website/public/2.x/adapter-java8/index.html ================================================ java8 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/adapter/java8/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/adapter-java8/overview-tree.html ================================================ Class Hierarchy (java8 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
================================================ FILE: website/public/2.x/adapter-java8/package-list ================================================ retrofit2.adapter.java8 ================================================ FILE: website/public/2.x/adapter-java8/retrofit2/adapter/java8/HttpException.html ================================================ HttpException (java8 API)
retrofit2.adapter.java8

Class HttpException

  • java.lang.Object
    • java.lang.Throwable
      • java.lang.Exception
        • java.lang.RuntimeException
          • retrofit2.HttpException
            • retrofit2.adapter.java8.HttpException
  • All Implemented Interfaces:
    java.io.Serializable

    Deprecated. 
    Use HttpException.

    @Deprecated
    public final class HttpException
    extends retrofit2.HttpException
    See Also:
    Serialized Form
    • Constructor Summary

      Constructors 
      Constructor and Description
      HttpException(retrofit2.Response<?> response)
      Deprecated. 
       
    • Method Summary

      • Methods inherited from class retrofit2.HttpException

        code, message, response
      • Methods inherited from class java.lang.Throwable

        addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • HttpException

        public HttpException(retrofit2.Response<?> response)
        Deprecated. 
================================================ FILE: website/public/2.x/adapter-java8/retrofit2/adapter/java8/Java8CallAdapterFactory.html ================================================ Java8CallAdapterFactory (java8 API)
retrofit2.adapter.java8

Class Java8CallAdapterFactory

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
      • retrofit2.adapter.java8.Java8CallAdapterFactory

  • Deprecated. 
    Retrofit includes support for CompletableFuture. This no longer needs to be added to the Retrofit instance explicitly.

    A call adapter which creates Java 8 futures.

    Adding this class to Retrofit allows you to return CompletableFuture from service methods.

    
     interface MyService {
       @GET("user/me")
       CompletableFuture<User> getUser()
     }
     
    There are two configurations supported for the CompletableFuture type parameter:
    • Direct body (e.g., CompletableFuture<User>) returns the deserialized body for 2XX responses, sets HttpException errors for non-2XX responses, and sets IOException for network errors.
    • Response wrapped body (e.g., CompletableFuture<Response<User>>) returns a Response object for all HTTP responses and sets IOException for network errors

    @Deprecated
    public final class Java8CallAdapterFactory
    extends retrofit2.CallAdapter.Factory
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method and Description
      static Java8CallAdapterFactory create()
      Deprecated. 
       
      retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit)
      Deprecated. 
       
      • Methods inherited from class retrofit2.CallAdapter.Factory

        getParameterUpperBound, getRawType
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • get

        @Nullable
        public retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType,
                                                        java.lang.annotation.Annotation[] annotations,
                                                        retrofit2.Retrofit retrofit)
        Deprecated. 
        Specified by:
        get in class retrofit2.CallAdapter.Factory
================================================ FILE: website/public/2.x/adapter-java8/retrofit2/adapter/java8/package-frame.html ================================================ retrofit2.adapter.java8 (java8 API)

retrofit2.adapter.java8

================================================ FILE: website/public/2.x/adapter-java8/retrofit2/adapter/java8/package-summary.html ================================================ retrofit2.adapter.java8 (java8 API)

@EverythingIsNonNull

Package retrofit2.adapter.java8

  • Class Summary 
    Class Description
    Java8CallAdapterFactory Deprecated
    Retrofit includes support for CompletableFuture.
  • Exception Summary 
    Exception Description
    HttpException Deprecated
    Use HttpException.
================================================ FILE: website/public/2.x/adapter-java8/retrofit2/adapter/java8/package-tree.html ================================================ retrofit2.adapter.java8 Class Hierarchy (java8 API)

Hierarchy For Package retrofit2.adapter.java8

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
================================================ FILE: website/public/2.x/adapter-java8/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/adapter-java8/serialized-form.html ================================================ Serialized Form (java8 API)

Serialized Form

================================================ FILE: website/public/2.x/adapter-java8/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/adapter-rxjava/allclasses-frame.html ================================================ All Classes (rxjava API)

All Classes

================================================ FILE: website/public/2.x/adapter-rxjava/allclasses-noframe.html ================================================ All Classes (rxjava API)

All Classes

================================================ FILE: website/public/2.x/adapter-rxjava/constant-values.html ================================================ Constant Field Values (rxjava API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/adapter-rxjava/deprecated-list.html ================================================ Deprecated List (rxjava API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/adapter-rxjava/help-doc.html ================================================ API Help (rxjava API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/adapter-rxjava/index-all.html ================================================ Index (rxjava API)
C E G H I R T 

C

create() - Static method in class retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
Returns an instance which creates synchronous observables that do not operate on any scheduler by default.
createAsync() - Static method in class retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
Returns an instance which creates asynchronous observables.
createWithScheduler(Scheduler) - Static method in class retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
Returns an instance which creates synchronous observables that subscribe on scheduler by default.

E

error(Throwable) - Static method in class retrofit2.adapter.rxjava.Result
 
error() - Method in class retrofit2.adapter.rxjava.Result
The error experienced while attempting to execute an HTTP request.

G

get(Type, Annotation[], Retrofit) - Method in class retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
 

H

HttpException - Exception in retrofit2.adapter.rxjava
Deprecated.
Use HttpException.
HttpException(Response<?>) - Constructor for exception retrofit2.adapter.rxjava.HttpException
Deprecated.
 

I

isError() - Method in class retrofit2.adapter.rxjava.Result
true if the request resulted in an error.

R

response(Response<T>) - Static method in class retrofit2.adapter.rxjava.Result
 
response() - Method in class retrofit2.adapter.rxjava.Result
The response received from executing an HTTP request.
Result<T> - Class in retrofit2.adapter.rxjava
The result of executing an HTTP request.
retrofit2.adapter.rxjava - package retrofit2.adapter.rxjava
 
RxJavaCallAdapterFactory - Class in retrofit2.adapter.rxjava
A call adapter which uses RxJava for creating observables.

T

toString() - Method in class retrofit2.adapter.rxjava.Result
 
C E G H I R T 
================================================ FILE: website/public/2.x/adapter-rxjava/index.html ================================================ rxjava API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/adapter/rxjava/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/adapter-rxjava/overview-tree.html ================================================ Class Hierarchy (rxjava API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • retrofit2.adapter.rxjava.Result<T>
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
================================================ FILE: website/public/2.x/adapter-rxjava/package-list ================================================ retrofit2.adapter.rxjava ================================================ FILE: website/public/2.x/adapter-rxjava/retrofit2/adapter/rxjava/HttpException.html ================================================ HttpException (rxjava API)
retrofit2.adapter.rxjava

Class HttpException

  • java.lang.Object
    • java.lang.Throwable
      • java.lang.Exception
        • java.lang.RuntimeException
          • retrofit2.HttpException
            • retrofit2.adapter.rxjava.HttpException
  • All Implemented Interfaces:
    java.io.Serializable

    Deprecated. 
    Use HttpException.

    @Deprecated
    public final class HttpException
    extends retrofit2.HttpException
    See Also:
    Serialized Form
    • Constructor Summary

      Constructors 
      Constructor and Description
      HttpException(retrofit2.Response<?> response)
      Deprecated. 
       
    • Method Summary

      • Methods inherited from class retrofit2.HttpException

        code, message, response
      • Methods inherited from class java.lang.Throwable

        addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • HttpException

        public HttpException(retrofit2.Response<?> response)
        Deprecated. 
================================================ FILE: website/public/2.x/adapter-rxjava/retrofit2/adapter/rxjava/Result.html ================================================ Result (rxjava API)
retrofit2.adapter.rxjava

Class Result<T>

  • java.lang.Object
    • retrofit2.adapter.rxjava.Result<T>


  • public final class Result<T>
    extends java.lang.Object
    The result of executing an HTTP request.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      java.lang.Throwable error()
      The error experienced while attempting to execute an HTTP request.
      static <T> Result<T> error(java.lang.Throwable error) 
      boolean isError()
      true if the request resulted in an error.
      retrofit2.Response<T> response()
      The response received from executing an HTTP request.
      static <T> Result<T> response(retrofit2.Response<T> response) 
      java.lang.String toString() 
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Method Detail

      • error

        public static <T> Result<T> error(java.lang.Throwable error)
      • response

        public static <T> Result<T> response(retrofit2.Response<T> response)
      • response

        @Nullable
        public retrofit2.Response<T> response()
        The response received from executing an HTTP request. Only present when isError() is false, null otherwise.
      • error

        @Nullable
        public java.lang.Throwable error()
        The error experienced while attempting to execute an HTTP request. Only present when isError() is true, null otherwise.

        If the error is an IOException then there was a problem with the transport to the remote server. Any other exception type indicates an unexpected failure and should be considered fatal (configuration error, programming error, etc.).

      • isError

        public boolean isError()
        true if the request resulted in an error. See error() for the cause.
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
================================================ FILE: website/public/2.x/adapter-rxjava/retrofit2/adapter/rxjava/RxJavaCallAdapterFactory.html ================================================ RxJavaCallAdapterFactory (rxjava API)
retrofit2.adapter.rxjava

Class RxJavaCallAdapterFactory

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
      • retrofit2.adapter.rxjava.RxJavaCallAdapterFactory


  • public final class RxJavaCallAdapterFactory
    extends retrofit2.CallAdapter.Factory
    A call adapter which uses RxJava for creating observables.

    Adding this class to Retrofit allows you to return an Observable, Single, or Completable from service methods.

    
     interface MyService {
       @GET("user/me")
       Observable<User> getUser()
     }
     
    There are three configurations supported for the Observable or Single type parameter:
    • Direct body (e.g., Observable<User>) calls onNext with the deserialized body for 2XX responses and calls onError with HttpException for non-2XX responses and IOException for network errors.
    • Response wrapped body (e.g., Observable<Response<User>>) calls onNext with a Response object for all HTTP responses and calls onError with IOException for network errors
    • Result wrapped body (e.g., Observable<Result<User>>) calls onNext with a Result object for all HTTP responses and errors.

    Note: Support for Single and Completable is experimental and subject to backwards-incompatible changes at any time since both of these types are not considered stable by RxJava.

    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static RxJavaCallAdapterFactory create()
      Returns an instance which creates synchronous observables that do not operate on any scheduler by default.
      static RxJavaCallAdapterFactory createAsync()
      Returns an instance which creates asynchronous observables.
      static RxJavaCallAdapterFactory createWithScheduler(rx.Scheduler scheduler)
      Returns an instance which creates synchronous observables that subscribe on scheduler by default.
      retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      • Methods inherited from class retrofit2.CallAdapter.Factory

        getParameterUpperBound, getRawType
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • create

        public static RxJavaCallAdapterFactory create()
        Returns an instance which creates synchronous observables that do not operate on any scheduler by default.
      • createAsync

        public static RxJavaCallAdapterFactory createAsync()
        Returns an instance which creates asynchronous observables.
      • createWithScheduler

        public static RxJavaCallAdapterFactory createWithScheduler(rx.Scheduler scheduler)
        Returns an instance which creates synchronous observables that subscribe on scheduler by default.
      • get

        @Nullable
        public retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType,
                                                        java.lang.annotation.Annotation[] annotations,
                                                        retrofit2.Retrofit retrofit)
        Specified by:
        get in class retrofit2.CallAdapter.Factory
================================================ FILE: website/public/2.x/adapter-rxjava/retrofit2/adapter/rxjava/package-frame.html ================================================ retrofit2.adapter.rxjava (rxjava API)

retrofit2.adapter.rxjava

================================================ FILE: website/public/2.x/adapter-rxjava/retrofit2/adapter/rxjava/package-summary.html ================================================ retrofit2.adapter.rxjava (rxjava API)

@EverythingIsNonNull

Package retrofit2.adapter.rxjava

  • Class Summary 
    Class Description
    Result<T>
    The result of executing an HTTP request.
    RxJavaCallAdapterFactory
    A call adapter which uses RxJava for creating observables.
  • Exception Summary 
    Exception Description
    HttpException Deprecated
    Use HttpException.
================================================ FILE: website/public/2.x/adapter-rxjava/retrofit2/adapter/rxjava/package-tree.html ================================================ retrofit2.adapter.rxjava Class Hierarchy (rxjava API)

Hierarchy For Package retrofit2.adapter.rxjava

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • retrofit2.adapter.rxjava.Result<T>
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
================================================ FILE: website/public/2.x/adapter-rxjava/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/adapter-rxjava/serialized-form.html ================================================ Serialized Form (rxjava API)

Serialized Form

================================================ FILE: website/public/2.x/adapter-rxjava/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/adapter-rxjava2/allclasses-frame.html ================================================ All Classes (rxjava2 API)

All Classes

================================================ FILE: website/public/2.x/adapter-rxjava2/allclasses-noframe.html ================================================ All Classes (rxjava2 API)

All Classes

================================================ FILE: website/public/2.x/adapter-rxjava2/constant-values.html ================================================ Constant Field Values (rxjava2 API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/adapter-rxjava2/deprecated-list.html ================================================ Deprecated List (rxjava2 API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/adapter-rxjava2/help-doc.html ================================================ API Help (rxjava2 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/adapter-rxjava2/index-all.html ================================================ Index (rxjava2 API)
C E G H I R 

C

create() - Static method in class retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
Returns an instance which creates synchronous observables that do not operate on any scheduler by default.
createAsync() - Static method in class retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
Returns an instance which creates asynchronous observables.
createWithScheduler(Scheduler) - Static method in class retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
Returns an instance which creates synchronous observables that subscribe on scheduler by default.

E

error(Throwable) - Static method in class retrofit2.adapter.rxjava2.Result
 
error() - Method in class retrofit2.adapter.rxjava2.Result
The error experienced while attempting to execute an HTTP request.

G

get(Type, Annotation[], Retrofit) - Method in class retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
 

H

HttpException - Exception in retrofit2.adapter.rxjava2
Deprecated.
Use HttpException.
HttpException(Response<?>) - Constructor for exception retrofit2.adapter.rxjava2.HttpException
Deprecated.
 

I

isError() - Method in class retrofit2.adapter.rxjava2.Result
true if the request resulted in an error.

R

response(Response<T>) - Static method in class retrofit2.adapter.rxjava2.Result
 
response() - Method in class retrofit2.adapter.rxjava2.Result
The response received from executing an HTTP request.
Result<T> - Class in retrofit2.adapter.rxjava2
The result of executing an HTTP request.
retrofit2.adapter.rxjava2 - package retrofit2.adapter.rxjava2
 
RxJava2CallAdapterFactory - Class in retrofit2.adapter.rxjava2
A call adapter which uses RxJava 2 for creating observables.
C E G H I R 
================================================ FILE: website/public/2.x/adapter-rxjava2/index.html ================================================ rxjava2 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/adapter/rxjava2/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/adapter-rxjava2/overview-tree.html ================================================ Class Hierarchy (rxjava2 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • retrofit2.adapter.rxjava2.Result<T>
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
          • retrofit2.HttpException
================================================ FILE: website/public/2.x/adapter-rxjava2/package-list ================================================ retrofit2.adapter.rxjava2 ================================================ FILE: website/public/2.x/adapter-rxjava2/retrofit2/adapter/rxjava2/HttpException.html ================================================ HttpException (rxjava2 API)
retrofit2.adapter.rxjava2

Class HttpException

  • java.lang.Object
    • java.lang.Throwable
      • java.lang.Exception
        • java.lang.RuntimeException
          • retrofit2.HttpException
            • retrofit2.adapter.rxjava2.HttpException
  • All Implemented Interfaces:
    java.io.Serializable

    Deprecated. 
    Use HttpException.

    @Deprecated
    public final class HttpException
    extends retrofit2.HttpException
    See Also:
    Serialized Form
    • Constructor Summary

      Constructors 
      Constructor and Description
      HttpException(retrofit2.Response<?> response)
      Deprecated. 
       
    • Method Summary

      • Methods inherited from class retrofit2.HttpException

        code, message, response
      • Methods inherited from class java.lang.Throwable

        addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • HttpException

        public HttpException(retrofit2.Response<?> response)
        Deprecated. 
================================================ FILE: website/public/2.x/adapter-rxjava2/retrofit2/adapter/rxjava2/Result.html ================================================ Result (rxjava2 API)
retrofit2.adapter.rxjava2

Class Result<T>

  • java.lang.Object
    • retrofit2.adapter.rxjava2.Result<T>


  • public final class Result<T>
    extends java.lang.Object
    The result of executing an HTTP request.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      java.lang.Throwable error()
      The error experienced while attempting to execute an HTTP request.
      static <T> Result<T> error(java.lang.Throwable error) 
      boolean isError()
      true if the request resulted in an error.
      retrofit2.Response<T> response()
      The response received from executing an HTTP request.
      static <T> Result<T> response(retrofit2.Response<T> response) 
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • error

        public static <T> Result<T> error(java.lang.Throwable error)
      • response

        public static <T> Result<T> response(retrofit2.Response<T> response)
      • response

        @Nullable
        public retrofit2.Response<T> response()
        The response received from executing an HTTP request. Only present when isError() is false, null otherwise.
      • error

        @Nullable
        public java.lang.Throwable error()
        The error experienced while attempting to execute an HTTP request. Only present when isError() is true, null otherwise.

        If the error is an IOException then there was a problem with the transport to the remote server. Any other exception type indicates an unexpected failure and should be considered fatal (configuration error, programming error, etc.).

      • isError

        public boolean isError()
        true if the request resulted in an error. See error() for the cause.
================================================ FILE: website/public/2.x/adapter-rxjava2/retrofit2/adapter/rxjava2/RxJava2CallAdapterFactory.html ================================================ RxJava2CallAdapterFactory (rxjava2 API)
retrofit2.adapter.rxjava2

Class RxJava2CallAdapterFactory

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
      • retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory


  • public final class RxJava2CallAdapterFactory
    extends retrofit2.CallAdapter.Factory
    A call adapter which uses RxJava 2 for creating observables.

    Adding this class to Retrofit allows you to return an Observable, Flowable, Single, Completable or Maybe from service methods.

    
     interface MyService {
       @GET("user/me")
       Observable<User> getUser()
     }
     
    There are three configurations supported for the Observable, Flowable, Single, Completable and Maybe type parameter:
    • Direct body (e.g., Observable<User>) calls onNext with the deserialized body for 2XX responses and calls onError with HttpException for non-2XX responses and IOException for network errors.
    • Response wrapped body (e.g., Observable<Response<User>>) calls onNext with a Response object for all HTTP responses and calls onError with IOException for network errors
    • Result wrapped body (e.g., Observable<Result<User>>) calls onNext with a Result object for all HTTP responses and errors.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static RxJava2CallAdapterFactory create()
      Returns an instance which creates synchronous observables that do not operate on any scheduler by default.
      static RxJava2CallAdapterFactory createAsync()
      Returns an instance which creates asynchronous observables.
      static RxJava2CallAdapterFactory createWithScheduler(io.reactivex.Scheduler scheduler)
      Returns an instance which creates synchronous observables that subscribe on scheduler by default.
      retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      • Methods inherited from class retrofit2.CallAdapter.Factory

        getParameterUpperBound, getRawType
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • create

        public static RxJava2CallAdapterFactory create()
        Returns an instance which creates synchronous observables that do not operate on any scheduler by default.
      • createAsync

        public static RxJava2CallAdapterFactory createAsync()
        Returns an instance which creates asynchronous observables.
      • createWithScheduler

        public static RxJava2CallAdapterFactory createWithScheduler(io.reactivex.Scheduler scheduler)
        Returns an instance which creates synchronous observables that subscribe on scheduler by default.
      • get

        @Nullable
        public retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType,
                                                        java.lang.annotation.Annotation[] annotations,
                                                        retrofit2.Retrofit retrofit)
        Specified by:
        get in class retrofit2.CallAdapter.Factory
================================================ FILE: website/public/2.x/adapter-rxjava2/retrofit2/adapter/rxjava2/package-frame.html ================================================ retrofit2.adapter.rxjava2 (rxjava2 API)

retrofit2.adapter.rxjava2

================================================ FILE: website/public/2.x/adapter-rxjava2/retrofit2/adapter/rxjava2/package-summary.html ================================================ retrofit2.adapter.rxjava2 (rxjava2 API)

@EverythingIsNonNull

Package retrofit2.adapter.rxjava2

  • Class Summary 
    Class Description
    Result<T>
    The result of executing an HTTP request.
    RxJava2CallAdapterFactory
    A call adapter which uses RxJava 2 for creating observables.
  • Exception Summary 
    Exception Description
    HttpException Deprecated
    Use HttpException.
================================================ FILE: website/public/2.x/adapter-rxjava2/retrofit2/adapter/rxjava2/package-tree.html ================================================ retrofit2.adapter.rxjava2 Class Hierarchy (rxjava2 API)

Hierarchy For Package retrofit2.adapter.rxjava2

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • retrofit2.adapter.rxjava2.Result<T>
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
          • retrofit2.HttpException
================================================ FILE: website/public/2.x/adapter-rxjava2/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/adapter-rxjava2/serialized-form.html ================================================ Serialized Form (rxjava2 API)

Serialized Form

================================================ FILE: website/public/2.x/adapter-rxjava2/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/adapter-rxjava3/allclasses-frame.html ================================================ All Classes (rxjava3 API)

All Classes

================================================ FILE: website/public/2.x/adapter-rxjava3/allclasses-noframe.html ================================================ All Classes (rxjava3 API)

All Classes

================================================ FILE: website/public/2.x/adapter-rxjava3/constant-values.html ================================================ Constant Field Values (rxjava3 API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/adapter-rxjava3/deprecated-list.html ================================================ Deprecated List (rxjava3 API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/adapter-rxjava3/help-doc.html ================================================ API Help (rxjava3 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/adapter-rxjava3/index-all.html ================================================ Index (rxjava3 API)
C E G H I R 

C

create() - Static method in class retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
Returns an instance which creates asynchronous observables that run on a background thread by default.
createSynchronous() - Static method in class retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
Returns an instance which creates synchronous observables that do not operate on any scheduler by default.
createWithScheduler(Scheduler) - Static method in class retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
Returns an instance which creates synchronous observables that subscribeOn(..) the supplied scheduler by default.

E

error(Throwable) - Static method in class retrofit2.adapter.rxjava3.Result
 
error() - Method in class retrofit2.adapter.rxjava3.Result
The error experienced while attempting to execute an HTTP request.

G

get(Type, Annotation[], Retrofit) - Method in class retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
 

H

HttpException - Exception in retrofit2.adapter.rxjava3
Deprecated.
Use HttpException.
HttpException(Response<?>) - Constructor for exception retrofit2.adapter.rxjava3.HttpException
Deprecated.
 

I

isError() - Method in class retrofit2.adapter.rxjava3.Result
true if the request resulted in an error.

R

response(Response<T>) - Static method in class retrofit2.adapter.rxjava3.Result
 
response() - Method in class retrofit2.adapter.rxjava3.Result
The response received from executing an HTTP request.
Result<T> - Class in retrofit2.adapter.rxjava3
The result of executing an HTTP request.
retrofit2.adapter.rxjava3 - package retrofit2.adapter.rxjava3
 
RxJava3CallAdapterFactory - Class in retrofit2.adapter.rxjava3
A call adapter which uses RxJava 3 for creating observables.
C E G H I R 
================================================ FILE: website/public/2.x/adapter-rxjava3/index.html ================================================ rxjava3 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/adapter/rxjava3/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/adapter-rxjava3/overview-tree.html ================================================ Class Hierarchy (rxjava3 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • retrofit2.adapter.rxjava3.Result<T>
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
          • retrofit2.HttpException
================================================ FILE: website/public/2.x/adapter-rxjava3/package-list ================================================ retrofit2.adapter.rxjava3 ================================================ FILE: website/public/2.x/adapter-rxjava3/retrofit2/adapter/rxjava3/HttpException.html ================================================ HttpException (rxjava3 API)
retrofit2.adapter.rxjava3

Class HttpException

  • java.lang.Object
    • java.lang.Throwable
      • java.lang.Exception
        • java.lang.RuntimeException
          • retrofit2.HttpException
            • retrofit2.adapter.rxjava3.HttpException
  • All Implemented Interfaces:
    java.io.Serializable

    Deprecated. 
    Use HttpException.

    @Deprecated
    public final class HttpException
    extends retrofit2.HttpException
    See Also:
    Serialized Form
    • Constructor Summary

      Constructors 
      Constructor and Description
      HttpException(retrofit2.Response<?> response)
      Deprecated. 
       
    • Method Summary

      • Methods inherited from class retrofit2.HttpException

        code, message, response
      • Methods inherited from class java.lang.Throwable

        addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • HttpException

        public HttpException(retrofit2.Response<?> response)
        Deprecated. 
================================================ FILE: website/public/2.x/adapter-rxjava3/retrofit2/adapter/rxjava3/Result.html ================================================ Result (rxjava3 API)
retrofit2.adapter.rxjava3

Class Result<T>

  • java.lang.Object
    • retrofit2.adapter.rxjava3.Result<T>


  • public final class Result<T>
    extends java.lang.Object
    The result of executing an HTTP request.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      java.lang.Throwable error()
      The error experienced while attempting to execute an HTTP request.
      static <T> Result<T> error(java.lang.Throwable error) 
      boolean isError()
      true if the request resulted in an error.
      retrofit2.Response<T> response()
      The response received from executing an HTTP request.
      static <T> Result<T> response(retrofit2.Response<T> response) 
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • error

        public static <T> Result<T> error(java.lang.Throwable error)
      • response

        public static <T> Result<T> response(retrofit2.Response<T> response)
      • response

        @Nullable
        public retrofit2.Response<T> response()
        The response received from executing an HTTP request. Only present when isError() is false, null otherwise.
      • error

        @Nullable
        public java.lang.Throwable error()
        The error experienced while attempting to execute an HTTP request. Only present when isError() is true, null otherwise.

        If the error is an IOException then there was a problem with the transport to the remote server. Any other exception type indicates an unexpected failure and should be considered fatal (configuration error, programming error, etc.).

      • isError

        public boolean isError()
        true if the request resulted in an error. See error() for the cause.
================================================ FILE: website/public/2.x/adapter-rxjava3/retrofit2/adapter/rxjava3/RxJava3CallAdapterFactory.html ================================================ RxJava3CallAdapterFactory (rxjava3 API)
retrofit2.adapter.rxjava3

Class RxJava3CallAdapterFactory

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
      • retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory


  • public final class RxJava3CallAdapterFactory
    extends retrofit2.CallAdapter.Factory
    A call adapter which uses RxJava 3 for creating observables.

    Adding this class to Retrofit allows you to return an Observable, Flowable, Single, Completable or Maybe from service methods.

    
     interface MyService {
       @GET("user/me")
       Observable<User> getUser()
     }
     
    There are three configurations supported for the Observable, Flowable, Single, Completable and Maybe type parameter:
    • Direct body (e.g., Observable<User>) calls onNext with the deserialized body for 2XX responses and calls onError with HttpException for non-2XX responses and IOException for network errors.
    • Response wrapped body (e.g., Observable<Response<User>>) calls onNext with a Response object for all HTTP responses and calls onError with IOException for network errors
    • Result wrapped body (e.g., Observable<Result<User>>) calls onNext with a Result object for all HTTP responses and errors.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static RxJava3CallAdapterFactory create()
      Returns an instance which creates asynchronous observables that run on a background thread by default.
      static RxJava3CallAdapterFactory createSynchronous()
      Returns an instance which creates synchronous observables that do not operate on any scheduler by default.
      static RxJava3CallAdapterFactory createWithScheduler(io.reactivex.rxjava3.core.Scheduler scheduler)
      Returns an instance which creates synchronous observables that subscribeOn(..) the supplied scheduler by default.
      retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      • Methods inherited from class retrofit2.CallAdapter.Factory

        getParameterUpperBound, getRawType
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • create

        public static RxJava3CallAdapterFactory create()
        Returns an instance which creates asynchronous observables that run on a background thread by default. Applying subscribeOn(..) has no effect on instances created by the returned factory.
      • createSynchronous

        public static RxJava3CallAdapterFactory createSynchronous()
        Returns an instance which creates synchronous observables that do not operate on any scheduler by default. Applying subscribeOn(..) will change the scheduler on which the HTTP calls are made.
      • createWithScheduler

        public static RxJava3CallAdapterFactory createWithScheduler(io.reactivex.rxjava3.core.Scheduler scheduler)
        Returns an instance which creates synchronous observables that subscribeOn(..) the supplied scheduler by default.
      • get

        @Nullable
        public retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType,
                                                        java.lang.annotation.Annotation[] annotations,
                                                        retrofit2.Retrofit retrofit)
        Specified by:
        get in class retrofit2.CallAdapter.Factory
================================================ FILE: website/public/2.x/adapter-rxjava3/retrofit2/adapter/rxjava3/package-frame.html ================================================ retrofit2.adapter.rxjava3 (rxjava3 API)

retrofit2.adapter.rxjava3

================================================ FILE: website/public/2.x/adapter-rxjava3/retrofit2/adapter/rxjava3/package-summary.html ================================================ retrofit2.adapter.rxjava3 (rxjava3 API)

@EverythingIsNonNull

Package retrofit2.adapter.rxjava3

  • Class Summary 
    Class Description
    Result<T>
    The result of executing an HTTP request.
    RxJava3CallAdapterFactory
    A call adapter which uses RxJava 3 for creating observables.
  • Exception Summary 
    Exception Description
    HttpException Deprecated
    Use HttpException.
================================================ FILE: website/public/2.x/adapter-rxjava3/retrofit2/adapter/rxjava3/package-tree.html ================================================ retrofit2.adapter.rxjava3 Class Hierarchy (rxjava3 API)

Hierarchy For Package retrofit2.adapter.rxjava3

Class Hierarchy

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
    • retrofit2.adapter.rxjava3.Result<T>
    • java.lang.Throwable (implements java.io.Serializable)
      • java.lang.Exception
        • java.lang.RuntimeException
          • retrofit2.HttpException
================================================ FILE: website/public/2.x/adapter-rxjava3/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/adapter-rxjava3/serialized-form.html ================================================ Serialized Form (rxjava3 API)

Serialized Form

================================================ FILE: website/public/2.x/adapter-rxjava3/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/adapter-scala/allclasses-frame.html ================================================ All Classes (scala API)

All Classes

================================================ FILE: website/public/2.x/adapter-scala/allclasses-noframe.html ================================================ All Classes (scala API)

All Classes

================================================ FILE: website/public/2.x/adapter-scala/constant-values.html ================================================ Constant Field Values (scala API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/adapter-scala/deprecated-list.html ================================================ Deprecated List (scala API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/adapter-scala/help-doc.html ================================================ API Help (scala API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/adapter-scala/index-all.html ================================================ Index (scala API)
C G R S 

C

create() - Static method in class retrofit2.adapter.scala.ScalaCallAdapterFactory
 

G

get(Type, Annotation[], Retrofit) - Method in class retrofit2.adapter.scala.ScalaCallAdapterFactory
 

R

retrofit2.adapter.scala - package retrofit2.adapter.scala
 

S

ScalaCallAdapterFactory - Class in retrofit2.adapter.scala
A call adapter which creates Scala futures.
C G R S 
================================================ FILE: website/public/2.x/adapter-scala/index.html ================================================ scala API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/adapter/scala/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/adapter-scala/overview-tree.html ================================================ Class Hierarchy (scala API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

================================================ FILE: website/public/2.x/adapter-scala/package-list ================================================ retrofit2.adapter.scala ================================================ FILE: website/public/2.x/adapter-scala/retrofit2/adapter/scala/ScalaCallAdapterFactory.html ================================================ ScalaCallAdapterFactory (scala API)
retrofit2.adapter.scala

Class ScalaCallAdapterFactory

  • java.lang.Object
    • retrofit2.CallAdapter.Factory
      • retrofit2.adapter.scala.ScalaCallAdapterFactory


  • public final class ScalaCallAdapterFactory
    extends retrofit2.CallAdapter.Factory
    A call adapter which creates Scala futures.

    Adding this class to Retrofit allows you to return Future from service methods.

    
     interface MyService {
       @GET("user/me")
       Future<User> getUser()
     }
     
    There are two configurations supported for the Future type parameter:
    • Direct body (e.g., Future<User>) returns the deserialized body for 2XX responses, sets HttpException errors for non-2XX responses, and sets IOException for network errors.
    • Response wrapped body (e.g., Future<Response<User>>) returns a Response object for all HTTP responses and sets IOException for network errors
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static ScalaCallAdapterFactory create() 
      retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      • Methods inherited from class retrofit2.CallAdapter.Factory

        getParameterUpperBound, getRawType
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • get

        @Nullable
        public retrofit2.CallAdapter<?,?> get(java.lang.reflect.Type returnType,
                                                        java.lang.annotation.Annotation[] annotations,
                                                        retrofit2.Retrofit retrofit)
        Specified by:
        get in class retrofit2.CallAdapter.Factory
================================================ FILE: website/public/2.x/adapter-scala/retrofit2/adapter/scala/package-frame.html ================================================ retrofit2.adapter.scala (scala API)

retrofit2.adapter.scala

================================================ FILE: website/public/2.x/adapter-scala/retrofit2/adapter/scala/package-summary.html ================================================ retrofit2.adapter.scala (scala API)

@EverythingIsNonNull

Package retrofit2.adapter.scala

================================================ FILE: website/public/2.x/adapter-scala/retrofit2/adapter/scala/package-tree.html ================================================ retrofit2.adapter.scala Class Hierarchy (scala API)

Hierarchy For Package retrofit2.adapter.scala

Class Hierarchy

================================================ FILE: website/public/2.x/adapter-scala/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/adapter-scala/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/converter-gson/allclasses-frame.html ================================================ All Classes (gson API)

All Classes

================================================ FILE: website/public/2.x/converter-gson/allclasses-noframe.html ================================================ All Classes (gson API)

All Classes

================================================ FILE: website/public/2.x/converter-gson/constant-values.html ================================================ Constant Field Values (gson API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/converter-gson/deprecated-list.html ================================================ Deprecated List (gson API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/converter-gson/help-doc.html ================================================ API Help (gson API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/converter-gson/index-all.html ================================================ Index (gson API)
C G R W 

C

create() - Static method in class retrofit2.converter.gson.GsonConverterFactory
Create an instance using a default Gson instance for conversion.
create(Gson) - Static method in class retrofit2.converter.gson.GsonConverterFactory
Create an instance using gson for conversion.

G

GsonConverterFactory - Class in retrofit2.converter.gson
A converter which uses Gson for JSON.

R

requestBodyConverter(Type, Annotation[], Annotation[], Retrofit) - Method in class retrofit2.converter.gson.GsonConverterFactory
 
responseBodyConverter(Type, Annotation[], Retrofit) - Method in class retrofit2.converter.gson.GsonConverterFactory
 
retrofit2.converter.gson - package retrofit2.converter.gson
 

W

withStreaming() - Method in class retrofit2.converter.gson.GsonConverterFactory
Return a new factory which streams serialization of request messages to bytes on the HTTP thread This is either the calling thread for Call.execute(), or one of OkHttp's background threads for Call.enqueue(retrofit2.Callback<T>).
C G R W 
================================================ FILE: website/public/2.x/converter-gson/index.html ================================================ gson API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/converter/gson/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/converter-gson/overview-tree.html ================================================ Class Hierarchy (gson API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

================================================ FILE: website/public/2.x/converter-gson/package-list ================================================ retrofit2.converter.gson ================================================ FILE: website/public/2.x/converter-gson/retrofit2/converter/gson/GsonConverterFactory.html ================================================ GsonConverterFactory (gson API)
retrofit2.converter.gson

Class GsonConverterFactory

  • java.lang.Object
    • retrofit2.Converter.Factory
      • retrofit2.converter.gson.GsonConverterFactory


  • public final class GsonConverterFactory
    extends retrofit2.Converter.Factory
    A converter which uses Gson for JSON.

    Because Gson is so flexible in the types it supports, this converter assumes that it can handle all types. If you are mixing JSON serialization with something else (such as protocol buffers), you must add this instance last to allow the other converters a chance to see their types.

    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static GsonConverterFactory create()
      Create an instance using a default Gson instance for conversion.
      static GsonConverterFactory create(com.google.gson.Gson gson)
      Create an instance using gson for conversion.
      retrofit2.Converter<?,okhttp3.RequestBody> requestBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] parameterAnnotations, java.lang.annotation.Annotation[] methodAnnotations, retrofit2.Retrofit retrofit) 
      retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      GsonConverterFactory withStreaming()
      Return a new factory which streams serialization of request messages to bytes on the HTTP thread This is either the calling thread for Call.execute(), or one of OkHttp's background threads for Call.enqueue(retrofit2.Callback<T>).
      • Methods inherited from class retrofit2.Converter.Factory

        getParameterUpperBound, getRawType, stringConverter
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • create

        public static GsonConverterFactory create()
        Create an instance using a default Gson instance for conversion. Encoding to JSON and decoding from JSON (when no charset is specified by a header) will use UTF-8.
      • create

        public static GsonConverterFactory create(com.google.gson.Gson gson)
        Create an instance using gson for conversion. Encoding to JSON and decoding from JSON (when no charset is specified by a header) will use UTF-8.
      • withStreaming

        public GsonConverterFactory withStreaming()
        Return a new factory which streams serialization of request messages to bytes on the HTTP thread This is either the calling thread for Call.execute(), or one of OkHttp's background threads for Call.enqueue(retrofit2.Callback<T>). Response bytes are always converted to message instances on one of OkHttp's background threads.
      • responseBodyConverter

        public retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type,
                                                                                 java.lang.annotation.Annotation[] annotations,
                                                                                 retrofit2.Retrofit retrofit)
        Overrides:
        responseBodyConverter in class retrofit2.Converter.Factory
      • requestBodyConverter

        public retrofit2.Converter<?,okhttp3.RequestBody> requestBodyConverter(java.lang.reflect.Type type,
                                                                               java.lang.annotation.Annotation[] parameterAnnotations,
                                                                               java.lang.annotation.Annotation[] methodAnnotations,
                                                                               retrofit2.Retrofit retrofit)
        Overrides:
        requestBodyConverter in class retrofit2.Converter.Factory
================================================ FILE: website/public/2.x/converter-gson/retrofit2/converter/gson/package-frame.html ================================================ retrofit2.converter.gson (gson API)

retrofit2.converter.gson

================================================ FILE: website/public/2.x/converter-gson/retrofit2/converter/gson/package-summary.html ================================================ retrofit2.converter.gson (gson API)

@EverythingIsNonNull

Package retrofit2.converter.gson

================================================ FILE: website/public/2.x/converter-gson/retrofit2/converter/gson/package-tree.html ================================================ retrofit2.converter.gson Class Hierarchy (gson API)

Hierarchy For Package retrofit2.converter.gson

Class Hierarchy

================================================ FILE: website/public/2.x/converter-gson/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/converter-gson/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/converter-guava/allclasses-frame.html ================================================ All Classes (guava API)

All Classes

================================================ FILE: website/public/2.x/converter-guava/allclasses-noframe.html ================================================ All Classes (guava API)

All Classes

================================================ FILE: website/public/2.x/converter-guava/constant-values.html ================================================ Constant Field Values (guava API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/converter-guava/deprecated-list.html ================================================ Deprecated List (guava API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/converter-guava/help-doc.html ================================================ API Help (guava API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/converter-guava/index-all.html ================================================ Index (guava API)
C G R 

C

create() - Static method in class retrofit.converter.guava.GuavaOptionalConverterFactory
 

G

GuavaOptionalConverterFactory - Class in retrofit.converter.guava
A converter for Optional<T> which delegates to another converter to deserialize T and then wraps it into Optional.

R

responseBodyConverter(Type, Annotation[], Retrofit) - Method in class retrofit.converter.guava.GuavaOptionalConverterFactory
 
retrofit.converter.guava - package retrofit.converter.guava
 
C G R 
================================================ FILE: website/public/2.x/converter-guava/index.html ================================================ guava API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit/converter/guava/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/converter-guava/overview-tree.html ================================================ Class Hierarchy (guava API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

================================================ FILE: website/public/2.x/converter-guava/package-list ================================================ retrofit.converter.guava ================================================ FILE: website/public/2.x/converter-guava/retrofit/converter/guava/GuavaOptionalConverterFactory.html ================================================ GuavaOptionalConverterFactory (guava API)
retrofit.converter.guava

Class GuavaOptionalConverterFactory

  • java.lang.Object
    • retrofit2.Converter.Factory
      • retrofit.converter.guava.GuavaOptionalConverterFactory


  • public final class GuavaOptionalConverterFactory
    extends retrofit2.Converter.Factory
    A converter for Optional<T> which delegates to another converter to deserialize T and then wraps it into Optional.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static GuavaOptionalConverterFactory create() 
      retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      • Methods inherited from class retrofit2.Converter.Factory

        getParameterUpperBound, getRawType, requestBodyConverter, stringConverter
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • responseBodyConverter

        @Nullable
        public retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type,
                                                                                           java.lang.annotation.Annotation[] annotations,
                                                                                           retrofit2.Retrofit retrofit)
        Overrides:
        responseBodyConverter in class retrofit2.Converter.Factory
================================================ FILE: website/public/2.x/converter-guava/retrofit/converter/guava/package-frame.html ================================================ retrofit.converter.guava (guava API)

retrofit.converter.guava

================================================ FILE: website/public/2.x/converter-guava/retrofit/converter/guava/package-summary.html ================================================ retrofit.converter.guava (guava API)

@EverythingIsNonNull

Package retrofit.converter.guava

  • Class Summary 
    Class Description
    GuavaOptionalConverterFactory
    A converter for Optional<T> which delegates to another converter to deserialize T and then wraps it into Optional.
================================================ FILE: website/public/2.x/converter-guava/retrofit/converter/guava/package-tree.html ================================================ retrofit.converter.guava Class Hierarchy (guava API)

Hierarchy For Package retrofit.converter.guava

Class Hierarchy

================================================ FILE: website/public/2.x/converter-guava/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/converter-guava/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/converter-jackson/allclasses-frame.html ================================================ All Classes (jackson API)

All Classes

================================================ FILE: website/public/2.x/converter-jackson/allclasses-noframe.html ================================================ All Classes (jackson API)

All Classes

================================================ FILE: website/public/2.x/converter-jackson/constant-values.html ================================================ Constant Field Values (jackson API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/converter-jackson/deprecated-list.html ================================================ Deprecated List (jackson API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/converter-jackson/help-doc.html ================================================ API Help (jackson API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/converter-jackson/index-all.html ================================================ Index (jackson API)
C J R W 

C

create() - Static method in class retrofit2.converter.jackson.JacksonConverterFactory
Create an instance using a default ObjectMapper instance for conversion.
create(ObjectMapper) - Static method in class retrofit2.converter.jackson.JacksonConverterFactory
Create an instance using mapper for conversion.
create(ObjectMapper, MediaType) - Static method in class retrofit2.converter.jackson.JacksonConverterFactory
Create an instance using mapper and mediaType for conversion.

J

JacksonConverterFactory - Class in retrofit2.converter.jackson
A converter which uses Jackson.

R

requestBodyConverter(Type, Annotation[], Annotation[], Retrofit) - Method in class retrofit2.converter.jackson.JacksonConverterFactory
 
responseBodyConverter(Type, Annotation[], Retrofit) - Method in class retrofit2.converter.jackson.JacksonConverterFactory
 
retrofit2.converter.jackson - package retrofit2.converter.jackson
 

W

withStreaming() - Method in class retrofit2.converter.jackson.JacksonConverterFactory
Return a new factory which streams serialization of request messages to bytes on the HTTP thread This is either the calling thread for Call.execute(), or one of OkHttp's background threads for Call.enqueue(retrofit2.Callback<T>).
C J R W 
================================================ FILE: website/public/2.x/converter-jackson/index.html ================================================ jackson API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/converter/jackson/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/converter-jackson/overview-tree.html ================================================ Class Hierarchy (jackson API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

================================================ FILE: website/public/2.x/converter-jackson/package-list ================================================ retrofit2.converter.jackson ================================================ FILE: website/public/2.x/converter-jackson/retrofit2/converter/jackson/JacksonConverterFactory.html ================================================ JacksonConverterFactory (jackson API)
retrofit2.converter.jackson

Class JacksonConverterFactory

  • java.lang.Object
    • retrofit2.Converter.Factory
      • retrofit2.converter.jackson.JacksonConverterFactory


  • public final class JacksonConverterFactory
    extends retrofit2.Converter.Factory
    A converter which uses Jackson.

    Because Jackson is so flexible in the types it supports, this converter assumes that it can handle all types. If you are mixing JSON serialization with something else (such as protocol buffers), you must add this instance last to allow the other converters a chance to see their types.

    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static JacksonConverterFactory create()
      Create an instance using a default ObjectMapper instance for conversion.
      static JacksonConverterFactory create(com.fasterxml.jackson.databind.ObjectMapper mapper)
      Create an instance using mapper for conversion.
      static JacksonConverterFactory create(com.fasterxml.jackson.databind.ObjectMapper mapper, okhttp3.MediaType mediaType)
      Create an instance using mapper and mediaType for conversion.
      retrofit2.Converter<?,okhttp3.RequestBody> requestBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] parameterAnnotations, java.lang.annotation.Annotation[] methodAnnotations, retrofit2.Retrofit retrofit) 
      retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      JacksonConverterFactory withStreaming()
      Return a new factory which streams serialization of request messages to bytes on the HTTP thread This is either the calling thread for Call.execute(), or one of OkHttp's background threads for Call.enqueue(retrofit2.Callback<T>).
      • Methods inherited from class retrofit2.Converter.Factory

        getParameterUpperBound, getRawType, stringConverter
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • create

        public static JacksonConverterFactory create()
        Create an instance using a default ObjectMapper instance for conversion.
      • create

        public static JacksonConverterFactory create(com.fasterxml.jackson.databind.ObjectMapper mapper)
        Create an instance using mapper for conversion.
      • create

        public static JacksonConverterFactory create(com.fasterxml.jackson.databind.ObjectMapper mapper,
                                                     okhttp3.MediaType mediaType)
        Create an instance using mapper and mediaType for conversion.
      • withStreaming

        public JacksonConverterFactory withStreaming()
        Return a new factory which streams serialization of request messages to bytes on the HTTP thread This is either the calling thread for Call.execute(), or one of OkHttp's background threads for Call.enqueue(retrofit2.Callback<T>). Response bytes are always converted to message instances on one of OkHttp's background threads.
      • responseBodyConverter

        public retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type,
                                                                                 java.lang.annotation.Annotation[] annotations,
                                                                                 retrofit2.Retrofit retrofit)
        Overrides:
        responseBodyConverter in class retrofit2.Converter.Factory
      • requestBodyConverter

        public retrofit2.Converter<?,okhttp3.RequestBody> requestBodyConverter(java.lang.reflect.Type type,
                                                                               java.lang.annotation.Annotation[] parameterAnnotations,
                                                                               java.lang.annotation.Annotation[] methodAnnotations,
                                                                               retrofit2.Retrofit retrofit)
        Overrides:
        requestBodyConverter in class retrofit2.Converter.Factory
================================================ FILE: website/public/2.x/converter-jackson/retrofit2/converter/jackson/package-frame.html ================================================ retrofit2.converter.jackson (jackson API)

retrofit2.converter.jackson

================================================ FILE: website/public/2.x/converter-jackson/retrofit2/converter/jackson/package-summary.html ================================================ retrofit2.converter.jackson (jackson API)

@EverythingIsNonNull

Package retrofit2.converter.jackson

================================================ FILE: website/public/2.x/converter-jackson/retrofit2/converter/jackson/package-tree.html ================================================ retrofit2.converter.jackson Class Hierarchy (jackson API)

Hierarchy For Package retrofit2.converter.jackson

Class Hierarchy

================================================ FILE: website/public/2.x/converter-jackson/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/converter-jackson/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/converter-java8/allclasses-frame.html ================================================ All Classes (java8 API)

All Classes

================================================ FILE: website/public/2.x/converter-java8/allclasses-noframe.html ================================================ All Classes (java8 API)

All Classes

================================================ FILE: website/public/2.x/converter-java8/constant-values.html ================================================ Constant Field Values (java8 API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/converter-java8/deprecated-list.html ================================================ Deprecated List (java8 API)

Deprecated API

Contents

  • Deprecated Classes 
    Class and Description
    retrofit.converter.java8.Java8OptionalConverterFactory
    Retrofit includes support for Optional. This no longer needs to be added to the Retrofit instance explicitly.

    A converter for Optional<T> which delegates to another converter to deserialize T and then wraps it into Optional.

================================================ FILE: website/public/2.x/converter-java8/help-doc.html ================================================ API Help (java8 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/converter-java8/index-all.html ================================================ Index (java8 API)
C J R 

C

create() - Static method in class retrofit.converter.java8.Java8OptionalConverterFactory
Deprecated.
 

J

Java8OptionalConverterFactory - Class in retrofit.converter.java8
Deprecated.
Retrofit includes support for Optional. This no longer needs to be added to the Retrofit instance explicitly.

A converter for Optional<T> which delegates to another converter to deserialize T and then wraps it into Optional.

R

responseBodyConverter(Type, Annotation[], Retrofit) - Method in class retrofit.converter.java8.Java8OptionalConverterFactory
Deprecated.
 
retrofit.converter.java8 - package retrofit.converter.java8
 
C J R 
================================================ FILE: website/public/2.x/converter-java8/index.html ================================================ java8 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit/converter/java8/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/converter-java8/overview-tree.html ================================================ Class Hierarchy (java8 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

================================================ FILE: website/public/2.x/converter-java8/package-list ================================================ retrofit.converter.java8 ================================================ FILE: website/public/2.x/converter-java8/retrofit/converter/java8/Java8OptionalConverterFactory.html ================================================ Java8OptionalConverterFactory (java8 API)
retrofit.converter.java8

Class Java8OptionalConverterFactory

  • java.lang.Object
    • retrofit2.Converter.Factory
      • retrofit.converter.java8.Java8OptionalConverterFactory

  • Deprecated. 
    Retrofit includes support for Optional. This no longer needs to be added to the Retrofit instance explicitly.

    A converter for Optional<T> which delegates to another converter to deserialize T and then wraps it into Optional.


    @Deprecated
    public final class Java8OptionalConverterFactory
    extends retrofit2.Converter.Factory
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method and Description
      static Java8OptionalConverterFactory create()
      Deprecated. 
       
      retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit)
      Deprecated. 
       
      • Methods inherited from class retrofit2.Converter.Factory

        getParameterUpperBound, getRawType, requestBodyConverter, stringConverter
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • responseBodyConverter

        @Nullable
        public retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type,
                                                                                           java.lang.annotation.Annotation[] annotations,
                                                                                           retrofit2.Retrofit retrofit)
        Deprecated. 
        Overrides:
        responseBodyConverter in class retrofit2.Converter.Factory
================================================ FILE: website/public/2.x/converter-java8/retrofit/converter/java8/package-frame.html ================================================ retrofit.converter.java8 (java8 API)

retrofit.converter.java8

================================================ FILE: website/public/2.x/converter-java8/retrofit/converter/java8/package-summary.html ================================================ retrofit.converter.java8 (java8 API)

@EverythingIsNonNull

Package retrofit.converter.java8

================================================ FILE: website/public/2.x/converter-java8/retrofit/converter/java8/package-tree.html ================================================ retrofit.converter.java8 Class Hierarchy (java8 API)

Hierarchy For Package retrofit.converter.java8

Class Hierarchy

================================================ FILE: website/public/2.x/converter-java8/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/converter-java8/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/converter-jaxb/allclasses-frame.html ================================================ All Classes (jaxb API)

All Classes

================================================ FILE: website/public/2.x/converter-jaxb/allclasses-noframe.html ================================================ All Classes (jaxb API)

All Classes

================================================ FILE: website/public/2.x/converter-jaxb/constant-values.html ================================================ Constant Field Values (jaxb API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/converter-jaxb/deprecated-list.html ================================================ Deprecated List (jaxb API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/converter-jaxb/help-doc.html ================================================ API Help (jaxb API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/converter-jaxb/index-all.html ================================================ Index (jaxb API)
C J R 

C

create() - Static method in class retrofit2.converter.jaxb.JaxbConverterFactory
Create an instance using a default JAXBContext instance for conversion.
create(JAXBContext) - Static method in class retrofit2.converter.jaxb.JaxbConverterFactory
Create an instance using context for conversion.

J

JaxbConverterFactory - Class in retrofit2.converter.jaxb
A converter which uses JAXB for XML.

R

requestBodyConverter(Type, Annotation[], Annotation[], Retrofit) - Method in class retrofit2.converter.jaxb.JaxbConverterFactory
 
responseBodyConverter(Type, Annotation[], Retrofit) - Method in class retrofit2.converter.jaxb.JaxbConverterFactory
 
retrofit2.converter.jaxb - package retrofit2.converter.jaxb
 
C J R 
================================================ FILE: website/public/2.x/converter-jaxb/index.html ================================================ jaxb API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/converter/jaxb/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/converter-jaxb/overview-tree.html ================================================ Class Hierarchy (jaxb API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

================================================ FILE: website/public/2.x/converter-jaxb/package-list ================================================ retrofit2.converter.jaxb ================================================ FILE: website/public/2.x/converter-jaxb/retrofit2/converter/jaxb/JaxbConverterFactory.html ================================================ JaxbConverterFactory (jaxb API)
retrofit2.converter.jaxb

Class JaxbConverterFactory

  • java.lang.Object
    • retrofit2.Converter.Factory
      • retrofit2.converter.jaxb.JaxbConverterFactory


  • public final class JaxbConverterFactory
    extends retrofit2.Converter.Factory
    A converter which uses JAXB for XML. All validation events are ignored.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static JaxbConverterFactory create()
      Create an instance using a default JAXBContext instance for conversion.
      static JaxbConverterFactory create(javax.xml.bind.JAXBContext context)
      Create an instance using context for conversion.
      retrofit2.Converter<?,okhttp3.RequestBody> requestBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] parameterAnnotations, java.lang.annotation.Annotation[] methodAnnotations, retrofit2.Retrofit retrofit) 
      retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      • Methods inherited from class retrofit2.Converter.Factory

        getParameterUpperBound, getRawType, stringConverter
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • create

        public static JaxbConverterFactory create()
        Create an instance using a default JAXBContext instance for conversion.
      • create

        public static JaxbConverterFactory create(javax.xml.bind.JAXBContext context)
        Create an instance using context for conversion.
      • requestBodyConverter

        @Nullable
        public retrofit2.Converter<?,okhttp3.RequestBody> requestBodyConverter(java.lang.reflect.Type type,
                                                                                         java.lang.annotation.Annotation[] parameterAnnotations,
                                                                                         java.lang.annotation.Annotation[] methodAnnotations,
                                                                                         retrofit2.Retrofit retrofit)
        Overrides:
        requestBodyConverter in class retrofit2.Converter.Factory
      • responseBodyConverter

        @Nullable
        public retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type,
                                                                                           java.lang.annotation.Annotation[] annotations,
                                                                                           retrofit2.Retrofit retrofit)
        Overrides:
        responseBodyConverter in class retrofit2.Converter.Factory
================================================ FILE: website/public/2.x/converter-jaxb/retrofit2/converter/jaxb/package-frame.html ================================================ retrofit2.converter.jaxb (jaxb API)

retrofit2.converter.jaxb

================================================ FILE: website/public/2.x/converter-jaxb/retrofit2/converter/jaxb/package-summary.html ================================================ retrofit2.converter.jaxb (jaxb API)

@EverythingIsNonNull

Package retrofit2.converter.jaxb

================================================ FILE: website/public/2.x/converter-jaxb/retrofit2/converter/jaxb/package-tree.html ================================================ retrofit2.converter.jaxb Class Hierarchy (jaxb API)

Hierarchy For Package retrofit2.converter.jaxb

Class Hierarchy

================================================ FILE: website/public/2.x/converter-jaxb/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/converter-jaxb/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/converter-jaxb3/allclasses-frame.html ================================================ All Classes (jaxb3 API)

All Classes

================================================ FILE: website/public/2.x/converter-jaxb3/allclasses-noframe.html ================================================ All Classes (jaxb3 API)

All Classes

================================================ FILE: website/public/2.x/converter-jaxb3/constant-values.html ================================================ Constant Field Values (jaxb3 API)

Constant Field Values

Contents

================================================ FILE: website/public/2.x/converter-jaxb3/deprecated-list.html ================================================ Deprecated List (jaxb3 API)

Deprecated API

Contents

================================================ FILE: website/public/2.x/converter-jaxb3/help-doc.html ================================================ API Help (jaxb3 API)

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
  • Package

    Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

    • Interfaces (italic)
    • Classes
    • Enums
    • Exceptions
    • Errors
    • Annotation Types
  • Class/Interface

    Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

    • Class inheritance diagram
    • Direct Subclasses
    • All Known Subinterfaces
    • All Known Implementing Classes
    • Class/interface declaration
    • Class/interface description
    • Nested Class Summary
    • Field Summary
    • Constructor Summary
    • Method Summary
    • Field Detail
    • Constructor Detail
    • Method Detail

    Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

  • Annotation Type

    Each annotation type has its own separate page with the following sections:

    • Annotation Type declaration
    • Annotation Type description
    • Required Element Summary
    • Optional Element Summary
    • Element Detail
  • Enum

    Each enum has its own separate page with the following sections:

    • Enum declaration
    • Enum description
    • Enum Constant Summary
    • Enum Constant Detail
  • Tree (Class Hierarchy)

    There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.

    • When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
    • When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
  • Deprecated API

    The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

  • Index

    The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

  • Prev/Next

    These links take you to the next or previous class, interface, package, or related page.

  • Frames/No Frames

    These links show and hide the HTML frames. All pages are available with or without frames.

  • All Classes

    The All Classes link shows all classes and interfaces except non-static nested types.

  • Serialized Form

    Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

  • Constant Field Values

    The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.
================================================ FILE: website/public/2.x/converter-jaxb3/index-all.html ================================================ Index (jaxb3 API)
C J R 

C

create() - Static method in class retrofit2.converter.jaxb3.JaxbConverterFactory
Create an instance using a default JAXBContext instance for conversion.
create(JAXBContext) - Static method in class retrofit2.converter.jaxb3.JaxbConverterFactory
Create an instance using context for conversion.

J

JaxbConverterFactory - Class in retrofit2.converter.jaxb3
A converter which uses JAXB for XML.

R

requestBodyConverter(Type, Annotation[], Annotation[], Retrofit) - Method in class retrofit2.converter.jaxb3.JaxbConverterFactory
 
responseBodyConverter(Type, Annotation[], Retrofit) - Method in class retrofit2.converter.jaxb3.JaxbConverterFactory
 
retrofit2.converter.jaxb3 - package retrofit2.converter.jaxb3
 
C J R 
================================================ FILE: website/public/2.x/converter-jaxb3/index.html ================================================ jaxb3 API <noscript> <div>JavaScript is disabled on your browser.</div> </noscript> <h2>Frame Alert</h2> <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="retrofit2/converter/jaxb3/package-summary.html">Non-frame version</a>.</p> ================================================ FILE: website/public/2.x/converter-jaxb3/overview-tree.html ================================================ Class Hierarchy (jaxb3 API)

Hierarchy For All Packages

Package Hierarchies:

Class Hierarchy

================================================ FILE: website/public/2.x/converter-jaxb3/package-list ================================================ retrofit2.converter.jaxb3 ================================================ FILE: website/public/2.x/converter-jaxb3/retrofit2/converter/jaxb3/JaxbConverterFactory.html ================================================ JaxbConverterFactory (jaxb3 API)
retrofit2.converter.jaxb3

Class JaxbConverterFactory

  • java.lang.Object
    • retrofit2.Converter.Factory
      • retrofit2.converter.jaxb3.JaxbConverterFactory


  • public final class JaxbConverterFactory
    extends retrofit2.Converter.Factory
    A converter which uses JAXB for XML. All validation events are ignored.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      static JaxbConverterFactory create()
      Create an instance using a default JAXBContext instance for conversion.
      static JaxbConverterFactory create(jakarta.xml.bind.JAXBContext context)
      Create an instance using context for conversion.
      retrofit2.Converter<?,okhttp3.RequestBody> requestBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] parameterAnnotations, java.lang.annotation.Annotation[] methodAnnotations, retrofit2.Retrofit retrofit) 
      retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type, java.lang.annotation.Annotation[] annotations, retrofit2.Retrofit retrofit) 
      • Methods inherited from class retrofit2.Converter.Factory

        getParameterUpperBound, getRawType, stringConverter
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • create

        public static JaxbConverterFactory create()
        Create an instance using a default JAXBContext instance for conversion.
      • create

        public static JaxbConverterFactory create(jakarta.xml.bind.JAXBContext context)
        Create an instance using context for conversion.
      • requestBodyConverter

        @Nullable
        public retrofit2.Converter<?,okhttp3.RequestBody> requestBodyConverter(java.lang.reflect.Type type,
                                                                                         java.lang.annotation.Annotation[] parameterAnnotations,
                                                                                         java.lang.annotation.Annotation[] methodAnnotations,
                                                                                         retrofit2.Retrofit retrofit)
        Overrides:
        requestBodyConverter in class retrofit2.Converter.Factory
      • responseBodyConverter

        @Nullable
        public retrofit2.Converter<okhttp3.ResponseBody,?> responseBodyConverter(java.lang.reflect.Type type,
                                                                                           java.lang.annotation.Annotation[] annotations,
                                                                                           retrofit2.Retrofit retrofit)
        Overrides:
        responseBodyConverter in class retrofit2.Converter.Factory
================================================ FILE: website/public/2.x/converter-jaxb3/retrofit2/converter/jaxb3/package-frame.html ================================================ retrofit2.converter.jaxb3 (jaxb3 API)

retrofit2.converter.jaxb3

================================================ FILE: website/public/2.x/converter-jaxb3/retrofit2/converter/jaxb3/package-summary.html ================================================ retrofit2.converter.jaxb3 (jaxb3 API)

@EverythingIsNonNull

Package retrofit2.converter.jaxb3

================================================ FILE: website/public/2.x/converter-jaxb3/retrofit2/converter/jaxb3/package-tree.html ================================================ retrofit2.converter.jaxb3 Class Hierarchy (jaxb3 API)

Hierarchy For Package retrofit2.converter.jaxb3

Class Hierarchy

================================================ FILE: website/public/2.x/converter-jaxb3/script.js ================================================ function show(type) { count = 0; for (var key in methods) { var row = document.getElementById(key); if ((methods[key] & type) != 0) { row.style.display = ''; row.className = (count++ % 2) ? rowColor : altColor; } else row.style.display = 'none'; } updateTabs(type); } function updateTabs(type) { for (var value in tabs) { var sNode = document.getElementById(tabs[value][0]); var spanNode = sNode.firstChild; if (value == type) { sNode.className = activeTableTab; spanNode.innerHTML = tabs[value][1]; } else { sNode.className = tableTab; spanNode.innerHTML = "" + tabs[value][1] + ""; } } } ================================================ FILE: website/public/2.x/converter-jaxb3/stylesheet.css ================================================ /* Javadoc style sheet */ /* Overall document style */ @import url('resources/fonts/dejavu.css'); body { background-color:#ffffff; color:#353833; font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; font-size:14px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family:'DejaVu Sans Mono', monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family:'DejaVu Sans Mono', monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family:'DejaVu Sans Mono',monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .useSummary td.colFirst, .useSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } ================================================ FILE: website/public/2.x/converter-kotlinx-serialization/index.html ================================================ kotlinx-serialization

kotlinx-serialization

Packages

================================================ FILE: website/public/2.x/converter-kotlinx-serialization/kotlinx-serialization/package-list ================================================ $dokka.format:html-v1 $dokka.linkExtension:html $dokka.location:retrofit2.converter.kotlinx.serialization////PointingToDeclaration/kotlinx-serialization/retrofit2.converter.kotlinx.serialization/index.html $dokka.location:retrofit2.converter.kotlinx.serialization//asConverterFactory/kotlinx.serialization.BinaryFormat#okhttp3.MediaType/PointingToDeclaration/kotlinx-serialization/retrofit2.converter.kotlinx.serialization/as-converter-factory.html $dokka.location:retrofit2.converter.kotlinx.serialization//asConverterFactory/kotlinx.serialization.StringFormat#okhttp3.MediaType/PointingToDeclaration/kotlinx-serialization/retrofit2.converter.kotlinx.serialization/as-converter-factory.html retrofit2.converter.kotlinx.serialization ================================================ FILE: website/public/2.x/converter-kotlinx-serialization/kotlinx-serialization/retrofit2.converter.kotlinx.serialization/as-converter-factory.html ================================================ asConverterFactory

asConverterFactory

@JvmName(name = "create")
fun StringFormat.asConverterFactory(contentType: MediaType): Converter.Factory

Return a Converter.Factory which uses Kotlin serialization for string-based payloads.

Because Kotlin serialization is so flexible in the types it supports, this converter assumes that it can handle all types. If you are mixing this with something else, you must add this instance last to allow the other converters a chance to see their types.


@JvmName(name = "create")
fun BinaryFormat.asConverterFactory(contentType: MediaType): Converter.Factory

Return a Converter.Factory which uses Kotlin serialization for byte-based payloads.

Because Kotlin serialization is so flexible in the types it supports, this converter assumes that it can handle all types. If you are mixing this with something else, you must add this instance last to allow the other converters a chance to see their types.

================================================ FILE: website/public/2.x/converter-kotlinx-serialization/kotlinx-serialization/retrofit2.converter.kotlinx.serialization/index.html ================================================ retrofit2.converter.kotlinx.serialization

Package-level declarations

Functions

Link copied to clipboard
@JvmName(name = "create")
fun BinaryFormat.asConverterFactory(contentType: MediaType): Converter.Factory

Return a Converter.Factory which uses Kotlin serialization for byte-based payloads.

@JvmName(name = "create")
fun StringFormat.asConverterFactory(contentType: MediaType): Converter.Factory

Return a Converter.Factory which uses Kotlin serialization for string-based payloads.

================================================ FILE: website/public/2.x/converter-kotlinx-serialization/navigation.html ================================================ ================================================ FILE: website/public/2.x/converter-kotlinx-serialization/scripts/clipboard.js ================================================ /* * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ window.addEventListener('load', () => { document.querySelectorAll('span.copy-icon').forEach(element => { element.addEventListener('click', (el) => copyElementsContentToClipboard(element)); }) document.querySelectorAll('span.anchor-icon').forEach(element => { element.addEventListener('click', (el) => { if(element.hasAttribute('pointing-to')){ const location = hrefWithoutCurrentlyUsedAnchor() + '#' + element.getAttribute('pointing-to') copyTextToClipboard(element, location) } }); }) }) const copyElementsContentToClipboard = (element) => { const selection = window.getSelection(); const range = document.createRange(); range.selectNodeContents(element.parentNode.parentNode); selection.removeAllRanges(); selection.addRange(range); copyAndShowPopup(element, () => selection.removeAllRanges()) } const copyTextToClipboard = (element, text) => { var textarea = document.createElement("textarea"); textarea.textContent = text; textarea.style.position = "fixed"; document.body.appendChild(textarea); textarea.select(); copyAndShowPopup(element, () => document.body.removeChild(textarea)) } const copyAndShowPopup = (element, after) => { try { document.execCommand('copy'); element.nextElementSibling.classList.add('active-popup'); setTimeout(() => { element.nextElementSibling.classList.remove('active-popup'); }, 1200); } catch (e) { console.error('Failed to write to clipboard:', e) } finally { if(after) after() } } const hrefWithoutCurrentlyUsedAnchor = () => window.location.href.split('#')[0] ================================================ FILE: website/public/2.x/converter-kotlinx-serialization/scripts/main.js ================================================ (()=>{var e={1817:e=>{e.exports=''},4811:e=>{e.exports=''},5742:e=>{e.exports=''},7112:e=>{e.exports=''},8420:e=>{e.exports=''},7004:e=>{e.exports=''},7222:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,'.avatar_d716 {\n display: inline-block;\n -o-object-fit: cover;\n object-fit: cover;\n -o-object-position: center;\n object-position: center;\n\n /* This is a "graceful degradation" fallback, while the real value is controlled by JS */\n\n border-radius: var(--ring-border-radius);\n}\n\n.subavatar_b10d {\n position: absolute;\n top: 15px;\n left: 27px;\n\n border: 1px var(--ring-content-background-color) solid;\n}\n\n.empty_a151 {\n display: inline-block;\n\n box-sizing: border-box;\n\n border: 1px solid var(--ring-borders-color);\n}\n',"",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/avatar/avatar.css"],names:[],mappings:"AAEA;EACE,qBAAqB;EACrB,oBAAiB;KAAjB,iBAAiB;EACjB,0BAAuB;KAAvB,uBAAuB;;EAEvB,wFAAwF;;EAExF,wCAAwC;AAC1C;;AAEA;EACE,kBAAkB;EAClB,SAAS;EACT,UAAU;;EAEV,sDAAsD;AACxD;;AAEA;EACE,qBAAqB;;EAErB,sBAAsB;;EAEtB,2CAA2C;AAC7C",sourcesContent:['@import "../global/variables.css";\n\n.avatar {\n display: inline-block;\n object-fit: cover;\n object-position: center;\n\n /* This is a "graceful degradation" fallback, while the real value is controlled by JS */\n\n border-radius: var(--ring-border-radius);\n}\n\n.subavatar {\n position: absolute;\n top: 15px;\n left: 27px;\n\n border: 1px var(--ring-content-background-color) solid;\n}\n\n.empty {\n display: inline-block;\n\n box-sizing: border-box;\n\n border: 1px solid var(--ring-borders-color);\n}\n'],sourceRoot:""}]),c.locals={avatar:"avatar_d716",subavatar:"subavatar_b10d",empty:"empty_a151"};const u=c},9892:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=a()(o());u.i(c.A),u.i(l.default,"",!0),u.push([e.id,'.heightS_b28d {\n --ring-button-height: 24px;\n --ring-button-font-size: var(--ring-font-size-smaller);\n}\n\n.heightM_dfd3 {\n --ring-button-height: 28px;\n --ring-button-font-size: var(--ring-font-size);\n}\n\n.heightL_a4d3 {\n --ring-button-height: 32px;\n --ring-button-font-size: var(--ring-font-size);\n}\n\n.button_aba4 {\n position: relative;\n\n display: inline-block;\n\n box-sizing: border-box;\n height: var(--ring-button-height);\n margin: 0;\n padding: 0 16px;\n\n cursor: pointer;\n transition: color var(--ring-ease), background-color var(--ring-ease), box-shadow var(--ring-ease);\n text-decoration: none;\n\n color: var(--ring-text-color);\n\n border: 0;\n border-radius: var(--ring-border-radius);\n outline: 0;\n background-color: var(--ring-content-background-color);\n box-shadow: inset 0 0 0 1px var(--ring-borders-color);\n\n font-family: var(--ring-font-family);\n font-size: var(--ring-button-font-size);\n\n line-height: var(--ring-button-height);\n}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.button_aba4:hover {\n transition: none;\n\n box-shadow: inset 0 0 0 1px var(--ring-border-hover-color);\n }}\n\n.button_aba4:active {\n transition: none;\n\n background-color: var(--ring-selected-background-color);\n box-shadow: inset 0 0 0 1px var(--ring-border-hover-color);\n }\n\n.button_aba4:focus-visible {\n transition: none;\n\n box-shadow: inset 0 0 0 1px var(--ring-border-hover-color), 0 0 0 1px var(--ring-border-hover-color);\n }\n\n.button_aba4.active_bbe6 {\n transition: none;\n\n background-color: var(--ring-hover-background-color);\n box-shadow: inset 0 0 0 1px var(--ring-main-color);\n }\n\n.button_aba4.active_bbe6:focus-visible {\n box-shadow: inset 0 0 0 2px var(--ring-main-color), 0 0 0 1px var(--ring-border-hover-color);\n }\n\n.button_aba4[disabled] {\n pointer-events: none;\n\n background-color: var(--ring-disabled-background-color);\n box-shadow: inset 0 0 0 1px var(--ring-border-disabled-color);\n }\n\n.button_aba4.active_bbe6[disabled] {\n background-color: var(--ring-disabled-selected-background-color);\n box-shadow: inset 0 0 0 1px var(--ring-border-selected-disabled-color);\n }\n\n.button_aba4[disabled],\n .button_aba4.withIcon_ef77[disabled] {\n color: var(--ring-disabled-color);\n }\n\n.button_aba4[disabled] .icon_e878 {\n color: var(--ring-icon-disabled-color);\n }\n\n.button_aba4::-moz-focus-inner {\n padding: 0;\n\n border: 0;\n outline: 0;\n }\n\n.withIcon_ef77 {\n color: var(--ring-secondary-color);\n}\n\n.primary_ddae {\n color: var(--ring-white-text-color);\n background-color: var(--ring-main-color);\n box-shadow: none;\n}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.primary_ddae:hover {\n transition: none;\n\n background-color: var(--ring-main-hover-color);\n box-shadow: none;\n }}\n\n.primary_ddae.withIcon_ef77,\n .primary_ddae.withIcon_ef77:active,\n .primary_ddae.withIcon_ef77.active_bbe6 {\n color: var(--ring-action-link-color);\n }\n\n.primary_ddae:focus-visible,\n .primary_ddae:active,\n .primary_ddae.active_bbe6 {\n background-color: var(--ring-button-primary-background-color);\n }\n\n.primary_ddae:active,\n .primary_ddae.active_bbe6 {\n box-shadow: inset 0 0 0 1px var(--ring-button-primary-border-color);\n }\n\n.primary_ddae[disabled] {\n background-color: var(--ring-disabled-background-color);\n box-shadow: inset 0 0 0 1px var(--ring-border-disabled-color);\n }\n\n.primary_ddae.loader_cbfc[disabled] {\n color: var(--ring-white-text-color);\n }\n\n.primary_ddae .loaderBackground_d9f5 {\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n\n border-radius: var(--ring-border-radius);\n }\n\n.primary_ddae .loaderBackground_d9f5::before {\n background-image:\n linear-gradient(\n to right,\n var(--ring-main-color),\n var(--ring-button-loader-background) 40%,\n var(--ring-main-color) 80%\n );\n }\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.danger_bcea:hover {\n transition: none;\n }}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.danger_bcea:hover {\n box-shadow: inset 0 0 0 1px var(--ring-button-danger-hover-color);\n }}\n\n.danger_bcea,\n .danger_bcea.withIcon_ef77,\n .danger_bcea.withIcon_ef77:active,\n .danger_bcea.withIcon_ef77.active_bbe6,\n .danger_bcea.text_fc2a,\n .danger_bcea.text_fc2a:active,\n .danger_bcea.text_fc2a.active_bbe6 {\n color: var(--ring-error-color);\n }\n\n.danger_bcea:active,\n .danger_bcea.active_bbe6 {\n background-color: var(--ring-button-danger-active-color);\n }\n\n.danger_bcea:active,\n .danger_bcea.active_bbe6,\n .danger_bcea:focus-visible {\n box-shadow: inset 0 0 0 1px var(--ring-button-danger-hover-color);\n }\n\n.danger_bcea:focus-visible {\n transition: none;\n }\n\n.text_fc2a.text_fc2a,\n.withIcon_ef77.withIcon_ef77 {\n background-color: transparent;\n box-shadow: none;\n}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.text_fc2a.text_fc2a:hover, .withIcon_ef77.withIcon_ef77:hover {\n transition: none;\n }}\n\n.text_fc2a.text_fc2a:active,\n .withIcon_ef77.withIcon_ef77:active,\n .text_fc2a.text_fc2a.active_bbe6,\n .withIcon_ef77.withIcon_ef77.active_bbe6 {\n background-color: transparent;\n box-shadow: none;\n }\n\n.text_fc2a.text_fc2a:focus-visible, .withIcon_ef77.withIcon_ef77:focus-visible {\n box-shadow: inset 0 0 0 2px var(--ring-border-hover-color);\n }\n\n.loader_cbfc.text_fc2a > .content_b2b8 {\n animation-name: text-loading_d1b4;\n animation-duration: 1200ms;\n animation-iteration-count: infinite;\n}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.text_fc2a.text_fc2a:hover {\n background-color: transparent;\n box-shadow: none;\n}}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.withIcon_ef77:hover:not(:focus-visible) {\n background-color: transparent;\n box-shadow: none;\n}}\n\n.text_fc2a {\n color: var(--ring-action-link-color);\n}\n\n.inline_b4a2 {\n display: inline-block;\n\n margin: 0;\n padding: 0;\n\n font-size: var(--ring-font-size);\n}\n\n.withIcon_ef77 {\n padding: 0 8px;\n}\n\n.text_fc2a:active,\n .text_fc2a.active_bbe6 {\n color: var(--ring-link-hover-color);\n }\n\n.withIcon_ef77:active,\n .withIcon_ef77.active_bbe6 {\n color: var(--ring-action-link-color);\n }\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.withIcon_ef77:hover {\n color: var(--ring-link-hover-color);\n}}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.text_fc2a:hover {\n color: var(--ring-link-hover-color);\n}}\n\n.icon_e878 {\n color: inherit;\n\n line-height: normal;\n}\n\n.icon_e878:not(:last-child) {\n margin-right: 4px;\n }\n\n.withNormalIcon_aaca .icon_e878 {\n transition: color var(--ring-ease);\n\n color: var(--ring-icon-color);\n}\n\n.withNormalIcon_aaca:active,\n.withNormalIcon_aaca.active_bbe6 {\n color: var(--ring-main-color);\n}\n\n.withNormalIcon_aaca:active .icon_e878, .withNormalIcon_aaca.active_bbe6 .icon_e878 {\n transition: none;\n\n color: inherit;\n }\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.withNormalIcon_aaca:hover .icon_e878,\n.withDangerIcon_e3ca:hover .icon_e878 {\n transition: none;\n\n color: inherit;\n}}\n\n.withDangerIcon_e3ca .icon_e878,\n.withDangerIcon_e3ca:active .icon_e878 {\n color: var(--ring-icon-error-color);\n}\n\n.loader_cbfc {\n position: relative;\n z-index: 0;\n\n pointer-events: none;\n\n background-color: transparent;\n}\n\n.loaderBackground_d9f5 {\n position: absolute;\n z-index: -1;\n top: 1px;\n right: 1px;\n bottom: 1px;\n left: 1px;\n\n overflow: hidden;\n\n border-radius: var(--ring-border-radius-small);\n}\n\n.loaderBackground_d9f5::before {\n display: block;\n\n width: calc(100% + 64px);\n height: 100%;\n\n content: "";\n animation: progress_ed8f 1s linear infinite;\n\n background-image:\n linear-gradient(\n to right,\n var(--ring-content-background-color),\n var(--ring-selected-background-color) 40%,\n var(--ring-content-background-color) 80%\n );\n\n background-repeat: repeat;\n background-size: 64px;\n }\n\n.delayed_d562 .content_b2b8::after {\n content: "…";\n}\n\n.short_a07a {\n width: 32px;\n padding: 0;\n}\n\n.dropdownIcon_e982 {\n margin-right: -2px;\n\n margin-left: 2px;\n\n transition: color var(--ring-ease);\n\n color: var(--ring-icon-secondary-color);\n\n line-height: normal;\n}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.button_aba4:hover .dropdownIcon_e982 {\n transition: none;\n\n color: var(--ring-main-color);\n}}\n\n@keyframes progress_ed8f {\n from {\n transform: translateX(-64px);\n }\n\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes text-loading_d1b4 {\n 50% {\n opacity: 0.5;\n }\n}\n',"",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/button/button.css",""],names:[],mappings:"AAOA;EACE,0BAAoC;EACpC,sDAAsD;AACxD;;AAEA;EACE,0BAAsC;EACtC,8CAA8C;AAChD;;AAEA;EACE,0BAAoC;EACpC,8CAA8C;AAChD;;AAEA;EACE,kBAAkB;;EAElB,qBAAqB;;EAErB,sBAAsB;EACtB,iCAAc;EACd,SAAS;EACT,eAAyB;;EAEzB,eAAe;EACf,kGAAkG;EAClG,qBAAqB;;EAErB,6BAA6B;;EAE7B,SAAS;EACT,wCAAwC;EACxC,UAAU;EACV,sDAAsD;EACtD,qDAAmD;;EAEnD,oCAAoC;EACpC,uCAAuC;;EAEvC,sCAAmB;AA2DrB;;AC1GA,wGAAA;IAAA,iBAAA;;IAAA,2DAAA;GAAA,CAAA;;ADuDE;IACE,gBAAgB;;IAEhB,uDAAuD;IACvD,0DAAwD;EAC1D;;AAEA;IACE,gBAAgB;;IAEhB,oGAAkG;EACpG;;AAEA;IACE,gBAAgB;;IAEhB,oDAAoD;IACpD,kDAAgD;EAClD;;AAEA;IACE,4FAA4F;EAC9F;;AAEA;IACE,oBAAoB;;IAEpB,uDAAuD;IACvD,6DAA2D;EAC7D;;AAEA;IACE,gEAAgE;IAChE,sEAAoE;EACtE;;AAEA;;IAEE,iCAAiC;EACnC;;AAEA;IACE,sCAAsC;EACxC;;AAEA;IACE,UAAU;;IAEV,SAAS;IACT,UAAU;EACZ;;AAGF;EACE,kCAAkC;AACpC;;AAEA;EACE,mCAAmC;EACnC,wCAAwC;EACxC,gBAAgB;AAqDlB;;ACxKA,wGAAA;IAAA,iBAAA;;IAAA,+CAAA;IAAA,iBAAA;GAAA,CAAA;;AD4HE;;;IAGE,oCAAoC;EACtC;;AAEA;;;IAGE,6DAA6D;EAC/D;;AAEA;;IAEE,mEAAiE;EACnE;;AAEA;IACE,uDAAuD;IACvD,6DAA2D;EAC7D;;AAEA;IACE,mCAAmC;EACrC;;AAEA;IACE,MAAM;IACN,QAAQ;IACR,SAAS;IACT,OAAO;;IAEP,wCAAwC;EAW1C;;AATE;MACE;;;;;;SAMG;IACL;;ACtKJ,wGAAA;IAAA,iBAAA;GAAA,CAAA;;AAAA,wGAAA;IAAA,kEAAA;GAAA,CAAA;;AD2KE;;;;;;;IAOE,8BAA8B;EAChC;;AAEA;;IAEE,wDAAwD;EAC1D;;AAEA;;;IAIE,iEAA+D;EACjE;;AAEA;IAEE,gBAAgB;EAClB;;AAGF;;EAEE,6BAA6B;EAC7B,gBAAgB;AAelB;;ACzNA,wGAAA;IAAA,iBAAA;GAAA,CAAA;;ADgNE;;;;IAEE,6BAA6B;IAC7B,gBAAgB;EAClB;;AAEA;IACE,0DAA0D;EAC5D;;AAGF;EACE,iCAA4B;EAC5B,0BAA0B;EAC1B,mCAAmC;AACrC;;AC/NA,wGAAA;EAAA,8BAAA;EAAA,iBAAA;CAAA,CAAA;;AAAA,wGAAA;EAAA,8BAAA;EAAA,iBAAA;CAAA,CAAA;;AD2OA;EACE,oCAAoC;AACtC;;AAEA;EACE,qBAAqB;;EAErB,SAAS;EACT,UAAU;;EAEV,gCAAgC;AAClC;;AAEA;EACE,cAAe;AACjB;;AAGE;;IAEE,mCAAmC;EACrC;;AAIA;;IAEE,oCAAoC;EACtC;;ACvQF,wGAAA;EAAA,oCAAA;CAAA,CAAA;;AAAA,wGAAA;EAAA,oCAAA;CAAA,CAAA;;ADkRA;EACE,cAAc;;EAEd,mBAAmB;AAKrB;;AAHE;IACE,iBAA8B;EAChC;;AAGF;EACE,kCAAkC;;EAElC,6BAA6B;AAC/B;;AAEA;;EAEE,6BAA6B;AAO/B;;AALE;IACE,gBAAgB;;IAEhB,cAAc;EAChB;;AC1SF,wGAAA;;EAAA,iBAAA;;EAAA,eAAA;CAAA,CAAA;;ADoTA;;EAEE,mCAAmC;AACrC;;AAEA;EACE,kBAAkB;EAClB,UAAU;;EAEV,oBAAoB;;EAEpB,6BAA6B;AAC/B;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,QAAQ;EACR,UAAU;EACV,WAAW;EACX,SAAS;;EAET,gBAAgB;;EAEhB,8CAA8C;AAsBhD;;AApBE;IACE,cAAc;;IAEd,wBAA+B;IAC/B,YAAY;;IAEZ,WAAW;IACX,2CAAsC;;IAEtC;;;;;;OAMG;;IAEH,yBAAyB;IACzB,qBAA4B;EAC9B;;AAGF;EACE,YAAY;AACd;;AAEA;EACE,WAAqB;EACrB,UAAU;AACZ;;AAEA;EACE,kBAAkB;;EAElB,gBAAgB;;EAEhB,kCAAkC;;EAElC,uCAAuC;;EAEvC,mBAAmB;AACrB;;ACvXA,wGAAA;EAAA,iBAAA;;EAAA,8BAAA;CAAA,CAAA;;AD+XA;EACE;IACE,4BAA4C;EAC9C;;EAEA;IACE,wBAAwB;EAC1B;AACF;;AAEA;EACE;IACE,YAAY;EACd;AACF",sourcesContent:['@import "../global/variables.css";\n\n@value unit from "../global/global.css";\n@value button-shadow: inset 0 0 0 1px;\n@value height: var(--ring-button-height);\n@value loaderWidth: calc(unit * 8);\n\n.heightS {\n --ring-button-height: calc(unit * 3);\n --ring-button-font-size: var(--ring-font-size-smaller);\n}\n\n.heightM {\n --ring-button-height: calc(unit * 3.5);\n --ring-button-font-size: var(--ring-font-size);\n}\n\n.heightL {\n --ring-button-height: calc(unit * 4);\n --ring-button-font-size: var(--ring-font-size);\n}\n\n.button {\n position: relative;\n\n display: inline-block;\n\n box-sizing: border-box;\n height: height;\n margin: 0;\n padding: 0 calc(unit * 2);\n\n cursor: pointer;\n transition: color var(--ring-ease), background-color var(--ring-ease), box-shadow var(--ring-ease);\n text-decoration: none;\n\n color: var(--ring-text-color);\n\n border: 0;\n border-radius: var(--ring-border-radius);\n outline: 0;\n background-color: var(--ring-content-background-color);\n box-shadow: button-shadow var(--ring-borders-color);\n\n font-family: var(--ring-font-family);\n font-size: var(--ring-button-font-size);\n\n line-height: height;\n\n &:hover {\n transition: none;\n\n box-shadow: button-shadow var(--ring-border-hover-color);\n }\n\n &:active {\n transition: none;\n\n background-color: var(--ring-selected-background-color);\n box-shadow: button-shadow var(--ring-border-hover-color);\n }\n\n &:focus-visible {\n transition: none;\n\n box-shadow: button-shadow var(--ring-border-hover-color), 0 0 0 1px var(--ring-border-hover-color);\n }\n\n &.active {\n transition: none;\n\n background-color: var(--ring-hover-background-color);\n box-shadow: button-shadow var(--ring-main-color);\n }\n\n &:focus-visible.active {\n box-shadow: inset 0 0 0 2px var(--ring-main-color), 0 0 0 1px var(--ring-border-hover-color);\n }\n\n &[disabled] {\n pointer-events: none;\n\n background-color: var(--ring-disabled-background-color);\n box-shadow: button-shadow var(--ring-border-disabled-color);\n }\n\n &[disabled].active {\n background-color: var(--ring-disabled-selected-background-color);\n box-shadow: button-shadow var(--ring-border-selected-disabled-color);\n }\n\n &[disabled],\n &[disabled].withIcon {\n color: var(--ring-disabled-color);\n }\n\n &[disabled] .icon {\n color: var(--ring-icon-disabled-color);\n }\n\n &::-moz-focus-inner {\n padding: 0;\n\n border: 0;\n outline: 0;\n }\n}\n\n.withIcon {\n color: var(--ring-secondary-color);\n}\n\n.primary {\n color: var(--ring-white-text-color);\n background-color: var(--ring-main-color);\n box-shadow: none;\n\n &:hover {\n transition: none;\n\n background-color: var(--ring-main-hover-color);\n box-shadow: none;\n }\n\n &.withIcon,\n &.withIcon:active,\n &.withIcon.active {\n color: var(--ring-action-link-color);\n }\n\n &:focus-visible,\n &:active,\n &.active {\n background-color: var(--ring-button-primary-background-color);\n }\n\n &:active,\n &.active {\n box-shadow: button-shadow var(--ring-button-primary-border-color);\n }\n\n &[disabled] {\n background-color: var(--ring-disabled-background-color);\n box-shadow: button-shadow var(--ring-border-disabled-color);\n }\n\n &[disabled].loader {\n color: var(--ring-white-text-color);\n }\n\n & .loaderBackground {\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n\n border-radius: var(--ring-border-radius);\n\n &::before {\n background-image:\n linear-gradient(\n to right,\n var(--ring-main-color),\n var(--ring-button-loader-background) 40%,\n var(--ring-main-color) 80%\n );\n }\n }\n}\n\n.danger {\n &,\n &.withIcon,\n &.withIcon:active,\n &.withIcon.active,\n &.text,\n &.text:active,\n &.text.active {\n color: var(--ring-error-color);\n }\n\n &:active,\n &.active {\n background-color: var(--ring-button-danger-active-color);\n }\n\n &:active,\n &.active,\n &:focus-visible,\n &:hover {\n box-shadow: button-shadow var(--ring-button-danger-hover-color);\n }\n\n &:focus-visible,\n &:hover {\n transition: none;\n }\n}\n\n.text.text,\n.withIcon.withIcon {\n background-color: transparent;\n box-shadow: none;\n\n &:hover {\n transition: none;\n }\n\n &:active,\n &.active {\n background-color: transparent;\n box-shadow: none;\n }\n\n &:focus-visible {\n box-shadow: inset 0 0 0 2px var(--ring-border-hover-color);\n }\n}\n\n.loader.text > .content {\n animation-name: text-loading;\n animation-duration: 1200ms;\n animation-iteration-count: infinite;\n}\n\n.text.text:hover {\n background-color: transparent;\n box-shadow: none;\n}\n\n.withIcon:hover:not(:focus-visible) {\n background-color: transparent;\n box-shadow: none;\n}\n\n.text {\n color: var(--ring-action-link-color);\n}\n\n.inline {\n display: inline-block;\n\n margin: 0;\n padding: 0;\n\n font-size: var(--ring-font-size);\n}\n\n.withIcon {\n padding: 0 unit;\n}\n\n.text {\n &:active,\n &.active {\n color: var(--ring-link-hover-color);\n }\n}\n\n.withIcon {\n &:active,\n &.active {\n color: var(--ring-action-link-color);\n }\n}\n\n.withIcon:hover {\n color: var(--ring-link-hover-color);\n}\n\n.text:hover {\n color: var(--ring-link-hover-color);\n}\n\n.icon {\n color: inherit;\n\n line-height: normal;\n\n &:not(:last-child) {\n margin-right: calc(unit * 0.5);\n }\n}\n\n.withNormalIcon .icon {\n transition: color var(--ring-ease);\n\n color: var(--ring-icon-color);\n}\n\n.withNormalIcon:active,\n.withNormalIcon.active {\n color: var(--ring-main-color);\n\n & .icon {\n transition: none;\n\n color: inherit;\n }\n}\n\n.withNormalIcon:hover .icon,\n.withDangerIcon:hover .icon {\n transition: none;\n\n color: inherit;\n}\n\n.withDangerIcon .icon,\n.withDangerIcon:active .icon {\n color: var(--ring-icon-error-color);\n}\n\n.loader {\n position: relative;\n z-index: 0;\n\n pointer-events: none;\n\n background-color: transparent;\n}\n\n.loaderBackground {\n position: absolute;\n z-index: -1;\n top: 1px;\n right: 1px;\n bottom: 1px;\n left: 1px;\n\n overflow: hidden;\n\n border-radius: var(--ring-border-radius-small);\n\n &::before {\n display: block;\n\n width: calc(100% + loaderWidth);\n height: 100%;\n\n content: "";\n animation: progress 1s linear infinite;\n\n background-image:\n linear-gradient(\n to right,\n var(--ring-content-background-color),\n var(--ring-selected-background-color) 40%,\n var(--ring-content-background-color) 80%\n );\n\n background-repeat: repeat;\n background-size: loaderWidth;\n }\n}\n\n.delayed .content::after {\n content: "…";\n}\n\n.short {\n width: calc(unit * 4);\n padding: 0;\n}\n\n.dropdownIcon {\n margin-right: -2px;\n\n margin-left: 2px;\n\n transition: color var(--ring-ease);\n\n color: var(--ring-icon-secondary-color);\n\n line-height: normal;\n}\n\n.button:hover .dropdownIcon {\n transition: none;\n\n color: var(--ring-main-color);\n}\n\n@keyframes progress {\n from {\n transform: translateX(calc(0 - loaderWidth));\n }\n\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes text-loading {\n 50% {\n opacity: 0.5;\n }\n}\n',null],sourceRoot:""}]),u.locals={unit:`${l.default.locals.unit}`,"button-shadow":"inset 0 0 0 1px",height:"var(--ring-button-height)",loaderWidth:"64px",heightS:"heightS_b28d",heightM:"heightM_dfd3",heightL:"heightL_a4d3",button:"button_aba4",active:"active_bbe6",withIcon:"withIcon_ef77",icon:"icon_e878",primary:"primary_ddae",loader:"loader_cbfc",loaderBackground:"loaderBackground_d9f5",danger:"danger_bcea",text:"text_fc2a",content:"content_b2b8","text-loading":"text-loading_d1b4",inline:"inline_b4a2",withNormalIcon:"withNormalIcon_aaca",withDangerIcon:"withDangerIcon_e3ca",progress:"progress_ed8f",delayed:"delayed_d562",short:"short_a07a",dropdownIcon:"dropdownIcon_e982"};const s=u},1866:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=a()(o());u.i(c.A),u.i(l.default,"",!0),u.push([e.id,".checkbox_dccf {\n position: relative;\n\n display: inline-block;\n\n text-align: left;\n\n color: var(--ring-text-color);\n outline: none;\n}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.checkbox_dccf:hover .cell_edda {\n transition: background-color var(--ring-ease);\n\n border-color: var(--ring-border-hover-color);\n }}\n\n.cell_edda {\n position: relative;\n top: -2px;\n\n display: inline-block;\n\n box-sizing: border-box;\n width: 14px;\n height: 14px;\n\n -webkit-user-select: none;\n\n -moz-user-select: none;\n\n user-select: none;\n transition: border-color var(--ring-ease), background-color var(--ring-ease), box-shadow var(--ring-ease);\n vertical-align: middle;\n pointer-events: none;\n\n border: 1px solid var(--ring-borders-color);\n border-radius: var(--ring-border-radius-small);\n background-color: var(--ring-content-background-color);\n}\n\n.icon_b476.icon_b476 {\n position: absolute;\n\n top: -1px;\n left: -1px;\n\n width: 16px;\n height: 16px;\n\n opacity: 0;\n color: var(--ring-white-text-color);\n}\n\n.icon_b476.icon_b476 svg {\n position: absolute;\n top: 0;\n left: 0;\n }\n\n.check_a219 {\n}\n\n.minus_de65 {\n}\n\n.input_a330 {\n position: absolute;\n top: 0;\n left: 0;\n\n width: 100%;\n height: 100%;\n margin: 0;\n\n cursor: pointer;\n\n opacity: 0;\n\n /* stylelint-disable-next-line selector-max-specificity */\n}\n\n.input_a330:checked + .cell_edda,\n .input_a330:indeterminate + .cell_edda {\n border-color: transparent;\n background-color: var(--ring-main-color);\n }\n\n/* stylelint-disable-next-line selector-max-specificity */\n\n.input_a330:checked + .cell_edda .check_a219 {\n opacity: 1;\n }\n\n.input_a330:focus-visible + .cell_edda,\n .input_a330.focus_eaa3 + .cell_edda {\n transition: background-color var(--ring-ease);\n\n border-color: var(--ring-border-hover-color);\n box-shadow: 0 0 0 1px var(--ring-border-hover-color);\n }\n\n/* stylelint-disable-next-line selector-max-specificity */\n\n.input_a330:indeterminate + .cell_edda .minus_de65 {\n opacity: 1;\n }\n\n.input_a330[disabled] {\n pointer-events: none;\n }\n\n/* stylelint-disable-next-line selector-max-specificity */\n\n.input_a330[disabled][disabled] + .cell_edda {\n border-color: var(--ring-border-disabled-color);\n background-color: var(--ring-disabled-background-color);\n }\n\n/* stylelint-disable-next-line selector-max-specificity */\n\n.input_a330[disabled]:checked + .cell_edda,\n .input_a330[disabled]:indeterminate + .cell_edda {\n border-color: var(--ring-border-selected-disabled-color);\n }\n\n/* stylelint-disable-next-line selector-max-specificity */\n\n.input_a330[disabled]:checked + .cell_edda .check_a219,\n .input_a330[disabled]:indeterminate + .cell_edda .minus_de65 {\n color: var(--ring-icon-disabled-color);\n }\n\n/* stylelint-disable-next-line selector-max-specificity */\n\n.input_a330:indeterminate:indeterminate + .cell_edda .check_a219 {\n transition: none;\n\n opacity: 0;\n }\n\n.input_a330[disabled] ~ .label_dcc7 {\n color: var(--ring-disabled-color);\n }\n\n.label_dcc7 {\n margin-left: 8px;\n\n line-height: normal;\n}\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/checkbox/checkbox.css",""],names:[],mappings:"AAKA;EACE,kBAAkB;;EAElB,qBAAqB;;EAErB,gBAAgB;;EAEhB,6BAA6B;EAC7B,aAAa;AAOf;;ACpBA,wGAAA;IAAA,8CAAA;;IAAA,6CAAA;GAAA,CAAA;;ADsBA;EACE,kBAAkB;EAClB,SAAS;;EAET,qBAAqB;;EAErB,sBAAsB;EACtB,WAAmB;EACnB,YAAoB;;EAEpB,yBAAiB;;KAAjB,sBAAiB;;UAAjB,iBAAiB;EACjB,yGAAyG;EACzG,sBAAsB;EACtB,oBAAoB;;EAEpB,2CAA2C;EAC3C,8CAA8C;EAC9C,sDAAsD;AACxD;;AAEA;EACE,kBAAkB;;EAElB,SAAS;EACT,UAAU;;EAEV,WAAqB;EACrB,YAAsB;;EAEtB,UAAU;EACV,mCAAmC;AAOrC;;AALE;IACE,kBAAkB;IAClB,MAAM;IACN,OAAO;EACT;;AAGF;AAEA;;AAEA;AAEA;;AAEA;EACE,kBAAkB;EAClB,MAAM;EACN,OAAO;;EAEP,WAAW;EACX,YAAY;EACZ,SAAS;;EAET,eAAe;;EAEf,UAAU;;EAEV,yDAAyD;AAyD3D;;AAxDE;;IAEE,yBAAyB;IACzB,wCAAwC;EAC1C;;AAEA,yDAAyD;;AACzD;IACE,UAAU;EACZ;;AAEA;;IAEE,6CAA6C;;IAE7C,4CAA4C;IAC5C,oDAAoD;EACtD;;AAEA,yDAAyD;;AACzD;IACE,UAAU;EACZ;;AAEA;IACE,oBAAoB;EACtB;;AAEA,yDAAyD;;AACzD;IACE,+CAA+C;IAC/C,uDAAuD;EACzD;;AAEA,yDAAyD;;AACzD;;IAEE,wDAAwD;EAC1D;;AAEA,yDAAyD;;AACzD;;IAEE,sCAAsC;EACxC;;AAEA,yDAAyD;;AACzD;IACE,gBAAgB;;IAEhB,UAAU;EACZ;;AAEA;IACE,iCAAiC;EACnC;;AAGF;EACE,gBAAiB;;EAEjB,mBAAmB;AACrB",sourcesContent:['@import "../global/variables.css";\n\n@value unit from "../global/global.css";\n@value checkboxSize: 14px;\n\n.checkbox {\n position: relative;\n\n display: inline-block;\n\n text-align: left;\n\n color: var(--ring-text-color);\n outline: none;\n\n &:hover .cell {\n transition: background-color var(--ring-ease);\n\n border-color: var(--ring-border-hover-color);\n }\n}\n\n.cell {\n position: relative;\n top: -2px;\n\n display: inline-block;\n\n box-sizing: border-box;\n width: checkboxSize;\n height: checkboxSize;\n\n user-select: none;\n transition: border-color var(--ring-ease), background-color var(--ring-ease), box-shadow var(--ring-ease);\n vertical-align: middle;\n pointer-events: none;\n\n border: 1px solid var(--ring-borders-color);\n border-radius: var(--ring-border-radius-small);\n background-color: var(--ring-content-background-color);\n}\n\n.icon.icon {\n position: absolute;\n\n top: -1px;\n left: -1px;\n\n width: calc(unit * 2);\n height: calc(unit * 2);\n\n opacity: 0;\n color: var(--ring-white-text-color);\n\n & svg {\n position: absolute;\n top: 0;\n left: 0;\n }\n}\n\n.check {\n composes: icon;\n}\n\n.minus {\n composes: icon;\n}\n\n.input {\n position: absolute;\n top: 0;\n left: 0;\n\n width: 100%;\n height: 100%;\n margin: 0;\n\n cursor: pointer;\n\n opacity: 0;\n\n /* stylelint-disable-next-line selector-max-specificity */\n &:checked + .cell,\n &:indeterminate + .cell {\n border-color: transparent;\n background-color: var(--ring-main-color);\n }\n\n /* stylelint-disable-next-line selector-max-specificity */\n &:checked + .cell .check {\n opacity: 1;\n }\n\n &:focus-visible + .cell,\n &.focus + .cell {\n transition: background-color var(--ring-ease);\n\n border-color: var(--ring-border-hover-color);\n box-shadow: 0 0 0 1px var(--ring-border-hover-color);\n }\n\n /* stylelint-disable-next-line selector-max-specificity */\n &:indeterminate + .cell .minus {\n opacity: 1;\n }\n\n &[disabled] {\n pointer-events: none;\n }\n\n /* stylelint-disable-next-line selector-max-specificity */\n &[disabled][disabled] + .cell {\n border-color: var(--ring-border-disabled-color);\n background-color: var(--ring-disabled-background-color);\n }\n\n /* stylelint-disable-next-line selector-max-specificity */\n &[disabled]:checked + .cell,\n &[disabled]:indeterminate + .cell {\n border-color: var(--ring-border-selected-disabled-color);\n }\n\n /* stylelint-disable-next-line selector-max-specificity */\n &[disabled]:checked + .cell .check,\n &[disabled]:indeterminate + .cell .minus {\n color: var(--ring-icon-disabled-color);\n }\n\n /* stylelint-disable-next-line selector-max-specificity */\n &:indeterminate:indeterminate + .cell .check {\n transition: none;\n\n opacity: 0;\n }\n\n &[disabled] ~ .label {\n color: var(--ring-disabled-color);\n }\n}\n\n.label {\n margin-left: unit;\n\n line-height: normal;\n}\n',null],sourceRoot:""}]),u.locals={unit:`${l.default.locals.unit}`,checkboxSize:"14px",checkbox:"checkbox_dccf",cell:"cell_edda",icon:"icon_b476",check:"check_a219 icon_b476",minus:"minus_de65 icon_b476",input:"input_a330",focus:"focus_eaa3",label:"label_dcc7"};const s=u},5486:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>l});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i)()(o());a.push([e.id,".label_bed7 {\n display: block;\n\n margin-bottom: calc(var(--ring-unit)*0.5);\n}\n\n.formLabel_f9ba {\n color: var(--ring-text-color);\n\n font-size: var(--ring-font-size);\n line-height: var(--ring-line-height);\n}\n\n.secondaryLabel_e8a1 {\n color: var(--ring-secondary-color);\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lowest);\n}\n\n.disabledLabel_e4c1 {\n color: var(--ring-disabled-color);\n}\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/control-label/control-label.css"],names:[],mappings:"AAAA;EACE,cAAc;;EAEd,yCAA2C;AAC7C;;AAEA;EACE,6BAA6B;;EAE7B,gCAAgC;EAChC,oCAAoC;AACtC;;AAEA;EACE,kCAAkC;;EAElC,wCAAwC;EACxC,2CAA2C;AAC7C;;AAEA;EACE,iCAAiC;AACnC",sourcesContent:[".label {\n display: block;\n\n margin-bottom: calc(var(--ring-unit) * 0.5);\n}\n\n.formLabel {\n color: var(--ring-text-color);\n\n font-size: var(--ring-font-size);\n line-height: var(--ring-line-height);\n}\n\n.secondaryLabel {\n color: var(--ring-secondary-color);\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lowest);\n}\n\n.disabledLabel {\n color: var(--ring-disabled-color);\n}\n"],sourceRoot:""}]),a.locals={label:"label_bed7",formLabel:"formLabel_f9ba",secondaryLabel:"secondaryLabel_e8a1",disabledLabel:"disabledLabel_e4c1"};const l=a},6506:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,".dropdown_a1de {\n display: inline-block;\n}\n\n.anchor_fdbe.anchor_fdbe {\n margin: 0 -3px;\n padding: 0 3px;\n\n font: inherit;\n}\n\n.chevron_ffc6 {\n margin-left: 2px;\n\n line-height: normal;\n}\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/dropdown/dropdown.css"],names:[],mappings:"AAEA;EACE,qBAAqB;AACvB;;AAEA;EACE,cAAc;EACd,cAAc;;EAEd,aAAa;AACf;;AAEA;EACE,gBAAgB;;EAEhB,mBAAmB;AACrB",sourcesContent:['@import "../global/variables.css";\n\n.dropdown {\n display: inline-block;\n}\n\n.anchor.anchor {\n margin: 0 -3px;\n padding: 0 3px;\n\n font: inherit;\n}\n\n.chevron {\n margin-left: 2px;\n\n line-height: normal;\n}\n'],sourceRoot:""}]),c.locals={dropdown:"dropdown_a1de",anchor:"anchor_fdbe",chevron:"chevron_ffc6"};const u=c},9106:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>l});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i)()(o());a.push([e.id,'/* https://readymag.com/artemtiunov/RingUILanguage/colours/ */\n\n/*\nUnit shouldn\'t be CSS custom property because it is not intended to change\nAlso it won\'t form in FF47 https://bugzilla.mozilla.org/show_bug.cgi?id=594933\n*/\n\n.clearfix_c694::after {\n display: block;\n clear: both;\n\n content: "";\n }\n\n.font_a1f6 {\n font-family: var(--ring-font-family);\n font-size: var(--ring-font-size);\n line-height: var(--ring-line-height);\n}\n\n.font-lower_c3c9 {\n\n line-height: var(--ring-line-height-lower);\n}\n\n.font-smaller_d963 {\n\n font-size: var(--ring-font-size-smaller);\n}\n\n.font-smaller-lower_ff5f {\n\n line-height: var(--ring-line-height-lowest);\n}\n\n.font-larger-lower_b336 {\n\n font-size: var(--ring-font-size-larger);\n}\n\n.font-larger_f035 {\n\n line-height: var(--ring-line-height-taller);\n}\n\n/* To be used at large sizes */\n/* As close as possible to Helvetica Neue Thin (to replace Gotham) */\n.thin-font_de5b {\n font-family: "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;\n font-size: var(--ring-font-size);\n font-weight: 100; /* Renders Helvetica Neue UltraLight on OS X */\n}\n\n.monospace-font_ac33 {\n font-family: var(--ring-font-family-monospace);\n font-size: var(--ring-font-size-smaller);\n}\n\n.ellipsis_e43b {\n overflow: hidden;\n\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.resetButton_ddd2 {\n overflow: visible;\n\n padding: 0;\n\n text-align: left;\n\n color: inherit;\n border: 0;\n\n background-color: transparent;\n\n font: inherit;\n}\n\n.resetButton_ddd2::-moz-focus-inner {\n padding: 0;\n\n border: 0;\n }\n\n/* Note: footer also has top margin which isn\'t taken into account here */\n\n/* Media breakpoints (minimal values) */\n\n/* Media queries */\n',"",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/global/global.css"],names:[],mappings:"AAAA,6DAA6D;;AAE7D;;;CAGC;;AAIC;IACE,cAAc;IACd,WAAW;;IAEX,WAAW;EACb;;AAGF;EACE,oCAAoC;EACpC,gCAAgC;EAChC,oCAAoC;AACtC;;AAEA;;EAGE,0CAA0C;AAC5C;;AAEA;;EAGE,wCAAwC;AAC1C;;AAEA;;EAGE,2CAA2C;AAC7C;;AAEA;;EAGE,uCAAuC;AACzC;;AAEA;;EAGE,2CAA2C;AAC7C;;AAEA,8BAA8B;AAC9B,oEAAoE;AACpE;EACE,uEAAuE;EACvE,gCAAgC;EAChC,gBAAgB,EAAE,+CAA+C;AACnE;;AAEA;EACE,8CAA8C;EAC9C,wCAAwC;AAC1C;;AAEA;EACE,gBAAgB;;EAEhB,mBAAmB;EACnB,uBAAuB;AACzB;;AAEA;EACE,iBAAiB;;EAEjB,UAAU;;EAEV,gBAAgB;;EAEhB,cAAc;EACd,SAAS;;EAET,6BAA6B;;EAE7B,aAAa;AAOf;;AALE;IACE,UAAU;;IAEV,SAAS;EACX;;AAGF,yEAAyE;;AAGzE,uCAAuC;;AAKvC,kBAAkB",sourcesContent:['/* https://readymag.com/artemtiunov/RingUILanguage/colours/ */\n\n/*\nUnit shouldn\'t be CSS custom property because it is not intended to change\nAlso it won\'t form in FF47 https://bugzilla.mozilla.org/show_bug.cgi?id=594933\n*/\n@value unit: 8px;\n\n.clearfix {\n &::after {\n display: block;\n clear: both;\n\n content: "";\n }\n}\n\n.font {\n font-family: var(--ring-font-family);\n font-size: var(--ring-font-size);\n line-height: var(--ring-line-height);\n}\n\n.font-lower {\n composes: font;\n\n line-height: var(--ring-line-height-lower);\n}\n\n.font-smaller {\n composes: font-lower;\n\n font-size: var(--ring-font-size-smaller);\n}\n\n.font-smaller-lower {\n composes: font-smaller;\n\n line-height: var(--ring-line-height-lowest);\n}\n\n.font-larger-lower {\n composes: font-lower;\n\n font-size: var(--ring-font-size-larger);\n}\n\n.font-larger {\n composes: font-larger-lower;\n\n line-height: var(--ring-line-height-taller);\n}\n\n/* To be used at large sizes */\n/* As close as possible to Helvetica Neue Thin (to replace Gotham) */\n.thin-font {\n font-family: "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;\n font-size: var(--ring-font-size);\n font-weight: 100; /* Renders Helvetica Neue UltraLight on OS X */\n}\n\n.monospace-font {\n font-family: var(--ring-font-family-monospace);\n font-size: var(--ring-font-size-smaller);\n}\n\n.ellipsis {\n overflow: hidden;\n\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.resetButton {\n overflow: visible;\n\n padding: 0;\n\n text-align: left;\n\n color: inherit;\n border: 0;\n\n background-color: transparent;\n\n font: inherit;\n\n &::-moz-focus-inner {\n padding: 0;\n\n border: 0;\n }\n}\n\n/* Note: footer also has top margin which isn\'t taken into account here */\n@value footer-height: calc(unit * 8);\n\n/* Media breakpoints (minimal values) */\n@value breakpoint-small: 640px;\n@value breakpoint-middle: 960px;\n@value breakpoint-large: 1200px;\n\n/* Media queries */\n@value extra-small-screen-media: (max-width: calc(breakpoint-small - 1px));\n@value small-screen-media: (min-width: breakpoint-small) and (max-width: calc(breakpoint-middle - 1px));\n@value middle-screen-media: (min-width: breakpoint-middle) and (max-width: calc(breakpoint-large - 1px));\n@value large-screen-media: (min-width: breakpoint-large);\n'],sourceRoot:""}]),a.locals={unit:"8px","footer-height":"64px","breakpoint-small":"640px","breakpoint-middle":"960px","breakpoint-large":"1200px","extra-small-screen-media":"(max-width: 639px)","small-screen-media":"(min-width: 640px) and (max-width: 959px)","middle-screen-media":"(min-width: 960px) and (max-width: 1199px)","large-screen-media":"(min-width: 1200px)",clearfix:"clearfix_c694",font:"font_a1f6","font-lower":"font-lower_c3c9 font_a1f6","font-smaller":"font-smaller_d963 font-lower_c3c9 font_a1f6","font-smaller-lower":"font-smaller-lower_ff5f font-smaller_d963 font-lower_c3c9 font_a1f6","font-larger-lower":"font-larger-lower_b336 font-lower_c3c9 font_a1f6","font-larger":"font-larger_f035 font-larger-lower_b336 font-lower_c3c9 font_a1f6","thin-font":"thin-font_de5b","monospace-font":"monospace-font_ac33",ellipsis:"ellipsis_e43b",resetButton:"resetButton_ddd2"};const l=a},5280:(e,n,t)=>{"use strict";t.d(n,{A:()=>l});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i)()(o());a.push([e.id,'/* stylelint-disable color-no-hex */\n\n.light_f331,\n:root {\n --ring-unit: 8px;\n\n /* Element */\n --ring-line-components: 223, 229, 235;\n --ring-line-color: rgb(var(--ring-line-components)); /* #dfe5eb */\n --ring-borders-components: 197, 209, 219;\n --ring-borders-color: rgb(var(--ring-borders-components)); /* #c5d1db */\n --ring-icon-components: 184, 209, 229;\n --ring-icon-color: rgb(var(--ring-icon-components)); /* #b8d1e5 */\n --ring-icon-secondary-components: 153, 153, 153;\n --ring-icon-secondary-color: rgb(var(--ring-icon-secondary-components)); /* #999 */\n --ring-border-disabled-components: 232, 232, 232;\n --ring-border-disabled-color: rgb(var(--ring-border-disabled-components)); /* #e8e8e8 */\n --ring-border-selected-disabled-components: 212, 212, 212;\n --ring-border-selected-disabled-color: rgb(var(--ring-border-selected-disabled-components)); /* #d4d4d4 */\n --ring-border-unselected-disabled-components: 232, 232, 232;\n --ring-border-unselected-disabled-color: rgb(var(--ring-border-unselected-disabled-components)); /* #e8e8e8 */ /* TODO remove in 6.0 */\n --ring-icon-disabled-components: 212, 212, 212;\n --ring-icon-disabled-color: rgb(var(--ring-icon-disabled-components)); /* #d4d4d4 */\n --ring-border-hover-components: 128, 198, 255;\n --ring-border-hover-color: rgb(var(--ring-border-hover-components)); /* #80c6ff */\n --ring-icon-hover-components: var(--ring-link-hover-color);\n --ring-icon-hover-color: var(--ring-link-hover-color);\n --ring-main-components: 0, 128, 229;\n --ring-main-color: rgb(var(--ring-main-components)); /* #0080e5 */\n --ring-action-link-components: var(--ring-main-components);\n --ring-action-link-color: rgb(var(--ring-main-components)); /* #0080e5 */\n --ring-main-hover-components: 0, 112, 204;\n --ring-main-hover-color: rgb(var(--ring-main-hover-components)); /* #0070cc */\n --ring-icon-error-components: 219, 88, 96;\n --ring-icon-error-color: rgb(var(--ring-icon-error-components)); /* #db5860 */\n --ring-icon-warning-components: 237, 162, 0;\n --ring-icon-warning-color: rgb(var(--ring-icon-warning-components)); /* #eda200 */\n --ring-icon-success-components: 89, 168, 105;\n --ring-icon-success-color: rgb(var(--ring-icon-success-components)); /* #59a869 */\n --ring-pale-control-components: 207, 219, 229;\n --ring-pale-control-color: rgb(var(--ring-pale-control-components)); /* #cfdbe5 */\n --ring-popup-border-components: 0, 28, 54;\n --ring-popup-border-color: var(--ring-line-color);\n --ring-popup-shadow-components: rgba(var(--ring-popup-border-components), 0.1);\n --ring-popup-shadow-color: rgba(var(--ring-popup-border-components), 0.1);\n --ring-popup-secondary-shadow-color: rgba(var(--ring-popup-border-components), 0.04);\n --ring-message-shadow-color: rgba(var(--ring-popup-border-components), 0.3);\n --ring-pinned-shadow-components: 115, 117, 119;\n --ring-pinned-shadow-color: rgb(var(--ring-pinned-shadow-components)); /* #737577 */\n --ring-button-danger-hover-components: var(--ring-icon-error-color);\n --ring-button-danger-hover-color: var(--ring-icon-error-color);\n --ring-button-primary-border-components: 0, 98, 178;\n --ring-button-primary-border-color: rgb(var(--ring-button-primary-border-components)); /* #0062b2 */\n --ring-popup-shadow: 0 2px 8px var(--ring-popup-shadow-color), 0 1px 2px var(--ring-popup-secondary-shadow-color);\n --ring-dialog-shadow: 0 4px 24px var(--ring-popup-shadow-color), 0 2px 6px var(--ring-popup-secondary-shadow-color);\n\n /* Text */\n --ring-search-components: 102, 158, 204;\n --ring-search-color: rgb(var(--ring-search-components)); /* #669ecc */\n --ring-hint-components: 64, 99, 128;\n --ring-hint-color: rgb(var(--ring-hint-components)); /* #406380 */\n --ring-link-components: 15, 91, 153;\n --ring-link-color: rgb(var(--ring-link-components)); /* #0f5b99 */\n --ring-link-hover-components: 255, 0, 140;\n --ring-link-hover-color: rgb(var(--ring-link-hover-components)); /* #ff008c */\n --ring-error-components: 169, 15, 26;\n --ring-error-color: rgb(var(--ring-error-components)); /* #a90f1a */\n --ring-warning-components: 178, 92, 0;\n --ring-warning-color: rgb(var(--ring-warning-components)); /* #b25c00 */\n --ring-success-components: 12, 117, 35;\n --ring-success-color: rgb(var(--ring-success-components)); /* #0c7523 */\n --ring-text-components: 31, 35, 38;\n --ring-text-color: rgb(var(--ring-text-components)); /* #1f2326 */\n --ring-active-text-color: var(--ring-text-color);\n --ring-white-text-components: 255, 255, 255;\n --ring-white-text-color: rgb(var(--ring-white-text-components)); /* #fff */\n --ring-heading-color: var(--ring-text-color);\n --ring-secondary-components: 115, 117, 119;\n --ring-secondary-color: rgb(var(--ring-secondary-components)); /* #737577 */\n --ring-disabled-components: 153, 153, 153;\n --ring-disabled-color: rgb(var(--ring-disabled-components)); /* #999 */\n\n /* Background */\n --ring-content-background-components: 255, 255, 255;\n --ring-content-background-color: rgb(var(--ring-content-background-components)); /* #fff */\n --ring-popup-background-components: 255, 255, 255;\n --ring-popup-background-color: rgb(var(--ring-popup-background-components)); /* #fff */\n --ring-sidebar-background-components: 247, 249, 250;\n --ring-sidebar-background-color: rgb(var(--ring-sidebar-background-components)); /* #f7f9fa */\n --ring-selected-background-components: 212, 237, 255;\n --ring-selected-background-color: rgb(var(--ring-selected-background-components)); /* #d4edff */\n --ring-hover-background-components: 235, 246, 255;\n --ring-hover-background-color: rgb(var(--ring-hover-background-components)); /* #ebf6ff */\n --ring-navigation-background-components: 255, 255, 255;\n --ring-navigation-background-color: rgb(var(--ring-navigation-background-components)); /* #fff */\n --ring-tag-background-components: 230, 236, 242;\n --ring-tag-background-color: rgb(var(--ring-tag-background-components)); /* #e6ecf2 */\n --ring-tag-hover-background-components: 211, 218, 224;\n --ring-tag-hover-background-color: rgb(var(--ring-tag-hover-background-components)); /* #d3dae0 */\n --ring-removed-background-components: 255, 213, 203;\n --ring-removed-background-color: rgb(var(--ring-removed-background-components)); /* #ffd5cb */\n --ring-warning-background-components: 250, 236, 205;\n --ring-warning-background-color: rgb(var(--ring-warning-background-components)); /* #faeccd */\n --ring-added-background-components: 216, 240, 216;\n --ring-added-background-color: rgb(var(--ring-added-background-components)); /* #d8f0d8 */\n --ring-disabled-background-components: 245, 245, 245;\n --ring-disabled-background-color: rgb(var(--ring-disabled-background-components)); /* #f5f5f5 */\n --ring-disabled-selected-background-components: 232, 232, 232;\n --ring-disabled-selected-background-color: rgb(var(--ring-disabled-selected-background-components)); /* #e8e8e8 */\n --ring-button-danger-active-components: 255, 231, 232;\n --ring-button-danger-active-color: rgb(var(--ring-button-danger-active-components)); /* #ffe7e8 */\n --ring-button-loader-background-components: 51, 163, 255;\n --ring-button-loader-background: rgb(var(--ring-button-loader-background-components)); /* #33a3ff */\n --ring-button-primary-background-components: 26, 152, 255;\n --ring-button-primary-background-color: rgb(var(--ring-button-primary-background-components)); /* #1a98ff */\n --ring-table-loader-background-color: rgba(var(--ring-content-background-components), 0.5); /* #ffffff80 */\n\n /* Code */\n --ring-code-background-color: var(--ring-content-background-color);\n --ring-code-components: 0, 0, 0;\n --ring-code-color: rgb(var(--ring-code-components)); /* #000 */\n --ring-code-comment-components: 112, 112, 112;\n --ring-code-comment-color: rgb(var(--ring-code-comment-components)); /* #707070 */\n --ring-code-meta-components: 112, 112, 112;\n --ring-code-meta-color: rgb(var(--ring-code-meta-components)); /* #707070 */\n --ring-code-keyword-components: 0, 0, 128;\n --ring-code-keyword-color: rgb(var(--ring-code-keyword-components)); /* #000080 */\n --ring-code-tag-background-components: 239, 239, 239;\n --ring-code-tag-background-color: rgb(var(--ring-code-tag-background-components)); /* #efefef */\n --ring-code-tag-color: var(--ring-code-keyword-color);\n --ring-code-tag-font-weight: bold;\n --ring-code-field-components: 102, 14, 122;\n --ring-code-field-color: rgb(var(--ring-code-field-components)); /* #660e7a */\n --ring-code-attribute-components: 0, 0, 255;\n --ring-code-attribute-color: rgb(var(--ring-code-attribute-components)); /* #00f */\n --ring-code-number-color: var(--ring-code-attribute-color);\n --ring-code-string-components: 0, 122, 0;\n --ring-code-string-color: rgb(var(--ring-code-string-components)); /* #007a00 */\n --ring-code-addition-components: 170, 222, 170;\n --ring-code-addition-color: rgb(var(--ring-code-addition-components)); /* #aadeaa */\n --ring-code-deletion-components: 200, 200, 200;\n --ring-code-deletion-color: rgb(var(--ring-code-deletion-components)); /* #c8c8c8 */\n\n /* Metrics */\n --ring-border-radius: 4px;\n --ring-border-radius-small: 2px;\n --ring-font-size-larger: 15px;\n --ring-font-size: 14px;\n --ring-font-size-smaller: 12px;\n --ring-line-height-taller: 21px;\n --ring-line-height: 20px;\n --ring-line-height-lower: 18px;\n --ring-line-height-lowest: 16px;\n --ring-ease: 0.3s ease-out;\n --ring-fast-ease: 0.15s ease-out;\n --ring-font-family: system-ui, -apple-system, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, Arial, sans-serif;\n --ring-font-family-monospace:\n Menlo,\n "Bitstream Vera Sans Mono",\n "Ubuntu Mono",\n Consolas,\n "Courier New",\n Courier,\n monospace;\n\n /* Common z-index-values */\n\n /* Invisible element is an absolutely positioned element which should be below */\n /* all other elements on the page */\n --ring-invisible-element-z-index: -1;\n\n /* z-index for position: fixed elements */\n --ring-fixed-z-index: 1;\n\n /* Elements that should overlay all other elements on the page */\n --ring-overlay-z-index: 5;\n\n /* Alerts should de displayed above overlays */\n --ring-alert-z-index: 6;\n}\n',"",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/global/variables.css"],names:[],mappings:"AAAA,mCAAmC;;AAEnC;;EAEE,gBAAgB;;EAEhB,YAAY;EACZ,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,wCAAwC;EACxC,yDAAyD,EAAE,YAAY;EACvE,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,+CAA+C;EAC/C,uEAAuE,EAAE,SAAS;EAClF,gDAAgD;EAChD,yEAAyE,EAAE,YAAY;EACvF,yDAAyD;EACzD,2FAA2F,EAAE,YAAY;EACzG,2DAA2D;EAC3D,+FAA+F,EAAE,YAAY,EAAE,uBAAuB;EACtI,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;EACnF,6CAA6C;EAC7C,mEAAmE,EAAE,YAAY;EACjF,0DAA0D;EAC1D,qDAAqD;EACrD,mCAAmC;EACnC,mDAAmD,EAAE,YAAY;EACjE,0DAA0D;EAC1D,0DAA0D,EAAE,YAAY;EACxE,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,2CAA2C;EAC3C,mEAAmE,EAAE,YAAY;EACjF,4CAA4C;EAC5C,mEAAmE,EAAE,YAAY;EACjF,6CAA6C;EAC7C,mEAAmE,EAAE,YAAY;EACjF,yCAAyC;EACzC,iDAAiD;EACjD,8EAA8E;EAC9E,yEAAyE;EACzE,oFAAoF;EACpF,2EAA2E;EAC3E,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;EACnF,mEAAmE;EACnE,8DAA8D;EAC9D,mDAAmD;EACnD,qFAAqF,EAAE,YAAY;EACnG,iHAAiH;EACjH,mHAAmH;;EAEnH,SAAS;EACT,uCAAuC;EACvC,uDAAuD,EAAE,YAAY;EACrE,mCAAmC;EACnC,mDAAmD,EAAE,YAAY;EACjE,mCAAmC;EACnC,mDAAmD,EAAE,YAAY;EACjE,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,oCAAoC;EACpC,qDAAqD,EAAE,YAAY;EACnE,qCAAqC;EACrC,yDAAyD,EAAE,YAAY;EACvE,sCAAsC;EACtC,yDAAyD,EAAE,YAAY;EACvE,kCAAkC;EAClC,mDAAmD,EAAE,YAAY;EACjE,gDAAgD;EAChD,2CAA2C;EAC3C,+DAA+D,EAAE,SAAS;EAC1E,4CAA4C;EAC5C,0CAA0C;EAC1C,6DAA6D,EAAE,YAAY;EAC3E,yCAAyC;EACzC,2DAA2D,EAAE,SAAS;;EAEtE,eAAe;EACf,mDAAmD;EACnD,+EAA+E,EAAE,SAAS;EAC1F,iDAAiD;EACjD,2EAA2E,EAAE,SAAS;EACtF,mDAAmD;EACnD,+EAA+E,EAAE,YAAY;EAC7F,oDAAoD;EACpD,iFAAiF,EAAE,YAAY;EAC/F,iDAAiD;EACjD,2EAA2E,EAAE,YAAY;EACzF,sDAAsD;EACtD,qFAAqF,EAAE,SAAS;EAChG,+CAA+C;EAC/C,uEAAuE,EAAE,YAAY;EACrF,qDAAqD;EACrD,mFAAmF,EAAE,YAAY;EACjG,mDAAmD;EACnD,+EAA+E,EAAE,YAAY;EAC7F,mDAAmD;EACnD,+EAA+E,EAAE,YAAY;EAC7F,iDAAiD;EACjD,2EAA2E,EAAE,YAAY;EACzF,oDAAoD;EACpD,iFAAiF,EAAE,YAAY;EAC/F,6DAA6D;EAC7D,mGAAmG,EAAE,YAAY;EACjH,qDAAqD;EACrD,mFAAmF,EAAE,YAAY;EACjG,wDAAwD;EACxD,qFAAqF,EAAE,YAAY;EACnG,yDAAyD;EACzD,6FAA6F,EAAE,YAAY;EAC3G,0FAA0F,EAAE,cAAc;;EAE1G,SAAS;EACT,kEAAkE;EAClE,+BAA+B;EAC/B,mDAAmD,EAAE,SAAS;EAC9D,6CAA6C;EAC7C,mEAAmE,EAAE,YAAY;EACjF,0CAA0C;EAC1C,6DAA6D,EAAE,YAAY;EAC3E,yCAAyC;EACzC,mEAAmE,EAAE,YAAY;EACjF,oDAAoD;EACpD,iFAAiF,EAAE,YAAY;EAC/F,qDAAqD;EACrD,iCAAiC;EACjC,0CAA0C;EAC1C,+DAA+D,EAAE,YAAY;EAC7E,2CAA2C;EAC3C,uEAAuE,EAAE,SAAS;EAClF,0DAA0D;EAC1D,wCAAwC;EACxC,iEAAiE,EAAE,YAAY;EAC/E,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;EACnF,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;;EAEnF,YAAY;EACZ,yBAAyB;EACzB,+BAA+B;EAC/B,6BAA6B;EAC7B,sBAAsB;EACtB,8BAA8B;EAC9B,+BAA+B;EAC/B,wBAAwB;EACxB,8BAA8B;EAC9B,+BAA+B;EAC/B,0BAA0B;EAC1B,gCAAgC;EAChC,+HAAgD;EAChD;;;;;;;aAOW;;EAEX,0BAA0B;;EAE1B,gFAAgF;EAChF,mCAAmC;EACnC,oCAAoC;;EAEpC,yCAAyC;EACzC,uBAAuB;;EAEvB,gEAAgE;EAChE,yBAAyB;;EAEzB,8CAA8C;EAC9C,uBAAuB;AACzB",sourcesContent:['/* stylelint-disable color-no-hex */\n\n.light,\n:root {\n --ring-unit: 8px;\n\n /* Element */\n --ring-line-components: 223, 229, 235;\n --ring-line-color: rgb(var(--ring-line-components)); /* #dfe5eb */\n --ring-borders-components: 197, 209, 219;\n --ring-borders-color: rgb(var(--ring-borders-components)); /* #c5d1db */\n --ring-icon-components: 184, 209, 229;\n --ring-icon-color: rgb(var(--ring-icon-components)); /* #b8d1e5 */\n --ring-icon-secondary-components: 153, 153, 153;\n --ring-icon-secondary-color: rgb(var(--ring-icon-secondary-components)); /* #999 */\n --ring-border-disabled-components: 232, 232, 232;\n --ring-border-disabled-color: rgb(var(--ring-border-disabled-components)); /* #e8e8e8 */\n --ring-border-selected-disabled-components: 212, 212, 212;\n --ring-border-selected-disabled-color: rgb(var(--ring-border-selected-disabled-components)); /* #d4d4d4 */\n --ring-border-unselected-disabled-components: 232, 232, 232;\n --ring-border-unselected-disabled-color: rgb(var(--ring-border-unselected-disabled-components)); /* #e8e8e8 */ /* TODO remove in 6.0 */\n --ring-icon-disabled-components: 212, 212, 212;\n --ring-icon-disabled-color: rgb(var(--ring-icon-disabled-components)); /* #d4d4d4 */\n --ring-border-hover-components: 128, 198, 255;\n --ring-border-hover-color: rgb(var(--ring-border-hover-components)); /* #80c6ff */\n --ring-icon-hover-components: var(--ring-link-hover-color);\n --ring-icon-hover-color: var(--ring-link-hover-color);\n --ring-main-components: 0, 128, 229;\n --ring-main-color: rgb(var(--ring-main-components)); /* #0080e5 */\n --ring-action-link-components: var(--ring-main-components);\n --ring-action-link-color: rgb(var(--ring-main-components)); /* #0080e5 */\n --ring-main-hover-components: 0, 112, 204;\n --ring-main-hover-color: rgb(var(--ring-main-hover-components)); /* #0070cc */\n --ring-icon-error-components: 219, 88, 96;\n --ring-icon-error-color: rgb(var(--ring-icon-error-components)); /* #db5860 */\n --ring-icon-warning-components: 237, 162, 0;\n --ring-icon-warning-color: rgb(var(--ring-icon-warning-components)); /* #eda200 */\n --ring-icon-success-components: 89, 168, 105;\n --ring-icon-success-color: rgb(var(--ring-icon-success-components)); /* #59a869 */\n --ring-pale-control-components: 207, 219, 229;\n --ring-pale-control-color: rgb(var(--ring-pale-control-components)); /* #cfdbe5 */\n --ring-popup-border-components: 0, 28, 54;\n --ring-popup-border-color: var(--ring-line-color);\n --ring-popup-shadow-components: rgba(var(--ring-popup-border-components), 0.1);\n --ring-popup-shadow-color: rgba(var(--ring-popup-border-components), 0.1);\n --ring-popup-secondary-shadow-color: rgba(var(--ring-popup-border-components), 0.04);\n --ring-message-shadow-color: rgba(var(--ring-popup-border-components), 0.3);\n --ring-pinned-shadow-components: 115, 117, 119;\n --ring-pinned-shadow-color: rgb(var(--ring-pinned-shadow-components)); /* #737577 */\n --ring-button-danger-hover-components: var(--ring-icon-error-color);\n --ring-button-danger-hover-color: var(--ring-icon-error-color);\n --ring-button-primary-border-components: 0, 98, 178;\n --ring-button-primary-border-color: rgb(var(--ring-button-primary-border-components)); /* #0062b2 */\n --ring-popup-shadow: 0 2px 8px var(--ring-popup-shadow-color), 0 1px 2px var(--ring-popup-secondary-shadow-color);\n --ring-dialog-shadow: 0 4px 24px var(--ring-popup-shadow-color), 0 2px 6px var(--ring-popup-secondary-shadow-color);\n\n /* Text */\n --ring-search-components: 102, 158, 204;\n --ring-search-color: rgb(var(--ring-search-components)); /* #669ecc */\n --ring-hint-components: 64, 99, 128;\n --ring-hint-color: rgb(var(--ring-hint-components)); /* #406380 */\n --ring-link-components: 15, 91, 153;\n --ring-link-color: rgb(var(--ring-link-components)); /* #0f5b99 */\n --ring-link-hover-components: 255, 0, 140;\n --ring-link-hover-color: rgb(var(--ring-link-hover-components)); /* #ff008c */\n --ring-error-components: 169, 15, 26;\n --ring-error-color: rgb(var(--ring-error-components)); /* #a90f1a */\n --ring-warning-components: 178, 92, 0;\n --ring-warning-color: rgb(var(--ring-warning-components)); /* #b25c00 */\n --ring-success-components: 12, 117, 35;\n --ring-success-color: rgb(var(--ring-success-components)); /* #0c7523 */\n --ring-text-components: 31, 35, 38;\n --ring-text-color: rgb(var(--ring-text-components)); /* #1f2326 */\n --ring-active-text-color: var(--ring-text-color);\n --ring-white-text-components: 255, 255, 255;\n --ring-white-text-color: rgb(var(--ring-white-text-components)); /* #fff */\n --ring-heading-color: var(--ring-text-color);\n --ring-secondary-components: 115, 117, 119;\n --ring-secondary-color: rgb(var(--ring-secondary-components)); /* #737577 */\n --ring-disabled-components: 153, 153, 153;\n --ring-disabled-color: rgb(var(--ring-disabled-components)); /* #999 */\n\n /* Background */\n --ring-content-background-components: 255, 255, 255;\n --ring-content-background-color: rgb(var(--ring-content-background-components)); /* #fff */\n --ring-popup-background-components: 255, 255, 255;\n --ring-popup-background-color: rgb(var(--ring-popup-background-components)); /* #fff */\n --ring-sidebar-background-components: 247, 249, 250;\n --ring-sidebar-background-color: rgb(var(--ring-sidebar-background-components)); /* #f7f9fa */\n --ring-selected-background-components: 212, 237, 255;\n --ring-selected-background-color: rgb(var(--ring-selected-background-components)); /* #d4edff */\n --ring-hover-background-components: 235, 246, 255;\n --ring-hover-background-color: rgb(var(--ring-hover-background-components)); /* #ebf6ff */\n --ring-navigation-background-components: 255, 255, 255;\n --ring-navigation-background-color: rgb(var(--ring-navigation-background-components)); /* #fff */\n --ring-tag-background-components: 230, 236, 242;\n --ring-tag-background-color: rgb(var(--ring-tag-background-components)); /* #e6ecf2 */\n --ring-tag-hover-background-components: 211, 218, 224;\n --ring-tag-hover-background-color: rgb(var(--ring-tag-hover-background-components)); /* #d3dae0 */\n --ring-removed-background-components: 255, 213, 203;\n --ring-removed-background-color: rgb(var(--ring-removed-background-components)); /* #ffd5cb */\n --ring-warning-background-components: 250, 236, 205;\n --ring-warning-background-color: rgb(var(--ring-warning-background-components)); /* #faeccd */\n --ring-added-background-components: 216, 240, 216;\n --ring-added-background-color: rgb(var(--ring-added-background-components)); /* #d8f0d8 */\n --ring-disabled-background-components: 245, 245, 245;\n --ring-disabled-background-color: rgb(var(--ring-disabled-background-components)); /* #f5f5f5 */\n --ring-disabled-selected-background-components: 232, 232, 232;\n --ring-disabled-selected-background-color: rgb(var(--ring-disabled-selected-background-components)); /* #e8e8e8 */\n --ring-button-danger-active-components: 255, 231, 232;\n --ring-button-danger-active-color: rgb(var(--ring-button-danger-active-components)); /* #ffe7e8 */\n --ring-button-loader-background-components: 51, 163, 255;\n --ring-button-loader-background: rgb(var(--ring-button-loader-background-components)); /* #33a3ff */\n --ring-button-primary-background-components: 26, 152, 255;\n --ring-button-primary-background-color: rgb(var(--ring-button-primary-background-components)); /* #1a98ff */\n --ring-table-loader-background-color: rgba(var(--ring-content-background-components), 0.5); /* #ffffff80 */\n\n /* Code */\n --ring-code-background-color: var(--ring-content-background-color);\n --ring-code-components: 0, 0, 0;\n --ring-code-color: rgb(var(--ring-code-components)); /* #000 */\n --ring-code-comment-components: 112, 112, 112;\n --ring-code-comment-color: rgb(var(--ring-code-comment-components)); /* #707070 */\n --ring-code-meta-components: 112, 112, 112;\n --ring-code-meta-color: rgb(var(--ring-code-meta-components)); /* #707070 */\n --ring-code-keyword-components: 0, 0, 128;\n --ring-code-keyword-color: rgb(var(--ring-code-keyword-components)); /* #000080 */\n --ring-code-tag-background-components: 239, 239, 239;\n --ring-code-tag-background-color: rgb(var(--ring-code-tag-background-components)); /* #efefef */\n --ring-code-tag-color: var(--ring-code-keyword-color);\n --ring-code-tag-font-weight: bold;\n --ring-code-field-components: 102, 14, 122;\n --ring-code-field-color: rgb(var(--ring-code-field-components)); /* #660e7a */\n --ring-code-attribute-components: 0, 0, 255;\n --ring-code-attribute-color: rgb(var(--ring-code-attribute-components)); /* #00f */\n --ring-code-number-color: var(--ring-code-attribute-color);\n --ring-code-string-components: 0, 122, 0;\n --ring-code-string-color: rgb(var(--ring-code-string-components)); /* #007a00 */\n --ring-code-addition-components: 170, 222, 170;\n --ring-code-addition-color: rgb(var(--ring-code-addition-components)); /* #aadeaa */\n --ring-code-deletion-components: 200, 200, 200;\n --ring-code-deletion-color: rgb(var(--ring-code-deletion-components)); /* #c8c8c8 */\n\n /* Metrics */\n --ring-border-radius: 4px;\n --ring-border-radius-small: 2px;\n --ring-font-size-larger: 15px;\n --ring-font-size: 14px;\n --ring-font-size-smaller: 12px;\n --ring-line-height-taller: 21px;\n --ring-line-height: 20px;\n --ring-line-height-lower: 18px;\n --ring-line-height-lowest: 16px;\n --ring-ease: 0.3s ease-out;\n --ring-fast-ease: 0.15s ease-out;\n --ring-font-family: system-ui, Arial, sans-serif;\n --ring-font-family-monospace:\n Menlo,\n "Bitstream Vera Sans Mono",\n "Ubuntu Mono",\n Consolas,\n "Courier New",\n Courier,\n monospace;\n\n /* Common z-index-values */\n\n /* Invisible element is an absolutely positioned element which should be below */\n /* all other elements on the page */\n --ring-invisible-element-z-index: -1;\n\n /* z-index for position: fixed elements */\n --ring-fixed-z-index: 1;\n\n /* Elements that should overlay all other elements on the page */\n --ring-overlay-z-index: 5;\n\n /* Alerts should de displayed above overlays */\n --ring-alert-z-index: 6;\n}\n'],sourceRoot:""}]),a.locals={light:"light_f331"};const l=a},9173:(e,n,t)=>{"use strict";t.d(n,{A:()=>l});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i)()(o());a.push([e.id,"/* stylelint-disable color-no-hex */\n\n.ring-ui-theme-dark,\n.dark_d4a9,\n:root.dark_d4a9 {\n --ring-line-components: 71, 81, 89;\n --ring-line-color: rgb(var(--ring-line-components)); /* #475159 */\n --ring-borders-components: 64, 99, 128;\n --ring-borders-color: rgb(var(--ring-borders-components)); /* #406380 */\n --ring-icon-components: 128, 146, 157;\n --ring-icon-color: rgb(var(--ring-icon-components)); /* #80929d */\n --ring-icon-secondary-components: 128, 146, 157;\n --ring-icon-secondary-color: rgb(var(--ring-icon-secondary-components)); /* #80929d */\n --ring-border-disabled-components: 54, 54, 54;\n --ring-border-disabled-color: rgb(var(--ring-border-disabled-components)); /* #363636 */\n --ring-border-selected-disabled-components: 54, 54, 54;\n --ring-border-selected-disabled-color: rgb(var(--ring-border-selected-disabled-components)); /* #363636 */\n --ring-border-unselected-disabled-components: 54, 54, 54;\n --ring-border-unselected-disabled-color: rgb(var(--ring-border-unselected-disabled-components)); /* #363636 */ /* TODO remove in 6.0 */\n --ring-icon-disabled-components: 80, 82, 83;\n --ring-icon-disabled-color: rgb(var(--ring-icon-disabled-components)); /* #505253 */\n --ring-border-hover-components: 112, 177, 230;\n --ring-border-hover-color: rgb(var(--ring-border-hover-components)); /* #70b1e6 */\n --ring-main-components: 0, 142, 255;\n --ring-main-color: rgb(var(--ring-main-components)); /* #008eff */\n --ring-action-link-components: var(--ring-main-components);\n --ring-action-link-color: rgb(var(--ring-main-components)); /* #008eff */\n --ring-main-hover-components: 0, 126, 229;\n --ring-main-hover-color: rgb(var(--ring-main-hover-components)); /* #007ee5 */\n --ring-icon-error-components: 219, 88, 96;\n --ring-icon-error-color: rgb(var(--ring-icon-error-components)); /* #db5860 */\n --ring-icon-warning-components: 237, 162, 0;\n --ring-icon-warning-color: rgb(var(--ring-icon-warning-components)); /* #eda200 */\n --ring-icon-success-components: 71, 212, 100;\n --ring-icon-success-color: rgb(var(--ring-icon-success-components)); /* #47d464 */\n --ring-popup-border-components: 0, 42, 76;\n --ring-popup-border-color: rgba(var(--ring-popup-border-components), 0.1);\n --ring-popup-shadow-color: rgba(var(--ring-popup-border-components), 0.15);\n --ring-message-shadow-color: rgba(var(--ring-popup-border-components), 0.3);\n --ring-pinned-shadow-components: 0, 0, 0;\n --ring-pinned-shadow-color: rgb(var(--ring-pinned-shadow-components)); /* #000 */\n --ring-button-danger-hover-color: var(--ring-error-color);\n --ring-button-primary-border-components: 128, 198, 255;\n --ring-button-primary-border-color: rgb(var(--ring-button-primary-border-components)); /* #80c6ff */\n\n /* Text */\n --ring-hint-components: 128, 146, 157;\n --ring-hint-color: rgb(var(--ring-hint-components)); /* #80929d */\n --ring-link-components: 112, 177, 230;\n --ring-link-color: rgb(var(--ring-link-components)); /* #70b1e6 */\n --ring-error-components: 219, 88, 96;\n --ring-error-color: rgb(var(--ring-error-components)); /* #db5860 */\n --ring-warning-components: 237, 162, 0;\n --ring-warning-color: rgb(var(--ring-warning-components)); /* #eda200 */\n --ring-success-components: 71, 212, 100;\n --ring-success-color: rgb(var(--ring-success-components)); /* #47d464 */\n --ring-text-components: 187, 187, 187;\n --ring-text-color: rgb(var(--ring-text-components)); /* #bbb */\n --ring-active-text-components: 255, 255, 255;\n --ring-active-text-color: rgb(var(--ring-active-text-components)); /* #fff */\n --ring-heading-color: var(--ring-text-color);\n --ring-secondary-components: 128, 146, 157;\n --ring-secondary-color: rgb(var(--ring-secondary-components)); /* #80929d */\n --ring-disabled-components: 81, 95, 104;\n --ring-disabled-color: rgb(var(--ring-disabled-components)); /* #515F68 */\n\n /* Background */\n --ring-content-background-components: 35, 39, 43;\n --ring-content-background-color: rgb(var(--ring-content-background-components)); /* #23272b */\n --ring-popup-background-components: 17, 19, 20;\n --ring-popup-background-color: rgb(var(--ring-popup-background-components)); /* #111314 */\n --ring-sidebar-background-components: 40, 52, 61;\n --ring-sidebar-background-color: rgb(var(--ring-sidebar-background-components)); /* #28343d */\n --ring-selected-background-components: 6, 38, 64;\n --ring-selected-background-color: rgb(var(--ring-selected-background-components)); /* #062640 */\n --ring-hover-background-components: 11, 26, 38;\n --ring-hover-background-color: rgb(var(--ring-hover-background-components)); /* #0b1a26 */\n --ring-navigation-background-components: 17, 19, 20;\n --ring-navigation-background-color: rgb(var(--ring-navigation-background-components)); /* #111314 */\n --ring-tag-background-components: 62, 77, 89;\n --ring-tag-background-color: rgb(var(--ring-tag-background-components)); /* #3e4d59 */\n --ring-tag-hover-background-components: 51, 62, 71;\n --ring-tag-hover-background-color: rgb(var(--ring-tag-hover-background-components)); /* #333e47 */\n --ring-removed-background-components: 143, 82, 71;\n --ring-removed-background-color: rgb(var(--ring-removed-background-components)); /* #8f5247 */\n --ring-warning-background-components: 89, 61, 1;\n --ring-warning-background-color: rgb(var(--ring-warning-background-components)); /* #593d01 */\n --ring-added-background-components: 54, 89, 71;\n --ring-added-background-color: rgb(var(--ring-added-background-components)); /* #365947 */\n --ring-disabled-background-components: 44, 47, 51;\n --ring-disabled-background-color: rgb(var(--ring-disabled-background-components)); /* #2C2F33 */\n --ring-disabled-selected-background-components: 44, 47, 51;\n --ring-disabled-selected-background-color: rgb(var(--ring-disabled-selected-background-components)); /* #2C2F33 */\n --ring-button-danger-active-components: 38, 8, 10;\n --ring-button-danger-active-color: rgb(var(--ring-button-danger-active-components)); /* #26080a */\n --ring-button-primary-background-components: 0, 126, 229;\n --ring-button-primary-background-color: rgb(var(--ring-button-primary-background-components)); /* #007ee5 */\n --ring-table-loader-background-color: rgba(var(--ring-content-background-components), 0.5); /* #23272b80 */\n\n /* Code */\n --ring-code-background-components: 43, 43, 43;\n --ring-code-background-color: rgb(var(--ring-code-background-components)); /* #2b2b2b */\n --ring-code-components: 169, 183, 198;\n --ring-code-color: rgb(var(--ring-code-components)); /* #a9b7c6 */\n --ring-code-meta-components: 187, 181, 41;\n --ring-code-meta-color: rgb(var(--ring-code-meta-components)); /* #bbb529 */\n --ring-code-keyword-components: 204, 120, 50;\n --ring-code-keyword-color: rgb(var(--ring-code-keyword-components)); /* #cc7832 */\n --ring-code-tag-background-components: 43, 43, 43;\n --ring-code-tag-background-color: rgb(var(--ring-code-tag-background-components)); /* #2b2b2b */\n --ring-code-tag-components: 232, 191, 106;\n --ring-code-tag-color: rgb(var(--ring-code-tag-components)); /* #e8bf6a */\n --ring-code-tag-font-weight: normal;\n --ring-code-field-components: 152, 118, 170;\n --ring-code-field-color: rgb(var(--ring-code-tag-font-weight)); /* #9876aa */\n --ring-code-attribute-components: 186, 186, 186;\n --ring-code-attribute-color: rgb(var(--ring-code-attribute-components)); /* #bababa */\n --ring-code-number-components: 104, 151, 187;\n --ring-code-number-color: rgb(var(--ring-code-number-components)); /* #6897bb */\n --ring-code-string-components: 106, 135, 89;\n --ring-code-string-color: rgb(var(--ring-code-string-components)); /* #6a8759 */\n --ring-code-addition-components: 68, 113, 82;\n --ring-code-addition-color: rgb(var(--ring-code-addition-components)); /* #447152 */\n --ring-code-deletion-components: 101, 110, 118;\n --ring-code-deletion-color: rgb(var(--ring-code-deletion-components)); /* #656e76 */\n\n color-scheme: dark;\n}\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/global/variables_dark.css"],names:[],mappings:"AAAA,mCAAmC;;AAEnC;;;EAGE,kCAAkC;EAClC,mDAAmD,EAAE,YAAY;EACjE,sCAAsC;EACtC,yDAAyD,EAAE,YAAY;EACvE,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,+CAA+C;EAC/C,uEAAuE,EAAE,YAAY;EACrF,6CAA6C;EAC7C,yEAAyE,EAAE,YAAY;EACvF,sDAAsD;EACtD,2FAA2F,EAAE,YAAY;EACzG,wDAAwD;EACxD,+FAA+F,EAAE,YAAY,EAAE,uBAAuB;EACtI,2CAA2C;EAC3C,qEAAqE,EAAE,YAAY;EACnF,6CAA6C;EAC7C,mEAAmE,EAAE,YAAY;EACjF,mCAAmC;EACnC,mDAAmD,EAAE,YAAY;EACjE,0DAA0D;EAC1D,0DAA0D,EAAE,YAAY;EACxE,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,2CAA2C;EAC3C,mEAAmE,EAAE,YAAY;EACjF,4CAA4C;EAC5C,mEAAmE,EAAE,YAAY;EACjF,yCAAyC;EACzC,yEAAyE;EACzE,0EAA0E;EAC1E,2EAA2E;EAC3E,wCAAwC;EACxC,qEAAqE,EAAE,SAAS;EAChF,yDAAyD;EACzD,sDAAsD;EACtD,qFAAqF,EAAE,YAAY;;EAEnG,SAAS;EACT,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,oCAAoC;EACpC,qDAAqD,EAAE,YAAY;EACnE,sCAAsC;EACtC,yDAAyD,EAAE,YAAY;EACvE,uCAAuC;EACvC,yDAAyD,EAAE,YAAY;EACvE,qCAAqC;EACrC,mDAAmD,EAAE,SAAS;EAC9D,4CAA4C;EAC5C,iEAAiE,EAAE,SAAS;EAC5E,4CAA4C;EAC5C,0CAA0C;EAC1C,6DAA6D,EAAE,YAAY;EAC3E,uCAAuC;EACvC,2DAA2D,EAAE,YAAY;;EAEzE,eAAe;EACf,gDAAgD;EAChD,+EAA+E,EAAE,YAAY;EAC7F,8CAA8C;EAC9C,2EAA2E,EAAE,YAAY;EACzF,gDAAgD;EAChD,+EAA+E,EAAE,YAAY;EAC7F,gDAAgD;EAChD,iFAAiF,EAAE,YAAY;EAC/F,8CAA8C;EAC9C,2EAA2E,EAAE,YAAY;EACzF,mDAAmD;EACnD,qFAAqF,EAAE,YAAY;EACnG,4CAA4C;EAC5C,uEAAuE,EAAE,YAAY;EACrF,kDAAkD;EAClD,mFAAmF,EAAE,YAAY;EACjG,iDAAiD;EACjD,+EAA+E,EAAE,YAAY;EAC7F,+CAA+C;EAC/C,+EAA+E,EAAE,YAAY;EAC7F,8CAA8C;EAC9C,2EAA2E,EAAE,YAAY;EACzF,iDAAiD;EACjD,iFAAiF,EAAE,YAAY;EAC/F,0DAA0D;EAC1D,mGAAmG,EAAE,YAAY;EACjH,iDAAiD;EACjD,mFAAmF,EAAE,YAAY;EACjG,wDAAwD;EACxD,6FAA6F,EAAE,YAAY;EAC3G,0FAA0F,EAAE,cAAc;;EAE1G,SAAS;EACT,6CAA6C;EAC7C,yEAAyE,EAAE,YAAY;EACvF,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,yCAAyC;EACzC,6DAA6D,EAAE,YAAY;EAC3E,4CAA4C;EAC5C,mEAAmE,EAAE,YAAY;EACjF,iDAAiD;EACjD,iFAAiF,EAAE,YAAY;EAC/F,yCAAyC;EACzC,2DAA2D,EAAE,YAAY;EACzE,mCAAmC;EACnC,2CAA2C;EAC3C,8DAA8D,EAAE,YAAY;EAC5E,+CAA+C;EAC/C,uEAAuE,EAAE,YAAY;EACrF,4CAA4C;EAC5C,iEAAiE,EAAE,YAAY;EAC/E,2CAA2C;EAC3C,iEAAiE,EAAE,YAAY;EAC/E,4CAA4C;EAC5C,qEAAqE,EAAE,YAAY;EACnF,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;;EAEnF,kBAAkB;AACpB",sourcesContent:["/* stylelint-disable color-no-hex */\n\n:global(.ring-ui-theme-dark),\n.dark,\n:root.dark {\n --ring-line-components: 71, 81, 89;\n --ring-line-color: rgb(var(--ring-line-components)); /* #475159 */\n --ring-borders-components: 64, 99, 128;\n --ring-borders-color: rgb(var(--ring-borders-components)); /* #406380 */\n --ring-icon-components: 128, 146, 157;\n --ring-icon-color: rgb(var(--ring-icon-components)); /* #80929d */\n --ring-icon-secondary-components: 128, 146, 157;\n --ring-icon-secondary-color: rgb(var(--ring-icon-secondary-components)); /* #80929d */\n --ring-border-disabled-components: 54, 54, 54;\n --ring-border-disabled-color: rgb(var(--ring-border-disabled-components)); /* #363636 */\n --ring-border-selected-disabled-components: 54, 54, 54;\n --ring-border-selected-disabled-color: rgb(var(--ring-border-selected-disabled-components)); /* #363636 */\n --ring-border-unselected-disabled-components: 54, 54, 54;\n --ring-border-unselected-disabled-color: rgb(var(--ring-border-unselected-disabled-components)); /* #363636 */ /* TODO remove in 6.0 */\n --ring-icon-disabled-components: 80, 82, 83;\n --ring-icon-disabled-color: rgb(var(--ring-icon-disabled-components)); /* #505253 */\n --ring-border-hover-components: 112, 177, 230;\n --ring-border-hover-color: rgb(var(--ring-border-hover-components)); /* #70b1e6 */\n --ring-main-components: 0, 142, 255;\n --ring-main-color: rgb(var(--ring-main-components)); /* #008eff */\n --ring-action-link-components: var(--ring-main-components);\n --ring-action-link-color: rgb(var(--ring-main-components)); /* #008eff */\n --ring-main-hover-components: 0, 126, 229;\n --ring-main-hover-color: rgb(var(--ring-main-hover-components)); /* #007ee5 */\n --ring-icon-error-components: 219, 88, 96;\n --ring-icon-error-color: rgb(var(--ring-icon-error-components)); /* #db5860 */\n --ring-icon-warning-components: 237, 162, 0;\n --ring-icon-warning-color: rgb(var(--ring-icon-warning-components)); /* #eda200 */\n --ring-icon-success-components: 71, 212, 100;\n --ring-icon-success-color: rgb(var(--ring-icon-success-components)); /* #47d464 */\n --ring-popup-border-components: 0, 42, 76;\n --ring-popup-border-color: rgba(var(--ring-popup-border-components), 0.1);\n --ring-popup-shadow-color: rgba(var(--ring-popup-border-components), 0.15);\n --ring-message-shadow-color: rgba(var(--ring-popup-border-components), 0.3);\n --ring-pinned-shadow-components: 0, 0, 0;\n --ring-pinned-shadow-color: rgb(var(--ring-pinned-shadow-components)); /* #000 */\n --ring-button-danger-hover-color: var(--ring-error-color);\n --ring-button-primary-border-components: 128, 198, 255;\n --ring-button-primary-border-color: rgb(var(--ring-button-primary-border-components)); /* #80c6ff */\n\n /* Text */\n --ring-hint-components: 128, 146, 157;\n --ring-hint-color: rgb(var(--ring-hint-components)); /* #80929d */\n --ring-link-components: 112, 177, 230;\n --ring-link-color: rgb(var(--ring-link-components)); /* #70b1e6 */\n --ring-error-components: 219, 88, 96;\n --ring-error-color: rgb(var(--ring-error-components)); /* #db5860 */\n --ring-warning-components: 237, 162, 0;\n --ring-warning-color: rgb(var(--ring-warning-components)); /* #eda200 */\n --ring-success-components: 71, 212, 100;\n --ring-success-color: rgb(var(--ring-success-components)); /* #47d464 */\n --ring-text-components: 187, 187, 187;\n --ring-text-color: rgb(var(--ring-text-components)); /* #bbb */\n --ring-active-text-components: 255, 255, 255;\n --ring-active-text-color: rgb(var(--ring-active-text-components)); /* #fff */\n --ring-heading-color: var(--ring-text-color);\n --ring-secondary-components: 128, 146, 157;\n --ring-secondary-color: rgb(var(--ring-secondary-components)); /* #80929d */\n --ring-disabled-components: 81, 95, 104;\n --ring-disabled-color: rgb(var(--ring-disabled-components)); /* #515F68 */\n\n /* Background */\n --ring-content-background-components: 35, 39, 43;\n --ring-content-background-color: rgb(var(--ring-content-background-components)); /* #23272b */\n --ring-popup-background-components: 17, 19, 20;\n --ring-popup-background-color: rgb(var(--ring-popup-background-components)); /* #111314 */\n --ring-sidebar-background-components: 40, 52, 61;\n --ring-sidebar-background-color: rgb(var(--ring-sidebar-background-components)); /* #28343d */\n --ring-selected-background-components: 6, 38, 64;\n --ring-selected-background-color: rgb(var(--ring-selected-background-components)); /* #062640 */\n --ring-hover-background-components: 11, 26, 38;\n --ring-hover-background-color: rgb(var(--ring-hover-background-components)); /* #0b1a26 */\n --ring-navigation-background-components: 17, 19, 20;\n --ring-navigation-background-color: rgb(var(--ring-navigation-background-components)); /* #111314 */\n --ring-tag-background-components: 62, 77, 89;\n --ring-tag-background-color: rgb(var(--ring-tag-background-components)); /* #3e4d59 */\n --ring-tag-hover-background-components: 51, 62, 71;\n --ring-tag-hover-background-color: rgb(var(--ring-tag-hover-background-components)); /* #333e47 */\n --ring-removed-background-components: 143, 82, 71;\n --ring-removed-background-color: rgb(var(--ring-removed-background-components)); /* #8f5247 */\n --ring-warning-background-components: 89, 61, 1;\n --ring-warning-background-color: rgb(var(--ring-warning-background-components)); /* #593d01 */\n --ring-added-background-components: 54, 89, 71;\n --ring-added-background-color: rgb(var(--ring-added-background-components)); /* #365947 */\n --ring-disabled-background-components: 44, 47, 51;\n --ring-disabled-background-color: rgb(var(--ring-disabled-background-components)); /* #2C2F33 */\n --ring-disabled-selected-background-components: 44, 47, 51;\n --ring-disabled-selected-background-color: rgb(var(--ring-disabled-selected-background-components)); /* #2C2F33 */\n --ring-button-danger-active-components: 38, 8, 10;\n --ring-button-danger-active-color: rgb(var(--ring-button-danger-active-components)); /* #26080a */\n --ring-button-primary-background-components: 0, 126, 229;\n --ring-button-primary-background-color: rgb(var(--ring-button-primary-background-components)); /* #007ee5 */\n --ring-table-loader-background-color: rgba(var(--ring-content-background-components), 0.5); /* #23272b80 */\n\n /* Code */\n --ring-code-background-components: 43, 43, 43;\n --ring-code-background-color: rgb(var(--ring-code-background-components)); /* #2b2b2b */\n --ring-code-components: 169, 183, 198;\n --ring-code-color: rgb(var(--ring-code-components)); /* #a9b7c6 */\n --ring-code-meta-components: 187, 181, 41;\n --ring-code-meta-color: rgb(var(--ring-code-meta-components)); /* #bbb529 */\n --ring-code-keyword-components: 204, 120, 50;\n --ring-code-keyword-color: rgb(var(--ring-code-keyword-components)); /* #cc7832 */\n --ring-code-tag-background-components: 43, 43, 43;\n --ring-code-tag-background-color: rgb(var(--ring-code-tag-background-components)); /* #2b2b2b */\n --ring-code-tag-components: 232, 191, 106;\n --ring-code-tag-color: rgb(var(--ring-code-tag-components)); /* #e8bf6a */\n --ring-code-tag-font-weight: normal;\n --ring-code-field-components: 152, 118, 170;\n --ring-code-field-color: rgb(var(--ring-code-tag-font-weight)); /* #9876aa */\n --ring-code-attribute-components: 186, 186, 186;\n --ring-code-attribute-color: rgb(var(--ring-code-attribute-components)); /* #bababa */\n --ring-code-number-components: 104, 151, 187;\n --ring-code-number-color: rgb(var(--ring-code-number-components)); /* #6897bb */\n --ring-code-string-components: 106, 135, 89;\n --ring-code-string-color: rgb(var(--ring-code-string-components)); /* #6a8759 */\n --ring-code-addition-components: 68, 113, 82;\n --ring-code-addition-color: rgb(var(--ring-code-addition-components)); /* #447152 */\n --ring-code-deletion-components: 101, 110, 118;\n --ring-code-deletion-color: rgb(var(--ring-code-deletion-components)); /* #656e76 */\n\n color-scheme: dark;\n}\n"],sourceRoot:""}]),a.locals={dark:"dark_d4a9"};const l=a},5066:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=a()(o());u.i(c.A),u.i(l.default,"",!0),u.push([e.id,'.icon_aaa7 {\n display: inline-block;\n\n fill: currentColor;\n}\n\n.glyph_f986 {\n display: inline-flex;\n\n margin-right: -1px;\n margin-left: -1px;\n\n pointer-events: none;\n}\n\n.glyph_f986[width="10"] {\n vertical-align: -1px;\n }\n\n.glyph_f986[width="14"] {\n margin-right: -2px;\n margin-left: 0;\n\n vertical-align: -3px;\n }\n\n.glyph_f986[width="16"] {\n vertical-align: -3px;\n }\n\n.glyph_f986[width="20"] {\n vertical-align: -2px;\n }\n\n.glyph_f986.compatibilityMode_d631 {\n width: 16px;\n height: 16px;\n margin-right: 0;\n margin-left: 0;\n }\n\n/* HACK: This media query hack makes styles applied for WebKit browsers only */\n/* stylelint-disable-next-line media-feature-name-no-vendor-prefix */\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n .glyph_f986 {\n width: auto; /* Safari size bug workaround, see https://youtrack.jetbrains.com/issue/RG-1983 */\n }\n}\n\n.gray_f6a8 {\n color: var(--ring-icon-secondary-color);\n}\n\n.hover_fc27 {\n color: var(--ring-icon-hover-color);\n}\n\n.green_bfb1 {\n color: var(--ring-icon-success-color);\n}\n\n.magenta_b045 {\n color: var(--ring-link-hover-color);\n}\n\n.red_a7ec {\n color: var(--ring-icon-error-color);\n}\n\n.blue_ec1e {\n color: var(--ring-main-color);\n}\n\n.white_c896 {\n color: var(--ring-white-text-color);\n}\n\n.loading_c5e2 {\n animation-name: icon-loading_fe22;\n animation-duration: 1200ms;\n animation-iteration-count: infinite;\n}\n\n@keyframes icon-loading_fe22 {\n 0% {\n transform: scale(1);\n }\n\n 50% {\n transform: scale(0.9);\n\n opacity: 0.5;\n }\n\n 100% {\n transform: scale(1);\n }\n}\n',"",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/icon/icon.css"],names:[],mappings:"AAIA;EACE,qBAAqB;;EAErB,kBAAkB;AACpB;;AAEA;EACE,oBAAoB;;EAEpB,kBAAkB;EAClB,iBAAiB;;EAEjB,oBAAoB;AA2BtB;;AAzBE;IACE,oBAAoB;EACtB;;AAEA;IACE,kBAAkB;IAClB,cAAc;;IAEd,oBAAoB;EACtB;;AAEA;IACE,oBAAoB;EACtB;;AAEA;IACE,oBAAoB;EACtB;;AAEA;IACE,WAAqB;IACrB,YAAsB;IACtB,eAAe;IACf,cAAc;EAChB;;AAGF,8EAA8E;AAC9E,oEAAoE;AACpE;EACE;IACE,WAAW,EAAE,iFAAiF;EAChG;AACF;;AAEA;EACE,uCAAuC;AACzC;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,qCAAqC;AACvC;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,6BAA6B;AAC/B;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,iCAA4B;EAC5B,0BAA0B;EAC1B,mCAAmC;AACrC;;AAEA;EACE;IACE,mBAAmB;EACrB;;EAEA;IACE,qBAAqB;;IAErB,YAAY;EACd;;EAEA;IACE,mBAAmB;EACrB;AACF",sourcesContent:['@import "../global/variables.css";\n\n@value unit from "../global/global.css";\n\n.icon {\n display: inline-block;\n\n fill: currentColor;\n}\n\n.glyph {\n display: inline-flex;\n\n margin-right: -1px;\n margin-left: -1px;\n\n pointer-events: none;\n\n &[width="10"] {\n vertical-align: -1px;\n }\n\n &[width="14"] {\n margin-right: -2px;\n margin-left: 0;\n\n vertical-align: -3px;\n }\n\n &[width="16"] {\n vertical-align: -3px;\n }\n\n &[width="20"] {\n vertical-align: -2px;\n }\n\n &.compatibilityMode {\n width: calc(unit * 2);\n height: calc(unit * 2);\n margin-right: 0;\n margin-left: 0;\n }\n}\n\n/* HACK: This media query hack makes styles applied for WebKit browsers only */\n/* stylelint-disable-next-line media-feature-name-no-vendor-prefix */\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n .glyph {\n width: auto; /* Safari size bug workaround, see https://youtrack.jetbrains.com/issue/RG-1983 */\n }\n}\n\n.gray {\n color: var(--ring-icon-secondary-color);\n}\n\n.hover {\n color: var(--ring-icon-hover-color);\n}\n\n.green {\n color: var(--ring-icon-success-color);\n}\n\n.magenta {\n color: var(--ring-link-hover-color);\n}\n\n.red {\n color: var(--ring-icon-error-color);\n}\n\n.blue {\n color: var(--ring-main-color);\n}\n\n.white {\n color: var(--ring-white-text-color);\n}\n\n.loading {\n animation-name: icon-loading;\n animation-duration: 1200ms;\n animation-iteration-count: infinite;\n}\n\n@keyframes icon-loading {\n 0% {\n transform: scale(1);\n }\n\n 50% {\n transform: scale(0.9);\n\n opacity: 0.5;\n }\n\n 100% {\n transform: scale(1);\n }\n}\n'],sourceRoot:""}]),u.locals={unit:`${l.default.locals.unit}`,icon:"icon_aaa7",glyph:"glyph_f986",compatibilityMode:"compatibilityMode_d631",gray:"gray_f6a8",hover:"hover_fc27",green:"green_bfb1",magenta:"magenta_b045",red:"red_a7ec",blue:"blue_ec1e",white:"white_c896",loading:"loading_c5e2","icon-loading":"icon-loading_fe22"};const s=u},8976:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=a()(o());u.i(c.A),u.i(l.default,"",!0),u.push([e.id,":root {\n --ring-input-xs: 96px;\n --ring-input-s: 96px;\n --ring-input-m: 240px;\n --ring-input-l: 400px;\n}\n\n/**\n * @name Input Sizes\n */\n\n/* XS */\n\n.ring-input-size_xs.ring-input-size_xs {\n display: inline-block;\n\n width: 96px;\n\n width: var(--ring-input-xs);\n}\n\n.ring-input-size_xs.ring-input-size_xs ~ .ring-error-bubble {\n left: 98px;\n left: calc(var(--ring-input-xs) + 2px);\n}\n\n/* S */\n\n.ring-input-size_s.ring-input-size_s {\n display: inline-block;\n\n width: 96px;\n\n width: var(--ring-input-s);\n}\n\n.ring-input-size_s.ring-input-size_s ~ .ring-error-bubble {\n left: 98px;\n left: calc(var(--ring-input-s) + 2px);\n}\n\n/* M */\n\n.ring-input-size_m.ring-input-size_m {\n display: inline-block;\n\n width: 240px;\n\n width: var(--ring-input-m);\n}\n\n.ring-input-size_m.ring-input-size_m ~ .ring-error-bubble {\n left: 242px;\n left: calc(var(--ring-input-m) + 2px);\n}\n\n.ring-input-size_md.ring-input-size_md {\n display: inline-block;\n\n width: 240px;\n\n width: var(--ring-input-m);\n}\n\n.ring-input-size_md.ring-input-size_md ~ .ring-error-bubble {\n left: 242px;\n left: calc(var(--ring-input-m) + 2px);\n}\n\n/* L */\n\n.ring-input-size_l.ring-input-size_l {\n display: inline-block;\n\n width: 400px;\n\n width: var(--ring-input-l);\n}\n\n.ring-input-size_l.ring-input-size_l ~ .ring-error-bubble {\n left: 402px;\n left: calc(var(--ring-input-l) + 2px);\n}\n\n.ring-input-height_s.ring-input-height_s {\n --ring-input-padding-block: 1px;\n}\n\n.ring-input-height_m.ring-input-height_m {\n --ring-input-padding-block: 3px;\n}\n\n.ring-input-height_l.ring-input-height_l {\n --ring-input-padding-block: 5px;\n}\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/input-size/input-size.css"],names:[],mappings:"AAIA;EACE,qBAAgC;EAChC,oBAA+B;EAC/B,qBAA+B;EAC/B,qBAA+B;AACjC;;AAEA;;EAEE;;AAEF,OAAO;;AAEP;EACE,qBAAqB;;EAErB,WAA2B;;EAA3B,2BAA2B;AAC7B;;AAEA;EACE,UAAsC;EAAtC,sCAAsC;AACxC;;AAEA,MAAM;;AAEN;EACE,qBAAqB;;EAErB,WAA0B;;EAA1B,0BAA0B;AAC5B;;AAEA;EACE,UAAqC;EAArC,qCAAqC;AACvC;;AAEA,MAAM;;AAEN;EACE,qBAAqB;;EAErB,YAA0B;;EAA1B,0BAA0B;AAC5B;;AAEA;EACE,WAAqC;EAArC,qCAAqC;AACvC;;AAEA;EACE,qBAAqB;;EAErB,YAA0B;;EAA1B,0BAA0B;AAC5B;;AAEA;EACE,WAAqC;EAArC,qCAAqC;AACvC;;AAEA,MAAM;;AAEN;EACE,qBAAqB;;EAErB,YAA0B;;EAA1B,0BAA0B;AAC5B;;AAEA;EACE,WAAqC;EAArC,qCAAqC;AACvC;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC",sourcesContent:['@import "../global/variables.css";\n\n@value unit from "../global/global.css";\n\n:root {\n --ring-input-xs: calc(unit * 12);\n --ring-input-s: calc(unit * 12);\n --ring-input-m: calc(unit * 30);\n --ring-input-l: calc(unit * 50);\n}\n\n/**\n * @name Input Sizes\n */\n\n/* XS */\n\n:global(.ring-input-size_xs.ring-input-size_xs) {\n display: inline-block;\n\n width: var(--ring-input-xs);\n}\n\n:global(.ring-input-size_xs.ring-input-size_xs ~ .ring-error-bubble) {\n left: calc(var(--ring-input-xs) + 2px);\n}\n\n/* S */\n\n:global(.ring-input-size_s.ring-input-size_s) {\n display: inline-block;\n\n width: var(--ring-input-s);\n}\n\n:global(.ring-input-size_s.ring-input-size_s ~ .ring-error-bubble) {\n left: calc(var(--ring-input-s) + 2px);\n}\n\n/* M */\n\n:global(.ring-input-size_m.ring-input-size_m) {\n display: inline-block;\n\n width: var(--ring-input-m);\n}\n\n:global(.ring-input-size_m.ring-input-size_m ~ .ring-error-bubble) {\n left: calc(var(--ring-input-m) + 2px);\n}\n\n:global(.ring-input-size_md.ring-input-size_md) {\n display: inline-block;\n\n width: var(--ring-input-m);\n}\n\n:global(.ring-input-size_md.ring-input-size_md ~ .ring-error-bubble) {\n left: calc(var(--ring-input-m) + 2px);\n}\n\n/* L */\n\n:global(.ring-input-size_l.ring-input-size_l) {\n display: inline-block;\n\n width: var(--ring-input-l);\n}\n\n:global(.ring-input-size_l.ring-input-size_l ~ .ring-error-bubble) {\n left: calc(var(--ring-input-l) + 2px);\n}\n\n:global(.ring-input-height_s.ring-input-height_s) {\n --ring-input-padding-block: 1px;\n}\n\n:global(.ring-input-height_m.ring-input-height_m) {\n --ring-input-padding-block: 3px;\n}\n\n:global(.ring-input-height_l.ring-input-height_l) {\n --ring-input-padding-block: 5px;\n}\n'],sourceRoot:""}]),u.locals={unit:`${l.default.locals.unit}`};const s=u},8266:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>f});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=t(9892),s=a()(o());s.i(c.A),s.i(u.default),s.i(l.default,"",!0),s.push([e.id,'.outerContainer_cb70 {\n --ring-input-icon-offset: 20px;\n --ring-input-padding-inline: 8px;\n --ring-input-background-color: var(--ring-content-background-color);\n}\n\n.borderless_f79b {\n /* stylelint-disable-next-line length-zero-no-unit */\n --ring-input-padding-inline: 0px;\n}\n\n.container_ee33 {\n position: relative;\n\n box-sizing: border-box;\n\n font-size: var(--ring-font-size);\n line-height: var(--ring-line-height);\n}\n\n.container_ee33 * {\n box-sizing: border-box;\n }\n\n.input_f220 {\n --ring-input-padding-start: var(--ring-input-padding-inline);\n --ring-input-padding-end: var(--ring-input-padding-inline);\n\n width: 100%;\n\n margin: 0;\n padding-top: var(--ring-input-padding-block);\n padding-right: var(--ring-input-padding-end);\n padding-bottom: var(--ring-input-padding-block);\n padding-left: var(--ring-input-padding-start);\n\n transition: border-color var(--ring-ease);\n\n color: var(--ring-text-color);\n border: 1px solid var(--ring-borders-color);\n border-radius: var(--ring-border-radius);\n outline: none;\n background-color: var(--ring-input-background-color);\n\n font: inherit;\n\n caret-color: var(--ring-main-color);\n}\n\n[dir="rtl"] .input_f220 {\n padding-right: var(--ring-input-padding-start);\n padding-left: var(--ring-input-padding-end);\n }\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.input_f220:hover {\n transition: none;\n\n border-color: var(--ring-border-hover-color);\n }}\n\n.error_ff90 .input_f220 {\n border-color: var(--ring-icon-error-color);\n }\n\n.input_f220:focus {\n transition: none;\n\n border-color: var(--ring-main-color);\n }\n\n.input_f220[disabled] {\n color: var(--ring-disabled-color);\n border-color: var(--ring-border-disabled-color);\n background-color: var(--ring-disabled-background-color);\n\n -webkit-text-fill-color: var(--ring-disabled-color); /* Required for Safari, see RG-2063 for details */\n }\n\n/*\n Kill yellow/blue webkit autocomplete\n https://css-tricks.com/snippets/css/change-autocomplete-styles-webkit-browsers/\n */\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.input_f220:-webkit-autofill:hover {\n -webkit-transition: background-color 50000s ease-in-out 0s;\n transition: background-color 50000s ease-in-out 0s;\n }}\n\n.input_f220:-webkit-autofill,\n .input_f220:-webkit-autofill:focus {\n -webkit-transition: background-color 50000s ease-in-out 0s;\n transition: background-color 50000s ease-in-out 0s;\n }\n\n.borderless_f79b .input_f220 {\n border-color: transparent;\n background-color: transparent;\n}\n\n.withIcon_f066 .input_f220 {\n --ring-input-padding-start: calc(var(--ring-input-padding-inline) + var(--ring-input-icon-offset));\n}\n\n.clearable_fd1e .input_f220 {\n --ring-input-padding-end: calc(var(--ring-input-padding-inline) + var(--ring-input-icon-offset));\n}\n\n.icon_e49c {\n position: absolute;\n top: calc(var(--ring-input-padding-block) + 1px);\n left: var(--ring-input-padding-inline);\n\n pointer-events: none;\n\n color: var(--ring-icon-secondary-color);\n}\n\n[dir="rtl"] .icon_e49c {\n right: 8px;\n left: auto;\n }\n\n.clear_ffc3 {\n position: absolute;\n top: calc(var(--ring-input-padding-block) + 2px);\n right: var(--ring-input-padding-inline);\n\n height: auto;\n\n padding-right: 0;\n\n line-height: inherit;\n}\n\n.empty_cc0d .clear_ffc3 {\n display: none;\n }\n\n[dir="rtl"] .clear_ffc3 {\n right: auto;\n left: 8px;\n }\n\ntextarea.input_f220 {\n overflow: hidden;\n\n box-sizing: border-box;\n\n resize: none;\n}\n\n.input_f220::-moz-placeholder {\n color: var(--ring-disabled-color);\n}\n\n.input_f220::placeholder {\n color: var(--ring-disabled-color);\n}\n\n.input_f220::-webkit-search-cancel-button {\n -webkit-appearance: none;\n}\n\n.errorText_e447 {\n margin-top: 4px;\n\n color: var(--ring-error-color);\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lowest);\n}\n\n.sizeS_c560 {\n width: 96px;\n}\n\n.sizeM_aee6 {\n width: 240px;\n}\n\n.sizeL_b0ca {\n width: 400px;\n}\n\n.sizeFULL_f4f9 {\n width: 100%;\n}\n\n.heightS_a68d {\n --ring-input-padding-block: 1px;\n}\n\n.heightM_bc35 {\n --ring-input-padding-block: 3px;\n}\n\n.heightL_f82d {\n --ring-input-padding-block: 5px;\n}\n',"",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/input/input.css",""],names:[],mappings:"AAKA;EACE,8BAA0C;EAC1C,gCAAiC;EACjC,mEAAmE;AACrE;;AAEA;EACE,oDAAoD;EACpD,gCAAgC;AAClC;;AAEA;EACE,kBAAkB;;EAElB,sBAAsB;;EAEtB,gCAAgC;EAChC,oCAAoC;AAKtC;;AAHE;IACE,sBAAsB;EACxB;;AAGF;EACE,4DAA4D;EAC5D,0DAA0D;;EAE1D,WAAW;;EAEX,SAAS;EACT,4CAA4C;EAC5C,4CAA4C;EAC5C,+CAA+C;EAC/C,6CAA6C;;EAE7C,yCAAyC;;EAEzC,6BAA6B;EAC7B,2CAA2C;EAC3C,wCAAwC;EACxC,aAAa;EACb,oDAAoD;;EAEpD,aAAa;;EAEb,mCAAmC;AA0CrC;;AAxCE;IACE,8CAA8C;IAC9C,2CAA2C;EAC7C;;ACxDF,wGAAA;IAAA,iBAAA;;IAAA,6CAAA;GAAA,CAAA;;ADgEE;IACE,0CAA0C;EAC5C;;AAEA;IACE,gBAAgB;;IAEhB,oCAAoC;EACtC;;AAEA;IACE,iCAAiC;IACjC,+CAA+C;IAC/C,uDAAuD;;IAEvD,mDAAmD,EAAE,iDAAiD;EACxG;;AAEA;;;GAGC;;ACrFH,wGAAA;MAAA,2DAAA;MAAA,mDAAA;KAAA,CAAA;;ADuFI;;MAGE,0DAAkD;MAAlD,kDAAkD;IACpD;;AAIJ;EACE,yBAAyB;EACzB,6BAA6B;AAC/B;;AAEA;EACE,kGAAkG;AACpG;;AAEA;EACE,gGAAgG;AAClG;;AAEA;EACE,kBAAkB;EAClB,gDAAgD;EAChD,sCAAsC;;EAEtC,oBAAoB;;EAEpB,uCAAuC;AAMzC;;AAJE;IACE,UAAW;IACX,UAAU;EACZ;;AAGF;EACE,kBAAkB;EAClB,gDAAgD;EAChD,uCAAuC;;EAEvC,YAAY;;EAEZ,gBAAgB;;EAEhB,oBAAoB;AAUtB;;AARE;IACE,aAAa;EACf;;AAEA;IACE,WAAW;IACX,SAAU;EACZ;;AAGF;EACE,gBAAgB;;EAEhB,sBAAsB;;EAEtB,YAAY;AACd;;AAEA;EACE,iCAAiC;AACnC;;AAFA;EACE,iCAAiC;AACnC;;AAEA;EACE,wBAAwB;AAC1B;;AAEA;EACE,eAA0B;;EAE1B,8BAA8B;;EAE9B,wCAAwC;EACxC,2CAA2C;AAC7C;;AAEA;EACE,WAAsB;AACxB;;AAEA;EACE,YAAsB;AACxB;;AAEA;EACE,YAAsB;AACxB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC",sourcesContent:['@import "../global/variables.css";\n@import "../button/button.css";\n\n@value unit from "../global/global.css";\n\n.outerContainer {\n --ring-input-icon-offset: calc(unit * 2.5);\n --ring-input-padding-inline: unit;\n --ring-input-background-color: var(--ring-content-background-color);\n}\n\n.borderless {\n /* stylelint-disable-next-line length-zero-no-unit */\n --ring-input-padding-inline: 0px;\n}\n\n.container {\n position: relative;\n\n box-sizing: border-box;\n\n font-size: var(--ring-font-size);\n line-height: var(--ring-line-height);\n\n & * {\n box-sizing: border-box;\n }\n}\n\n.input {\n --ring-input-padding-start: var(--ring-input-padding-inline);\n --ring-input-padding-end: var(--ring-input-padding-inline);\n\n width: 100%;\n\n margin: 0;\n padding-top: var(--ring-input-padding-block);\n padding-right: var(--ring-input-padding-end);\n padding-bottom: var(--ring-input-padding-block);\n padding-left: var(--ring-input-padding-start);\n\n transition: border-color var(--ring-ease);\n\n color: var(--ring-text-color);\n border: 1px solid var(--ring-borders-color);\n border-radius: var(--ring-border-radius);\n outline: none;\n background-color: var(--ring-input-background-color);\n\n font: inherit;\n\n caret-color: var(--ring-main-color);\n\n [dir="rtl"] & {\n padding-right: var(--ring-input-padding-start);\n padding-left: var(--ring-input-padding-end);\n }\n\n &:hover {\n transition: none;\n\n border-color: var(--ring-border-hover-color);\n }\n\n .error & {\n border-color: var(--ring-icon-error-color);\n }\n\n &:focus {\n transition: none;\n\n border-color: var(--ring-main-color);\n }\n\n &[disabled] {\n color: var(--ring-disabled-color);\n border-color: var(--ring-border-disabled-color);\n background-color: var(--ring-disabled-background-color);\n\n -webkit-text-fill-color: var(--ring-disabled-color); /* Required for Safari, see RG-2063 for details */\n }\n\n /*\n Kill yellow/blue webkit autocomplete\n https://css-tricks.com/snippets/css/change-autocomplete-styles-webkit-browsers/\n */\n &:-webkit-autofill {\n &,\n &:hover,\n &:focus {\n transition: background-color 50000s ease-in-out 0s;\n }\n }\n}\n\n.borderless .input {\n border-color: transparent;\n background-color: transparent;\n}\n\n.withIcon .input {\n --ring-input-padding-start: calc(var(--ring-input-padding-inline) + var(--ring-input-icon-offset));\n}\n\n.clearable .input {\n --ring-input-padding-end: calc(var(--ring-input-padding-inline) + var(--ring-input-icon-offset));\n}\n\n.icon {\n position: absolute;\n top: calc(var(--ring-input-padding-block) + 1px);\n left: var(--ring-input-padding-inline);\n\n pointer-events: none;\n\n color: var(--ring-icon-secondary-color);\n\n [dir="rtl"] & {\n right: unit;\n left: auto;\n }\n}\n\n.clear {\n position: absolute;\n top: calc(var(--ring-input-padding-block) + 2px);\n right: var(--ring-input-padding-inline);\n\n height: auto;\n\n padding-right: 0;\n\n line-height: inherit;\n\n .empty & {\n display: none;\n }\n\n [dir="rtl"] & {\n right: auto;\n left: unit;\n }\n}\n\ntextarea.input {\n overflow: hidden;\n\n box-sizing: border-box;\n\n resize: none;\n}\n\n.input::placeholder {\n color: var(--ring-disabled-color);\n}\n\n.input::-webkit-search-cancel-button {\n -webkit-appearance: none;\n}\n\n.errorText {\n margin-top: calc(unit / 2);\n\n color: var(--ring-error-color);\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lowest);\n}\n\n.sizeS {\n width: calc(unit * 12);\n}\n\n.sizeM {\n width: calc(unit * 30);\n}\n\n.sizeL {\n width: calc(unit * 50);\n}\n\n.sizeFULL {\n width: 100%;\n}\n\n.heightS {\n --ring-input-padding-block: 1px;\n}\n\n.heightM {\n --ring-input-padding-block: 3px;\n}\n\n.heightL {\n --ring-input-padding-block: 5px;\n}\n',null],sourceRoot:""}]),s.locals={unit:`${l.default.locals.unit}`,outerContainer:"outerContainer_cb70",borderless:"borderless_f79b",container:"container_ee33",input:"input_f220",error:"error_ff90",withIcon:"withIcon_f066",clearable:"clearable_fd1e",icon:"icon_e49c",clear:"clear_ffc3",empty:"empty_cc0d",errorText:"errorText_e447",sizeS:"sizeS_c560",sizeM:"sizeM_aee6",sizeL:"sizeL_b0ca",sizeFULL:"sizeFULL_f4f9",heightS:"heightS_a68d",heightM:"heightM_bc35",heightL:"heightL_f82d"};const f=s},6960:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,".link_e6e5 {\n cursor: pointer;\n transition: color var(--ring-fast-ease);\n\n color: var(--ring-link-color);\n\n outline: none;\n}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5:hover {\n transition: none;\n\n color: var(--ring-link-hover-color);\n }}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5:hover {\n text-decoration: none;\n }}\n\n.link_e6e5 {\n text-decoration: none;\n }\n\n.link_e6e5.hover_bed7 {\n transition: none;\n\n color: var(--ring-link-hover-color);\n }\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5:hover .inner_e3ba {\n border-width: 0;\n border-bottom: 2px solid;\n border-image-source: linear-gradient(currentcolor 50%, transparent 50%);\n border-image-slice: 0 0 100% 0;\n }}\n\n.link_e6e5.active_f804 {\n color: inherit;\n }\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5.compatibilityUnderlineMode_e7a0:hover {\n text-decoration: underline;\n\n /* stylelint-disable-next-line selector-max-specificity */\n }\n .link_e6e5.compatibilityUnderlineMode_e7a0:hover .inner_e3ba {\n border: none;\n }}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5.pseudo_d9ae:hover {\n text-decoration: none;\n\n /* stylelint-disable-next-line selector-max-specificity */\n }\n .link_e6e5.pseudo_d9ae:hover .inner_e3ba {\n border: none;\n }}\n\n.link_e6e5:focus-visible {\n box-shadow: 0 0 0 2px var(--ring-border-hover-color);\n }\n\n@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5:hover .inner_e3ba {\n border-bottom-width: 1px;\n }}\n}\n\n.text_e98a {\n border-radius: var(--ring-border-radius);\n}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.inherit_d267:not(:hover) {\n color: inherit;\n}}\n\n.pseudo_d9ae {\n margin: 0;\n padding: 0;\n\n text-align: left;\n\n border: 0;\n\n background: transparent;\n\n font: inherit;\n}\n\n.pseudo_d9ae::-moz-focus-inner {\n padding: 0;\n\n border: 0;\n }\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/link/link.css",""],names:[],mappings:"AAEA;EACE,eAAe;EACf,uCAAuC;;EAEvC,6BAA6B;;EA2C7B,aAAa;AAKf;;ACtDA,wGAAA;IAAA,iBAAA;;IAAA,oCAAA;GAAA,CAAA;;AAAA,wGAAA;IAAA,sBAAA;GAAA,CAAA;;ADQE;IAEE,qBAAqB;EACvB;;AAEA;IAEE,gBAAgB;;IAEhB,mCAAmC;EACrC;;AClBF,wGAAA;IAAA,gBAAA;IAAA,yBAAA;IAAA,wEAAA;IAAA,+BAAA;GAAA,CAAA;;AD2BE;IACE,cAAc;EAChB;;AC7BF,wGAAA;IAAA,2BAAA;;IAAA,0DAAA;GAAA;IAAA;MAAA,aAAA;KAAA,CAAA;;AAAA,wGAAA;IAAA,sBAAA;;IAAA,0DAAA;GAAA;IAAA;MAAA,aAAA;KAAA,CAAA;;ADmDE;IACE,oDAAoD;EACtD;;AAGF,qECxDA,wGAAA;IAAA,yBAAA;GAAA,CAAA;AD4DA;;AAEA;EACE,wCAAwC;AAC1C;;AChEA,wGAAA;EAAA,eAAA;CAAA,CAAA;;ADsEA;EACE,SAAS;EACT,UAAU;;EAEV,gBAAgB;;EAEhB,SAAS;;EAET,uBAAuB;;EAEvB,aAAa;AAOf;;AALE;IACE,UAAU;;IAEV,SAAS;EACX",sourcesContent:['@import "../global/variables.css";\n\n.link {\n cursor: pointer;\n transition: color var(--ring-fast-ease);\n\n color: var(--ring-link-color);\n\n &,\n &:hover {\n text-decoration: none;\n }\n\n &:hover,\n &.hover {\n transition: none;\n\n color: var(--ring-link-hover-color);\n }\n\n &:hover .inner {\n border-width: 0;\n border-bottom: 2px solid;\n border-image-source: linear-gradient(currentcolor 50%, transparent 50%);\n border-image-slice: 0 0 100% 0;\n }\n\n &.active {\n color: inherit;\n }\n\n &.compatibilityUnderlineMode:hover {\n text-decoration: underline;\n\n /* stylelint-disable-next-line selector-max-specificity */\n & .inner {\n border: none;\n }\n }\n\n &.pseudo:hover {\n text-decoration: none;\n\n /* stylelint-disable-next-line selector-max-specificity */\n & .inner {\n border: none;\n }\n }\n\n outline: none;\n\n &:focus-visible {\n box-shadow: 0 0 0 2px var(--ring-border-hover-color);\n }\n}\n\n@media (min-resolution: 2dppx) {\n .link:hover .inner {\n border-bottom-width: 1px;\n }\n}\n\n.text {\n border-radius: var(--ring-border-radius);\n}\n\n.inherit:not(:hover) {\n color: inherit;\n}\n\n.pseudo {\n margin: 0;\n padding: 0;\n\n text-align: left;\n\n border: 0;\n\n background: transparent;\n\n font: inherit;\n\n &::-moz-focus-inner {\n padding: 0;\n\n border: 0;\n }\n}\n',null],sourceRoot:""}]),c.locals={link:"link_e6e5",hover:"hover_bed7",inner:"inner_e3ba",active:"active_f804",compatibilityUnderlineMode:"compatibilityUnderlineMode_e7a0",pseudo:"pseudo_d9ae",text:"text_e98a",inherit:"inherit_d267"};const u=c},480:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=a()(o());u.i(c.A),u.i(l.default,"",!0),u.push([e.id,'.list_a01c {\n position: relative;\n\n z-index: 1;\n\n border-radius: var(--ring-border-radius);\n\n line-height: normal;\n}\n\n.simpleInner_a4f8 {\n overflow: auto;\n}\n\n.scrolling_a910 {\n pointer-events: none;\n}\n\n.separator_c26e {\n display: block;\n\n min-height: 8px;\n\n margin-top: 8px;\n padding: 0 16px 1px;\n\n text-align: right;\n white-space: nowrap;\n\n color: var(--ring-secondary-color);\n border-top: 1px solid var(--ring-line-color);\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lower);\n}\n\n.separator_first_ec9e {\n margin-top: 0;\n padding-top: 0;\n\n border: none;\n}\n\n.item_eadd {\n display: block;\n\n box-sizing: border-box;\n\n width: 100%;\n\n text-align: left;\n vertical-align: bottom;\n white-space: nowrap;\n text-decoration: none;\n\n outline: none;\n\n font-size: var(--ring-font-size);\n}\n\n.item_eadd.item_eadd {\n padding: 3px 16px 5px;\n\n line-height: 24px;\n}\n\n.itemContainer_f365 {\n position: relative;\n}\n\n.compact_efa8 {\n line-height: 16px;\n}\n\n.error_aa15 {\n cursor: default;\n}\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.error_aa15:hover {\n color: var(--ring-error-color);\n }}\n\n/* Override ring-link */\n\n.error_aa15,\n .error_aa15:focus,\n .error_aa15:visited {\n color: var(--ring-error-color);\n }\n\n.add_a8da {\n padding: 8px 16px;\n\n line-height: 32px;\n}\n\n.top_c4d5 {\n display: flex;\n align-items: baseline;\n flex-direction: row;\n}\n\n.left_ea6b {\n align-self: center;\n flex-shrink: 0;\n}\n\n.label_dac9 {\n overflow: hidden;\n flex-grow: 1;\n flex-shrink: 1;\n\n text-align: left;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n[dir="rtl"] .label_dac9 {\n text-align: right;\n direction: ltr;\n }\n\n.description_efcc {\n overflow: hidden;\n flex-shrink: 100;\n\n padding-left: 8px;\n\n text-align: right;\n white-space: nowrap;\n text-overflow: ellipsis;\n\n color: var(--ring-secondary-color);\n\n font-size: var(--ring-font-size-smaller);\n font-weight: 400;\n line-height: var(--ring-line-height-lowest);\n}\n\n.right_df77 {\n display: flex;\n align-items: center;\n align-self: center;\n flex-direction: row;\n flex-shrink: 0;\n}\n\n.details_a2b7 {\n margin-bottom: 6px;\n\n white-space: normal;\n\n color: var(--ring-secondary-color);\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lowest);\n}\n\n.padded_a74d {\n margin-left: 20px;\n}\n\n/* Override :last-child */\n.hint_d29d.hint_d29d {\n margin-bottom: 0;\n\n border-top: 1px solid var(--ring-line-color);\n background-color: var(--ring-sidebar-background-color);\n\n font-size: var(--ring-font-size-smaller);\n}\n\n.action_d10e {\n cursor: pointer;\n\n color: var(--ring-text-color);\n}\n\n/* override link */\n.actionLink_a4c7.actionLink_a4c7 {\n transition: none;\n}\n\n.hover_a4cd:not(.error_aa15) {\n background-color: var(--ring-selected-background-color);\n}\n\n.icon_f1f3 {\n display: inline-block;\n\n width: 20px;\n height: 20px;\n margin-left: 16px;\n\n background-repeat: no-repeat;\n background-position: center;\n\n background-size: contain;\n}\n\n.highlight_e4dd {\n color: var(--ring-link-hover-color);\n}\n\n.service_a4fc {\n color: var(--ring-secondary-color);\n}\n\n.glyph_dfd5 {\n float: left;\n\n width: 20px;\n\n margin-right: 8px;\n\n color: var(--ring-icon-secondary-color);\n}\n\n.avatar_f258 {\n\n top: 0;\n\n height: 20px;\n\n -o-object-fit: cover;\n\n object-fit: cover;\n -o-object-position: center;\n object-position: center;\n}\n\n.rightGlyph_fb77 {\n\n float: right;\n\n margin-right: 0;\n margin-left: 16px;\n}\n\n.checkboxContainer_c949 {\n position: absolute;\n top: 7px;\n left: 19px;\n\n width: 20px;\n height: 20px;\n margin-right: 8px;\n}\n\n.compact_efa8 .checkboxContainer_c949 {\n top: 0;\n\n width: 16px;\n height: 16px;\n}\n\n.title_e1bf {\n display: block;\n\n margin-top: 10px;\n margin-bottom: 6px;\n padding: 8px 16px 0;\n\n text-align: left;\n}\n\n[dir="rtl"] .title_e1bf {\n text-align: right;\n direction: ltr;\n }\n\n.title_first_ac55 {\n margin-top: 0;\n}\n\n.text_fe0e {\n letter-spacing: 1.5px;\n text-transform: uppercase;\n\n color: var(--ring-secondary-color);\n\n font-size: var(--ring-font-size-smaller);\n}\n\n.fade_d35c {\n position: absolute;\n bottom: 0;\n\n width: 100%;\n height: 24px;\n\n pointer-events: none;\n\n background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--ring-content-background-color));\n}\n\n.disabled_c3d8 {\n pointer-events: none;\n\n color: var(--ring-disabled-color);\n}\n',"",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/list/list.css",""],names:[],mappings:"AAKA;EACE,kBAAkB;;EAElB,UAAU;;EAEV,wCAAwC;;EAExC,mBAAmB;AACrB;;AAEA;EACE,cAAc;AAChB;;AAEA;EACE,oBAAoB;AACtB;;AAEA;EACE,cAAc;;EAEd,eAAuB;;EAEvB,eAAuB;EACvB,mBAA6B;;EAE7B,iBAAiB;EACjB,mBAAmB;;EAEnB,kCAAkC;EAClC,4CAA4C;;EAE5C,wCAAwC;EACxC,0CAA0C;AAC5C;;AAEA;EACE,aAAa;EACb,cAAc;;EAEd,YAAY;AACd;;AAEA;EACE,cAAc;;EAEd,sBAAsB;;EAEtB,WAAW;;EAEX,gBAAgB;EAChB,sBAAsB;EACtB,mBAAmB;EACnB,qBAAqB;;EAErB,aAAa;;EAEb,gCAAgC;AAClC;;AAEA;EACE,qBAA+B;;EAE/B,iBAA2B;AAC7B;;AAEA;EACE,kBAAkB;AACpB;;AAEA;EACE,iBAA2B;AAC7B;;AAEA;EACE,eAAe;AASjB;;ACzFA,wGAAA;IAAA,+BAAA;GAAA,CAAA;;ADkFE,uBAAuB;;AACvB;;;IAIE,8BAA8B;EAChC;;AAGF;EACE,iBAA4B;;EAE5B,iBAA2B;AAC7B;;AAEA;EACE,aAAa;EACb,qBAAqB;EACrB,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;EAClB,cAAc;AAChB;;AAEA;EACE,gBAAgB;EAChB,YAAY;EACZ,cAAc;;EAEd,gBAAgB;EAChB,mBAAmB;EACnB,uBAAuB;AAMzB;;AAJE;IACE,iBAAiB;IACjB,cAAc;EAChB;;AAGF;EACE,gBAAgB;EAChB,gBAAgB;;EAEhB,iBAAkB;;EAElB,iBAAiB;EACjB,mBAAmB;EACnB,uBAAuB;;EAEvB,kCAAkC;;EAElC,wCAAwC;EACxC,gBAAgB;EAChB,2CAA2C;AAC7C;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,kBAAkB;EAClB,mBAAmB;EACnB,cAAc;AAChB;;AAEA;EACE,kBAAkB;;EAElB,mBAAmB;;EAEnB,kCAAkC;;EAElC,wCAAwC;EACxC,2CAA2C;AAC7C;;AAEA;EACE,iBAAiB;AACnB;;AAEA,yBAAyB;AACzB;EACE,gBAAgB;;EAEhB,4CAA4C;EAC5C,sDAAsD;;EAEtD,wCAAwC;AAC1C;;AAEA;EACE,eAAe;;EAEf,6BAA6B;AAC/B;;AAEA,kBAAkB;AAClB;EACE,gBAAgB;AAClB;;AAEA;EACE,uDAAuD;AACzD;;AAEA;EACE,qBAAqB;;EAErB,WAAW;EACX,YAAY;EACZ,iBAA2B;;EAE3B,4BAA4B;EAC5B,2BAA2B;;EAE3B,wBAAwB;AAC1B;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,kCAAkC;AACpC;;AAEA;EACE,WAAW;;EAEX,WAAW;;EAEX,iBAAkB;;EAElB,uCAAuC;AACzC;;AAEA;;EAGE,MAAM;;EAEN,YAAY;;EAEZ,oBAAiB;;KAAjB,iBAAiB;EACjB,0BAAuB;KAAvB,uBAAuB;AACzB;;AAEA;;EAGE,YAAY;;EAEZ,eAAe;EACf,iBAA2B;AAC7B;;AAEA;EACE,kBAAkB;EAClB,QAAQ;EACR,UAAU;;EAEV,WAAW;EACX,YAAY;EACZ,iBAAkB;AACpB;;AAEA;EACE,MAAM;;EAEN,WAAqB;EACrB,YAAsB;AACxB;;AAEA;EACE,cAAc;;EAEd,gBAAgB;EAChB,kBAAkB;EAClB,mBAAqC;;EAErC,gBAAgB;AAMlB;;AAJE;IACE,iBAAiB;IACjB,cAAc;EAChB;;AAGF;EACE,aAAa;AACf;;AAEA;EACE,qBAAqB;EACrB,yBAAyB;;EAEzB,kCAAkC;;EAElC,wCAAwC;AAC1C;;AAEA;EACE,kBAAkB;EAClB,SAAS;;EAET,WAAW;EACX,YAAsB;;EAEtB,oBAAoB;;EAEpB,oGAAoG;AACtG;;AAEA;EACE,oBAAoB;;EAEpB,iCAAiC;AACnC",sourcesContent:['@import "../global/variables.css";\n\n@value unit from "../global/global.css";\n@value listSpacing: unit;\n\n.list {\n position: relative;\n\n z-index: 1;\n\n border-radius: var(--ring-border-radius);\n\n line-height: normal;\n}\n\n.simpleInner {\n overflow: auto;\n}\n\n.scrolling {\n pointer-events: none;\n}\n\n.separator {\n display: block;\n\n min-height: listSpacing;\n\n margin-top: listSpacing;\n padding: 0 calc(unit * 2) 1px;\n\n text-align: right;\n white-space: nowrap;\n\n color: var(--ring-secondary-color);\n border-top: 1px solid var(--ring-line-color);\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lower);\n}\n\n.separator_first {\n margin-top: 0;\n padding-top: 0;\n\n border: none;\n}\n\n.item {\n display: block;\n\n box-sizing: border-box;\n\n width: 100%;\n\n text-align: left;\n vertical-align: bottom;\n white-space: nowrap;\n text-decoration: none;\n\n outline: none;\n\n font-size: var(--ring-font-size);\n}\n\n.item.item {\n padding: 3px calc(unit * 2) 5px;\n\n line-height: calc(unit * 3);\n}\n\n.itemContainer {\n position: relative;\n}\n\n.compact {\n line-height: calc(unit * 2);\n}\n\n.error {\n cursor: default;\n\n /* Override ring-link */\n &,\n &:hover,\n &:focus,\n &:visited {\n color: var(--ring-error-color);\n }\n}\n\n.add {\n padding: unit calc(2 * unit);\n\n line-height: calc(4 * unit);\n}\n\n.top {\n display: flex;\n align-items: baseline;\n flex-direction: row;\n}\n\n.left {\n align-self: center;\n flex-shrink: 0;\n}\n\n.label {\n overflow: hidden;\n flex-grow: 1;\n flex-shrink: 1;\n\n text-align: left;\n white-space: nowrap;\n text-overflow: ellipsis;\n\n [dir="rtl"] & {\n text-align: right;\n direction: ltr;\n }\n}\n\n.description {\n overflow: hidden;\n flex-shrink: 100;\n\n padding-left: unit;\n\n text-align: right;\n white-space: nowrap;\n text-overflow: ellipsis;\n\n color: var(--ring-secondary-color);\n\n font-size: var(--ring-font-size-smaller);\n font-weight: 400;\n line-height: var(--ring-line-height-lowest);\n}\n\n.right {\n display: flex;\n align-items: center;\n align-self: center;\n flex-direction: row;\n flex-shrink: 0;\n}\n\n.details {\n margin-bottom: 6px;\n\n white-space: normal;\n\n color: var(--ring-secondary-color);\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lowest);\n}\n\n.padded {\n margin-left: 20px;\n}\n\n/* Override :last-child */\n.hint.hint {\n margin-bottom: 0;\n\n border-top: 1px solid var(--ring-line-color);\n background-color: var(--ring-sidebar-background-color);\n\n font-size: var(--ring-font-size-smaller);\n}\n\n.action {\n cursor: pointer;\n\n color: var(--ring-text-color);\n}\n\n/* override link */\n.actionLink.actionLink {\n transition: none;\n}\n\n.hover:not(.error) {\n background-color: var(--ring-selected-background-color);\n}\n\n.icon {\n display: inline-block;\n\n width: 20px;\n height: 20px;\n margin-left: calc(unit * 2);\n\n background-repeat: no-repeat;\n background-position: center;\n\n background-size: contain;\n}\n\n.highlight {\n color: var(--ring-link-hover-color);\n}\n\n.service {\n color: var(--ring-secondary-color);\n}\n\n.glyph {\n float: left;\n\n width: 20px;\n\n margin-right: unit;\n\n color: var(--ring-icon-secondary-color);\n}\n\n.avatar {\n composes: glyph;\n\n top: 0;\n\n height: 20px;\n\n object-fit: cover;\n object-position: center;\n}\n\n.rightGlyph {\n composes: glyph;\n\n float: right;\n\n margin-right: 0;\n margin-left: calc(unit * 2);\n}\n\n.checkboxContainer {\n position: absolute;\n top: 7px;\n left: 19px;\n\n width: 20px;\n height: 20px;\n margin-right: unit;\n}\n\n.compact .checkboxContainer {\n top: 0;\n\n width: calc(unit * 2);\n height: calc(unit * 2);\n}\n\n.title {\n display: block;\n\n margin-top: 10px;\n margin-bottom: 6px;\n padding: listSpacing calc(unit * 2) 0;\n\n text-align: left;\n\n [dir="rtl"] & {\n text-align: right;\n direction: ltr;\n }\n}\n\n.title_first {\n margin-top: 0;\n}\n\n.text {\n letter-spacing: 1.5px;\n text-transform: uppercase;\n\n color: var(--ring-secondary-color);\n\n font-size: var(--ring-font-size-smaller);\n}\n\n.fade {\n position: absolute;\n bottom: 0;\n\n width: 100%;\n height: calc(unit * 3);\n\n pointer-events: none;\n\n background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--ring-content-background-color));\n}\n\n.disabled {\n pointer-events: none;\n\n color: var(--ring-disabled-color);\n}\n',null],sourceRoot:""}]),u.locals={unit:`${l.default.locals.unit}`,listSpacing:"8px",list:"list_a01c",simpleInner:"simpleInner_a4f8",scrolling:"scrolling_a910",separator:"separator_c26e",separator_first:"separator_first_ec9e",item:"item_eadd",itemContainer:"itemContainer_f365",compact:"compact_efa8",error:"error_aa15",add:"add_a8da",top:"top_c4d5",left:"left_ea6b",label:"label_dac9",description:"description_efcc",right:"right_df77",details:"details_a2b7",padded:"padded_a74d",hint:"hint_d29d",action:"action_d10e",actionLink:"actionLink_a4c7",hover:"hover_a4cd",icon:"icon_f1f3",highlight:"highlight_e4dd",service:"service_a4fc",glyph:"glyph_dfd5",avatar:"avatar_f258 glyph_dfd5",rightGlyph:"rightGlyph_fb77 glyph_dfd5",checkboxContainer:"checkboxContainer_c949",title:"title_e1bf",title_first:"title_first_ac55",text:"text_fe0e",fade:"fade_d35c",disabled:"disabled_c3d8"};const s=u},1586:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>f});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9173),c=t(9106),u=t(5280),s=a()(o());s.i(u.A),s.i(l.A,"",!0),s.i(c.default,"",!0),s.push([e.id,`:root {\n /* stylelint-disable-next-line color-no-hex */\n --ring-loader-inline-stops: #ff00eb, #bd3bff, #008eff, #58ba00, #f48700, #ff00eb;\n}\n\n.${l.A.locals.dark},\n.ring-ui-theme-dark {\n /* stylelint-disable-next-line color-no-hex */\n --ring-loader-inline-stops: #ff2eef, #d178ff, #289fff, #88d444, #ffe000, #ff2eef;\n}\n\n@keyframes spin_ad60 {\n 0% {\n transform: rotate(0);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes pulse_c906 {\n 0% {\n transform: scale(1);\n }\n\n 100% {\n transform: scale(1.41667);\n }\n}\n\n.loader_d294,\n.ring-loader-inline {\n /* needed for better backward-compatibility */\n\n position: relative;\n\n display: inline-block;\n\n overflow: hidden;\n\n transform: rotate(0);\n animation: spin_ad60 1s linear infinite;\n vertical-align: -3px;\n\n border-radius: 8px;\n}\n\n.loader_d294,\n .ring-loader-inline,\n .loader_d294::after,\n .ring-loader-inline::after {\n transform-origin: 50% 50%;\n }\n\n.loader_d294::after, .ring-loader-inline::after {\n display: block;\n\n width: 16px;\n height: 16px;\n\n content: "";\n animation: pulse_c906 0.85s cubic-bezier(0.68, 0, 0.74, 0.74) infinite alternate;\n\n background-image: conic-gradient(#ff00eb, #bd3bff, #008eff, #58ba00, #f48700, #ff00eb);\n\n background-image: conic-gradient(var(--ring-loader-inline-stops));\n -webkit-mask-image: radial-gradient(8px, transparent 71.875%, var(--ring-content-background-color) 71.875%);\n mask-image: radial-gradient(8px, transparent 71.875%, var(--ring-content-background-color) 71.875%);\n }\n\n.children_ece6 {\n margin-left: 4px;\n}\n`,"",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/loader-inline/loader-inline.css"],names:[],mappings:"AAKA;EACE,6CAA6C;EAC7C,gFAAgF;AAClF;;AAEA;;EAEE,6CAA6C;EAC7C,gFAAgF;AAClF;;AAEA;EACE;IACE,oBAAoB;EACtB;;EAEA;IACE,yBAAyB;EAC3B;AACF;;AAEA;EACE;IACE,mBAAmB;EACrB;;EAEA;IACE,yBAA+B;EACjC;AACF;;AAEA;;EAEE,6CAA6C;;EAE7C,kBAAkB;;EAElB,qBAAqB;;EAErB,gBAAgB;;EAEhB,oBAAoB;EACpB,uCAAkC;EAClC,oBAAoB;;EAEpB,kBAAmB;AAmBrB;;AAjBE;;;;IAEE,yBAAyB;EAC3B;;AAEA;IACE,cAAc;;IAEd,WAAqB;IACrB,YAAsB;;IAEtB,WAAW;IACX,gFAA2E;;IAE3E,sFAAiE;;IAAjE,iEAAiE;IACjE,2GAAoG;YAApG,mGAAoG;EACtG;;AAGF;EACE,gBAA2B;AAC7B",sourcesContent:['@import "../global/variables.css";\n\n@value dark from "../global/variables_dark.css";\n@value unit from "../global/global.css";\n\n:root {\n /* stylelint-disable-next-line color-no-hex */\n --ring-loader-inline-stops: #ff00eb, #bd3bff, #008eff, #58ba00, #f48700, #ff00eb;\n}\n\n.dark,\n:global(.ring-ui-theme-dark) {\n /* stylelint-disable-next-line color-no-hex */\n --ring-loader-inline-stops: #ff2eef, #d178ff, #289fff, #88d444, #ffe000, #ff2eef;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes pulse {\n 0% {\n transform: scale(1);\n }\n\n 100% {\n transform: scale(calc(17 / 12));\n }\n}\n\n.loader,\n:global(.ring-loader-inline) {\n /* needed for better backward-compatibility */\n\n position: relative;\n\n display: inline-block;\n\n overflow: hidden;\n\n transform: rotate(0);\n animation: spin 1s linear infinite;\n vertical-align: -3px;\n\n border-radius: unit;\n\n &,\n &::after {\n transform-origin: 50% 50%;\n }\n\n &::after {\n display: block;\n\n width: calc(unit * 2);\n height: calc(unit * 2);\n\n content: "";\n animation: pulse 0.85s cubic-bezier(0.68, 0, 0.74, 0.74) infinite alternate;\n\n background-image: conic-gradient(var(--ring-loader-inline-stops));\n mask-image: radial-gradient(unit, transparent 71.875%, var(--ring-content-background-color) 71.875%);\n }\n}\n\n.children {\n margin-left: calc(unit / 2);\n}\n'],sourceRoot:""}]),s.locals={dark:`${l.A.locals.dark}`,unit:`${c.default.locals.unit}`,loader:"loader_d294",spin:"spin_ad60",pulse:"pulse_c906",children:"children_ece6"};const f=s},8890:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=a()(o());u.i(c.A),u.i(l.default,"",!0),u.push([e.id,".popup_f35e {\n\n position: fixed;\n z-index: var(--ring-overlay-z-index);\n top: -100vh;\n left: -100vw;\n\n overflow-y: auto;\n\n box-sizing: border-box;\n\n border: 1px solid var(--ring-popup-border-color);\n border-radius: var(--ring-border-radius);\n\n background-color: var(--ring-popup-background-color);\n box-shadow: var(--ring-popup-shadow);\n}\n\n.hidden_c587 {\n display: none;\n}\n\n.showing_b07a {\n opacity: 0;\n}\n\n.attached_ea95 {\n border-top: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/popup/popup.css"],names:[],mappings:"AAEA;;EAGE,eAAe;EACf,oCAAoC;EACpC,WAAW;EACX,YAAY;;EAEZ,gBAAgB;;EAEhB,sBAAsB;;EAEtB,gDAAgD;EAChD,wCAAwC;;EAExC,oDAAoD;EACpD,oCAAoC;AACtC;;AAEA;EACE,aAAa;AACf;;AAEA;EACE,UAAU;AACZ;;AAEA;EACE,aAAa;EACb,yBAAyB;EACzB,0BAA0B;AAC5B",sourcesContent:['@import "../global/variables.css";\n\n.popup {\n composes: font from "../global/global.css";\n\n position: fixed;\n z-index: var(--ring-overlay-z-index);\n top: -100vh;\n left: -100vw;\n\n overflow-y: auto;\n\n box-sizing: border-box;\n\n border: 1px solid var(--ring-popup-border-color);\n border-radius: var(--ring-border-radius);\n\n background-color: var(--ring-popup-background-color);\n box-shadow: var(--ring-popup-shadow);\n}\n\n.hidden {\n display: none;\n}\n\n.showing {\n opacity: 0;\n}\n\n.attached {\n border-top: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n'],sourceRoot:""}]),u.locals={popup:`popup_f35e ${l.default.locals.font}`,hidden:"hidden_c587",showing:"showing_b07a",attached:"attached_ea95"};const s=u},4481:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=a()(o());u.i(c.A),u.i(l.default,"",!0),u.push([e.id,'@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.filterWithTagsFocused_ffbf.filterWithTagsFocused_ffbf:hover {\n border-color: var(--ring-main-color);\n}}\n\n.filterWithTags_ff56 {\n overflow: hidden;\n\n margin: 16px 8px 0;\n padding: 3px;\n\n text-align: left;\n\n border: 1px solid var(--ring-borders-color);\n border-radius: var(--ring-border-radius);\n}\n\n.filterWithTags_ff56 .filterWrapper_dd63 {\n padding-right: 0;\n padding-left: 0;\n\n border-bottom: none;\n }\n\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.filterWithTags_ff56:hover {\n border-color: var(--ring-border-hover-color);\n }}\n\n.filterWithTagsFocused_ffbf {\n border-color: var(--ring-main-color);\n}\n\n.filterWithTagsInput_ab94 {\n padding: 0;\n\n border: none;\n}\n\n.filter_deda {\n flex-grow: 1;\n\n width: 0;\n}\n\n.popup_f21d {\n overscroll-behavior: contain;\n}\n\n.filterWrapper_dd63 {\n position: relative;\n\n display: flex;\n\n margin: 0;\n padding-right: 8px;\n padding-left: 44px;\n\n border-bottom: 1px solid var(--ring-borders-color);\n}\n\n[dir="rtl"] .filterWrapper_dd63 {\n padding-right: 44px;\n padding-left: 8px;\n }\n\n.filterIcon_b648 {\n position: absolute;\n top: 7px;\n left: 16px;\n\n color: var(--ring-icon-color);\n}\n\n[dir="rtl"] .filterIcon_b648 {\n right: 16px;\n left: auto;\n }\n\n.bottomLine_c880 {\n text-align: center;\n}\n\n.bottomLine_c880.bottomLineOverItem_dfb4 {\n position: relative;\n\n z-index: var(--ring-fixed-z-index);\n\n margin-top: -36px;\n\n background-color: var(--ring-content-background-color);\n }\n\n.message_ccdf {\n display: inline-block;\n\n margin: 8px 0;\n padding: 0 16px;\n}\n\n.selectAll_ff5e {\n display: flex;\n justify-content: space-between;\n\n padding: 8px 16px 0;\n}\n',"",{version:3,sources:["","webpack://./node_modules/@jetbrains/ring-ui/components/select/select-popup.css"],names:[],mappings:"AAAA,wGAAA;EAAA,qCAAA;CAAA,CAAA;;ACIA;EACE,gBAAgB;;EAEhB,kBAA6B;EAC7B,YAAY;;EAEZ,gBAAgB;;EAEhB,2CAA2C;EAC3C,wCAAwC;AAY1C;;AAVE;IACE,gBAAgB;IAChB,eAAe;;IAEf,mBAAmB;EACrB;;ADpBF,wGAAA;IAAA,6CAAA;GAAA,CAAA;;AC2BA;EAEE,oCAAoC;AACtC;;AAEA;EACE,UAAU;;EAEV,YAAY;AACd;;AAEA;EACE,YAAY;;EAEZ,QAAQ;AACV;;AAEA;EACE,4BAA4B;AAC9B;;AAEA;EACE,kBAAkB;;EAElB,aAAa;;EAEb,SAAS;EACT,kBAAmB;EACnB,kBAA8B;;EAE9B,kDAAkD;AAMpD;;AAJE;IACE,mBAA+B;IAC/B,iBAAkB;EACpB;;AAGF;EACE,kBAAkB;EAClB,QAAQ;EACR,UAAoB;;EAEpB,6BAA6B;AAM/B;;AAJE;IACE,WAAqB;IACrB,UAAU;EACZ;;AAGF;EACE,kBAAkB;AAWpB;;AATE;IACE,kBAAkB;;IAElB,kCAAkC;;IAElC,iBAAiB;;IAEjB,sDAAsD;EACxD;;AAGF;EACE,qBAAqB;;EAErB,aAAc;EACd,eAAyB;AAC3B;;AAEA;EACE,aAAa;EACb,8BAA8B;;EAE9B,mBAAmB;AACrB",sourcesContent:[null,'@import "../global/variables.css";\n\n@value unit from "../global/global.css";\n\n.filterWithTags {\n overflow: hidden;\n\n margin: calc(unit * 2) unit 0;\n padding: 3px;\n\n text-align: left;\n\n border: 1px solid var(--ring-borders-color);\n border-radius: var(--ring-border-radius);\n\n & .filterWrapper {\n padding-right: 0;\n padding-left: 0;\n\n border-bottom: none;\n }\n\n &:hover {\n border-color: var(--ring-border-hover-color);\n }\n}\n\n.filterWithTagsFocused,\n.filterWithTagsFocused.filterWithTagsFocused:hover {\n border-color: var(--ring-main-color);\n}\n\n.filterWithTagsInput {\n padding: 0;\n\n border: none;\n}\n\n.filter {\n flex-grow: 1;\n\n width: 0;\n}\n\n.popup {\n overscroll-behavior: contain;\n}\n\n.filterWrapper {\n position: relative;\n\n display: flex;\n\n margin: 0;\n padding-right: unit;\n padding-left: calc(unit * 5.5);\n\n border-bottom: 1px solid var(--ring-borders-color);\n\n [dir="rtl"] & {\n padding-right: calc(unit * 5.5);\n padding-left: unit;\n }\n}\n\n.filterIcon {\n position: absolute;\n top: 7px;\n left: calc(unit * 2);\n\n color: var(--ring-icon-color);\n\n [dir="rtl"] & {\n right: calc(unit * 2);\n left: auto;\n }\n}\n\n.bottomLine {\n text-align: center;\n\n &.bottomLineOverItem {\n position: relative;\n\n z-index: var(--ring-fixed-z-index);\n\n margin-top: -36px;\n\n background-color: var(--ring-content-background-color);\n }\n}\n\n.message {\n display: inline-block;\n\n margin: unit 0;\n padding: 0 calc(2 * unit);\n}\n\n.selectAll {\n display: flex;\n justify-content: space-between;\n\n padding: 8px 16px 0;\n}\n'],sourceRoot:""}]),u.locals={unit:`${l.default.locals.unit}`,filterWithTagsFocused:"filterWithTagsFocused_ffbf",filterWithTags:"filterWithTags_ff56",filterWrapper:"filterWrapper_dd63",filterWithTagsInput:"filterWithTagsInput_ab94",filter:"filter_deda",popup:"popup_f21d",filterIcon:"filterIcon_b648",bottomLine:"bottomLine_c880",bottomLineOverItem:"bottomLineOverItem_dfb4",message:"message_ccdf",selectAll:"selectAll_ff5e"};const s=u},2636:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>f});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(9892),u=t(5280),s=a()(o());s.i(u.A),s.i(l.default,"",!0),s.i(c.default,"",!0),s.push([e.id,'@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.select_e2a5:hover .value_b3a3,\n.select_e2a5:hover .icons_c4a9 {\n transition: none;\n\n color: var(--ring-main-color);\n}}\n\n.select_e2a5 {\n position: relative;\n\n display: inline-block;\n\n white-space: nowrap;\n\n color: var(--ring-text-color);\n}\n\n.toolbar_d3be {\n border-top: 1px solid var(--ring-line-color);\n}\n\n.button_ef00 {\n width: 100%;\n padding: 0;\n\n text-align: left;\n}\n\n[dir="rtl"] .button_ef00 {\n text-align: right;\n direction: ltr;\n }\n\n.toolbar_d3be .button_ef00 {\n height: 32px;\n margin: 8px 0;\n }\n\n.button_ef00.buttonSpaced_f316 {\n padding: 0 16px;\n }\n\n.icons_c4a9 {\n position: absolute;\n top: 0;\n right: 5px;\n bottom: 0;\n\n transition: color var(--ring-ease);\n\n color: var(--ring-icon-secondary-color);\n\n line-height: normal;\n}\n\n.inputMode_a6f6 .icons_c4a9 {\n font-size: var(--ring-font-size);\n }\n\n.selectedIcon_a62c {\n\n position: relative;\n top: 3px;\n\n display: inline-block;\n\n width: 16px;\n height: 16px;\n margin: 0 4px;\n\n background-repeat: no-repeat;\n background-position: center;\n\n background-size: contain;\n}\n\n.clearIcon_c750 {\n padding: 0 3px;\n\n vertical-align: -2px;\n}\n\n.sizeS_e8c3 {\n width: 96px;\n}\n\n.sizeM_ed34 {\n width: 240px;\n}\n\n.sizeL_c053 {\n width: 400px;\n}\n\n.sizeFULL_c585 {\n width: 100%;\n}\n\n.sizeAUTO_a07c {\n max-width: 100%;\n}\n\n.buttonMode_dd69 {\n position: relative;\n\n cursor: pointer;\n}\n\n.value_b3a3 {\n\n display: inline-block;\n\n box-sizing: border-box;\n width: 100%;\n height: 33px;\n padding: 0 0 3px;\n\n cursor: pointer;\n transition: color var(--ring-ease), border-color var(--ring-ease);\n text-align: left;\n vertical-align: top;\n\n color: var(--ring-text-color);\n\n border: none;\n border-bottom: 1px solid var(--ring-borders-color);\n outline: none;\n background: transparent;\n}\n\n.value_b3a3:focus {\n border-color: var(--ring-main-color);\n }\n\n.value_b3a3.open_f1b1,\n .value_b3a3:active {\n border-color: transparent;\n }\n\n.value_b3a3::-moz-focus-inner {\n padding: 0;\n\n border: 0;\n outline: 0;\n }\n\n.buttonContainer_b2b9 {\n position: relative;\n\n font-size: var(--ring-font-size);\n}\n\n.buttonValue_b4ad {\n\n display: block;\n\n width: 100%;\n padding-left: 8px;\n\n text-align: left;\n vertical-align: -8px;\n}\n\n.buttonValue_b4ad:focus-visible {\n box-shadow: inset 0 0 0 1px var(--ring-main-color);\n}\n\n.buttonValueOpen_d9d3.buttonValueOpen_d9d3 {\n box-shadow: inset 0 0 0 1px var(--ring-main-color);\n}\n\n.buttonValueEmpty_e6b3.buttonValueEmpty_e6b3 {\n color: var(--ring-disabled-color);\n}\n\n.heightS_b721 .buttonValue_b4ad {\n font-size: var(--ring-font-size);\n}\n\n.label_e56f {\n position: relative;\n\n color: var(--ring-secondary-color);\n}\n\n:focus-visible + .icons_c4a9,\n.value_b3a3:focus,\n.value_b3a3:focus + .icons_c4a9,\n.open_f1b1,\n.open_f1b1 + .icons_c4a9,\n.buttonValueOpen_d9d3 + .icons_c4a9 {\n transition: none;\n\n color: var(--ring-main-color);\n}\n\n.disabled_b89f {\n pointer-events: none;\n\n color: var(--ring-disabled-color);\n}\n\n.disabled_b89f .value_b3a3 {\n color: var(--ring-disabled-color);\n border-bottom-style: dashed;\n }\n\n.avatar_f4dd {\n margin-right: 4px;\n\n vertical-align: -5px;\n}\n\n.popup_acec {\n min-width: 240px;\n max-width: 320px;\n}\n\n.chevron_d51f.chevron_d51f {\n padding: 0 3px;\n\n transition: none;\n vertical-align: -1px;\n\n color: inherit;\n}\n\n.chevronIcon_f6cf.chevronIcon_f6cf {\n transition: none;\n\n color: inherit;\n}\n',"",{version:3,sources:["","webpack://./node_modules/@jetbrains/ring-ui/components/select/select.css"],names:[],mappings:"AAAA,wGAAA;;EAAA,iBAAA;;EAAA,8BAAA;CAAA,CAAA;;ACKA;EACE,kBAAkB;;EAElB,qBAAqB;;EAErB,mBAAmB;;EAEnB,6BAA6B;AAC/B;;AAEA;EACE,4CAA4C;AAC9C;;AAEA;EACE,WAAW;EACX,UAAU;;EAEV,gBAAgB;AAelB;;AAbE;IACE,iBAAiB;IACjB,cAAc;EAChB;;AAEA;IACE,YAAsB;IACtB,aAAc;EAChB;;AAEA;IACE,eAAyB;EAC3B;;AAGF;EACE,kBAAkB;EAClB,MAAM;EACN,UAAU;EACV,SAAS;;EAET,kCAAkC;;EAElC,uCAAuC;;EAEvC,mBAAmB;AAKrB;;AAHE;IACE,gCAAgC;EAClC;;AAGF;;EAGE,kBAAkB;EAClB,QAAQ;;EAER,qBAAqB;;EAErB,WAAqB;EACrB,YAAsB;EACtB,aAAa;;EAEb,4BAA4B;EAC5B,2BAA2B;;EAE3B,wBAAwB;AAC1B;;AAEA;EACE,cAAc;;EAEd,oBAAoB;AACtB;;AAEA;EACE,WAAsB;AACxB;;AAEA;EACE,YAAsB;AACxB;;AAEA;EACE,YAAsB;AACxB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,kBAAkB;;EAElB,eAAe;AACjB;;AAEA;;EAIE,qBAAqB;;EAErB,sBAAsB;EACtB,WAAW;EACX,YAA4B;EAC5B,gBAAgB;;EAEhB,eAAe;EACf,iEAAiE;EACjE,gBAAgB;EAChB,mBAAmB;;EAEnB,6BAA6B;;EAE7B,YAAY;EACZ,kDAAkD;EAClD,aAAa;EACb,uBAAuB;AAiBzB;;AAfE;IACE,oCAAoC;EACtC;;AAEA;;IAEE,yBAAyB;EAC3B;;AAEA;IACE,UAAU;;IAEV,SAAS;IACT,UAAU;EACZ;;AAGF;EACE,kBAAkB;;EAElB,gCAAgC;AAClC;;AAEA;;EAGE,cAAc;;EAEd,WAAW;EACX,iBAAkB;;EAElB,gBAAgB;EAChB,oBAA8B;AAChC;;AAEA;EACE,kDAAgD;AAClD;;AAEA;EACE,kDAAgD;AAClD;;AAEA;EACE,iCAAiC;AACnC;;AAEA;EACE,gCAAgC;AAClC;;AAEA;EACE,kBAAkB;;EAElB,kCAAkC;AACpC;;AAEA;;;;;;EAQE,gBAAgB;;EAEhB,6BAA6B;AAC/B;;AAEA;EACE,oBAAoB;;EAEpB,iCAAiC;AAMnC;;AAJE;IACE,iCAAiC;IACjC,2BAA2B;EAC7B;;AAGF;EACE,iBAAiB;;EAEjB,oBAAoB;AACtB;;AAEA;EACE,gBAA0B;EAC1B,gBAA0B;AAC5B;;AAEA;EACE,cAAc;;EAEd,gBAAgB;EAChB,oBAAoB;;EAEpB,cAAc;AAChB;;AAEA;EACE,gBAAgB;;EAEhB,cAAc;AAChB",sourcesContent:[null,'@import "../global/variables.css";\n\n@value unit from "../global/global.css";\n@value button-shadow from "../button/button.css";\n\n.select {\n position: relative;\n\n display: inline-block;\n\n white-space: nowrap;\n\n color: var(--ring-text-color);\n}\n\n.toolbar {\n border-top: 1px solid var(--ring-line-color);\n}\n\n.button {\n width: 100%;\n padding: 0;\n\n text-align: left;\n\n [dir="rtl"] & {\n text-align: right;\n direction: ltr;\n }\n\n .toolbar & {\n height: calc(4 * unit);\n margin: unit 0;\n }\n\n &.buttonSpaced {\n padding: 0 calc(2 * unit);\n }\n}\n\n.icons {\n position: absolute;\n top: 0;\n right: 5px;\n bottom: 0;\n\n transition: color var(--ring-ease);\n\n color: var(--ring-icon-secondary-color);\n\n line-height: normal;\n\n .inputMode & {\n font-size: var(--ring-font-size);\n }\n}\n\n.selectedIcon {\n composes: resetButton from "../global/global.css";\n\n position: relative;\n top: 3px;\n\n display: inline-block;\n\n width: calc(2 * unit);\n height: calc(2 * unit);\n margin: 0 4px;\n\n background-repeat: no-repeat;\n background-position: center;\n\n background-size: contain;\n}\n\n.clearIcon {\n padding: 0 3px;\n\n vertical-align: -2px;\n}\n\n.sizeS {\n width: calc(unit * 12);\n}\n\n.sizeM {\n width: calc(unit * 30);\n}\n\n.sizeL {\n width: calc(unit * 50);\n}\n\n.sizeFULL {\n width: 100%;\n}\n\n.sizeAUTO {\n max-width: 100%;\n}\n\n.buttonMode {\n position: relative;\n\n cursor: pointer;\n}\n\n.value {\n composes: ellipsis from "../global/global.css";\n composes: font from "../global/global.css";\n\n display: inline-block;\n\n box-sizing: border-box;\n width: 100%;\n height: calc(unit * 4 + 1px);\n padding: 0 0 3px;\n\n cursor: pointer;\n transition: color var(--ring-ease), border-color var(--ring-ease);\n text-align: left;\n vertical-align: top;\n\n color: var(--ring-text-color);\n\n border: none;\n border-bottom: 1px solid var(--ring-borders-color);\n outline: none;\n background: transparent;\n\n &:focus {\n border-color: var(--ring-main-color);\n }\n\n &.open,\n &:active {\n border-color: transparent;\n }\n\n &::-moz-focus-inner {\n padding: 0;\n\n border: 0;\n outline: 0;\n }\n}\n\n.buttonContainer {\n position: relative;\n\n font-size: var(--ring-font-size);\n}\n\n.buttonValue {\n composes: ellipsis from "../global/global.css";\n\n display: block;\n\n width: 100%;\n padding-left: unit;\n\n text-align: left;\n vertical-align: calc(0 - unit);\n}\n\n.buttonValue:focus-visible {\n box-shadow: button-shadow var(--ring-main-color);\n}\n\n.buttonValueOpen.buttonValueOpen {\n box-shadow: button-shadow var(--ring-main-color);\n}\n\n.buttonValueEmpty.buttonValueEmpty {\n color: var(--ring-disabled-color);\n}\n\n.heightS .buttonValue {\n font-size: var(--ring-font-size);\n}\n\n.label {\n position: relative;\n\n color: var(--ring-secondary-color);\n}\n\n.select:hover .value,\n.select:hover .icons,\n:focus-visible + .icons,\n.value:focus,\n.value:focus + .icons,\n.open,\n.open + .icons,\n.buttonValueOpen + .icons {\n transition: none;\n\n color: var(--ring-main-color);\n}\n\n.disabled {\n pointer-events: none;\n\n color: var(--ring-disabled-color);\n\n & .value {\n color: var(--ring-disabled-color);\n border-bottom-style: dashed;\n }\n}\n\n.avatar {\n margin-right: 4px;\n\n vertical-align: -5px;\n}\n\n.popup {\n min-width: calc(unit * 30);\n max-width: calc(unit * 40);\n}\n\n.chevron.chevron {\n padding: 0 3px;\n\n transition: none;\n vertical-align: -1px;\n\n color: inherit;\n}\n\n.chevronIcon.chevronIcon {\n transition: none;\n\n color: inherit;\n}\n'],sourceRoot:""}]),s.locals={unit:`${l.default.locals.unit}`,"button-shadow":`${c.default.locals["button-shadow"]}`,select:"select_e2a5",value:`value_b3a3 ${l.default.locals.ellipsis} ${l.default.locals.font}`,icons:"icons_c4a9",toolbar:"toolbar_d3be",button:"button_ef00",buttonSpaced:"buttonSpaced_f316",inputMode:"inputMode_a6f6",selectedIcon:`selectedIcon_a62c ${l.default.locals.resetButton}`,clearIcon:"clearIcon_c750",sizeS:"sizeS_e8c3",sizeM:"sizeM_ed34",sizeL:"sizeL_c053",sizeFULL:"sizeFULL_c585",sizeAUTO:"sizeAUTO_a07c",buttonMode:"buttonMode_dd69",open:"open_f1b1",buttonContainer:"buttonContainer_b2b9",buttonValue:`buttonValue_b4ad ${l.default.locals.ellipsis}`,buttonValueOpen:"buttonValueOpen_d9d3",buttonValueEmpty:"buttonValueEmpty_e6b3",heightS:"heightS_b721",label:"label_e56f",disabled:"disabled_b89f",avatar:"avatar_f4dd",popup:"popup_acec",chevron:"chevron_d51f",chevronIcon:"chevronIcon_f6cf"};const f=s},8102:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,".trapButton_c32e {\n position: absolute;\n left: -9999px;\n}\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/tab-trap/tab-trap.css"],names:[],mappings:"AAEA;EACE,kBAAkB;EAClB,aAAa;AACf",sourcesContent:['@import "../global/variables.css";\n\n.trapButton {\n position: absolute;\n left: -9999px;\n}\n'],sourceRoot:""}]),c.locals={trapButton:"trapButton_c32e"};const u=c},4561:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=a()(o());u.i(c.A),u.i(l.default,"",!0),u.push([e.id,'@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.tag_b7aa:hover,\n.tagAngled_c869:hover::before {\n transition: none;\n\n background-color: var(--ring-tag-hover-background-color);\n}}\n\n.tag_b7aa {\n\n position: relative;\n z-index: 1;\n\n display: inline-flex;\n\n box-sizing: border-box;\n max-width: 100%;\n height: 20px;\n\n padding: 0 8px;\n\n cursor: pointer;\n\n vertical-align: top;\n\n color: var(--ring-text-color);\n\n border: none;\n border-radius: var(--ring-border-radius);\n\n font-size: 12px;\n line-height: var(--ring-line-height);\n}\n\n.tag_b7aa,\n.tagAngled_c869::before {\n transition: background-color var(--ring-ease);\n\n background-color: var(--ring-tag-background-color);\n}\n\n.withRemove_c0a5 {\n padding-right: 22px;\n}\n\n.container_cb34 {\n position: relative;\n\n display: inline-block;\n\n max-width: calc(100% - 4px);\n\n margin-right: 4px;\n\n white-space: nowrap;\n}\n\n.focused_fd92,\n.tag_b7aa:focus-visible {\n position: relative;\n\n outline: none;\n box-shadow: 0 0 0 2px var(--ring-border-hover-color);\n}\n\n.focused_fd92,\n.focused_fd92.tagAngled_c869::before,\n.tag_b7aa:focus-visible,\n.tagAngled_c869:focus-visible::before {\n transition: none;\n\n background-color: var(--ring-tag-hover-background-color);\n}\n\n.tagAngled_c869 {\n /* it needs to fix vertical alignment broken by "overflow: hidden". Remove this class, when IE11 will be deprecated */\n\n margin-bottom: -5px !important;\n\n margin-left: 8px;\n padding-left: 4px;\n\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.tagAngled_c869::before {\n position: absolute;\n z-index: -1;\n top: 0;\n left: 0;\n\n box-sizing: border-box;\n width: 12px;\n height: 12px;\n\n content: "";\n transform: scaleY(1.177) rotate(45deg);\n transform-origin: 0 0;\n\n border: none;\n }\n\n.tagAngled_c869.focused_fd92,\n .tagAngled_c869:focus {\n box-shadow: 0 0 0 1px var(--ring-border-hover-color) inset, 0 0 0 1px var(--ring-border-hover-color);\n }\n\n.tagAngled_c869:focus::before {\n box-shadow:\n 1px -1px var(--ring-border-hover-color) inset,\n -0.8px 0.8px 0 0.5px var(--ring-border-hover-color);\n }\n\n.content_a838 {\n}\n\n.disabled_b740.tag_b7aa,\n.disabled_b740.tagAngled_c869::before {\n pointer-events: none;\n\n color: var(--ring-disabled-color);\n background-color: var(--ring-disabled-background-color);\n}\n\n.remove_eff8 {\n position: absolute;\n z-index: 1;\n top: 2px;\n right: 0;\n\n height: auto;\n padding: 0 4px;\n\n line-height: 16px;\n}\n\n.removeIcon_accf.removeIcon_accf {\n color: var(--ring-icon-secondary-color);\n}\n\n.icon_e877 {\n margin-right: 6px;\n\n color: var(--ring-icon-secondary-color);\n}\n\n.icon_e877 svg {\n vertical-align: -3px;\n }\n\n.avatarContainer_ee1b {\n display: inline-block;\n overflow: hidden;\n\n box-sizing: border-box;\n width: 20px;\n height: 20px;\n margin-right: 4px;\n margin-left: -8px;\n\n vertical-align: top;\n\n border-top-left-radius: var(--ring-border-radius);\n border-bottom-left-radius: var(--ring-border-radius);\n}\n\n.customIcon_ac93 {\n max-width: 16px;\n max-height: 16px;\n\n margin-right: 4px;\n\n vertical-align: bottom;\n}\n\n.avatarIcon_a8ff {\n width: 20px;\n\n margin-right: -4px;\n\n -o-object-fit: contain;\n\n object-fit: contain;\n -o-object-position: center;\n object-position: center;\n}\n',"",{version:3,sources:["","webpack://./node_modules/@jetbrains/ring-ui/components/tag/tag.css"],names:[],mappings:"AAAA,wGAAA;;EAAA,iBAAA;;EAAA,yDAAA;CAAA,CAAA;;ACKA;;EAGE,kBAAkB;EAClB,UAAU;;EAEV,oBAAoB;;EAEpB,sBAAsB;EACtB,eAAe;EACf,YAAkB;;EAElB,cAAe;;EAEf,eAAe;;EAEf,mBAAmB;;EAEnB,6BAA6B;;EAE7B,YAAY;EACZ,wCAAwC;;EAExC,eAAe;EACf,oCAAoC;AACtC;;AAEA;;EAEE,6CAA6C;;EAE7C,kDAAkD;AACpD;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;;EAElB,qBAAqB;;EAErB,2BAAgC;;EAEhC,iBAA4B;;EAE5B,mBAAmB;AACrB;;AAEA;;EAEE,kBAAkB;;EAElB,aAAa;EACb,oDAAoD;AACtD;;AAEA;;;;EAME,gBAAgB;;EAEhB,wDAAwD;AAC1D;;AAEA;EACE,qHAAqH;;EAErH,8BAA8B;;EAE9B,gBAAiB;EACjB,iBAA4B;;EAE5B,yBAAyB;EACzB,4BAA4B;AA6B9B;;AA3BE;IACE,kBAAkB;IAClB,WAAW;IACX,MAAM;IACN,OAAO;;IAEP,sBAAsB;IACtB,WAAW;IACX,YAAY;;IAEZ,WAAW;IACX,sCAAsC;IACtC,qBAAqB;;IAErB,YAAY;EACd;;AAEA;;IAEE,oGAAoG;EACtG;;AAEA;IACE;;yDAEqD;EACvD;;AAGF;AAEA;;AAEA;;EAEE,oBAAoB;;EAEpB,iCAAiC;EACjC,uDAAuD;AACzD;;AAEA;EACE,kBAAkB;EAClB,UAAU;EACV,QAAQ;EACR,QAAQ;;EAER,YAAY;EACZ,cAAyB;;EAEzB,iBAA2B;AAC7B;;AAEA;EACE,uCAAuC;AACzC;;AAEA;EACE,iBAAiB;;EAEjB,uCAAuC;AAKzC;;AAHE;IACE,oBAAoB;EACtB;;AAGF;EACE,qBAAqB;EACrB,gBAAgB;;EAEhB,sBAAsB;EACtB,WAAiB;EACjB,YAAkB;EAClB,iBAA4B;EAC5B,iBAA2B;;EAE3B,mBAAmB;;EAEnB,iDAAiD;EACjD,oDAAoD;AACtD;;AAEA;EACE,eAAyB;EACzB,gBAA0B;;EAE1B,iBAA4B;;EAE5B,sBAAsB;AACxB;;AAEA;EACE,WAAiB;;EAEjB,kBAAkB;;EAElB,sBAAmB;;KAAnB,mBAAmB;EACnB,0BAAuB;KAAvB,uBAAuB;AACzB",sourcesContent:[null,'@import "../global/variables.css";\n\n@value unit from "../global/global.css";\n@value max-height: 20px;\n\n.tag {\n composes: resetButton from "../global/global.css";\n\n position: relative;\n z-index: 1;\n\n display: inline-flex;\n\n box-sizing: border-box;\n max-width: 100%;\n height: max-height;\n\n padding: 0 unit;\n\n cursor: pointer;\n\n vertical-align: top;\n\n color: var(--ring-text-color);\n\n border: none;\n border-radius: var(--ring-border-radius);\n\n font-size: 12px;\n line-height: var(--ring-line-height);\n}\n\n.tag,\n.tagAngled::before {\n transition: background-color var(--ring-ease);\n\n background-color: var(--ring-tag-background-color);\n}\n\n.withRemove {\n padding-right: 22px;\n}\n\n.container {\n position: relative;\n\n display: inline-block;\n\n max-width: calc(100% - unit / 2);\n\n margin-right: calc(unit / 2);\n\n white-space: nowrap;\n}\n\n.focused,\n.tag:focus-visible {\n position: relative;\n\n outline: none;\n box-shadow: 0 0 0 2px var(--ring-border-hover-color);\n}\n\n.focused,\n.focused.tagAngled::before,\n.tag:focus-visible,\n.tagAngled:focus-visible::before,\n.tag:hover,\n.tagAngled:hover::before {\n transition: none;\n\n background-color: var(--ring-tag-hover-background-color);\n}\n\n.tagAngled {\n /* it needs to fix vertical alignment broken by "overflow: hidden". Remove this class, when IE11 will be deprecated */\n\n margin-bottom: -5px !important;\n\n margin-left: unit;\n padding-left: calc(unit / 2);\n\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n\n &::before {\n position: absolute;\n z-index: -1;\n top: 0;\n left: 0;\n\n box-sizing: border-box;\n width: 12px;\n height: 12px;\n\n content: "";\n transform: scaleY(1.177) rotate(45deg);\n transform-origin: 0 0;\n\n border: none;\n }\n\n &.focused,\n &:focus {\n box-shadow: 0 0 0 1px var(--ring-border-hover-color) inset, 0 0 0 1px var(--ring-border-hover-color);\n }\n\n &:focus::before {\n box-shadow:\n 1px -1px var(--ring-border-hover-color) inset,\n -0.8px 0.8px 0 0.5px var(--ring-border-hover-color);\n }\n}\n\n.content {\n composes: ellipsis from "../global/global.css";\n}\n\n.disabled.tag,\n.disabled.tagAngled::before {\n pointer-events: none;\n\n color: var(--ring-disabled-color);\n background-color: var(--ring-disabled-background-color);\n}\n\n.remove {\n position: absolute;\n z-index: 1;\n top: 2px;\n right: 0;\n\n height: auto;\n padding: 0 calc(unit / 2);\n\n line-height: calc(unit * 2);\n}\n\n.removeIcon.removeIcon {\n color: var(--ring-icon-secondary-color);\n}\n\n.icon {\n margin-right: 6px;\n\n color: var(--ring-icon-secondary-color);\n\n & svg {\n vertical-align: -3px;\n }\n}\n\n.avatarContainer {\n display: inline-block;\n overflow: hidden;\n\n box-sizing: border-box;\n width: max-height;\n height: max-height;\n margin-right: calc(unit / 2);\n margin-left: calc(0 - unit);\n\n vertical-align: top;\n\n border-top-left-radius: var(--ring-border-radius);\n border-bottom-left-radius: var(--ring-border-radius);\n}\n\n.customIcon {\n max-width: calc(unit * 2);\n max-height: calc(unit * 2);\n\n margin-right: calc(unit / 2);\n\n vertical-align: bottom;\n}\n\n.avatarIcon {\n width: max-height;\n\n margin-right: -4px;\n\n object-fit: contain;\n object-position: center;\n}\n'],sourceRoot:""}]),u.locals={unit:`${l.default.locals.unit}`,"max-height":"20px",tag:`tag_b7aa ${l.default.locals.resetButton}`,tagAngled:"tagAngled_c869",withRemove:"withRemove_c0a5",container:"container_cb34",focused:"focused_fd92",content:`content_a838 ${l.default.locals.ellipsis}`,disabled:"disabled_b740",remove:"remove_eff8",removeIcon:"removeIcon_accf",icon:"icon_e877",avatarContainer:"avatarContainer_ee1b",customIcon:"customIcon_ac93",avatarIcon:"avatarIcon_a8ff"};const s=u},6162:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,".text_f1dc {\n color: var(--ring-text-color);\n}\n\n.sizeS_b3aa {\n font-size: var(--ring-font-size-smaller);\n}\n\n.sizeM_ae72 {\n font-size: var(--ring-font-size);\n}\n\n.sizeL_f259 {\n font-size: var(--ring-font-size-larger);\n}\n\n.info_c0a4 {\n color: var(--ring-secondary-color);\n}\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/text/text.css"],names:[],mappings:"AAEA;EACE,6BAA6B;AAC/B;;AAEA;EACE,wCAAwC;AAC1C;;AAEA;EACE,gCAAgC;AAClC;;AAEA;EACE,uCAAuC;AACzC;;AAEA;EACE,kCAAkC;AACpC",sourcesContent:['@import "../global/variables.css";\n\n.text {\n color: var(--ring-text-color);\n}\n\n.sizeS {\n font-size: var(--ring-font-size-smaller);\n}\n\n.sizeM {\n font-size: var(--ring-font-size);\n}\n\n.sizeL {\n font-size: var(--ring-font-size-larger);\n}\n\n.info {\n color: var(--ring-secondary-color);\n}\n'],sourceRoot:""}]),c.locals={text:"text_f1dc",sizeS:"sizeS_b3aa",sizeM:"sizeM_ae72",sizeL:"sizeL_f259",info:"info_c0a4"};const u=c},938:(e,n,t)=>{"use strict";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),u=a()(o());u.i(c.A),u.i(l.default,"",!0),u.push([e.id,".tooltip_fbfb {\n max-width: 400px;\n padding: 8px;\n\n text-align: left;\n\n color: var(--ring-text-color);\n}\n\n.long_b7a5 {\n padding: 8px 12px;\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lowest);\n}\n","",{version:3,sources:["webpack://./node_modules/@jetbrains/ring-ui/components/tooltip/tooltip.css"],names:[],mappings:"AAIA;EACE,gBAA0B;EAC1B,YAAa;;EAEb,gBAAgB;;EAEhB,6BAA6B;AAC/B;;AAEA;EACE,iBAA8B;;EAE9B,wCAAwC;EACxC,2CAA2C;AAC7C",sourcesContent:['@import "../global/variables.css";\n\n@value unit from "../global/global.css";\n\n.tooltip {\n max-width: calc(unit * 50);\n padding: unit;\n\n text-align: left;\n\n color: var(--ring-text-color);\n}\n\n.long {\n padding: unit calc(unit * 1.5);\n\n font-size: var(--ring-font-size-smaller);\n line-height: var(--ring-line-height-lowest);\n}\n'],sourceRoot:""}]),u.locals={unit:`${l.default.locals.unit}`,tooltip:"tooltip_fbfb",long:"long_b7a5"};const s=u},7156:e=>{"use strict";e.exports=function(e){var n=[];return n.toString=function(){return this.map((function(n){var t="",r=void 0!==n[5];return n[4]&&(t+="@supports (".concat(n[4],") {")),n[2]&&(t+="@media ".concat(n[2]," {")),r&&(t+="@layer".concat(n[5].length>0?" ".concat(n[5]):""," {")),t+=e(n),r&&(t+="}"),n[2]&&(t+="}"),n[4]&&(t+="}"),t})).join("")},n.i=function(e,t,r,o,i){"string"==typeof e&&(e=[[null,e,void 0]]);var a={};if(r)for(var l=0;l0?" ".concat(s[5]):""," {").concat(s[1],"}")),s[5]=i),t&&(s[2]?(s[1]="@media ".concat(s[2]," {").concat(s[1],"}"),s[2]=t):s[2]=t),o&&(s[4]?(s[1]="@supports (".concat(s[4],") {").concat(s[1],"}"),s[4]=o):s[4]="".concat(o)),n.push(s))}},n}},1404:e=>{"use strict";e.exports=function(e){var n=e[1],t=e[3];if(!t)return n;if("function"==typeof btoa){var r=btoa(unescape(encodeURIComponent(JSON.stringify(t)))),o="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(r),i="/*# ".concat(o," */");return[n].concat([i]).join("\n")}return[n].join("\n")}},4504:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(7222);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},9102:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(9892);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},6860:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(1866);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},3912:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(5486);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},8764:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(6506);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},6620:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(9106);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},9468:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(5066);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},274:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(8976);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},5924:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(8266);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},7826:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(6960);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},1914:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(480);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},8130:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(1586);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},1564:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(8890);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},5103:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(4481);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},3006:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(2636);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},9344:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(8102);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},4512:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(4561);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},6932:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(6162);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},8132:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),u=t(938);u=u.__esModule?u.default:u;var s={};s.styleTagTransform=c,s.setAttributes=a,s.insert=i.bind(null,"head"),s.domAPI=o,s.insertStyleElement=l;r(u,s);e.exports=u&&u.locals||{}},8298:e=>{"use strict";var n=[];function t(e){for(var t=-1,r=0;r{"use strict";var n={};e.exports=function(e,t){var r=function(e){if(void 0===n[e]){var t=document.querySelector(e);if(window.HTMLIFrameElement&&t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(e){t=null}n[e]=t}return n[e]}(e);if(!r)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");r.appendChild(t)}},9742:e=>{"use strict";e.exports=function(e){var n=document.createElement("style");return e.setAttributes(n,e.attributes),e.insert(n,e.options),n}},9986:(e,n,t)=>{"use strict";e.exports=function(e){var n=t.nc;n&&e.setAttribute("nonce",n)}},5163:e=>{"use strict";e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var n=e.insertStyleElement(e);return{update:function(t){!function(e,n,t){var r="";t.supports&&(r+="@supports (".concat(t.supports,") {")),t.media&&(r+="@media ".concat(t.media," {"));var o=void 0!==t.layer;o&&(r+="@layer".concat(t.layer.length>0?" ".concat(t.layer):""," {")),r+=t.css,o&&(r+="}"),t.media&&(r+="}"),t.supports&&(r+="}");var i=t.sourceMap;i&&"undefined"!=typeof btoa&&(r+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i))))," */")),n.styleTagTransform(r,e,n.options)}(n,e,t)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(n)}}}},6291:e=>{"use strict";e.exports=function(e,n){if(n.styleSheet)n.styleSheet.cssText=e;else{for(;n.firstChild;)n.removeChild(n.firstChild);n.appendChild(document.createTextNode(e))}}},9511:(e,n,t)=>{"use strict";var r=t(8075)("ArrayBuffer.prototype.byteLength",!0),o=t(4670);e.exports=function(e){return o(e)?r?r(e):e.byteLength:NaN}},8075:(e,n,t)=>{"use strict";var r=t(453),o=t(487),i=o(r("String.prototype.indexOf"));e.exports=function(e,n){var t=r(e,!!n);return"function"==typeof t&&i(e,".prototype.")>-1?o(t):t}},487:(e,n,t)=>{"use strict";var r=t(6743),o=t(453),i=t(6897),a=t(9675),l=o("%Function.prototype.apply%"),c=o("%Function.prototype.call%"),u=o("%Reflect.apply%",!0)||r.call(c,l),s=t(3036),f=o("%Math.max%");e.exports=function(e){if("function"!=typeof e)throw new a("a function is required");var n=u(r,c,arguments);return i(n,1+f(0,e.length-(arguments.length-1)),!0)};var p=function(){return u(r,l,arguments)};s?s(e.exports,"apply",{value:p}):e.exports.apply=p},5888:(e,n,t)=>{"use strict";e.exports=function(e,n){var t=this,r=t.constructor;return t.options=Object.assign({storeInstancesGlobally:!0},n||{}),t.callbacks={},t.directMap={},t.sequenceLevels={},t.resetTimer=null,t.ignoreNextKeyup=!1,t.ignoreNextKeypress=!1,t.nextExpectedAction=!1,t.element=e,t.addEvents(),t.options.storeInstancesGlobally&&r.instances.push(t),t},e.exports.prototype.bind=t(1210),e.exports.prototype.bindMultiple=t(4382),e.exports.prototype.unbind=t(3709),e.exports.prototype.trigger=t(3149),e.exports.prototype.reset=t(6726),e.exports.prototype.stopCallback=t(4446),e.exports.prototype.handleKey=t(4320),e.exports.prototype.addEvents=t(6687),e.exports.prototype.bindSingle=t(2214),e.exports.prototype.getKeyInfo=t(4174),e.exports.prototype.pickBestAction=t(6004),e.exports.prototype.getReverseMap=t(5193),e.exports.prototype.getMatches=t(9132),e.exports.prototype.resetSequences=t(3229),e.exports.prototype.fireCallback=t(7922),e.exports.prototype.bindSequence=t(3256),e.exports.prototype.resetSequenceTimer=t(602),e.exports.prototype.detach=t(3502),e.exports.instances=[],e.exports.reset=t(6255),e.exports.REVERSE_MAP=null},6687:(e,n,t)=>{"use strict";e.exports=function(){var e=this,n=t(2904),r=e.element;e.eventHandler=t(8178).bind(e),n(r,"keypress",e.eventHandler),n(r,"keydown",e.eventHandler),n(r,"keyup",e.eventHandler)}},1210:e=>{"use strict";e.exports=function(e,n,t){return e=e instanceof Array?e:[e],this.bindMultiple(e,n,t),this}},4382:e=>{"use strict";e.exports=function(e,n,t){for(var r=0;r{"use strict";e.exports=function(e,n,r,o){var i=this;function a(n){return function(){i.nextExpectedAction=n,++i.sequenceLevels[e],i.resetSequenceTimer()}}function l(n){var a;i.fireCallback(r,n,e),"keyup"!==o&&(a=t(3970),i.ignoreNextKeyup=a(n)),setTimeout((function(){i.resetSequences()}),10)}i.sequenceLevels[e]=0;for(var c=0;c{"use strict";e.exports=function(e,n,t,r,o){var i=this;i.directMap[e+":"+t]=n;var a,l=(e=e.replace(/\s+/g," ")).split(" ");l.length>1?i.bindSequence(e,l,n,t):(a=i.getKeyInfo(e,t),i.callbacks[a.key]=i.callbacks[a.key]||[],i.getMatches(a.key,a.modifiers,{type:a.action},r,e,o),i.callbacks[a.key][r?"unshift":"push"]({callback:n,modifiers:a.modifiers,action:a.action,seq:r,level:o,combo:e}))}},3502:(e,n,t)=>{var r=t(2904).off;e.exports=function(){var e=this,n=e.element;r(n,"keypress",e.eventHandler),r(n,"keydown",e.eventHandler),r(n,"keyup",e.eventHandler)}},2904:e=>{function n(e,n,t,r){return!e.addEventListener&&(n="on"+n),(e.addEventListener||e.attachEvent).call(e,n,t,r),t}e.exports=n,e.exports.on=n,e.exports.off=function(e,n,t,r){return!e.removeEventListener&&(n="on"+n),(e.removeEventListener||e.detachEvent).call(e,n,t,r),t}},7922:(e,n,t)=>{"use strict";e.exports=function(e,n,r,o){this.stopCallback(n,n.target||n.srcElement,r,o)||!1===e(n,r)&&(t(2156)(n),t(1849)(n))}},4174:(e,n,t)=>{"use strict";e.exports=function(e,n){var r,o,i,a,l,c,u=[];for(r=t(7486)(e),a=t(7641),l=t(7984),c=t(5962),i=0;i{"use strict";e.exports=function(e,n,r,o,i,a){var l,c,u,s,f=this,p=[],d=r.type;"keypress"!==d||r.code&&"Arrow"===r.code.slice(0,5)||(f.callbacks["any-character"]||[]).forEach((function(e){p.push(e)}));if(!f.callbacks[e])return p;for(u=t(5962),"keyup"===d&&u(e)&&(n=[e]),l=0;l{"use strict";e.exports=function(){var e,n=this.constructor;if(!n.REVERSE_MAP)for(var r in n.REVERSE_MAP={},e=t(6814))r>95&&r<112||e.hasOwnProperty(r)&&(n.REVERSE_MAP[e[r]]=r);return n.REVERSE_MAP}},4320:(e,n,t)=>{"use strict";e.exports=function(e,n,r){var o,i,a,l,c=this,u={},s=0,f=!1;for(o=c.getMatches(e,n,r),i=0;i{"use strict";e.exports=function(e){var n,r=this;"number"!=typeof e.which&&(e.which=e.keyCode);var o=t(3970)(e);void 0!==o&&("keyup"!==e.type||r.ignoreNextKeyup!==o?(n=t(5273),r.handleKey(o,n(e),e)):r.ignoreNextKeyup=!1)}},7238:e=>{"use strict";e.exports=function(e,n){return e.sort().join(",")===n.sort().join(",")}},6004:e=>{"use strict";e.exports=function(e,n,t){return t||(t=this.getReverseMap()[e]?"keydown":"keypress"),"keypress"===t&&n.length&&(t="keydown"),t}},6726:e=>{"use strict";e.exports=function(){return this.callbacks={},this.directMap={},this}},602:e=>{"use strict";e.exports=function(){var e=this;clearTimeout(e.resetTimer),e.resetTimer=setTimeout((function(){e.resetSequences()}),1e3)}},3229:e=>{"use strict";e.exports=function(e){var n=this;e=e||{};var t,r=!1;for(t in n.sequenceLevels)e[t]?r=!0:n.sequenceLevels[t]=0;r||(n.nextExpectedAction=!1)}},4446:e=>{"use strict";e.exports=function(e,n){if((" "+n.className+" ").indexOf(" combokeys ")>-1)return!1;var t=n.tagName.toLowerCase();return"input"===t||"select"===t||"textarea"===t||n.isContentEditable}},3149:e=>{"use strict";e.exports=function(e,n){return this.directMap[e+":"+n]&&this.directMap[e+":"+n]({},e),this}},3709:e=>{"use strict";e.exports=function(e,n){return this.bind(e,(function(){}),n)}},6255:e=>{"use strict";e.exports=function(){this.instances.forEach((function(e){e.reset()}))}},3970:(e,n,t)=>{"use strict";e.exports=function(e){var n,r;if(n=t(6814),r=t(4082),"keypress"===e.type){var o=String.fromCharCode(e.which);return e.shiftKey||(o=o.toLowerCase()),o}return void 0!==n[e.which]?n[e.which]:void 0!==r[e.which]?r[e.which]:String.fromCharCode(e.which).toLowerCase()}},5273:e=>{"use strict";e.exports=function(e){var n=[];return e.shiftKey&&n.push("shift"),e.altKey&&n.push("alt"),e.ctrlKey&&n.push("ctrl"),e.metaKey&&n.push("meta"),n}},5962:e=>{"use strict";e.exports=function(e){return"shift"===e||"ctrl"===e||"alt"===e||"meta"===e}},7486:e=>{"use strict";e.exports=function(e){return"+"===e?["+"]:e.split("+")}},2156:e=>{"use strict";e.exports=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1}},7984:e=>{"use strict";e.exports={"~":"`","!":"1","@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"}},7641:e=>{"use strict";e.exports={option:"alt",command:"meta",return:"enter",escape:"esc",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"}},4082:e=>{"use strict";e.exports={106:"*",107:"plus",109:"minus",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"}},6814:e=>{"use strict";e.exports={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",173:"minus",187:"plus",189:"minus",224:"meta"};for(var n=1;n<20;++n)e.exports[111+n]="f"+n;for(n=0;n<=9;++n)e.exports[n+96]=n},1849:e=>{"use strict";e.exports=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}},4982:(e,n,t)=>{"use strict";var r=t(6525),o=t(8075),i=t(1589),a=t(453),l=t(4552),c=t(920),u=t(7653),s=t(7244),f=t(4634),p=t(4670),d=t(2120),g=t(4035),h=t(7070),v=t(1189),b=t(1539),A=t(593),m=t(5767),y=t(9511),E=o("SharedArrayBuffer.prototype.byteLength",!0),C=o("Date.prototype.getTime"),w=Object.getPrototypeOf,_=o("Object.prototype.toString"),x=a("%Set%",!0),S=o("Map.prototype.has",!0),k=o("Map.prototype.get",!0),O=o("Map.prototype.size",!0),B=o("Set.prototype.add",!0),T=o("Set.prototype.delete",!0),P=o("Set.prototype.has",!0),I=o("Set.prototype.size",!0);function j(e,n,t,r){for(var o,i=l(e);(o=i.next())&&!o.done;)if(N(n,o.value,t,r))return T(e,o.value),!0;return!1}function z(e){return void 0===e?null:"object"!=typeof e?"symbol"!=typeof e&&("string"!=typeof e&&"number"!=typeof e||+e==+e):void 0}function D(e,n,t,o,i,a){var l=z(t);if(null!=l)return l;var c=k(n,l),u=r({},i,{strict:!1});return!(void 0===c&&!S(n,l)||!N(o,c,u,a))&&(!S(e,l)&&N(o,c,u,a))}function R(e,n,t){var r=z(t);return null!=r?r:P(n,r)&&!P(e,r)}function M(e,n,t,r,o,i){for(var a,c,u=l(e);(a=u.next())&&!a.done;)if(N(t,c=a.value,o,i)&&N(r,k(n,c),o,i))return T(e,c),!0;return!1}function N(e,n,t,o){var a=t||{};if(a.strict?u(e,n):e===n)return!0;if(b(e)!==b(n))return!1;if(!e||!n||"object"!=typeof e&&"object"!=typeof n)return a.strict?u(e,n):e==n;var c,T=o.has(e),z=o.has(n);if(T&&z){if(o.get(e)===o.get(n))return!0}else c={};return T||o.set(e,c),z||o.set(n,c),function(e,n,t,o){var a,c;if(typeof e!=typeof n)return!1;if(null==e||null==n)return!1;if(_(e)!==_(n))return!1;if(s(e)!==s(n))return!1;var u=f(e),b=f(n);if(u!==b)return!1;var T=e instanceof Error,z=n instanceof Error;if(T!==z)return!1;if((T||z)&&(e.name!==n.name||e.message!==n.message))return!1;var L=g(e),U=g(n);if(L!==U)return!1;if((L||U)&&(e.source!==n.source||i(e)!==i(n)))return!1;var H=d(e),W=d(n);if(H!==W)return!1;if((H||W)&&C(e)!==C(n))return!1;if(t.strict&&w&&w(e)!==w(n))return!1;var G=m(e),Y=m(n);if(G!==Y)return!1;if(G||Y){if(e.length!==n.length)return!1;for(a=0;a=0;a--)if(Z[a]!=J[a])return!1;for(a=Z.length-1;a>=0;a--)if(!N(e[c=Z[a]],n[c],t,o))return!1;var ee=A(e),ne=A(n);if(ee!==ne)return!1;if("Set"===ee||"Set"===ne)return function(e,n,t,r){if(I(e)!==I(n))return!1;var o,i,a,c=l(e),u=l(n);for(;(o=c.next())&&!o.done;)if(o.value&&"object"==typeof o.value)a||(a=new x),B(a,o.value);else if(!P(n,o.value)){if(t.strict)return!1;if(!R(e,n,o.value))return!1;a||(a=new x),B(a,o.value)}if(a){for(;(i=u.next())&&!i.done;)if(i.value&&"object"==typeof i.value){if(!j(a,i.value,t.strict,r))return!1}else if(!t.strict&&!P(e,i.value)&&!j(a,i.value,t.strict,r))return!1;return 0===I(a)}return!0}(e,n,t,o);if("Map"===ee)return function(e,n,t,o){if(O(e)!==O(n))return!1;var i,a,c,u,s,f,p=l(e),d=l(n);for(;(i=p.next())&&!i.done;)if(u=i.value[0],s=i.value[1],u&&"object"==typeof u)c||(c=new x),B(c,u);else if(void 0===(f=k(n,u))&&!S(n,u)||!N(s,f,t,o)){if(t.strict)return!1;if(!D(e,n,u,s,t,o))return!1;c||(c=new x),B(c,u)}if(c){for(;(a=d.next())&&!a.done;)if(u=a.value[0],f=a.value[1],u&&"object"==typeof u){if(!M(c,e,u,f,t,o))return!1}else if(!(t.strict||e.has(u)&&N(k(e,u),f,t,o)||M(c,e,u,f,r({},t,{strict:!1}),o)))return!1;return 0===I(c)}return!0}(e,n,t,o);return!0}(e,n,a,o)}function F(e){return!(!e||"object"!=typeof e||"number"!=typeof e.length)&&("function"==typeof e.copy&&"function"==typeof e.slice&&(!(e.length>0&&"number"!=typeof e[0])&&!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))))}e.exports=function(e,n,t){return N(e,n,t,c())}},41:(e,n,t)=>{"use strict";var r=t(3036),o=t(8068),i=t(9675),a=t(5795);e.exports=function(e,n,t){if(!e||"object"!=typeof e&&"function"!=typeof e)throw new i("`obj` must be an object or a function`");if("string"!=typeof n&&"symbol"!=typeof n)throw new i("`property` must be a string or a symbol`");if(arguments.length>3&&"boolean"!=typeof arguments[3]&&null!==arguments[3])throw new i("`nonEnumerable`, if provided, must be a boolean or null");if(arguments.length>4&&"boolean"!=typeof arguments[4]&&null!==arguments[4])throw new i("`nonWritable`, if provided, must be a boolean or null");if(arguments.length>5&&"boolean"!=typeof arguments[5]&&null!==arguments[5])throw new i("`nonConfigurable`, if provided, must be a boolean or null");if(arguments.length>6&&"boolean"!=typeof arguments[6])throw new i("`loose`, if provided, must be a boolean");var l=arguments.length>3?arguments[3]:null,c=arguments.length>4?arguments[4]:null,u=arguments.length>5?arguments[5]:null,s=arguments.length>6&&arguments[6],f=!!a&&a(e,n);if(r)r(e,n,{configurable:null===u&&f?f.configurable:!u,enumerable:null===l&&f?f.enumerable:!l,value:t,writable:null===c&&f?f.writable:!c});else{if(!s&&(l||c||u))throw new o("This environment does not support defining a property as non-configurable, non-writable, or non-enumerable.");e[n]=t}}},8452:(e,n,t)=>{"use strict";var r=t(1189),o="function"==typeof Symbol&&"symbol"==typeof Symbol("foo"),i=Object.prototype.toString,a=Array.prototype.concat,l=t(41),c=t(592)(),u=function(e,n,t,r){if(n in e)if(!0===r){if(e[n]===t)return}else if("function"!=typeof(o=r)||"[object Function]"!==i.call(o)||!r())return;var o;c?l(e,n,t,!0):l(e,n,t)},s=function(e,n){var t=arguments.length>2?arguments[2]:{},i=r(n);o&&(i=a.call(i,Object.getOwnPropertySymbols(n)));for(var l=0;l{"use strict";var r=t(453)("%Object.defineProperty%",!0)||!1;if(r)try{r({},"a",{value:1})}catch(e){r=!1}e.exports=r},1237:e=>{"use strict";e.exports=EvalError},9383:e=>{"use strict";e.exports=Error},9290:e=>{"use strict";e.exports=RangeError},9538:e=>{"use strict";e.exports=ReferenceError},8068:e=>{"use strict";e.exports=SyntaxError},9675:e=>{"use strict";e.exports=TypeError},5345:e=>{"use strict";e.exports=URIError},2682:(e,n,t)=>{"use strict";var r=t(9600),o=Object.prototype.toString,i=Object.prototype.hasOwnProperty;e.exports=function(e,n,t){if(!r(n))throw new TypeError("iterator must be a function");var a;arguments.length>=3&&(a=t),"[object Array]"===o.call(e)?function(e,n,t){for(var r=0,o=e.length;r{"use strict";var n=Object.prototype.toString,t=Math.max,r=function(e,n){for(var t=[],r=0;r{"use strict";var r=t(9353);e.exports=Function.prototype.bind||r},4462:e=>{"use strict";var n=function(){return"string"==typeof function(){}.name},t=Object.getOwnPropertyDescriptor;if(t)try{t([],"length")}catch(e){t=null}n.functionsHaveConfigurableNames=function(){if(!n()||!t)return!1;var e=t((function(){}),"name");return!!e&&!!e.configurable};var r=Function.prototype.bind;n.boundFunctionsHaveNames=function(){return n()&&"function"==typeof r&&""!==function(){}.bind().name},e.exports=n},453:(e,n,t)=>{"use strict";var r,o=t(9383),i=t(1237),a=t(9290),l=t(9538),c=t(8068),u=t(9675),s=t(5345),f=Function,p=function(e){try{return f('"use strict"; return ('+e+").constructor;")()}catch(e){}},d=Object.getOwnPropertyDescriptor;if(d)try{d({},"")}catch(e){d=null}var g=function(){throw new u},h=d?function(){try{return g}catch(e){try{return d(arguments,"callee").get}catch(e){return g}}}():g,v=t(4039)(),b=t(24)(),A=Object.getPrototypeOf||(b?function(e){return e.__proto__}:null),m={},y="undefined"!=typeof Uint8Array&&A?A(Uint8Array):r,E={__proto__:null,"%AggregateError%":"undefined"==typeof AggregateError?r:AggregateError,"%Array%":Array,"%ArrayBuffer%":"undefined"==typeof ArrayBuffer?r:ArrayBuffer,"%ArrayIteratorPrototype%":v&&A?A([][Symbol.iterator]()):r,"%AsyncFromSyncIteratorPrototype%":r,"%AsyncFunction%":m,"%AsyncGenerator%":m,"%AsyncGeneratorFunction%":m,"%AsyncIteratorPrototype%":m,"%Atomics%":"undefined"==typeof Atomics?r:Atomics,"%BigInt%":"undefined"==typeof BigInt?r:BigInt,"%BigInt64Array%":"undefined"==typeof BigInt64Array?r:BigInt64Array,"%BigUint64Array%":"undefined"==typeof BigUint64Array?r:BigUint64Array,"%Boolean%":Boolean,"%DataView%":"undefined"==typeof DataView?r:DataView,"%Date%":Date,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":o,"%eval%":eval,"%EvalError%":i,"%Float32Array%":"undefined"==typeof Float32Array?r:Float32Array,"%Float64Array%":"undefined"==typeof Float64Array?r:Float64Array,"%FinalizationRegistry%":"undefined"==typeof FinalizationRegistry?r:FinalizationRegistry,"%Function%":f,"%GeneratorFunction%":m,"%Int8Array%":"undefined"==typeof Int8Array?r:Int8Array,"%Int16Array%":"undefined"==typeof Int16Array?r:Int16Array,"%Int32Array%":"undefined"==typeof Int32Array?r:Int32Array,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":v&&A?A(A([][Symbol.iterator]())):r,"%JSON%":"object"==typeof JSON?JSON:r,"%Map%":"undefined"==typeof Map?r:Map,"%MapIteratorPrototype%":"undefined"!=typeof Map&&v&&A?A((new Map)[Symbol.iterator]()):r,"%Math%":Math,"%Number%":Number,"%Object%":Object,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":"undefined"==typeof Promise?r:Promise,"%Proxy%":"undefined"==typeof Proxy?r:Proxy,"%RangeError%":a,"%ReferenceError%":l,"%Reflect%":"undefined"==typeof Reflect?r:Reflect,"%RegExp%":RegExp,"%Set%":"undefined"==typeof Set?r:Set,"%SetIteratorPrototype%":"undefined"!=typeof Set&&v&&A?A((new Set)[Symbol.iterator]()):r,"%SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?r:SharedArrayBuffer,"%String%":String,"%StringIteratorPrototype%":v&&A?A(""[Symbol.iterator]()):r,"%Symbol%":v?Symbol:r,"%SyntaxError%":c,"%ThrowTypeError%":h,"%TypedArray%":y,"%TypeError%":u,"%Uint8Array%":"undefined"==typeof Uint8Array?r:Uint8Array,"%Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?r:Uint8ClampedArray,"%Uint16Array%":"undefined"==typeof Uint16Array?r:Uint16Array,"%Uint32Array%":"undefined"==typeof Uint32Array?r:Uint32Array,"%URIError%":s,"%WeakMap%":"undefined"==typeof WeakMap?r:WeakMap,"%WeakRef%":"undefined"==typeof WeakRef?r:WeakRef,"%WeakSet%":"undefined"==typeof WeakSet?r:WeakSet};if(A)try{null.error}catch(e){var C=A(A(e));E["%Error.prototype%"]=C}var w=function e(n){var t;if("%AsyncFunction%"===n)t=p("async function () {}");else if("%GeneratorFunction%"===n)t=p("function* () {}");else if("%AsyncGeneratorFunction%"===n)t=p("async function* () {}");else if("%AsyncGenerator%"===n){var r=e("%AsyncGeneratorFunction%");r&&(t=r.prototype)}else if("%AsyncIteratorPrototype%"===n){var o=e("%AsyncGenerator%");o&&A&&(t=A(o.prototype))}return E[n]=t,t},_={__proto__:null,"%ArrayBufferPrototype%":["ArrayBuffer","prototype"],"%ArrayPrototype%":["Array","prototype"],"%ArrayProto_entries%":["Array","prototype","entries"],"%ArrayProto_forEach%":["Array","prototype","forEach"],"%ArrayProto_keys%":["Array","prototype","keys"],"%ArrayProto_values%":["Array","prototype","values"],"%AsyncFunctionPrototype%":["AsyncFunction","prototype"],"%AsyncGenerator%":["AsyncGeneratorFunction","prototype"],"%AsyncGeneratorPrototype%":["AsyncGeneratorFunction","prototype","prototype"],"%BooleanPrototype%":["Boolean","prototype"],"%DataViewPrototype%":["DataView","prototype"],"%DatePrototype%":["Date","prototype"],"%ErrorPrototype%":["Error","prototype"],"%EvalErrorPrototype%":["EvalError","prototype"],"%Float32ArrayPrototype%":["Float32Array","prototype"],"%Float64ArrayPrototype%":["Float64Array","prototype"],"%FunctionPrototype%":["Function","prototype"],"%Generator%":["GeneratorFunction","prototype"],"%GeneratorPrototype%":["GeneratorFunction","prototype","prototype"],"%Int8ArrayPrototype%":["Int8Array","prototype"],"%Int16ArrayPrototype%":["Int16Array","prototype"],"%Int32ArrayPrototype%":["Int32Array","prototype"],"%JSONParse%":["JSON","parse"],"%JSONStringify%":["JSON","stringify"],"%MapPrototype%":["Map","prototype"],"%NumberPrototype%":["Number","prototype"],"%ObjectPrototype%":["Object","prototype"],"%ObjProto_toString%":["Object","prototype","toString"],"%ObjProto_valueOf%":["Object","prototype","valueOf"],"%PromisePrototype%":["Promise","prototype"],"%PromiseProto_then%":["Promise","prototype","then"],"%Promise_all%":["Promise","all"],"%Promise_reject%":["Promise","reject"],"%Promise_resolve%":["Promise","resolve"],"%RangeErrorPrototype%":["RangeError","prototype"],"%ReferenceErrorPrototype%":["ReferenceError","prototype"],"%RegExpPrototype%":["RegExp","prototype"],"%SetPrototype%":["Set","prototype"],"%SharedArrayBufferPrototype%":["SharedArrayBuffer","prototype"],"%StringPrototype%":["String","prototype"],"%SymbolPrototype%":["Symbol","prototype"],"%SyntaxErrorPrototype%":["SyntaxError","prototype"],"%TypedArrayPrototype%":["TypedArray","prototype"],"%TypeErrorPrototype%":["TypeError","prototype"],"%Uint8ArrayPrototype%":["Uint8Array","prototype"],"%Uint8ClampedArrayPrototype%":["Uint8ClampedArray","prototype"],"%Uint16ArrayPrototype%":["Uint16Array","prototype"],"%Uint32ArrayPrototype%":["Uint32Array","prototype"],"%URIErrorPrototype%":["URIError","prototype"],"%WeakMapPrototype%":["WeakMap","prototype"],"%WeakSetPrototype%":["WeakSet","prototype"]},x=t(6743),S=t(9957),k=x.call(Function.call,Array.prototype.concat),O=x.call(Function.apply,Array.prototype.splice),B=x.call(Function.call,String.prototype.replace),T=x.call(Function.call,String.prototype.slice),P=x.call(Function.call,RegExp.prototype.exec),I=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,j=/\\(\\)?/g,z=function(e,n){var t,r=e;if(S(_,r)&&(r="%"+(t=_[r])[0]+"%"),S(E,r)){var o=E[r];if(o===m&&(o=w(r)),void 0===o&&!n)throw new u("intrinsic "+e+" exists, but is not available. Please file an issue!");return{alias:t,name:r,value:o}}throw new c("intrinsic "+e+" does not exist!")};e.exports=function(e,n){if("string"!=typeof e||0===e.length)throw new u("intrinsic name must be a non-empty string");if(arguments.length>1&&"boolean"!=typeof n)throw new u('"allowMissing" argument must be a boolean');if(null===P(/^%?[^%]*%?$/,e))throw new c("`%` may not be present anywhere but at the beginning and end of the intrinsic name");var t=function(e){var n=T(e,0,1),t=T(e,-1);if("%"===n&&"%"!==t)throw new c("invalid intrinsic syntax, expected closing `%`");if("%"===t&&"%"!==n)throw new c("invalid intrinsic syntax, expected opening `%`");var r=[];return B(e,I,(function(e,n,t,o){r[r.length]=t?B(o,j,"$1"):n||e})),r}(e),r=t.length>0?t[0]:"",o=z("%"+r+"%",n),i=o.name,a=o.value,l=!1,s=o.alias;s&&(r=s[0],O(t,k([0,1],s)));for(var f=1,p=!0;f=t.length){var b=d(a,g);a=(p=!!b)&&"get"in b&&!("originalValue"in b.get)?b.get:a[g]}else p=S(a,g),a=a[g];p&&!l&&(E[i]=a)}}return a}},5795:(e,n,t)=>{"use strict";var r=t(453)("%Object.getOwnPropertyDescriptor%",!0);if(r)try{r([],"length")}catch(e){r=null}e.exports=r},9790:e=>{"use strict";var n="undefined"!=typeof BigInt&&BigInt;e.exports=function(){return"function"==typeof n&&"function"==typeof BigInt&&"bigint"==typeof n(42)&&"bigint"==typeof BigInt(42)}},592:(e,n,t)=>{"use strict";var r=t(3036),o=function(){return!!r};o.hasArrayLengthDefineBug=function(){if(!r)return null;try{return 1!==r([],"length",{value:1}).length}catch(e){return!0}},e.exports=o},24:e=>{"use strict";var n={__proto__:null,foo:{}},t=Object;e.exports=function(){return{__proto__:n}.foo===n.foo&&!(n instanceof t)}},4039:(e,n,t)=>{"use strict";var r="undefined"!=typeof Symbol&&Symbol,o=t(1333);e.exports=function(){return"function"==typeof r&&("function"==typeof Symbol&&("symbol"==typeof r("foo")&&("symbol"==typeof Symbol("bar")&&o())))}},1333:e=>{"use strict";e.exports=function(){if("function"!=typeof Symbol||"function"!=typeof Object.getOwnPropertySymbols)return!1;if("symbol"==typeof Symbol.iterator)return!0;var e={},n=Symbol("test"),t=Object(n);if("string"==typeof n)return!1;if("[object Symbol]"!==Object.prototype.toString.call(n))return!1;if("[object Symbol]"!==Object.prototype.toString.call(t))return!1;for(n in e[n]=42,e)return!1;if("function"==typeof Object.keys&&0!==Object.keys(e).length)return!1;if("function"==typeof Object.getOwnPropertyNames&&0!==Object.getOwnPropertyNames(e).length)return!1;var r=Object.getOwnPropertySymbols(e);if(1!==r.length||r[0]!==n)return!1;if(!Object.prototype.propertyIsEnumerable.call(e,n))return!1;if("function"==typeof Object.getOwnPropertyDescriptor){var o=Object.getOwnPropertyDescriptor(e,n);if(42!==o.value||!0!==o.enumerable)return!1}return!0}},9092:(e,n,t)=>{"use strict";var r=t(1333);e.exports=function(){return r()&&!!Symbol.toStringTag}},9957:(e,n,t)=>{"use strict";var r=Function.prototype.call,o=Object.prototype.hasOwnProperty,i=t(6743);e.exports=i.call(r,o)},63:(e,n,t)=>{"use strict";var r=t(9957),o=t(920)(),i=t(9675),a={assert:function(e,n){if(!e||"object"!=typeof e&&"function"!=typeof e)throw new i("`O` is not an object");if("string"!=typeof n)throw new i("`slot` must be a string");if(o.assert(e),!a.has(e,n))throw new i("`"+n+"` is not present on `O`")},get:function(e,n){if(!e||"object"!=typeof e&&"function"!=typeof e)throw new i("`O` is not an object");if("string"!=typeof n)throw new i("`slot` must be a string");var t=o.get(e);return t&&t["$"+n]},has:function(e,n){if(!e||"object"!=typeof e&&"function"!=typeof e)throw new i("`O` is not an object");if("string"!=typeof n)throw new i("`slot` must be a string");var t=o.get(e);return!!t&&r(t,"$"+n)},set:function(e,n,t){if(!e||"object"!=typeof e&&"function"!=typeof e)throw new i("`O` is not an object");if("string"!=typeof n)throw new i("`slot` must be a string");var r=o.get(e);r||(r={},o.set(e,r)),r["$"+n]=t}};Object.freeze&&Object.freeze(a),e.exports=a},7244:(e,n,t)=>{"use strict";var r=t(9092)(),o=t(8075)("Object.prototype.toString"),i=function(e){return!(r&&e&&"object"==typeof e&&Symbol.toStringTag in e)&&"[object Arguments]"===o(e)},a=function(e){return!!i(e)||null!==e&&"object"==typeof e&&"number"==typeof e.length&&e.length>=0&&"[object Array]"!==o(e)&&"[object Function]"===o(e.callee)},l=function(){return i(arguments)}();i.isLegacyArguments=a,e.exports=l?i:a},4670:(e,n,t)=>{"use strict";var r=t(487),o=t(8075),i=t(453)("%ArrayBuffer%",!0),a=o("ArrayBuffer.prototype.byteLength",!0),l=o("Object.prototype.toString"),c=!!i&&!a&&new i(0).slice,u=!!c&&r(c);e.exports=a||u?function(e){if(!e||"object"!=typeof e)return!1;try{return a?a(e):u(e,0),!0}catch(e){return!1}}:i?function(e){return"[object ArrayBuffer]"===l(e)}:function(e){return!1}},9803:(e,n,t)=>{"use strict";if(t(9790)()){var r=BigInt.prototype.valueOf;e.exports=function(e){return null!=e&&"boolean"!=typeof e&&"string"!=typeof e&&"number"!=typeof e&&"symbol"!=typeof e&&"function"!=typeof e&&("bigint"==typeof e||function(e){try{return r.call(e),!0}catch(e){}return!1}(e))}}else e.exports=function(e){return!1}},5128:(e,n,t)=>{"use strict";var r=t(8075),o=r("Boolean.prototype.toString"),i=r("Object.prototype.toString"),a=t(9092)();e.exports=function(e){return"boolean"==typeof e||null!==e&&"object"==typeof e&&(a&&Symbol.toStringTag in e?function(e){try{return o(e),!0}catch(e){return!1}}(e):"[object Boolean]"===i(e))}},9600:e=>{"use strict";var n,t,r=Function.prototype.toString,o="object"==typeof Reflect&&null!==Reflect&&Reflect.apply;if("function"==typeof o&&"function"==typeof Object.defineProperty)try{n=Object.defineProperty({},"length",{get:function(){throw t}}),t={},o((function(){throw 42}),null,n)}catch(e){e!==t&&(o=null)}else o=null;var i=/^\s*class\b/,a=function(e){try{var n=r.call(e);return i.test(n)}catch(e){return!1}},l=function(e){try{return!a(e)&&(r.call(e),!0)}catch(e){return!1}},c=Object.prototype.toString,u="function"==typeof Symbol&&!!Symbol.toStringTag,s=!(0 in[,]),f=function(){return!1};if("object"==typeof document){var p=document.all;c.call(p)===c.call(document.all)&&(f=function(e){if((s||!e)&&(void 0===e||"object"==typeof e))try{var n=c.call(e);return("[object HTMLAllCollection]"===n||"[object HTML document.all class]"===n||"[object HTMLCollection]"===n||"[object Object]"===n)&&null==e("")}catch(e){}return!1})}e.exports=o?function(e){if(f(e))return!0;if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;try{o(e,null,n)}catch(e){if(e!==t)return!1}return!a(e)&&l(e)}:function(e){if(f(e))return!0;if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if(u)return l(e);if(a(e))return!1;var n=c.call(e);return!("[object Function]"!==n&&"[object GeneratorFunction]"!==n&&!/^\[object HTML/.test(n))&&l(e)}},2120:(e,n,t)=>{"use strict";var r=Date.prototype.getDay,o=Object.prototype.toString,i=t(9092)();e.exports=function(e){return"object"==typeof e&&null!==e&&(i?function(e){try{return r.call(e),!0}catch(e){return!1}}(e):"[object Date]"===o.call(e))}},1421:e=>{"use strict";var n,t="function"==typeof Map&&Map.prototype?Map:null,r="function"==typeof Set&&Set.prototype?Set:null;t||(n=function(e){return!1});var o=t?Map.prototype.has:null,i=r?Set.prototype.has:null;n||o||(n=function(e){return!1}),e.exports=n||function(e){if(!e||"object"!=typeof e)return!1;try{if(o.call(e),i)try{i.call(e)}catch(e){return!0}return e instanceof t}catch(e){}return!1}},1703:(e,n,t)=>{"use strict";var r=Number.prototype.toString,o=Object.prototype.toString,i=t(9092)();e.exports=function(e){return"number"==typeof e||"object"==typeof e&&(i?function(e){try{return r.call(e),!0}catch(e){return!1}}(e):"[object Number]"===o.call(e))}},4035:(e,n,t)=>{"use strict";var r,o,i,a,l=t(8075),c=t(9092)();if(c){r=l("Object.prototype.hasOwnProperty"),o=l("RegExp.prototype.exec"),i={};var u=function(){throw i};a={toString:u,valueOf:u},"symbol"==typeof Symbol.toPrimitive&&(a[Symbol.toPrimitive]=u)}var s=l("Object.prototype.toString"),f=Object.getOwnPropertyDescriptor;e.exports=c?function(e){if(!e||"object"!=typeof e)return!1;var n=f(e,"lastIndex");if(!(n&&r(n,"value")))return!1;try{o(e,a)}catch(e){return e===i}}:function(e){return!(!e||"object"!=typeof e&&"function"!=typeof e)&&"[object RegExp]"===s(e)}},256:e=>{"use strict";var n,t="function"==typeof Map&&Map.prototype?Map:null,r="function"==typeof Set&&Set.prototype?Set:null;r||(n=function(e){return!1});var o=t?Map.prototype.has:null,i=r?Set.prototype.has:null;n||i||(n=function(e){return!1}),e.exports=n||function(e){if(!e||"object"!=typeof e)return!1;try{if(i.call(e),o)try{o.call(e)}catch(e){return!0}return e instanceof r}catch(e){}return!1}},7070:(e,n,t)=>{"use strict";var r=t(8075)("SharedArrayBuffer.prototype.byteLength",!0);e.exports=r?function(e){if(!e||"object"!=typeof e)return!1;try{return r(e),!0}catch(e){return!1}}:function(e){return!1}},4761:(e,n,t)=>{"use strict";var r=String.prototype.valueOf,o=Object.prototype.toString,i=t(9092)();e.exports=function(e){return"string"==typeof e||"object"==typeof e&&(i?function(e){try{return r.call(e),!0}catch(e){return!1}}(e):"[object String]"===o.call(e))}},3612:(e,n,t)=>{"use strict";var r=Object.prototype.toString;if(t(4039)()){var o=Symbol.prototype.toString,i=/^Symbol\(.*\)$/;e.exports=function(e){if("symbol"==typeof e)return!0;if("[object Symbol]"!==r.call(e))return!1;try{return function(e){return"symbol"==typeof e.valueOf()&&i.test(o.call(e))}(e)}catch(e){return!1}}}else e.exports=function(e){return!1}},7842:e=>{"use strict";var n,t="function"==typeof WeakMap&&WeakMap.prototype?WeakMap:null,r="function"==typeof WeakSet&&WeakSet.prototype?WeakSet:null;t||(n=function(e){return!1});var o=t?t.prototype.has:null,i=r?r.prototype.has:null;n||o||(n=function(e){return!1}),e.exports=n||function(e){if(!e||"object"!=typeof e)return!1;try{if(o.call(e,o),i)try{i.call(e,i)}catch(e){return!0}return e instanceof t}catch(e){}return!1}},2648:(e,n,t)=>{"use strict";var r=t(453),o=t(8075),i=r("%WeakSet%",!0),a=o("WeakSet.prototype.has",!0);if(a){var l=o("WeakMap.prototype.has",!0);e.exports=function(e){if(!e||"object"!=typeof e)return!1;try{if(a(e,a),l)try{l(e,l)}catch(e){return!0}return e instanceof i}catch(e){}return!1}}else e.exports=function(e){return!1}},4634:e=>{var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},2543:function(e,n,t){var r; /** * @license * Lodash * Copyright OpenJS Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */e=t.nmd(e),function(){var o,i="Expected a function",a="__lodash_hash_undefined__",l="__lodash_placeholder__",c=16,u=32,s=64,f=128,p=256,d=1/0,g=9007199254740991,h=NaN,v=4294967295,b=[["ary",f],["bind",1],["bindKey",2],["curry",8],["curryRight",c],["flip",512],["partial",u],["partialRight",s],["rearg",p]],A="[object Arguments]",m="[object Array]",y="[object Boolean]",E="[object Date]",C="[object Error]",w="[object Function]",_="[object GeneratorFunction]",x="[object Map]",S="[object Number]",k="[object Object]",O="[object Promise]",B="[object RegExp]",T="[object Set]",P="[object String]",I="[object Symbol]",j="[object WeakMap]",z="[object ArrayBuffer]",D="[object DataView]",R="[object Float32Array]",M="[object Float64Array]",N="[object Int8Array]",F="[object Int16Array]",L="[object Int32Array]",U="[object Uint8Array]",H="[object Uint8ClampedArray]",W="[object Uint16Array]",G="[object Uint32Array]",Y=/\b__p \+= '';/g,q=/\b(__p \+=) '' \+/g,V=/(__e\(.*?\)|\b__t\)) \+\n'';/g,$=/&(?:amp|lt|gt|quot|#39);/g,K=/[&<>"']/g,Q=RegExp($.source),X=RegExp(K.source),Z=/<%-([\s\S]+?)%>/g,J=/<%([\s\S]+?)%>/g,ee=/<%=([\s\S]+?)%>/g,ne=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,te=/^\w*$/,re=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,oe=/[\\^$.*+?()[\]{}|]/g,ie=RegExp(oe.source),ae=/^\s+/,le=/\s/,ce=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,ue=/\{\n\/\* \[wrapped with (.+)\] \*/,se=/,? & /,fe=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,pe=/[()=,{}\[\]\/\s]/,de=/\\(\\)?/g,ge=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,he=/\w*$/,ve=/^[-+]0x[0-9a-f]+$/i,be=/^0b[01]+$/i,Ae=/^\[object .+?Constructor\]$/,me=/^0o[0-7]+$/i,ye=/^(?:0|[1-9]\d*)$/,Ee=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Ce=/($^)/,we=/['\n\r\u2028\u2029\\]/g,_e="\\ud800-\\udfff",xe="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",Se="\\u2700-\\u27bf",ke="a-z\\xdf-\\xf6\\xf8-\\xff",Oe="A-Z\\xc0-\\xd6\\xd8-\\xde",Be="\\ufe0e\\ufe0f",Te="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Pe="['’]",Ie="["+_e+"]",je="["+Te+"]",ze="["+xe+"]",De="\\d+",Re="["+Se+"]",Me="["+ke+"]",Ne="[^"+_e+Te+De+Se+ke+Oe+"]",Fe="\\ud83c[\\udffb-\\udfff]",Le="[^"+_e+"]",Ue="(?:\\ud83c[\\udde6-\\uddff]){2}",He="[\\ud800-\\udbff][\\udc00-\\udfff]",We="["+Oe+"]",Ge="\\u200d",Ye="(?:"+Me+"|"+Ne+")",qe="(?:"+We+"|"+Ne+")",Ve="(?:['’](?:d|ll|m|re|s|t|ve))?",$e="(?:['’](?:D|LL|M|RE|S|T|VE))?",Ke="(?:"+ze+"|"+Fe+")"+"?",Qe="["+Be+"]?",Xe=Qe+Ke+("(?:"+Ge+"(?:"+[Le,Ue,He].join("|")+")"+Qe+Ke+")*"),Ze="(?:"+[Re,Ue,He].join("|")+")"+Xe,Je="(?:"+[Le+ze+"?",ze,Ue,He,Ie].join("|")+")",en=RegExp(Pe,"g"),nn=RegExp(ze,"g"),tn=RegExp(Fe+"(?="+Fe+")|"+Je+Xe,"g"),rn=RegExp([We+"?"+Me+"+"+Ve+"(?="+[je,We,"$"].join("|")+")",qe+"+"+$e+"(?="+[je,We+Ye,"$"].join("|")+")",We+"?"+Ye+"+"+Ve,We+"+"+$e,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",De,Ze].join("|"),"g"),on=RegExp("["+Ge+_e+xe+Be+"]"),an=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,ln=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],cn=-1,un={};un[R]=un[M]=un[N]=un[F]=un[L]=un[U]=un[H]=un[W]=un[G]=!0,un[A]=un[m]=un[z]=un[y]=un[D]=un[E]=un[C]=un[w]=un[x]=un[S]=un[k]=un[B]=un[T]=un[P]=un[j]=!1;var sn={};sn[A]=sn[m]=sn[z]=sn[D]=sn[y]=sn[E]=sn[R]=sn[M]=sn[N]=sn[F]=sn[L]=sn[x]=sn[S]=sn[k]=sn[B]=sn[T]=sn[P]=sn[I]=sn[U]=sn[H]=sn[W]=sn[G]=!0,sn[C]=sn[w]=sn[j]=!1;var fn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},pn=parseFloat,dn=parseInt,gn="object"==typeof t.g&&t.g&&t.g.Object===Object&&t.g,hn="object"==typeof self&&self&&self.Object===Object&&self,vn=gn||hn||Function("return this")(),bn=n&&!n.nodeType&&n,An=bn&&e&&!e.nodeType&&e,mn=An&&An.exports===bn,yn=mn&&gn.process,En=function(){try{var e=An&&An.require&&An.require("util").types;return e||yn&&yn.binding&&yn.binding("util")}catch(e){}}(),Cn=En&&En.isArrayBuffer,wn=En&&En.isDate,_n=En&&En.isMap,xn=En&&En.isRegExp,Sn=En&&En.isSet,kn=En&&En.isTypedArray;function On(e,n,t){switch(t.length){case 0:return e.call(n);case 1:return e.call(n,t[0]);case 2:return e.call(n,t[0],t[1]);case 3:return e.call(n,t[0],t[1],t[2])}return e.apply(n,t)}function Bn(e,n,t,r){for(var o=-1,i=null==e?0:e.length;++o-1}function Dn(e,n,t){for(var r=-1,o=null==e?0:e.length;++r-1;);return t}function ot(e,n){for(var t=e.length;t--&&Gn(n,e[t],0)>-1;);return t}var it=Kn({À:"A",Á:"A",Â:"A",Ã:"A",Ä:"A",Å:"A",à:"a",á:"a",â:"a",ã:"a",ä:"a",å:"a",Ç:"C",ç:"c",Ð:"D",ð:"d",È:"E",É:"E",Ê:"E",Ë:"E",è:"e",é:"e",ê:"e",ë:"e",Ì:"I",Í:"I",Î:"I",Ï:"I",ì:"i",í:"i",î:"i",ï:"i",Ñ:"N",ñ:"n",Ò:"O",Ó:"O",Ô:"O",Õ:"O",Ö:"O",Ø:"O",ò:"o",ó:"o",ô:"o",õ:"o",ö:"o",ø:"o",Ù:"U",Ú:"U",Û:"U",Ü:"U",ù:"u",ú:"u",û:"u",ü:"u",Ý:"Y",ý:"y",ÿ:"y",Æ:"Ae",æ:"ae",Þ:"Th",þ:"th",ß:"ss",Ā:"A",Ă:"A",Ą:"A",ā:"a",ă:"a",ą:"a",Ć:"C",Ĉ:"C",Ċ:"C",Č:"C",ć:"c",ĉ:"c",ċ:"c",č:"c",Ď:"D",Đ:"D",ď:"d",đ:"d",Ē:"E",Ĕ:"E",Ė:"E",Ę:"E",Ě:"E",ē:"e",ĕ:"e",ė:"e",ę:"e",ě:"e",Ĝ:"G",Ğ:"G",Ġ:"G",Ģ:"G",ĝ:"g",ğ:"g",ġ:"g",ģ:"g",Ĥ:"H",Ħ:"H",ĥ:"h",ħ:"h",Ĩ:"I",Ī:"I",Ĭ:"I",Į:"I",İ:"I",ĩ:"i",ī:"i",ĭ:"i",į:"i",ı:"i",Ĵ:"J",ĵ:"j",Ķ:"K",ķ:"k",ĸ:"k",Ĺ:"L",Ļ:"L",Ľ:"L",Ŀ:"L",Ł:"L",ĺ:"l",ļ:"l",ľ:"l",ŀ:"l",ł:"l",Ń:"N",Ņ:"N",Ň:"N",Ŋ:"N",ń:"n",ņ:"n",ň:"n",ŋ:"n",Ō:"O",Ŏ:"O",Ő:"O",ō:"o",ŏ:"o",ő:"o",Ŕ:"R",Ŗ:"R",Ř:"R",ŕ:"r",ŗ:"r",ř:"r",Ś:"S",Ŝ:"S",Ş:"S",Š:"S",ś:"s",ŝ:"s",ş:"s",š:"s",Ţ:"T",Ť:"T",Ŧ:"T",ţ:"t",ť:"t",ŧ:"t",Ũ:"U",Ū:"U",Ŭ:"U",Ů:"U",Ű:"U",Ų:"U",ũ:"u",ū:"u",ŭ:"u",ů:"u",ű:"u",ų:"u",Ŵ:"W",ŵ:"w",Ŷ:"Y",ŷ:"y",Ÿ:"Y",Ź:"Z",Ż:"Z",Ž:"Z",ź:"z",ż:"z",ž:"z",IJ:"IJ",ij:"ij",Œ:"Oe",œ:"oe",ʼn:"'n",ſ:"s"}),at=Kn({"&":"&","<":"<",">":">",'"':""","'":"'"});function lt(e){return"\\"+fn[e]}function ct(e){return on.test(e)}function ut(e){var n=-1,t=Array(e.size);return e.forEach((function(e,r){t[++n]=[r,e]})),t}function st(e,n){return function(t){return e(n(t))}}function ft(e,n){for(var t=-1,r=e.length,o=0,i=[];++t",""":'"',"'":"'"});var At=function e(n){var t,r=(n=null==n?vn:At.defaults(vn.Object(),n,At.pick(vn,ln))).Array,le=n.Date,_e=n.Error,xe=n.Function,Se=n.Math,ke=n.Object,Oe=n.RegExp,Be=n.String,Te=n.TypeError,Pe=r.prototype,Ie=xe.prototype,je=ke.prototype,ze=n["__core-js_shared__"],De=Ie.toString,Re=je.hasOwnProperty,Me=0,Ne=(t=/[^.]+$/.exec(ze&&ze.keys&&ze.keys.IE_PROTO||""))?"Symbol(src)_1."+t:"",Fe=je.toString,Le=De.call(ke),Ue=vn._,He=Oe("^"+De.call(Re).replace(oe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),We=mn?n.Buffer:o,Ge=n.Symbol,Ye=n.Uint8Array,qe=We?We.allocUnsafe:o,Ve=st(ke.getPrototypeOf,ke),$e=ke.create,Ke=je.propertyIsEnumerable,Qe=Pe.splice,Xe=Ge?Ge.isConcatSpreadable:o,Ze=Ge?Ge.iterator:o,Je=Ge?Ge.toStringTag:o,tn=function(){try{var e=di(ke,"defineProperty");return e({},"",{}),e}catch(e){}}(),on=n.clearTimeout!==vn.clearTimeout&&n.clearTimeout,fn=le&&le.now!==vn.Date.now&&le.now,gn=n.setTimeout!==vn.setTimeout&&n.setTimeout,hn=Se.ceil,bn=Se.floor,An=ke.getOwnPropertySymbols,yn=We?We.isBuffer:o,En=n.isFinite,Un=Pe.join,Kn=st(ke.keys,ke),mt=Se.max,yt=Se.min,Et=le.now,Ct=n.parseInt,wt=Se.random,_t=Pe.reverse,xt=di(n,"DataView"),St=di(n,"Map"),kt=di(n,"Promise"),Ot=di(n,"Set"),Bt=di(n,"WeakMap"),Tt=di(ke,"create"),Pt=Bt&&new Bt,It={},jt=Fi(xt),zt=Fi(St),Dt=Fi(kt),Rt=Fi(Ot),Mt=Fi(Bt),Nt=Ge?Ge.prototype:o,Ft=Nt?Nt.valueOf:o,Lt=Nt?Nt.toString:o;function Ut(e){if(tl(e)&&!Ya(e)&&!(e instanceof Yt)){if(e instanceof Gt)return e;if(Re.call(e,"__wrapped__"))return Li(e)}return new Gt(e)}var Ht=function(){function e(){}return function(n){if(!nl(n))return{};if($e)return $e(n);e.prototype=n;var t=new e;return e.prototype=o,t}}();function Wt(){}function Gt(e,n){this.__wrapped__=e,this.__actions__=[],this.__chain__=!!n,this.__index__=0,this.__values__=o}function Yt(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=v,this.__views__=[]}function qt(e){var n=-1,t=null==e?0:e.length;for(this.clear();++n=n?e:n)),e}function ur(e,n,t,r,i,a){var l,c=1&n,u=2&n,s=4&n;if(t&&(l=i?t(e,r,i,a):t(e)),l!==o)return l;if(!nl(e))return e;var f=Ya(e);if(f){if(l=function(e){var n=e.length,t=new e.constructor(n);n&&"string"==typeof e[0]&&Re.call(e,"index")&&(t.index=e.index,t.input=e.input);return t}(e),!c)return Po(e,l)}else{var p=vi(e),d=p==w||p==_;if(Ka(e))return xo(e,c);if(p==k||p==A||d&&!i){if(l=u||d?{}:Ai(e),!c)return u?function(e,n){return Io(e,hi(e),n)}(e,function(e,n){return e&&Io(n,jl(n),e)}(l,e)):function(e,n){return Io(e,gi(e),n)}(e,ir(l,e))}else{if(!sn[p])return i?e:{};l=function(e,n,t){var r=e.constructor;switch(n){case z:return So(e);case y:case E:return new r(+e);case D:return function(e,n){var t=n?So(e.buffer):e.buffer;return new e.constructor(t,e.byteOffset,e.byteLength)}(e,t);case R:case M:case N:case F:case L:case U:case H:case W:case G:return ko(e,t);case x:return new r;case S:case P:return new r(e);case B:return function(e){var n=new e.constructor(e.source,he.exec(e));return n.lastIndex=e.lastIndex,n}(e);case T:return new r;case I:return o=e,Ft?ke(Ft.call(o)):{}}var o}(e,p,c)}}a||(a=new Qt);var g=a.get(e);if(g)return g;a.set(e,l),ll(e)?e.forEach((function(r){l.add(ur(r,n,t,r,e,a))})):rl(e)&&e.forEach((function(r,o){l.set(o,ur(r,n,t,o,e,a))}));var h=f?o:(s?u?ai:ii:u?jl:Il)(e);return Tn(h||e,(function(r,o){h&&(r=e[o=r]),tr(l,o,ur(r,n,t,o,e,a))})),l}function sr(e,n,t){var r=t.length;if(null==e)return!r;for(e=ke(e);r--;){var i=t[r],a=n[i],l=e[i];if(l===o&&!(i in e)||!a(l))return!1}return!0}function fr(e,n,t){if("function"!=typeof e)throw new Te(i);return Ii((function(){e.apply(o,t)}),n)}function pr(e,n,t,r){var o=-1,i=zn,a=!0,l=e.length,c=[],u=n.length;if(!l)return c;t&&(n=Rn(n,et(t))),r?(i=Dn,a=!1):n.length>=200&&(i=tt,a=!1,n=new Kt(n));e:for(;++o-1},Vt.prototype.set=function(e,n){var t=this.__data__,r=rr(t,e);return r<0?(++this.size,t.push([e,n])):t[r][1]=n,this},$t.prototype.clear=function(){this.size=0,this.__data__={hash:new qt,map:new(St||Vt),string:new qt}},$t.prototype.delete=function(e){var n=fi(this,e).delete(e);return this.size-=n?1:0,n},$t.prototype.get=function(e){return fi(this,e).get(e)},$t.prototype.has=function(e){return fi(this,e).has(e)},$t.prototype.set=function(e,n){var t=fi(this,e),r=t.size;return t.set(e,n),this.size+=t.size==r?0:1,this},Kt.prototype.add=Kt.prototype.push=function(e){return this.__data__.set(e,a),this},Kt.prototype.has=function(e){return this.__data__.has(e)},Qt.prototype.clear=function(){this.__data__=new Vt,this.size=0},Qt.prototype.delete=function(e){var n=this.__data__,t=n.delete(e);return this.size=n.size,t},Qt.prototype.get=function(e){return this.__data__.get(e)},Qt.prototype.has=function(e){return this.__data__.has(e)},Qt.prototype.set=function(e,n){var t=this.__data__;if(t instanceof Vt){var r=t.__data__;if(!St||r.length<199)return r.push([e,n]),this.size=++t.size,this;t=this.__data__=new $t(r)}return t.set(e,n),this.size=t.size,this};var dr=Do(Er),gr=Do(Cr,!0);function hr(e,n){var t=!0;return dr(e,(function(e,r,o){return t=!!n(e,r,o)})),t}function vr(e,n,t){for(var r=-1,i=e.length;++r0&&t(l)?n>1?Ar(l,n-1,t,r,o):Mn(o,l):r||(o[o.length]=l)}return o}var mr=Ro(),yr=Ro(!0);function Er(e,n){return e&&mr(e,n,Il)}function Cr(e,n){return e&&yr(e,n,Il)}function wr(e,n){return jn(n,(function(n){return Za(e[n])}))}function _r(e,n){for(var t=0,r=(n=Eo(n,e)).length;null!=e&&tn}function Or(e,n){return null!=e&&Re.call(e,n)}function Br(e,n){return null!=e&&n in ke(e)}function Tr(e,n,t){for(var i=t?Dn:zn,a=e[0].length,l=e.length,c=l,u=r(l),s=1/0,f=[];c--;){var p=e[c];c&&n&&(p=Rn(p,et(n))),s=yt(p.length,s),u[c]=!t&&(n||a>=120&&p.length>=120)?new Kt(c&&p):o}p=e[0];var d=-1,g=u[0];e:for(;++d=l?c:c*("desc"==t[r]?-1:1)}return e.index-n.index}(e,n,t)}))}function qr(e,n,t){for(var r=-1,o=n.length,i={};++r-1;)l!==e&&Qe.call(l,c,1),Qe.call(e,c,1);return e}function $r(e,n){for(var t=e?n.length:0,r=t-1;t--;){var o=n[t];if(t==r||o!==i){var i=o;yi(o)?Qe.call(e,o,1):po(e,o)}}return e}function Kr(e,n){return e+bn(wt()*(n-e+1))}function Qr(e,n){var t="";if(!e||n<1||n>g)return t;do{n%2&&(t+=e),(n=bn(n/2))&&(e+=e)}while(n);return t}function Xr(e,n){return ji(Oi(e,n,oc),e+"")}function Zr(e){return Zt(Ul(e))}function Jr(e,n){var t=Ul(e);return Ri(t,cr(n,0,t.length))}function eo(e,n,t,r){if(!nl(e))return e;for(var i=-1,a=(n=Eo(n,e)).length,l=a-1,c=e;null!=c&&++ii?0:i+n),(t=t>i?i:t)<0&&(t+=i),i=n>t?0:t-n>>>0,n>>>=0;for(var a=r(i);++o>>1,a=e[i];null!==a&&!ul(a)&&(t?a<=n:a=200){var u=n?null:Xo(e);if(u)return pt(u);a=!1,o=tt,c=new Kt}else c=n?[]:l;e:for(;++r=r?e:oo(e,n,t)}var _o=on||function(e){return vn.clearTimeout(e)};function xo(e,n){if(n)return e.slice();var t=e.length,r=qe?qe(t):new e.constructor(t);return e.copy(r),r}function So(e){var n=new e.constructor(e.byteLength);return new Ye(n).set(new Ye(e)),n}function ko(e,n){var t=n?So(e.buffer):e.buffer;return new e.constructor(t,e.byteOffset,e.length)}function Oo(e,n){if(e!==n){var t=e!==o,r=null===e,i=e==e,a=ul(e),l=n!==o,c=null===n,u=n==n,s=ul(n);if(!c&&!s&&!a&&e>n||a&&l&&u&&!c&&!s||r&&l&&u||!t&&u||!i)return 1;if(!r&&!a&&!s&&e1?t[i-1]:o,l=i>2?t[2]:o;for(a=e.length>3&&"function"==typeof a?(i--,a):o,l&&Ei(t[0],t[1],l)&&(a=i<3?o:a,i=1),n=ke(n);++r-1?i[a?n[l]:l]:o}}function Uo(e){return oi((function(n){var t=n.length,r=t,a=Gt.prototype.thru;for(e&&n.reverse();r--;){var l=n[r];if("function"!=typeof l)throw new Te(i);if(a&&!c&&"wrapper"==ci(l))var c=new Gt([],!0)}for(r=c?r:t;++r1&&y.reverse(),d&&sc))return!1;var s=a.get(e),f=a.get(n);if(s&&f)return s==n&&f==e;var p=-1,d=!0,g=2&t?new Kt:o;for(a.set(e,n),a.set(n,e);++p-1&&e%1==0&&e1?"& ":"")+n[r],n=n.join(t>2?", ":" "),e.replace(ce,"{\n/* [wrapped with "+n+"] */\n")}(r,function(e,n){return Tn(b,(function(t){var r="_."+t[0];n&t[1]&&!zn(e,r)&&e.push(r)})),e.sort()}(function(e){var n=e.match(ue);return n?n[1].split(se):[]}(r),t)))}function Di(e){var n=0,t=0;return function(){var r=Et(),i=16-(r-t);if(t=r,i>0){if(++n>=800)return arguments[0]}else n=0;return e.apply(o,arguments)}}function Ri(e,n){var t=-1,r=e.length,i=r-1;for(n=n===o?r:n;++t1?e[n-1]:o;return t="function"==typeof t?(e.pop(),t):o,aa(e,t)}));function da(e){var n=Ut(e);return n.__chain__=!0,n}function ga(e,n){return n(e)}var ha=oi((function(e){var n=e.length,t=n?e[0]:0,r=this.__wrapped__,i=function(n){return lr(n,e)};return!(n>1||this.__actions__.length)&&r instanceof Yt&&yi(t)?((r=r.slice(t,+t+(n?1:0))).__actions__.push({func:ga,args:[i],thisArg:o}),new Gt(r,this.__chain__).thru((function(e){return n&&!e.length&&e.push(o),e}))):this.thru(i)}));var va=jo((function(e,n,t){Re.call(e,t)?++e[t]:ar(e,t,1)}));var ba=Lo(Gi),Aa=Lo(Yi);function ma(e,n){return(Ya(e)?Tn:dr)(e,si(n,3))}function ya(e,n){return(Ya(e)?Pn:gr)(e,si(n,3))}var Ea=jo((function(e,n,t){Re.call(e,t)?e[t].push(n):ar(e,t,[n])}));var Ca=Xr((function(e,n,t){var o=-1,i="function"==typeof n,a=Va(e)?r(e.length):[];return dr(e,(function(e){a[++o]=i?On(n,e,t):Pr(e,n,t)})),a})),wa=jo((function(e,n,t){ar(e,t,n)}));function _a(e,n){return(Ya(e)?Rn:Lr)(e,si(n,3))}var xa=jo((function(e,n,t){e[t?0:1].push(n)}),(function(){return[[],[]]}));var Sa=Xr((function(e,n){if(null==e)return[];var t=n.length;return t>1&&Ei(e,n[0],n[1])?n=[]:t>2&&Ei(n[0],n[1],n[2])&&(n=[n[0]]),Yr(e,Ar(n,1),[])})),ka=fn||function(){return vn.Date.now()};function Oa(e,n,t){return n=t?o:n,n=e&&null==n?e.length:n,Jo(e,f,o,o,o,o,n)}function Ba(e,n){var t;if("function"!=typeof n)throw new Te(i);return e=hl(e),function(){return--e>0&&(t=n.apply(this,arguments)),e<=1&&(n=o),t}}var Ta=Xr((function(e,n,t){var r=1;if(t.length){var o=ft(t,ui(Ta));r|=u}return Jo(e,r,n,t,o)})),Pa=Xr((function(e,n,t){var r=3;if(t.length){var o=ft(t,ui(Pa));r|=u}return Jo(n,r,e,t,o)}));function Ia(e,n,t){var r,a,l,c,u,s,f=0,p=!1,d=!1,g=!0;if("function"!=typeof e)throw new Te(i);function h(n){var t=r,i=a;return r=a=o,f=n,c=e.apply(i,t)}function v(e){var t=e-s;return s===o||t>=n||t<0||d&&e-f>=l}function b(){var e=ka();if(v(e))return A(e);u=Ii(b,function(e){var t=n-(e-s);return d?yt(t,l-(e-f)):t}(e))}function A(e){return u=o,g&&r?h(e):(r=a=o,c)}function m(){var e=ka(),t=v(e);if(r=arguments,a=this,s=e,t){if(u===o)return function(e){return f=e,u=Ii(b,n),p?h(e):c}(s);if(d)return _o(u),u=Ii(b,n),h(s)}return u===o&&(u=Ii(b,n)),c}return n=bl(n)||0,nl(t)&&(p=!!t.leading,l=(d="maxWait"in t)?mt(bl(t.maxWait)||0,n):l,g="trailing"in t?!!t.trailing:g),m.cancel=function(){u!==o&&_o(u),f=0,r=s=a=u=o},m.flush=function(){return u===o?c:A(ka())},m}var ja=Xr((function(e,n){return fr(e,1,n)})),za=Xr((function(e,n,t){return fr(e,bl(n)||0,t)}));function Da(e,n){if("function"!=typeof e||null!=n&&"function"!=typeof n)throw new Te(i);var t=function(){var r=arguments,o=n?n.apply(this,r):r[0],i=t.cache;if(i.has(o))return i.get(o);var a=e.apply(this,r);return t.cache=i.set(o,a)||i,a};return t.cache=new(Da.Cache||$t),t}function Ra(e){if("function"!=typeof e)throw new Te(i);return function(){var n=arguments;switch(n.length){case 0:return!e.call(this);case 1:return!e.call(this,n[0]);case 2:return!e.call(this,n[0],n[1]);case 3:return!e.call(this,n[0],n[1],n[2])}return!e.apply(this,n)}}Da.Cache=$t;var Ma=Co((function(e,n){var t=(n=1==n.length&&Ya(n[0])?Rn(n[0],et(si())):Rn(Ar(n,1),et(si()))).length;return Xr((function(r){for(var o=-1,i=yt(r.length,t);++o=n})),Ga=Ir(function(){return arguments}())?Ir:function(e){return tl(e)&&Re.call(e,"callee")&&!Ke.call(e,"callee")},Ya=r.isArray,qa=Cn?et(Cn):function(e){return tl(e)&&Sr(e)==z};function Va(e){return null!=e&&el(e.length)&&!Za(e)}function $a(e){return tl(e)&&Va(e)}var Ka=yn||bc,Qa=wn?et(wn):function(e){return tl(e)&&Sr(e)==E};function Xa(e){if(!tl(e))return!1;var n=Sr(e);return n==C||"[object DOMException]"==n||"string"==typeof e.message&&"string"==typeof e.name&&!il(e)}function Za(e){if(!nl(e))return!1;var n=Sr(e);return n==w||n==_||"[object AsyncFunction]"==n||"[object Proxy]"==n}function Ja(e){return"number"==typeof e&&e==hl(e)}function el(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=g}function nl(e){var n=typeof e;return null!=e&&("object"==n||"function"==n)}function tl(e){return null!=e&&"object"==typeof e}var rl=_n?et(_n):function(e){return tl(e)&&vi(e)==x};function ol(e){return"number"==typeof e||tl(e)&&Sr(e)==S}function il(e){if(!tl(e)||Sr(e)!=k)return!1;var n=Ve(e);if(null===n)return!0;var t=Re.call(n,"constructor")&&n.constructor;return"function"==typeof t&&t instanceof t&&De.call(t)==Le}var al=xn?et(xn):function(e){return tl(e)&&Sr(e)==B};var ll=Sn?et(Sn):function(e){return tl(e)&&vi(e)==T};function cl(e){return"string"==typeof e||!Ya(e)&&tl(e)&&Sr(e)==P}function ul(e){return"symbol"==typeof e||tl(e)&&Sr(e)==I}var sl=kn?et(kn):function(e){return tl(e)&&el(e.length)&&!!un[Sr(e)]};var fl=$o(Fr),pl=$o((function(e,n){return e<=n}));function dl(e){if(!e)return[];if(Va(e))return cl(e)?ht(e):Po(e);if(Ze&&e[Ze])return function(e){for(var n,t=[];!(n=e.next()).done;)t.push(n.value);return t}(e[Ze]());var n=vi(e);return(n==x?ut:n==T?pt:Ul)(e)}function gl(e){return e?(e=bl(e))===d||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}function hl(e){var n=gl(e),t=n%1;return n==n?t?n-t:n:0}function vl(e){return e?cr(hl(e),0,v):0}function bl(e){if("number"==typeof e)return e;if(ul(e))return h;if(nl(e)){var n="function"==typeof e.valueOf?e.valueOf():e;e=nl(n)?n+"":n}if("string"!=typeof e)return 0===e?e:+e;e=Jn(e);var t=be.test(e);return t||me.test(e)?dn(e.slice(2),t?2:8):ve.test(e)?h:+e}function Al(e){return Io(e,jl(e))}function ml(e){return null==e?"":so(e)}var yl=zo((function(e,n){if(xi(n)||Va(n))Io(n,Il(n),e);else for(var t in n)Re.call(n,t)&&tr(e,t,n[t])})),El=zo((function(e,n){Io(n,jl(n),e)})),Cl=zo((function(e,n,t,r){Io(n,jl(n),e,r)})),wl=zo((function(e,n,t,r){Io(n,Il(n),e,r)})),_l=oi(lr);var xl=Xr((function(e,n){e=ke(e);var t=-1,r=n.length,i=r>2?n[2]:o;for(i&&Ei(n[0],n[1],i)&&(r=1);++t1),n})),Io(e,ai(e),t),r&&(t=ur(t,7,ti));for(var o=n.length;o--;)po(t,n[o]);return t}));var Ml=oi((function(e,n){return null==e?{}:function(e,n){return qr(e,n,(function(n,t){return Ol(e,t)}))}(e,n)}));function Nl(e,n){if(null==e)return{};var t=Rn(ai(e),(function(e){return[e]}));return n=si(n),qr(e,t,(function(e,t){return n(e,t[0])}))}var Fl=Zo(Il),Ll=Zo(jl);function Ul(e){return null==e?[]:nt(e,Il(e))}var Hl=No((function(e,n,t){return n=n.toLowerCase(),e+(t?Wl(n):n)}));function Wl(e){return Xl(ml(e).toLowerCase())}function Gl(e){return(e=ml(e))&&e.replace(Ee,it).replace(nn,"")}var Yl=No((function(e,n,t){return e+(t?"-":"")+n.toLowerCase()})),ql=No((function(e,n,t){return e+(t?" ":"")+n.toLowerCase()})),Vl=Mo("toLowerCase");var $l=No((function(e,n,t){return e+(t?"_":"")+n.toLowerCase()}));var Kl=No((function(e,n,t){return e+(t?" ":"")+Xl(n)}));var Ql=No((function(e,n,t){return e+(t?" ":"")+n.toUpperCase()})),Xl=Mo("toUpperCase");function Zl(e,n,t){return e=ml(e),(n=t?o:n)===o?function(e){return an.test(e)}(e)?function(e){return e.match(rn)||[]}(e):function(e){return e.match(fe)||[]}(e):e.match(n)||[]}var Jl=Xr((function(e,n){try{return On(e,o,n)}catch(e){return Xa(e)?e:new _e(e)}})),ec=oi((function(e,n){return Tn(n,(function(n){n=Ni(n),ar(e,n,Ta(e[n],e))})),e}));function nc(e){return function(){return e}}var tc=Uo(),rc=Uo(!0);function oc(e){return e}function ic(e){return Rr("function"==typeof e?e:ur(e,1))}var ac=Xr((function(e,n){return function(t){return Pr(t,e,n)}})),lc=Xr((function(e,n){return function(t){return Pr(e,t,n)}}));function cc(e,n,t){var r=Il(n),o=wr(n,r);null!=t||nl(n)&&(o.length||!r.length)||(t=n,n=e,e=this,o=wr(n,Il(n)));var i=!(nl(t)&&"chain"in t&&!t.chain),a=Za(e);return Tn(o,(function(t){var r=n[t];e[t]=r,a&&(e.prototype[t]=function(){var n=this.__chain__;if(i||n){var t=e(this.__wrapped__);return(t.__actions__=Po(this.__actions__)).push({func:r,args:arguments,thisArg:e}),t.__chain__=n,t}return r.apply(e,Mn([this.value()],arguments))})})),e}function uc(){}var sc=Yo(Rn),fc=Yo(In),pc=Yo(Ln);function dc(e){return Ci(e)?$n(Ni(e)):function(e){return function(n){return _r(n,e)}}(e)}var gc=Vo(),hc=Vo(!0);function vc(){return[]}function bc(){return!1}var Ac=Go((function(e,n){return e+n}),0),mc=Qo("ceil"),yc=Go((function(e,n){return e/n}),1),Ec=Qo("floor");var Cc,wc=Go((function(e,n){return e*n}),1),_c=Qo("round"),xc=Go((function(e,n){return e-n}),0);return Ut.after=function(e,n){if("function"!=typeof n)throw new Te(i);return e=hl(e),function(){if(--e<1)return n.apply(this,arguments)}},Ut.ary=Oa,Ut.assign=yl,Ut.assignIn=El,Ut.assignInWith=Cl,Ut.assignWith=wl,Ut.at=_l,Ut.before=Ba,Ut.bind=Ta,Ut.bindAll=ec,Ut.bindKey=Pa,Ut.castArray=function(){if(!arguments.length)return[];var e=arguments[0];return Ya(e)?e:[e]},Ut.chain=da,Ut.chunk=function(e,n,t){n=(t?Ei(e,n,t):n===o)?1:mt(hl(n),0);var i=null==e?0:e.length;if(!i||n<1)return[];for(var a=0,l=0,c=r(hn(i/n));ai?0:i+t),(r=r===o||r>i?i:hl(r))<0&&(r+=i),r=t>r?0:vl(r);t>>0)?(e=ml(e))&&("string"==typeof n||null!=n&&!al(n))&&!(n=so(n))&&ct(e)?wo(ht(e),0,t):e.split(n,t):[]},Ut.spread=function(e,n){if("function"!=typeof e)throw new Te(i);return n=null==n?0:mt(hl(n),0),Xr((function(t){var r=t[n],o=wo(t,0,n);return r&&Mn(o,r),On(e,this,o)}))},Ut.tail=function(e){var n=null==e?0:e.length;return n?oo(e,1,n):[]},Ut.take=function(e,n,t){return e&&e.length?oo(e,0,(n=t||n===o?1:hl(n))<0?0:n):[]},Ut.takeRight=function(e,n,t){var r=null==e?0:e.length;return r?oo(e,(n=r-(n=t||n===o?1:hl(n)))<0?0:n,r):[]},Ut.takeRightWhile=function(e,n){return e&&e.length?ho(e,si(n,3),!1,!0):[]},Ut.takeWhile=function(e,n){return e&&e.length?ho(e,si(n,3)):[]},Ut.tap=function(e,n){return n(e),e},Ut.throttle=function(e,n,t){var r=!0,o=!0;if("function"!=typeof e)throw new Te(i);return nl(t)&&(r="leading"in t?!!t.leading:r,o="trailing"in t?!!t.trailing:o),Ia(e,n,{leading:r,maxWait:n,trailing:o})},Ut.thru=ga,Ut.toArray=dl,Ut.toPairs=Fl,Ut.toPairsIn=Ll,Ut.toPath=function(e){return Ya(e)?Rn(e,Ni):ul(e)?[e]:Po(Mi(ml(e)))},Ut.toPlainObject=Al,Ut.transform=function(e,n,t){var r=Ya(e),o=r||Ka(e)||sl(e);if(n=si(n,4),null==t){var i=e&&e.constructor;t=o?r?new i:[]:nl(e)&&Za(i)?Ht(Ve(e)):{}}return(o?Tn:Er)(e,(function(e,r,o){return n(t,e,r,o)})),t},Ut.unary=function(e){return Oa(e,1)},Ut.union=ta,Ut.unionBy=ra,Ut.unionWith=oa,Ut.uniq=function(e){return e&&e.length?fo(e):[]},Ut.uniqBy=function(e,n){return e&&e.length?fo(e,si(n,2)):[]},Ut.uniqWith=function(e,n){return n="function"==typeof n?n:o,e&&e.length?fo(e,o,n):[]},Ut.unset=function(e,n){return null==e||po(e,n)},Ut.unzip=ia,Ut.unzipWith=aa,Ut.update=function(e,n,t){return null==e?e:go(e,n,yo(t))},Ut.updateWith=function(e,n,t,r){return r="function"==typeof r?r:o,null==e?e:go(e,n,yo(t),r)},Ut.values=Ul,Ut.valuesIn=function(e){return null==e?[]:nt(e,jl(e))},Ut.without=la,Ut.words=Zl,Ut.wrap=function(e,n){return Na(yo(n),e)},Ut.xor=ca,Ut.xorBy=ua,Ut.xorWith=sa,Ut.zip=fa,Ut.zipObject=function(e,n){return Ao(e||[],n||[],tr)},Ut.zipObjectDeep=function(e,n){return Ao(e||[],n||[],eo)},Ut.zipWith=pa,Ut.entries=Fl,Ut.entriesIn=Ll,Ut.extend=El,Ut.extendWith=Cl,cc(Ut,Ut),Ut.add=Ac,Ut.attempt=Jl,Ut.camelCase=Hl,Ut.capitalize=Wl,Ut.ceil=mc,Ut.clamp=function(e,n,t){return t===o&&(t=n,n=o),t!==o&&(t=(t=bl(t))==t?t:0),n!==o&&(n=(n=bl(n))==n?n:0),cr(bl(e),n,t)},Ut.clone=function(e){return ur(e,4)},Ut.cloneDeep=function(e){return ur(e,5)},Ut.cloneDeepWith=function(e,n){return ur(e,5,n="function"==typeof n?n:o)},Ut.cloneWith=function(e,n){return ur(e,4,n="function"==typeof n?n:o)},Ut.conformsTo=function(e,n){return null==n||sr(e,n,Il(n))},Ut.deburr=Gl,Ut.defaultTo=function(e,n){return null==e||e!=e?n:e},Ut.divide=yc,Ut.endsWith=function(e,n,t){e=ml(e),n=so(n);var r=e.length,i=t=t===o?r:cr(hl(t),0,r);return(t-=n.length)>=0&&e.slice(t,i)==n},Ut.eq=Ua,Ut.escape=function(e){return(e=ml(e))&&X.test(e)?e.replace(K,at):e},Ut.escapeRegExp=function(e){return(e=ml(e))&&ie.test(e)?e.replace(oe,"\\$&"):e},Ut.every=function(e,n,t){var r=Ya(e)?In:hr;return t&&Ei(e,n,t)&&(n=o),r(e,si(n,3))},Ut.find=ba,Ut.findIndex=Gi,Ut.findKey=function(e,n){return Hn(e,si(n,3),Er)},Ut.findLast=Aa,Ut.findLastIndex=Yi,Ut.findLastKey=function(e,n){return Hn(e,si(n,3),Cr)},Ut.floor=Ec,Ut.forEach=ma,Ut.forEachRight=ya,Ut.forIn=function(e,n){return null==e?e:mr(e,si(n,3),jl)},Ut.forInRight=function(e,n){return null==e?e:yr(e,si(n,3),jl)},Ut.forOwn=function(e,n){return e&&Er(e,si(n,3))},Ut.forOwnRight=function(e,n){return e&&Cr(e,si(n,3))},Ut.get=kl,Ut.gt=Ha,Ut.gte=Wa,Ut.has=function(e,n){return null!=e&&bi(e,n,Or)},Ut.hasIn=Ol,Ut.head=Vi,Ut.identity=oc,Ut.includes=function(e,n,t,r){e=Va(e)?e:Ul(e),t=t&&!r?hl(t):0;var o=e.length;return t<0&&(t=mt(o+t,0)),cl(e)?t<=o&&e.indexOf(n,t)>-1:!!o&&Gn(e,n,t)>-1},Ut.indexOf=function(e,n,t){var r=null==e?0:e.length;if(!r)return-1;var o=null==t?0:hl(t);return o<0&&(o=mt(r+o,0)),Gn(e,n,o)},Ut.inRange=function(e,n,t){return n=gl(n),t===o?(t=n,n=0):t=gl(t),function(e,n,t){return e>=yt(n,t)&&e=-9007199254740991&&e<=g},Ut.isSet=ll,Ut.isString=cl,Ut.isSymbol=ul,Ut.isTypedArray=sl,Ut.isUndefined=function(e){return e===o},Ut.isWeakMap=function(e){return tl(e)&&vi(e)==j},Ut.isWeakSet=function(e){return tl(e)&&"[object WeakSet]"==Sr(e)},Ut.join=function(e,n){return null==e?"":Un.call(e,n)},Ut.kebabCase=Yl,Ut.last=Xi,Ut.lastIndexOf=function(e,n,t){var r=null==e?0:e.length;if(!r)return-1;var i=r;return t!==o&&(i=(i=hl(t))<0?mt(r+i,0):yt(i,r-1)),n==n?function(e,n,t){for(var r=t+1;r--;)if(e[r]===n)return r;return r}(e,n,i):Wn(e,qn,i,!0)},Ut.lowerCase=ql,Ut.lowerFirst=Vl,Ut.lt=fl,Ut.lte=pl,Ut.max=function(e){return e&&e.length?vr(e,oc,kr):o},Ut.maxBy=function(e,n){return e&&e.length?vr(e,si(n,2),kr):o},Ut.mean=function(e){return Vn(e,oc)},Ut.meanBy=function(e,n){return Vn(e,si(n,2))},Ut.min=function(e){return e&&e.length?vr(e,oc,Fr):o},Ut.minBy=function(e,n){return e&&e.length?vr(e,si(n,2),Fr):o},Ut.stubArray=vc,Ut.stubFalse=bc,Ut.stubObject=function(){return{}},Ut.stubString=function(){return""},Ut.stubTrue=function(){return!0},Ut.multiply=wc,Ut.nth=function(e,n){return e&&e.length?Gr(e,hl(n)):o},Ut.noConflict=function(){return vn._===this&&(vn._=Ue),this},Ut.noop=uc,Ut.now=ka,Ut.pad=function(e,n,t){e=ml(e);var r=(n=hl(n))?gt(e):0;if(!n||r>=n)return e;var o=(n-r)/2;return qo(bn(o),t)+e+qo(hn(o),t)},Ut.padEnd=function(e,n,t){e=ml(e);var r=(n=hl(n))?gt(e):0;return n&&rn){var r=e;e=n,n=r}if(t||e%1||n%1){var i=wt();return yt(e+i*(n-e+pn("1e-"+((i+"").length-1))),n)}return Kr(e,n)},Ut.reduce=function(e,n,t){var r=Ya(e)?Nn:Qn,o=arguments.length<3;return r(e,si(n,4),t,o,dr)},Ut.reduceRight=function(e,n,t){var r=Ya(e)?Fn:Qn,o=arguments.length<3;return r(e,si(n,4),t,o,gr)},Ut.repeat=function(e,n,t){return n=(t?Ei(e,n,t):n===o)?1:hl(n),Qr(ml(e),n)},Ut.replace=function(){var e=arguments,n=ml(e[0]);return e.length<3?n:n.replace(e[1],e[2])},Ut.result=function(e,n,t){var r=-1,i=(n=Eo(n,e)).length;for(i||(i=1,e=o);++rg)return[];var t=v,r=yt(e,v);n=si(n),e-=v;for(var o=Zn(r,n);++t=a)return e;var c=t-gt(r);if(c<1)return r;var u=l?wo(l,0,c).join(""):e.slice(0,c);if(i===o)return u+r;if(l&&(c+=u.length-c),al(i)){if(e.slice(c).search(i)){var s,f=u;for(i.global||(i=Oe(i.source,ml(he.exec(i))+"g")),i.lastIndex=0;s=i.exec(f);)var p=s.index;u=u.slice(0,p===o?c:p)}}else if(e.indexOf(so(i),c)!=c){var d=u.lastIndexOf(i);d>-1&&(u=u.slice(0,d))}return u+r},Ut.unescape=function(e){return(e=ml(e))&&Q.test(e)?e.replace($,bt):e},Ut.uniqueId=function(e){var n=++Me;return ml(e)+n},Ut.upperCase=Ql,Ut.upperFirst=Xl,Ut.each=ma,Ut.eachRight=ya,Ut.first=Vi,cc(Ut,(Cc={},Er(Ut,(function(e,n){Re.call(Ut.prototype,n)||(Cc[n]=e)})),Cc),{chain:!1}),Ut.VERSION="4.17.21",Tn(["bind","bindKey","curry","curryRight","partial","partialRight"],(function(e){Ut[e].placeholder=Ut})),Tn(["drop","take"],(function(e,n){Yt.prototype[e]=function(t){t=t===o?1:mt(hl(t),0);var r=this.__filtered__&&!n?new Yt(this):this.clone();return r.__filtered__?r.__takeCount__=yt(t,r.__takeCount__):r.__views__.push({size:yt(t,v),type:e+(r.__dir__<0?"Right":"")}),r},Yt.prototype[e+"Right"]=function(n){return this.reverse()[e](n).reverse()}})),Tn(["filter","map","takeWhile"],(function(e,n){var t=n+1,r=1==t||3==t;Yt.prototype[e]=function(e){var n=this.clone();return n.__iteratees__.push({iteratee:si(e,3),type:t}),n.__filtered__=n.__filtered__||r,n}})),Tn(["head","last"],(function(e,n){var t="take"+(n?"Right":"");Yt.prototype[e]=function(){return this[t](1).value()[0]}})),Tn(["initial","tail"],(function(e,n){var t="drop"+(n?"":"Right");Yt.prototype[e]=function(){return this.__filtered__?new Yt(this):this[t](1)}})),Yt.prototype.compact=function(){return this.filter(oc)},Yt.prototype.find=function(e){return this.filter(e).head()},Yt.prototype.findLast=function(e){return this.reverse().find(e)},Yt.prototype.invokeMap=Xr((function(e,n){return"function"==typeof e?new Yt(this):this.map((function(t){return Pr(t,e,n)}))})),Yt.prototype.reject=function(e){return this.filter(Ra(si(e)))},Yt.prototype.slice=function(e,n){e=hl(e);var t=this;return t.__filtered__&&(e>0||n<0)?new Yt(t):(e<0?t=t.takeRight(-e):e&&(t=t.drop(e)),n!==o&&(t=(n=hl(n))<0?t.dropRight(-n):t.take(n-e)),t)},Yt.prototype.takeRightWhile=function(e){return this.reverse().takeWhile(e).reverse()},Yt.prototype.toArray=function(){return this.take(v)},Er(Yt.prototype,(function(e,n){var t=/^(?:filter|find|map|reject)|While$/.test(n),r=/^(?:head|last)$/.test(n),i=Ut[r?"take"+("last"==n?"Right":""):n],a=r||/^find/.test(n);i&&(Ut.prototype[n]=function(){var n=this.__wrapped__,l=r?[1]:arguments,c=n instanceof Yt,u=l[0],s=c||Ya(n),f=function(e){var n=i.apply(Ut,Mn([e],l));return r&&p?n[0]:n};s&&t&&"function"==typeof u&&1!=u.length&&(c=s=!1);var p=this.__chain__,d=!!this.__actions__.length,g=a&&!p,h=c&&!d;if(!a&&s){n=h?n:new Yt(this);var v=e.apply(n,l);return v.__actions__.push({func:ga,args:[f],thisArg:o}),new Gt(v,p)}return g&&h?e.apply(this,l):(v=this.thru(f),g?r?v.value()[0]:v.value():v)})})),Tn(["pop","push","shift","sort","splice","unshift"],(function(e){var n=Pe[e],t=/^(?:push|sort|unshift)$/.test(e)?"tap":"thru",r=/^(?:pop|shift)$/.test(e);Ut.prototype[e]=function(){var e=arguments;if(r&&!this.__chain__){var o=this.value();return n.apply(Ya(o)?o:[],e)}return this[t]((function(t){return n.apply(Ya(t)?t:[],e)}))}})),Er(Yt.prototype,(function(e,n){var t=Ut[n];if(t){var r=t.name+"";Re.call(It,r)||(It[r]=[]),It[r].push({name:n,func:t})}})),It[Ho(o,2).name]=[{name:"wrapper",func:o}],Yt.prototype.clone=function(){var e=new Yt(this.__wrapped__);return e.__actions__=Po(this.__actions__),e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=Po(this.__iteratees__),e.__takeCount__=this.__takeCount__,e.__views__=Po(this.__views__),e},Yt.prototype.reverse=function(){if(this.__filtered__){var e=new Yt(this);e.__dir__=-1,e.__filtered__=!0}else(e=this.clone()).__dir__*=-1;return e},Yt.prototype.value=function(){var e=this.__wrapped__.value(),n=this.__dir__,t=Ya(e),r=n<0,o=t?e.length:0,i=function(e,n,t){var r=-1,o=t.length;for(;++r=this.__values__.length;return{done:e,value:e?o:this.__values__[this.__index__++]}},Ut.prototype.plant=function(e){for(var n,t=this;t instanceof Wt;){var r=Li(t);r.__index__=0,r.__values__=o,n?i.__wrapped__=r:n=r;var i=r;t=t.__wrapped__}return i.__wrapped__=e,n},Ut.prototype.reverse=function(){var e=this.__wrapped__;if(e instanceof Yt){var n=e;return this.__actions__.length&&(n=new Yt(this)),(n=n.reverse()).__actions__.push({func:ga,args:[na],thisArg:o}),new Gt(n,this.__chain__)}return this.thru(na)},Ut.prototype.toJSON=Ut.prototype.valueOf=Ut.prototype.value=function(){return vo(this.__wrapped__,this.__actions__)},Ut.prototype.first=Ut.prototype.head,Ze&&(Ut.prototype[Ze]=function(){return this}),Ut}();vn._=At,(r=function(){return At}.call(n,t,n,e))===o||(e.exports=r)}.call(this)},5228:e=>{"use strict"; /* object-assign (c) Sindre Sorhus @license MIT */var n=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},t=0;t<10;t++)n["_"+String.fromCharCode(t)]=t;if("0123456789"!==Object.getOwnPropertyNames(n).map((function(e){return n[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,o){for(var i,a,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),c=1;c{var r="function"==typeof Map&&Map.prototype,o=Object.getOwnPropertyDescriptor&&r?Object.getOwnPropertyDescriptor(Map.prototype,"size"):null,i=r&&o&&"function"==typeof o.get?o.get:null,a=r&&Map.prototype.forEach,l="function"==typeof Set&&Set.prototype,c=Object.getOwnPropertyDescriptor&&l?Object.getOwnPropertyDescriptor(Set.prototype,"size"):null,u=l&&c&&"function"==typeof c.get?c.get:null,s=l&&Set.prototype.forEach,f="function"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,p="function"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,d="function"==typeof WeakRef&&WeakRef.prototype?WeakRef.prototype.deref:null,g=Boolean.prototype.valueOf,h=Object.prototype.toString,v=Function.prototype.toString,b=String.prototype.match,A=String.prototype.slice,m=String.prototype.replace,y=String.prototype.toUpperCase,E=String.prototype.toLowerCase,C=RegExp.prototype.test,w=Array.prototype.concat,_=Array.prototype.join,x=Array.prototype.slice,S=Math.floor,k="function"==typeof BigInt?BigInt.prototype.valueOf:null,O=Object.getOwnPropertySymbols,B="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol.prototype.toString:null,T="function"==typeof Symbol&&"object"==typeof Symbol.iterator,P="function"==typeof Symbol&&Symbol.toStringTag&&(typeof Symbol.toStringTag===T||"symbol")?Symbol.toStringTag:null,I=Object.prototype.propertyIsEnumerable,j=("function"==typeof Reflect?Reflect.getPrototypeOf:Object.getPrototypeOf)||([].__proto__===Array.prototype?function(e){return e.__proto__}:null);function z(e,n){if(e===1/0||e===-1/0||e!=e||e&&e>-1e3&&e<1e3||C.call(/e/,n))return n;var t=/[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;if("number"==typeof e){var r=e<0?-S(-e):S(e);if(r!==e){var o=String(r),i=A.call(n,o.length+1);return m.call(o,t,"$&_")+"."+m.call(m.call(i,/([0-9]{3})/g,"$&_"),/_$/,"")}}return m.call(n,t,"$&_")}var D=t(2634),R=D.custom,M=H(R)?R:null;function N(e,n,t){var r="double"===(t.quoteStyle||n)?'"':"'";return r+e+r}function F(e){return m.call(String(e),/"/g,""")}function L(e){return!("[object Array]"!==Y(e)||P&&"object"==typeof e&&P in e)}function U(e){return!("[object RegExp]"!==Y(e)||P&&"object"==typeof e&&P in e)}function H(e){if(T)return e&&"object"==typeof e&&e instanceof Symbol;if("symbol"==typeof e)return!0;if(!e||"object"!=typeof e||!B)return!1;try{return B.call(e),!0}catch(e){}return!1}e.exports=function e(n,r,o,l){var c=r||{};if(G(c,"quoteStyle")&&"single"!==c.quoteStyle&&"double"!==c.quoteStyle)throw new TypeError('option "quoteStyle" must be "single" or "double"');if(G(c,"maxStringLength")&&("number"==typeof c.maxStringLength?c.maxStringLength<0&&c.maxStringLength!==1/0:null!==c.maxStringLength))throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');var h=!G(c,"customInspect")||c.customInspect;if("boolean"!=typeof h&&"symbol"!==h)throw new TypeError("option \"customInspect\", if provided, must be `true`, `false`, or `'symbol'`");if(G(c,"indent")&&null!==c.indent&&"\t"!==c.indent&&!(parseInt(c.indent,10)===c.indent&&c.indent>0))throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');if(G(c,"numericSeparator")&&"boolean"!=typeof c.numericSeparator)throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');var y=c.numericSeparator;if(void 0===n)return"undefined";if(null===n)return"null";if("boolean"==typeof n)return n?"true":"false";if("string"==typeof n)return V(n,c);if("number"==typeof n){if(0===n)return 1/0/n>0?"0":"-0";var C=String(n);return y?z(n,C):C}if("bigint"==typeof n){var S=String(n)+"n";return y?z(n,S):S}var O=void 0===c.depth?5:c.depth;if(void 0===o&&(o=0),o>=O&&O>0&&"object"==typeof n)return L(n)?"[Array]":"[Object]";var R=function(e,n){var t;if("\t"===e.indent)t="\t";else{if(!("number"==typeof e.indent&&e.indent>0))return null;t=_.call(Array(e.indent+1)," ")}return{base:t,prev:_.call(Array(n+1),t)}}(c,o);if(void 0===l)l=[];else if(q(l,n)>=0)return"[Circular]";function W(n,t,r){if(t&&(l=x.call(l)).push(t),r){var i={depth:c.depth};return G(c,"quoteStyle")&&(i.quoteStyle=c.quoteStyle),e(n,i,o+1,l)}return e(n,c,o+1,l)}if("function"==typeof n&&!U(n)){var $=function(e){if(e.name)return e.name;var n=b.call(v.call(e),/^function\s*([\w$]+)/);if(n)return n[1];return null}(n),ee=J(n,W);return"[Function"+($?": "+$:" (anonymous)")+"]"+(ee.length>0?" { "+_.call(ee,", ")+" }":"")}if(H(n)){var ne=T?m.call(String(n),/^(Symbol\(.*\))_[^)]*$/,"$1"):B.call(n);return"object"!=typeof n||T?ne:K(ne)}if(function(e){if(!e||"object"!=typeof e)return!1;if("undefined"!=typeof HTMLElement&&e instanceof HTMLElement)return!0;return"string"==typeof e.nodeName&&"function"==typeof e.getAttribute}(n)){for(var te="<"+E.call(String(n.nodeName)),re=n.attributes||[],oe=0;oe"}if(L(n)){if(0===n.length)return"[]";var ie=J(n,W);return R&&!function(e){for(var n=0;n=0)return!1;return!0}(ie)?"["+Z(ie,R)+"]":"[ "+_.call(ie,", ")+" ]"}if(function(e){return!("[object Error]"!==Y(e)||P&&"object"==typeof e&&P in e)}(n)){var ae=J(n,W);return"cause"in Error.prototype||!("cause"in n)||I.call(n,"cause")?0===ae.length?"["+String(n)+"]":"{ ["+String(n)+"] "+_.call(ae,", ")+" }":"{ ["+String(n)+"] "+_.call(w.call("[cause]: "+W(n.cause),ae),", ")+" }"}if("object"==typeof n&&h){if(M&&"function"==typeof n[M]&&D)return D(n,{depth:O-o});if("symbol"!==h&&"function"==typeof n.inspect)return n.inspect()}if(function(e){if(!i||!e||"object"!=typeof e)return!1;try{i.call(e);try{u.call(e)}catch(e){return!0}return e instanceof Map}catch(e){}return!1}(n)){var le=[];return a&&a.call(n,(function(e,t){le.push(W(t,n,!0)+" => "+W(e,n))})),X("Map",i.call(n),le,R)}if(function(e){if(!u||!e||"object"!=typeof e)return!1;try{u.call(e);try{i.call(e)}catch(e){return!0}return e instanceof Set}catch(e){}return!1}(n)){var ce=[];return s&&s.call(n,(function(e){ce.push(W(e,n))})),X("Set",u.call(n),ce,R)}if(function(e){if(!f||!e||"object"!=typeof e)return!1;try{f.call(e,f);try{p.call(e,p)}catch(e){return!0}return e instanceof WeakMap}catch(e){}return!1}(n))return Q("WeakMap");if(function(e){if(!p||!e||"object"!=typeof e)return!1;try{p.call(e,p);try{f.call(e,f)}catch(e){return!0}return e instanceof WeakSet}catch(e){}return!1}(n))return Q("WeakSet");if(function(e){if(!d||!e||"object"!=typeof e)return!1;try{return d.call(e),!0}catch(e){}return!1}(n))return Q("WeakRef");if(function(e){return!("[object Number]"!==Y(e)||P&&"object"==typeof e&&P in e)}(n))return K(W(Number(n)));if(function(e){if(!e||"object"!=typeof e||!k)return!1;try{return k.call(e),!0}catch(e){}return!1}(n))return K(W(k.call(n)));if(function(e){return!("[object Boolean]"!==Y(e)||P&&"object"==typeof e&&P in e)}(n))return K(g.call(n));if(function(e){return!("[object String]"!==Y(e)||P&&"object"==typeof e&&P in e)}(n))return K(W(String(n)));if("undefined"!=typeof window&&n===window)return"{ [object Window] }";if("undefined"!=typeof globalThis&&n===globalThis||void 0!==t.g&&n===t.g)return"{ [object globalThis] }";if(!function(e){return!("[object Date]"!==Y(e)||P&&"object"==typeof e&&P in e)}(n)&&!U(n)){var ue=J(n,W),se=j?j(n)===Object.prototype:n instanceof Object||n.constructor===Object,fe=n instanceof Object?"":"null prototype",pe=!se&&P&&Object(n)===n&&P in n?A.call(Y(n),8,-1):fe?"Object":"",de=(se||"function"!=typeof n.constructor?"":n.constructor.name?n.constructor.name+" ":"")+(pe||fe?"["+_.call(w.call([],pe||[],fe||[]),": ")+"] ":"");return 0===ue.length?de+"{}":R?de+"{"+Z(ue,R)+"}":de+"{ "+_.call(ue,", ")+" }"}return String(n)};var W=Object.prototype.hasOwnProperty||function(e){return e in this};function G(e,n){return W.call(e,n)}function Y(e){return h.call(e)}function q(e,n){if(e.indexOf)return e.indexOf(n);for(var t=0,r=e.length;tn.maxStringLength){var t=e.length-n.maxStringLength,r="... "+t+" more character"+(t>1?"s":"");return V(A.call(e,0,n.maxStringLength),n)+r}return N(m.call(m.call(e,/(['\\])/g,"\\$1"),/[\x00-\x1f]/g,$),"single",n)}function $(e){var n=e.charCodeAt(0),t={8:"b",9:"t",10:"n",12:"f",13:"r"}[n];return t?"\\"+t:"\\x"+(n<16?"0":"")+y.call(n.toString(16))}function K(e){return"Object("+e+")"}function Q(e){return e+" { ? }"}function X(e,n,t,r){return e+" ("+n+") {"+(r?Z(t,r):_.call(t,", "))+"}"}function Z(e,n){if(0===e.length)return"";var t="\n"+n.prev+n.base;return t+_.call(e,","+t)+"\n"+n.prev}function J(e,n){var t=L(e),r=[];if(t){r.length=e.length;for(var o=0;o{"use strict";var n=function(e){return e!=e};e.exports=function(e,t){return 0===e&&0===t?1/e==1/t:e===t||!(!n(e)||!n(t))}},7653:(e,n,t)=>{"use strict";var r=t(8452),o=t(487),i=t(9211),a=t(9394),l=t(6576),c=o(a(),Object);r(c,{getPolyfill:a,implementation:i,shim:l}),e.exports=c},9394:(e,n,t)=>{"use strict";var r=t(9211);e.exports=function(){return"function"==typeof Object.is?Object.is:r}},6576:(e,n,t)=>{"use strict";var r=t(9394),o=t(8452);e.exports=function(){var e=r();return o(Object,{is:e},{is:function(){return Object.is!==e}}),e}},8875:(e,n,t)=>{"use strict";var r;if(!Object.keys){var o=Object.prototype.hasOwnProperty,i=Object.prototype.toString,a=t(1093),l=Object.prototype.propertyIsEnumerable,c=!l.call({toString:null},"toString"),u=l.call((function(){}),"prototype"),s=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],f=function(e){var n=e.constructor;return n&&n.prototype===e},p={$applicationCache:!0,$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$onmozfullscreenchange:!0,$onmozfullscreenerror:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},d=function(){if("undefined"==typeof window)return!1;for(var e in window)try{if(!p["$"+e]&&o.call(window,e)&&null!==window[e]&&"object"==typeof window[e])try{f(window[e])}catch(e){return!0}}catch(e){return!0}return!1}();r=function(e){var n=null!==e&&"object"==typeof e,t="[object Function]"===i.call(e),r=a(e),l=n&&"[object String]"===i.call(e),p=[];if(!n&&!t&&!r)throw new TypeError("Object.keys called on a non-object");var g=u&&t;if(l&&e.length>0&&!o.call(e,0))for(var h=0;h0)for(var v=0;v{"use strict";var r=Array.prototype.slice,o=t(1093),i=Object.keys,a=i?function(e){return i(e)}:t(8875),l=Object.keys;a.shim=function(){if(Object.keys){var e=function(){var e=Object.keys(arguments);return e&&e.length===arguments.length}(1,2);e||(Object.keys=function(e){return o(e)?l(r.call(e)):l(e)})}else Object.keys=a;return Object.keys||a},e.exports=a},1093:e=>{"use strict";var n=Object.prototype.toString;e.exports=function(e){var t=n.call(e),r="[object Arguments]"===t;return r||(r="[object Array]"!==t&&null!==e&&"object"==typeof e&&"number"==typeof e.length&&e.length>=0&&"[object Function]"===n.call(e.callee)),r}},8403:(e,n,t)=>{"use strict";var r=t(1189),o=t(1333)(),i=t(8075),a=Object,l=i("Array.prototype.push"),c=i("Object.prototype.propertyIsEnumerable"),u=o?Object.getOwnPropertySymbols:null;e.exports=function(e,n){if(null==e)throw new TypeError("target must be an object");var t=a(e);if(1===arguments.length)return t;for(var i=1;i{"use strict";var r=t(8452),o=t(487),i=t(8403),a=t(1514),l=t(984),c=o.apply(a()),u=function(e,n){return c(Object,arguments)};r(u,{getPolyfill:a,implementation:i,shim:l}),e.exports=u},1514:(e,n,t)=>{"use strict";var r=t(8403);e.exports=function(){return Object.assign?function(){if(!Object.assign)return!1;for(var e="abcdefghijklmnopqrst",n=e.split(""),t={},r=0;r{"use strict";var r=t(8452),o=t(1514);e.exports=function(){var e=o();return r(Object,{assign:e},{assign:function(){return Object.assign!==e}}),e}},6578:e=>{"use strict";e.exports=["Float32Array","Float64Array","Int8Array","Int16Array","Int32Array","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array"]},2694:(e,n,t)=>{"use strict";var r=t(6925);function o(){}function i(){}i.resetWarningCache=o,e.exports=function(){function e(e,n,t,o,i,a){if(a!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function n(){return e}e.isRequired=e;var t={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:n,element:e,elementType:e,instanceOf:n,node:e,objectOf:n,oneOf:n,oneOfType:n,shape:n,exact:n,checkPropTypes:i,resetWarningCache:o};return t.PropTypes=t,t}},5556:(e,n,t)=>{e.exports=t(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},2551:(e,n,t)=>{"use strict";var r=t(6540),o=t(5228),i=t(9982); /** @license React v17.0.2 * react-dom.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */function a(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,t=1;t