@Override public Object parse(final TypeLiteral<?> type, final Context ctx) throws Throwable { MediaType ctype = ctx.type(); if (ctype.isAny()) { // */* return ctx.next(); } JavaType javaType = mapper.constructType(type.getType()); if (matcher.matches(ctype) && mapper.canDeserialize(javaType)) { return ctx .ifparam(values -> mapper.readValue(values.iterator().next(), javaType)) .ifbody(body -> mapper.readValue(body.bytes(), javaType)); } return ctx.next(); }
/** * Produces a matcher for the given media types. * * @param acceptable The acceptable/target media types. * @return A media type matcher. */ public static Matcher matcher(final List<MediaType> acceptable) { requireNonNull(acceptable, "Acceptables media types are required."); return new Matcher(acceptable); }
/** * Given: * * <pre> * text/html, application/xhtml; {@literal *}/{@literal *} * </pre> * * <pre> * matches(text/html) // true through text/html * matches(application/json) // true through {@literal *}/{@literal *} * </pre> * * @param candidate A candidate media type. Required. * @return True if the matcher matches the given media type. */ public boolean matches(final MediaType candidate) { return doFirst(ImmutableList.of(candidate)).isPresent(); }
/** * Test if the route matches the given verb, path, content type and accept header. * * @param method A HTTP verb. * @param path Current HTTP path. * @param contentType The <code>Content-Type</code> header. * @param accept The <code>Accept</code> header. * @return A route or an empty optional. */ @Nonnull public Optional<Route> matches(final String method, final String path, final MediaType contentType, final List<MediaType> accept) { String fpath = method + path; if (excludes.size() > 0 && excludes(fpath)) { return Optional.empty(); } RouteMatcher matcher = cpattern.matcher(fpath); if (matcher.matches()) { List<MediaType> result = MediaType.matcher(accept).filter(this.produces); if (result.size() > 0 && canConsume(contentType)) { // keep accept when */* List<MediaType> produces = result.size() == 1 && result.get(0).name().equals("*/*") ? accept : this.produces; return Optional .of(asRoute(method, matcher, produces, new RouteSourceImpl(declaringClass, line))); } } return Optional.empty(); }
/** * Given: * * <pre> * text/html, application/xhtml; {@literal *}/{@literal *} * </pre> * * <pre> * first(text/html) -> returns text/html * first(application/json) -> returns application/json * </pre> * * @param candidates One ore more candidates media type. Required. * @return A first most relevant media type or an empty optional. */ private Optional<MediaType> doFirst(final List<MediaType> candidates) { List<MediaType> result = filter(candidates); return result.size() == 0 ? Optional.empty() : Optional.of(result.get(0)); } }
/** * Given: * * <pre> * text/html, application/xhtml; {@literal *}/{@literal *} * </pre> * * <pre> * first(text/html) // returns text/html * first(application/json) // returns application/json * </pre> * * @param candidates One ore more candidates media type. Required. * @return A first most relevant media type or an empty optional. */ public Optional<MediaType> first(final List<MediaType> candidates) { return doFirst(candidates); }
/** * Given: * * <pre> * text/html, application/xhtml; {@literal *}/{@literal *} * </pre> * * <pre> * first(text/html) // returns text/html * first(application/json) // returns application/json * </pre> * * @param candidate A candidate media type. Required. * @return A first most relevant media type or an empty optional. */ public Optional<MediaType> first(final MediaType candidate) { return first(ImmutableList.of(candidate)); }
/** * Given: * * <pre> * text/html, application/xhtml; {@literal *}/{@literal *} * </pre> * * <pre> * matches(text/html) // true through text/html * matches(application/json) // true through {@literal *}/{@literal *} * </pre> * * @param candidate A candidate media type. Required. * @return True if the matcher matches the given media type. */ public boolean matches(final MediaType candidate) { return doFirst(ImmutableList.of(candidate)).isPresent(); }
/** * Given: * * <pre> * text/html, application/xhtml; {@literal *}/{@literal *} * </pre> * * <pre> * matches(text/html) // true through text/html * matches(application/json) // true through {@literal *}/{@literal *} * </pre> * * @param candidates One ore more candidates media type. Required. * @return True if the matcher matches the given media type. */ public boolean matches(final List<MediaType> candidates) { return filter(candidates).size() > 0; }
@Override public Object parse(final TypeLiteral<?> type, final Context ctx) throws Throwable { MediaType ctype = ctx.type(); if (ctype.isAny()) { // */* return ctx.next(); } JavaType javaType = mapper.constructType(type.getType()); if (matcher.matches(ctype) && mapper.canDeserialize(javaType)) { return ctx .ifparam(values -> mapper.readValue(values.iterator().next(), javaType)) .ifbody(body -> mapper.readValue(body.bytes(), javaType)); } return ctx.next(); }
/** * Test if the route definition can consume a media type. * * @param types A media types to test. * @return True, if the route can produces the given media type. */ public boolean canProduce(final List<MediaType> types) { return MediaType.matcher(types).matches(produces); }
/** * Produces a matcher for the given media types. * * @param acceptable The acceptable/target media types. * @return A media type matcher. */ public static Matcher matcher(final List<MediaType> acceptable) { requireNonNull(acceptable, "Acceptables media types are required."); return new Matcher(acceptable); }
@Override public Optional<MediaType> accepts(final List<MediaType> types) { requireNonNull(types, "Media types are required."); return MediaType.matcher(accept()).first(types); }
@Override @SuppressWarnings("unchecked") public <T> T get(final List<MediaType> types) { Supplier<Object> provider = MediaType .matcher(types) .first(ImmutableList.copyOf(data.keySet())) .map(it -> data.remove(it)) .orElseThrow( () -> new Err(Status.NOT_ACCEPTABLE, Joiner.on(", ").join(types))); return (T) provider.get(); }
@Override public boolean accepts(final MediaType type) { if (matcher == null) { matcher = MediaType.matcher(produces); } return matcher.matches(type); }
/** * Test if the route definition can consume a media type. * * @param type A media type to test. * @return True, if the route can consume the given media type. */ public boolean canConsume(final MediaType type) { return MediaType.matcher(Arrays.asList(type)).matches(consumes); }
/** * Test if the route definition can consume a media type. * * @param type A media type to test. * @return True, if the route can consume the given media type. */ public boolean canConsume(final String type) { return MediaType.matcher(MediaType.valueOf(type)).matches(consumes); }
/** * Test if the route matches the given verb, path, content type and accept header. * * @param method A HTTP verb. * @param path Current HTTP path. * @param contentType The <code>Content-Type</code> header. * @param accept The <code>Accept</code> header. * @return A route or an empty optional. */ @Nonnull public Optional<Route> matches(final String method, final String path, final MediaType contentType, final List<MediaType> accept) { String fpath = method + path; if (excludes.size() > 0 && excludes(fpath)) { return Optional.empty(); } RouteMatcher matcher = cpattern.matcher(fpath); if (matcher.matches()) { List<MediaType> result = MediaType.matcher(accept).filter(this.produces); if (result.size() > 0 && canConsume(contentType)) { // keep accept when */* List<MediaType> produces = result.size() == 1 && result.get(0).name().equals("*/*") ? accept : this.produces; return Optional .of(asRoute(method, matcher, produces, new RouteSourceImpl(declaringClass, line))); } } return Optional.empty(); }
/** * Given: * * <pre> * text/html, application/xhtml; {@literal *}/{@literal *} * </pre> * * <pre> * first(text/html) -> returns text/html * first(application/json) -> returns application/json * </pre> * * @param candidates One ore more candidates media type. Required. * @return A first most relevant media type or an empty optional. */ private Optional<MediaType> doFirst(final List<MediaType> candidates) { List<MediaType> result = filter(candidates); return result.size() == 0 ? Optional.empty() : Optional.of(result.get(0)); } }
/** * Given: * * <pre> * text/html, application/xhtml; {@literal *}/{@literal *} * </pre> * * <pre> * first(text/html) // returns text/html * first(application/json) // returns application/json * </pre> * * @param candidate A candidate media type. Required. * @return A first most relevant media type or an empty optional. */ public Optional<MediaType> first(final MediaType candidate) { return first(ImmutableList.of(candidate)); }