/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.jooby;
import static java.util.Objects.requireNonNull;
import java.util.function.Supplier;
/**
* A {@link Result} builder with some utility static methods.
*
* @author edgar
* @since 0.5.0
*/
public class Results {
/**
* Set the result
*
* @param entity A result value.
* @return A new result.
*/
public static Result with(final Object entity) {
return new Result().set(entity);
}
/**
* Set the result
*
* @param entity A result value.
* @param status A HTTP status.
* @return A new result.
*/
public static Result with(final Object entity, final Status status) {
return new Result().status(status).set(entity);
}
/**
* Set the result
*
* @param entity A result value.
* @param status A HTTP status.
* @return A new result.
*/
public static Result with(final Object entity, final int status) {
return with(entity, Status.valueOf(status));
}
/**
* Set the response status.
*
* @param status A status!
* @return A new result.
*/
public static Result with(final Status status) {
requireNonNull(status, "A HTTP status is required.");
return new Result().status(status);
}
/**
* Set the response status.
*
* @param status A status!
* @return A new result.
*/
public static Result with(final int status) {
requireNonNull(status, "A HTTP status is required.");
return new Result().status(status);
}
/**
* @return A new result with {@link Status#OK}.
*/
public static Result ok() {
return with(Status.OK);
}
/**
* @param view View to render.
* @return A new view.
*/
public static View html(final String view) {
return new View(view);
}
/**
* @param entity A result content!
* @return A new json result.
*/
public static Result json(final Object entity) {
return with(entity, 200).type(MediaType.json);
}
/**
* @param entity A result content!
* @return A new json result.
*/
public static Result xml(final Object entity) {
return with(entity, 200).type(MediaType.xml);
}
/**
* @param entity A result content!
* @return A new result with {@link Status#OK} and given content.
*/
public static Result ok(final Object entity) {
return ok().set(entity);
}
/**
* @return A new result with {@link Status#ACCEPTED}.
*/
public static Result accepted() {
return with(Status.ACCEPTED);
}
/**
* @param content A result content!
* @return A new result with {@link Status#ACCEPTED}.
*/
public static Result accepted(final Object content) {
return accepted().set(content);
}
/**
* @return A new result with {@link Status#NO_CONTENT}.
*/
public static Result noContent() {
return with(Status.NO_CONTENT);
}
/**
* Redirect to the given url with status code defaulting to {@link Status#FOUND}.
*
* <pre>
* rsp.redirect("/foo/bar");
* rsp.redirect("http://example.com");
* rsp.redirect("http://example.com");
* rsp.redirect("../login");
* </pre>
*
* Redirects can be a fully qualified URI for redirecting to a different site:
*
* <pre>
* rsp.redirect("http://google.com");
* </pre>
*
* Redirects can be relative to the root of the host name. For example, if you were
* on <code>http://example.com/admin/post/new</code>, the following redirect to /admin would
* land you at <code>http://example.com/admin</code>:
*
* <pre>
* rsp.redirect("/admin");
* </pre>
*
* Redirects can be relative to the current URL. A redirection of post/new, from
* <code>http://example.com/blog/admin/</code> (notice the trailing slash), would give you
* <code>http://example.com/blog/admin/post/new.</code>
*
* <pre>
* rsp.redirect("post/new");
* </pre>
*
* Redirecting to post/new from <code>http://example.com/blog/admin</code> (no trailing slash),
* will take you to <code>http://example.com/blog/post/new</code>.
*
* <p>
* If you found the above behavior confusing, think of path segments as directories (have trailing
* slashes) and files, it will start to make sense.
* </p>
*
* Pathname relative redirects are also possible. If you were on
* <code>http://example.com/admin/post/new</code>, the following redirect would land you at
* <code>http//example.com/admin</code>:
*
* <pre>
* rsp.redirect("..");
* </pre>
*
* A back redirection will redirect the request back to the <code>Referer</code>, defaulting to
* <code>/</code> when missing.
*
* <pre>
* rsp.redirect("back");
* </pre>
*
* @param location A location.
* @return A new result.
*/
public static Result redirect(final String location) {
return redirect(Status.FOUND, location);
}
/**
* Redirect to the given url with status code defaulting to {@link Status#FOUND}.
*
* <pre>
* rsp.redirect("/foo/bar");
* rsp.redirect("http://example.com");
* rsp.redirect("http://example.com");
* rsp.redirect("../login");
* </pre>
*
* Redirects can be a fully qualified URI for redirecting to a different site:
*
* <pre>
* rsp.redirect("http://google.com");
* </pre>
*
* Redirects can be relative to the root of the host name. For example, if you were
* on <code>http://example.com/admin/post/new</code>, the following redirect to /admin would
* land you at <code>http://example.com/admin</code>:
*
* <pre>
* rsp.redirect("/admin");
* </pre>
*
* Redirects can be relative to the current URL. A redirection of post/new, from
* <code>http://example.com/blog/admin/</code> (notice the trailing slash), would give you
* <code>http://example.com/blog/admin/post/new.</code>
*
* <pre>
* rsp.redirect("post/new");
* </pre>
*
* Redirecting to post/new from <code>http://example.com/blog/admin</code> (no trailing slash),
* will take you to <code>http://example.com/blog/post/new</code>.
*
* <p>
* If you found the above behavior confusing, think of path segments as directories (have trailing
* slashes) and files, it will start to make sense.
* </p>
*
* Pathname relative redirects are also possible. If you were on
* <code>http://example.com/admin/post/new</code>, the following redirect would land you at
* <code>http//example.com/admin</code>:
*
* <pre>
* rsp.redirect("..");
* </pre>
*
* A back redirection will redirect the request back to the <code>Referer</code>, defaulting to
* <code>/</code> when missing.
*
* <pre>
* rsp.redirect("back");
* </pre>
*
* @param location A location.
* @return A new result.
*/
public static Result tempRedirect(final String location) {
return redirect(Status.TEMPORARY_REDIRECT, location);
}
/**
* Redirect to the given url with status code defaulting to {@link Status#FOUND}.
*
* <pre>
* rsp.redirect("/foo/bar");
* rsp.redirect("http://example.com");
* rsp.redirect("http://example.com");
* rsp.redirect("../login");
* </pre>
*
* Redirects can be a fully qualified URI for redirecting to a different site:
*
* <pre>
* rsp.redirect("http://google.com");
* </pre>
*
* Redirects can be relative to the root of the host name. For example, if you were
* on <code>http://example.com/admin/post/new</code>, the following redirect to /admin would
* land you at <code>http://example.com/admin</code>:
*
* <pre>
* rsp.redirect("/admin");
* </pre>
*
* Redirects can be relative to the current URL. A redirection of post/new, from
* <code>http://example.com/blog/admin/</code> (notice the trailing slash), would give you
* <code>http://example.com/blog/admin/post/new.</code>
*
* <pre>
* rsp.redirect("post/new");
* </pre>
*
* Redirecting to post/new from <code>http://example.com/blog/admin</code> (no trailing slash),
* will take you to <code>http://example.com/blog/post/new</code>.
*
* <p>
* If you found the above behavior confusing, think of path segments as directories (have trailing
* slashes) and files, it will start to make sense.
* </p>
*
* Pathname relative redirects are also possible. If you were on
* <code>http://example.com/admin/post/new</code>, the following redirect would land you at
* <code>http//example.com/admin</code>:
*
* <pre>
* rsp.redirect("..");
* </pre>
*
* A back redirection will redirect the request back to the <code>Referer</code>, defaulting to
* <code>/</code> when missing.
*
* <pre>
* rsp.redirect("back");
* </pre>
*
* @param location A location.
* @return A new result.
*/
public static Result moved(final String location) {
return redirect(Status.MOVED_PERMANENTLY, location);
}
/**
* Redirect to the given url with status code defaulting to {@link Status#FOUND}.
*
* <pre>
* rsp.redirect("/foo/bar");
* rsp.redirect("http://example.com");
* rsp.redirect("http://example.com");
* rsp.redirect("../login");
* </pre>
*
* Redirects can be a fully qualified URI for redirecting to a different site:
*
* <pre>
* rsp.redirect("http://google.com");
* </pre>
*
* Redirects can be relative to the root of the host name. For example, if you were
* on <code>http://example.com/admin/post/new</code>, the following redirect to /admin would
* land you at <code>http://example.com/admin</code>:
*
* <pre>
* rsp.redirect("/admin");
* </pre>
*
* Redirects can be relative to the current URL. A redirection of post/new, from
* <code>http://example.com/blog/admin/</code> (notice the trailing slash), would give you
* <code>http://example.com/blog/admin/post/new.</code>
*
* <pre>
* rsp.redirect("post/new");
* </pre>
*
* Redirecting to post/new from <code>http://example.com/blog/admin</code> (no trailing slash),
* will take you to <code>http://example.com/blog/post/new</code>.
*
* <p>
* If you found the above behavior confusing, think of path segments as directories (have trailing
* slashes) and files, it will start to make sense.
* </p>
*
* Pathname relative redirects are also possible. If you were on
* <code>http://example.com/admin/post/new</code>, the following redirect would land you at
* <code>http//example.com/admin</code>:
*
* <pre>
* rsp.redirect("..");
* </pre>
*
* A back redirection will redirect the request back to the <code>Referer</code>, defaulting to
* <code>/</code> when missing.
*
* <pre>
* rsp.redirect("back");
* </pre>
*
* @param location A location.
* @return A new result.
*/
public static Result seeOther(final String location) {
return redirect(Status.SEE_OTHER, location);
}
/**
* Performs content-negotiation on the Accept HTTP header on the request object. It select a
* handler for the request, based on the acceptable types ordered by their quality values.
* If the header is not specified, the first callback is invoked. When no match is found,
* the server responds with 406 "Not Acceptable", or invokes the default callback: {@code ** / *}.
*
* <pre>
* get("/jsonOrHtml", () {@literal ->}
* Results
* .when("text/html", () {@literal ->} View.of("view", "model", model))
* .when("application/json", () {@literal ->} model)
* .when("*", () {@literal ->} Status.NOT_ACCEPTABLE)
* );
* </pre>
*
* @param type A media type.
* @param supplier A result supplier.
* @return A new result.
*/
public static Result when(final String type, final Supplier<Object> supplier) {
return new Result().when(type, supplier);
}
/**
* Performs content-negotiation on the Accept HTTP header on the request object. It select a
* handler for the request, based on the acceptable types ordered by their quality values.
* If the header is not specified, the first callback is invoked. When no match is found,
* the server responds with 406 "Not Acceptable", or invokes the default callback: {@code ** / *}.
*
* <pre>
* get("/jsonOrHtml", () {@literal ->}
* Results
* .when("text/html", () {@literal ->} View.of("view", "model", model))
* .when("application/json", () {@literal ->} model)
* .when("*", () {@literal ->} Status.NOT_ACCEPTABLE)
* );
* </pre>
*
* @param type A media type.
* @param supplier A result supplier.
* @return A new result.
*/
public static Result when(final MediaType type, final Supplier<Object> supplier) {
return new Result().when(type, supplier);
}
/**
* Produces a redirect (302) status code and set the <code>Location</code> header too.
*
* @param status A HTTP redirect status.
* @param location A location.
* @return A new result.
*/
private static Result redirect(final Status status, final String location) {
requireNonNull(location, "A location is required.");
return with(status).header("location", location);
}
}