Skip to content

Commit

Permalink
Merge pull request square#2324 from square/jw/2017-05-11/optional-con…
Browse files Browse the repository at this point in the history
…verters

Add converters which facilitate the use of Optional.
  • Loading branch information
swankjesse authored May 13, 2017
2 parents cc0df11 + e985d55 commit 85593d2
Show file tree
Hide file tree
Showing 16 changed files with 566 additions and 0 deletions.
30 changes: 30 additions & 0 deletions retrofit-converters/guava/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Guava Converter
===============

A `Converter` which supports Guava's `Optional<T>` by delegating to other converters for `T`
and then wrapping it into `Optional`.


Download
--------

Download [the latest JAR][1] or grab via [Maven][2]:
```xml
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-guava</artifactId>
<version>latest.version</version>
</dependency>
```
or [Gradle][2]:
```groovy
compile 'com.squareup.retrofit2:converter-guava: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-guava&v=LATEST
[2]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-guava%22
[snap]: https://oss.sonatype.org/content/repositories/snapshots/
48 changes: 48 additions & 0 deletions retrofit-converters/guava/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit-converters</artifactId>
<version>2.3.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>converter-guava</artifactId>
<name>Converter: Guava</name>

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>retrofit</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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<T>} 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() {
}

@Nullable @Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (getRawType(type) != Optional.class) {
return null;
}

Type innerType = getParameterUpperBound(0, (ParameterizedType) type);
Converter<ResponseBody, Object> delegate =
retrofit.nextResponseBodyConverter(this, innerType, annotations);
return new OptionalConverter<>(delegate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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<T> implements Converter<ResponseBody, Optional<T>> {
private final Converter<ResponseBody, T> delegate;

OptionalConverter(Converter<ResponseBody, T> delegate) {
this.delegate = delegate;
}

@Override public Optional<T> convert(ResponseBody value) throws IOException {
return Optional.fromNullable(delegate.convert(value));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@ParametersAreNonnullByDefault
package retrofit.converter.guava;

import javax.annotation.ParametersAreNonnullByDefault;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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.io.IOException;
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<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return new Converter<ResponseBody, Object>() {
@Override public Object convert(ResponseBody value) throws IOException {
return null;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.http.GET;

import static org.assertj.core.api.Assertions.assertThat;

public final class GuavaOptionalConverterFactoryTest {
interface Service {
@GET("/") Call<Optional<Object>> optional();
@GET("/") Call<Object> 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<Object> 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();
}
}
30 changes: 30 additions & 0 deletions retrofit-converters/java8/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Java 8 Converter
================

A `Converter` which supports Java 8's `Optional<T>` by delegating to other converters for `T`
and then wrapping it into `Optional`.


Download
--------

Download [the latest JAR][1] or grab via [Maven][2]:
```xml
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-java8</artifactId>
<version>latest.version</version>
</dependency>
```
or [Gradle][2]:
```groovy
compile 'com.squareup.retrofit2:converter-java8: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-java8&v=LATEST
[2]: http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.squareup.retrofit2%22%20a%3A%22converter-java8%22
[snap]: https://oss.sonatype.org/content/repositories/snapshots/
65 changes: 65 additions & 0 deletions retrofit-converters/java8/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit-converters</artifactId>
<version>2.3.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>converter-java8</artifactId>
<name>Converter: Java 8</name>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>retrofit</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>${animal.sniffer.version}</version>
<configuration>
<signature>
<groupId>org.kaazing.mojo.signature</groupId>
<artifactId>java18</artifactId>
<version>1.0</version>
</signature>
</configuration>
</plugin>
</plugins>
</build>
</project>
Loading

0 comments on commit 85593d2

Please sign in to comment.