com.github.dreamhead.moco.rest.RestRequestDispatcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of moco-core Show documentation
Show all versions of moco-core Show documentation
Moco is an easy setup stub framework, mainly focusing on testing and integration.
package com.github.dreamhead.moco.rest;
import com.github.dreamhead.moco.HttpMethod;
import com.github.dreamhead.moco.HttpRequest;
import com.github.dreamhead.moco.Moco;
import com.github.dreamhead.moco.RequestMatcher;
import com.github.dreamhead.moco.ResponseHandler;
import com.github.dreamhead.moco.RestIdMatcher;
import com.github.dreamhead.moco.RestSetting;
import com.github.dreamhead.moco.handler.JsonResponseHandler;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import io.netty.handler.codec.http.HttpResponseStatus;
import static com.github.dreamhead.moco.Moco.by;
import static com.github.dreamhead.moco.Moco.status;
import static com.github.dreamhead.moco.Moco.uri;
import static com.github.dreamhead.moco.rest.RestIdMatchers.eq;
import static com.github.dreamhead.moco.util.URLs.join;
import static com.github.dreamhead.moco.util.URLs.resourceRoot;
import static com.google.common.base.Optional.absent;
import static com.google.common.base.Optional.of;
public final class RestRequestDispatcher {
private static final ResponseHandler NOT_FOUND_HANDLER = status(HttpResponseStatus.NOT_FOUND.code());
private static final ResponseHandler BAD_REQUEST_HANDLER = status(HttpResponseStatus.BAD_REQUEST.code());
private final RestIdMatcher name;
private final RequestMatcher allMatcher;
private final RequestMatcher singleMatcher;
private final CompositeRestSetting getAllSettings;
private final CompositeRestSetting getSingleSettings;
private final CompositeRestSetting postSettings;
private final CompositeRestSetting putSettings;
private final CompositeRestSetting deleteSettings;
private final CompositeRestSetting headSettings;
private final CompositeRestSetting headAllSettings;
private final CompositeRestSetting patchSettings;
private final FluentIterable subResourceSettings;
public RestRequestDispatcher(final String name, final Iterable settings) {
this.name = eq(name);
this.getAllSettings = filterSettings(settings, RestAllSetting.class, HttpMethod.GET);
this.getSingleSettings = filterSettings(settings, RestSingleSetting.class, HttpMethod.GET);
this.postSettings = filterSettings(settings, RestAllSetting.class, HttpMethod.POST);
this.putSettings = filterSettings(settings, RestSingleSetting.class, HttpMethod.PUT);
this.deleteSettings = filterSettings(settings, RestSingleSetting.class, HttpMethod.DELETE);
this.headSettings = filterSettings(settings, RestSingleSetting.class, HttpMethod.HEAD);
this.headAllSettings = filterSettings(settings, RestAllSetting.class, HttpMethod.HEAD);
this.patchSettings = filterSettings(settings, RestSingleSetting.class, HttpMethod.PATCH);
this.subResourceSettings = filter(settings, SubResourceSetting.class);
this.allMatcher = by(uri(resourceRoot(name)));
this.singleMatcher = Moco.match(uri(join(resourceRoot(name), "[^/]*")));
}
private CompositeRestSetting filterSettings(final Iterable settings,
final Class type,
final HttpMethod method) {
return new CompositeRestSetting(filter(settings, type, method));
}
private Function super T, T> toInstance(final Class clazz) {
return new Function() {
@Override
public T apply(final T input) {
return clazz.cast(input);
}
};
}
private FluentIterable filter(final Iterable settings,
final Class type,
final HttpMethod method) {
return filter(settings, type)
.filter(isForMethod(method));
}
private FluentIterable filter(final Iterable settings,
final Class type) {
return FluentIterable.from(settings)
.filter(type)
.transform(toInstance(type));
}
private Predicate isForMethod(final HttpMethod method) {
return new Predicate() {
@Override
public boolean apply(final T input) {
return input.isSimple() && input.isFor(method);
}
};
}
private Predicate isJsonHandlers() {
return new Predicate() {
@Override
public boolean apply(final SimpleRestSetting setting) {
return setting.getHandler() instanceof JsonResponseHandler;
}
};
}
private Function toJsonHandler() {
return new Function() {
@Override
public JsonResponseHandler apply(final SimpleRestSetting setting) {
return JsonResponseHandler.class.cast(setting.getHandler());
}
};
}
private Function toPojo() {
return new Function() {
@Override
public Object apply(final JsonResponseHandler handler) {
return handler.getPojo();
}
};
}
private Optional getSingleOrAllHandler(final HttpRequest httpRequest,
final CompositeRestSetting single,
final CompositeRestSetting all,
final RestIdMatcher name) {
Optional singleHandler = single.getMatched(name, httpRequest);
if (singleHandler.isPresent()) {
return singleHandler;
}
Optional allHandler = all.getMatched(name, httpRequest);
if (allHandler.isPresent()) {
return allHandler;
}
return absent();
}
private Optional getHeadHandler(final HttpRequest httpRequest) {
Optional handler = getSingleOrAllHandler(httpRequest,
headSettings,
headAllSettings,
name);
if (handler.isPresent()) {
return handler;
}
return of(NOT_FOUND_HANDLER);
}
private Optional getGetHandler(final HttpRequest httpRequest) {
Optional matchedSetting = getSingleOrAllHandler(httpRequest,
getSingleSettings,
getAllSettings, name);
if (matchedSetting.isPresent()) {
return matchedSetting;
}
if (allMatcher.match(httpRequest)) {
FluentIterable settings = FluentIterable.from(getSingleSettings.getSettings());
if (!settings.isEmpty() && settings.allMatch(isJsonHandlers())) {
ImmutableList