All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zalando.riptide.Route Maven / Gradle / Ivy

package org.zalando.riptide;

import com.google.common.reflect.TypeParameter;
import com.google.common.reflect.TypeToken;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMessage;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.zalando.fauxpas.ThrowingConsumer;
import org.zalando.fauxpas.ThrowingFunction;
import org.zalando.fauxpas.ThrowingRunnable;

import java.io.IOException;
import java.net.URI;
import java.util.List;

import static org.zalando.fauxpas.TryWith.tryWith;

@FunctionalInterface
public interface Route {

    void execute(final ClientHttpResponse response, final MessageReader reader) throws Exception;

    static Route call(final ThrowingRunnable runnable) {
        return (response, reader) ->
                tryWith(response, (ClientHttpResponse _) -> runnable.tryRun());
    }

    static Route call(final ThrowingConsumer consumer) {
        return (response, reader) ->
                tryWith(response, consumer);
    }

    static  Route call(final Class type, final ThrowingConsumer consumer) {
        return call(TypeToken.of(type), consumer);
    }

    static  Route call(final TypeToken type, final ThrowingConsumer consumer) {
        return (response, reader) -> {
            final I body = reader.read(type, response);
            consumer.accept(body);
        };
    }

    static  TypeToken> listOf(final Class entityType) {
        return listOf(TypeToken.of(entityType));
    }

    @SuppressWarnings("serial")
    static  TypeToken> listOf(final TypeToken entityType) {
        final TypeToken> listType = new TypeToken>() {
            // nothing to implement!
        };

        final TypeParameter elementType = new TypeParameter() {
            // nothing to implement!
        };

        return listType.where(elementType, entityType);
    }

    static  TypeToken> responseEntityOf(final Class entityType) {
        return responseEntityOf(TypeToken.of(entityType));
    }

    static  TypeToken> responseEntityOf(final TypeToken entityType) {
        final TypeToken> responseEntityType = new TypeToken>() {
            // nothing to implement!
        };

        final TypeParameter elementType = new TypeParameter() {
            // nothing to implement!
        };

        return responseEntityType.where(elementType, entityType);
    }

    static ThrowingConsumer pass() {
        return response -> {
            // nothing to do!
        };
    }

    static ThrowingFunction headers() {
        return HttpMessage::getHeaders;
    }

    static ThrowingFunction location() {
        return response ->
                response.getHeaders().getLocation();
    }

    static ThrowingConsumer noRoute() {
        return response -> {
            throw new NoRouteException(response);
        };
    }

    static  ThrowingConsumer propagate() {
        return entity -> {
            if (entity instanceof IOException) {
                throw (IOException) entity;
            } else {
                throw new IOException(entity);
            }
        };
    }

    static  Adapter to(
            final ThrowingFunction function) {
        return consumer ->
                response -> consumer.accept(function.apply(response));
    }

    @FunctionalInterface
    interface Adapter {
        ThrowingConsumer andThen(final ThrowingConsumer consumer);
    }

}