package com.temenos.interaction.core.hypermedia; /* * #%L * interaction-core * %% * Copyright (C) 2012 - 2013 Temenos Holdings N.V. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.ws.rs.HttpMethod; import javax.ws.rs.core.MultivaluedMap; /** * A Link (see http://tools.ietf.org/html/rfc5988) * @author aphethean */ public class Link { private Transition transition; // id private String id; // title (5.4 Target Attributes) private String title; // rel (5.3 Relation Type) private String rel; // href (5.1 Target IRI) private String href; // type (5.4 Target Attributes) private String[] produces; // extensions private String method; private String[] consumes; private MultivaluedMap<String, String> extensions; //LinkId private String linkId; //Source Field private String sourceField; /** * Construct a simple link used for GET operations. * @param title * @param rel * @param href * @param type * @param extensions */ public Link(String title, String rel, String href, String type, MultivaluedMap<String, String> extensions) { this(null, title, rel, href, null, (type != null ? type.split(" ") : null), HttpMethod.GET, null); } /** * Construct a link from a transition. * @param transition */ public Link(Transition transition, String rel, String href, String method) { this(transition, transition.getLabel() != null && !transition.getLabel().equals("") ? transition.getLabel() : transition.getTarget().getName(), rel, href, null, null, method, null); } /** * Construct a link from a transition having a uri with a multivalue drill-down * @param transition */ public Link(Transition transition, String rel, String href, String method, String sourceField) { this(transition, transition.getLabel() != null && !transition.getLabel().equals("") ? transition.getLabel() : transition.getTarget().getName(), rel, href, null, null, method, null, sourceField); } public Link(Transition transition, String title, String rel, String href, String[] consumes, String[] produces, String method, MultivaluedMap<String, String> extensions) { this(transition, title, rel, href, consumes, produces, method, extensions, null); } public Link(Transition transition, String title, String rel, String href, String[] consumes, String[] produces, String method, MultivaluedMap<String, String> extensions, String sourceField) { this.transition = transition; if (title == null && transition != null) { title = transition.getId(); } id = transition != null ? transition.getId() : title; this.title = title; this.rel = rel; this.href = href; this.consumes = consumes; this.produces = produces; this.method = method; this.extensions = extensions; this.linkId = transition != null ? transition.getLinkId() : null; this.sourceField = sourceField; } public Transition getTransition() { return transition; } public String getId() { return id; } public String getRel() { return rel; } public String getMethod() { return method; } public String getHref() { return href; } public String getSourceField() { return sourceField; } public String getLinkId() { if(linkId == null) { linkId = transition != null ? transition.getLinkId() : null; } return linkId; } /** * Obtain the transition, i.e. the link relative to the REST service. * * @param basePath Path to REST service * @return relativePath of transition relative to REST service */ public String getRelativeHref(String basePath) { String baseUri = HypermediaTemplateHelper.getTemplatedBaseUri(basePath, href); StringBuffer regex = new StringBuffer("(?<=" + baseUri + ")\\S+"); Pattern p = Pattern.compile(regex.toString()); Matcher m = p.matcher(href); while (m.find()) { return m.group(); } return href; } public String[] getConsumes() { return consumes; } public String[] getProduces() { return produces; } public String getTitle() { return title; } public MultivaluedMap<String, String> getExtensions() { return extensions; } public String toString() { StringBuffer buf = new StringBuffer("<"); buf.append(href).append(">"); if (rel != null) { buf.append("; rel=\"").append(rel).append("\""); } if (produces != null && produces.length > 0) { buf.append("; type=\"").append(produces[0]); for (int i = 1; i < produces.length; i++) buf.append(",").append(produces[i]); buf.append("\""); } if (title != null) { buf.append("; title=\"").append(title).append("\""); } if (extensions != null) { for (String key : getExtensions().keySet()) { List<String> values = getExtensions().get(key); for (String val : values) { buf.append("; ").append(key).append("=\"").append(val) .append("\""); } } } if (linkId != null) { buf.append("; linkId=\"").append(linkId).append("\""); } if (sourceField != null) { buf.append("; sourceField=\"").append(sourceField).append("\""); } return buf.toString(); } public boolean equals(Object other) { if (this == other) { return true; } if (other instanceof Link) { Link otherLink = (Link) other; return this.toString().equals(otherLink.toString()); } return false; } public int hashCode() { return this.toString().hashCode(); } public static class Builder { private Transition transition; private String id; private String title; private String rel; private String href; private String[] produces; private String method; private String[] consumes; private MultivaluedMap<String, String> extensions; private String linkId; private String sourceField; public Builder transition(Transition transition) { this.transition = transition; return this; } public Builder id(String id) { this.id = id; return this; } public Builder title(String title) { this.title = title; return this; } public Builder rel(String rel) { this.rel = rel; return this; } public Builder href(String href) { this.href = href; return this; } public Builder produces(String[] produces) { this.produces = produces; return this; } public Builder method(String method) { this.method = method; return this; } public Builder consumes(String[] consumes) { this.consumes = consumes; return this; } public Builder extensions(MultivaluedMap<String, String> extensions) { this.extensions = extensions; return this; } public Builder linkId(String linkId) { this.linkId = linkId; return this; } public Builder sourceField(String sourceField) { this.sourceField = sourceField; return this; } public Link build() { return new Link(this); } } private Link(Builder builder) { this.transition = builder.transition; this.id = builder.id; this.title = builder.title; this.rel = builder.rel; this.href = builder.href; this.produces = builder.produces; this.method = builder.method; this.consumes = builder.consumes; this.extensions = builder.extensions; if(builder.linkId == null) { this.linkId = builder.transition != null ? builder.transition.getLinkId() : null; } else { this.linkId = builder.linkId; } this.sourceField = builder.sourceField; } }