org.zalando.riptide.DefaultRoutingTree Maven / Gradle / Ivy
package org.zalando.riptide;
import org.springframework.http.client.ClientHttpResponse;
import org.zalando.fauxpas.ThrowingSupplier;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import static java.util.Collections.unmodifiableMap;
import static java.util.stream.Collectors.toMap;
final class DefaultRoutingTree implements RoutingTree {
private final Navigator navigator;
private final Map routes;
private final Optional wildcard;
DefaultRoutingTree(final Navigator navigator, final List> bindings) {
this(navigator, map(bindings));
}
private DefaultRoutingTree(final Navigator navigator, final Map routes) {
this(navigator, unmodifiableMap(routes), Optional.ofNullable(routes.remove(null)));
}
private DefaultRoutingTree(final Navigator navigator, final Map routes, final Optional wildcard) {
this.navigator = navigator;
this.routes = routes;
this.wildcard = wildcard;
}
@Override
public Set keySet() {
return routes.keySet();
}
@Override
public Optional get(final A attribute) {
return Optional.ofNullable(routes.get(attribute));
}
@Override
public Optional getWildcard() {
return wildcard;
}
@Override
public RoutingTree merge(final List> bindings) {
final List> present = new ArrayList<>(routes.size() + 1);
routes.forEach((attribute, route) -> present.add(Binding.create(attribute, route)));
wildcard.ifPresent(route -> present.add(Binding.create(null, route)));
return RoutingTree.dispatch(navigator, navigator.merge(present, bindings));
}
private static Map map(final List> bindings) {
return bindings.stream()
.collect(toMap(Binding::getAttribute, Binding::getRoute, (u, v) -> {
throw new IllegalArgumentException(String.format("Duplicate key %s", u));
}, LinkedHashMap::new));
}
@Override
public void execute(final ClientHttpResponse response, final MessageReader reader) throws Exception {
final Optional route = navigator.navigate(response, this);
if (route.isPresent()) {
try {
route.get().execute(response, reader);
} catch (final NoRouteException e) {
executeWildcardOrThrow(response, reader, always(e));
}
} else {
executeWildcardOrThrow(response, reader, () -> new NoRouteException(response));
}
}
private void executeWildcardOrThrow(final ClientHttpResponse response,
final MessageReader reader, final ThrowingSupplier e) throws Exception {
if (wildcard.isPresent()) {
wildcard.get().execute(response, reader);
} else {
throw e.get();
}
}
private static ThrowingSupplier always(final T t) {
return () -> t;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy