io.muserver.rest.LinkHeaderDelegate Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mu-server Show documentation
Show all versions of mu-server Show documentation
A simple but powerful web server framework
package io.muserver.rest;
import io.muserver.Mutils;
import io.muserver.ParameterizedHeaderWithValue;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilderException;
import javax.ws.rs.ext.RuntimeDelegate;
import java.net.URI;
import java.util.*;
import static io.muserver.Mutils.coalesce;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
class LinkHeaderDelegate implements RuntimeDelegate.HeaderDelegate {
private static final RuntimeDelegate.HeaderDelegate HEADER_DELEGATE;
static {
MuRuntimeDelegate.ensureSet();
HEADER_DELEGATE =
RuntimeDelegate.getInstance().createHeaderDelegate(Link.class);
}
@Override
public Link fromString(String value) {
if (value == null) {
throw new IllegalArgumentException("value cannot be null");
}
List hList = ParameterizedHeaderWithValue.fromString(value);
if (hList.isEmpty()) {
throw new IllegalArgumentException("Could not parse link value");
}
ParameterizedHeaderWithValue h = hList.get(0);
String uri = h.value();
if (!uri.startsWith("<") || !uri.endsWith(">")) {
throw new IllegalArgumentException("Link was not a valid link");
}
Map parma = h.parameters();
Link.Builder builder = new MuLinkBuilder()
.uri(uri.substring(1, uri.length() - 1))
.rel(parma.get("rel"))
.title(parma.get("title"))
.type(parma.get("type"));
for (Map.Entry entry : parma.entrySet()) {
String key = entry.getKey();
if ("rel".equals(key) || "title".equals(key) || "type".equals(key)) {
continue;
}
builder.param(key, entry.getValue());
}
return builder.build();
}
@Override
public String toString(Link value) {
StringBuilder sb = new StringBuilder();
sb.append("<").append(value.getUri().toString()).append(">");
if (value.getRels().size() > 0) {
sb.append("; " + "rel" + "=\"").append(String.join(" ", value.getRels())).append("\"");
}
app(sb, "title", value.getTitle());
app(sb, "type", value.getType());
for (Map.Entry entry : value.getParams().entrySet()) {
app(sb, entry.getKey(), entry.getValue());
}
return sb.toString();
}
private static void app(StringBuilder sb, String key, String value) {
if (value != null && !value.isEmpty()) {
sb.append("; ").append(key).append("=\"").append(value.replace("\"", "\\\"")).append("\"");
}
}
static class MuLink extends Link {
private final URI uri;
private final List rels;
private final String title;
private final String type;
private final Map params;
MuLink(URI uri, List rels, String title, String type, Map params) {
Mutils.notNull("uri", uri);
Mutils.notNull("rels", rels);
Mutils.notNull("params", params);
this.uri = uri;
this.rels = rels;
this.title = title;
this.type = type;
this.params = params;
}
@Override
public URI getUri() {
return uri;
}
@Override
public UriBuilder getUriBuilder() {
return UriBuilder.fromUri(uri);
}
@Override
public String getRel() {
return rels.isEmpty() ? null : rels.get(0);
}
@Override
public List getRels() {
return rels;
}
@Override
public String getTitle() {
return title;
}
@Override
public String getType() {
return type;
}
@Override
public Map getParams() {
return params;
}
@Override
public String toString() {
return HEADER_DELEGATE.toString(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MuLink muLink = (MuLink) o;
return uri.equals(muLink.uri) &&
Objects.equals(rels, muLink.rels) &&
Objects.equals(title, muLink.title) &&
Objects.equals(type, muLink.type) &&
Objects.equals(params, muLink.params);
}
@Override
public int hashCode() {
return Objects.hash(uri, rels, title, type, params);
}
}
static class MuLinkBuilder implements Link.Builder {
private UriBuilder uri;
private List rels;
private String title;
private String type;
private Map params;
private URI baseUri;
@Override
public Link.Builder link(Link link) {
this.uri = link.getUriBuilder();
this.rels = link.getRels();
this.title = link.getTitle();
this.type = link.getType();
this.params = link.getParams();
return this;
}
@Override
public Link.Builder link(String link) {
return this.link(HEADER_DELEGATE.fromString(link));
}
@Override
public Link.Builder uri(URI uri) {
this.uri = UriBuilder.fromUri(uri);
return this;
}
@Override
public Link.Builder uri(String uri) {
this.uri = UriBuilder.fromUri(uri);
return this;
}
@Override
public Link.Builder baseUri(URI uri) {
this.baseUri = uri;
return this;
}
@Override
public Link.Builder baseUri(String uri) {
return baseUri(URI.create(uri));
}
@Override
public Link.Builder uriBuilder(UriBuilder uriBuilder) {
this.uri = uriBuilder;
return this;
}
@Override
public Link.Builder rel(String rel) {
if (rel == null || rel.isEmpty()) {
return this;
}
if (rels == null) {
rels = new ArrayList<>();
}
rels.add(rel);
return this;
}
@Override
public Link.Builder title(String title) {
this.title = title;
return this;
}
@Override
public Link.Builder type(String type) {
this.type = type;
return this;
}
@Override
public Link.Builder param(String name, String value) {
if (params == null) {
params = new HashMap<>();
}
params.put(name, value);
return this;
}
@Override
public Link build(Object... values) {
return buildRelativized(null, values);
}
@Override
public Link buildRelativized(URI relativeTo, Object... values) {
if (this.uri == null) {
throw new UriBuilderException("No URI has been set");
}
URI built = this.uri.build(values);
if (baseUri != null) {
built = baseUri.resolve(built);
}
if (relativeTo != null) {
built = relativeTo.relativize(built);
}
return new MuLink(built, coalesce(rels, emptyList()), title, type, coalesce(params, emptyMap()));
}
}
}