All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.ws.rs.core.Link Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * http://glassfish.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package javax.ws.rs.core;

import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.ws.rs.ext.RuntimeDelegate;

import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.namespace.QName;

/**
 * 

Class representing hypermedia links. A hypermedia link may include additional * parameters beyond its underlying URI. Parameters such as {@code rel} or {@code type} * provide additional meta-data. Links in responses can be followed by * creating an {@link javax.ws.rs.client.Invocation.Builder} or a * {@link javax.ws.rs.client.WebTarget}.

* *

The methods {@link #toString} and {@link #valueOf} can be used to serialize * and de-serialize a link into a link header (RFC 5988).

* * @author Marek Potociar * @author Santiago Pericas-Geertsen * @see javax.ws.rs.client.Client#invocation * @see javax.ws.rs.client.Client#target(javax.ws.rs.core.Link) * @see javax.ws.rs.core.Response#getLink(java.lang.String) * @since 2.0 */ public abstract class Link { /** * Title link param from RFC 5988. */ public static final String TITLE = "title"; /** * Rel link param from RFC 5988. */ public static final String REL = "rel"; /** * Type link param from RFC 5988. */ public static final String TYPE = "type"; /** * Returns the underlying URI associated with this link. * * @return underlying URI. */ public abstract URI getUri(); /** * Convenience method that returns a {@link javax.ws.rs.core.UriBuilder} * initialized with this link's underlying URI. * * @return UriBuilder initialized using underlying URI. */ public abstract UriBuilder getUriBuilder(); /** * Returns the value associated with the link {@code rel} param, or * {@code null} if this param is not specified. * * @return relation types as string or {@code null}. */ public abstract String getRel(); /** * Returns the value associated with the link {@code rel} param as a list * of strings or the empty list if {@code rel} is not defined. * * @return relation types as list of strings or empty list. */ public abstract List getRels(); /** * Returns the value associated with the link {@code title} param, or * {@code null} if this param is not specified. * * @return value of title parameter or {@code null}. */ public abstract String getTitle(); /** * Returns the value associated with the link {@code type} param, or * {@code null} if this param is not specified. * * @return value of type parameter or {@code null}. */ public abstract String getType(); /** * Returns an immutable map that includes all the link parameters * defined on this link. If defined, this map will include entries * for {@code rel}, {@code title} and {@code type}. * * @return immutable map of link parameters. */ public abstract Map getParams(); /** * Returns a string representation as a link header (RFC 5988). * All link params are serialized as link-param="value" where value * is a quoted-string. For example, * * ; title="employee"; rel="manager friend" * * @return string link header representation for this link. */ @Override public abstract String toString(); /** * Simple parser to convert link header string representations into a link. *
     * link ::= '<' uri '>' (';' link-param)*
     * link-param ::= name '=' quoted-string
     * 
* * See RFC 5988 for more information. * * @param value String representation. * @return newly parsed link. * @throws IllegalArgumentException if a syntax error is found. * @see Link.Builder#link(java.lang.String) */ public static Link valueOf(String value) { Builder b = RuntimeDelegate.getInstance().createLinkBuilder(); b.link(value); return b.build(); } /** * Create a new builder instance initialized from an existing URI. * * @param uri a URI that will be used to initialize the builder. * @return a new builder. * @throws IllegalArgumentException if uri is {@code null}. */ public static Builder fromUri(URI uri) { Builder b = RuntimeDelegate.getInstance().createLinkBuilder(); b.uri(uri); return b; } /** * Create a new builder instance initialized from an existing URI represented as a string. * * @param uri a URI that will be used to initialize the builder. * @return a new builder. * @throws IllegalArgumentException if uri is {@code null}. */ public static Builder fromUri(String uri) { Builder b = RuntimeDelegate.getInstance().createLinkBuilder(); b.uri(uri); return b; } /** * Create a new builder instance initialized from a URI builder. * * @param uriBuilder instance of URI builder. * @return a new builder. */ public static Builder fromUriBuilder(UriBuilder uriBuilder) { Builder b = RuntimeDelegate.getInstance().createLinkBuilder(); b.uriBuilder(uriBuilder); return b; } /** * Create a new builder instance initialized from another link. * * @param link other link used for initialization. * @return a new builder. */ public static Builder fromLink(Link link) { Builder b = RuntimeDelegate.getInstance().createLinkBuilder(); b.link(link); return b; } /** * Convenience method to build a link from a path. Equivalent to * {@code fromUriBuilder(UriBuilder.fromPath(path))}. * * @param path a URI path that will be used to initialize the Link, may contain * URI template parameters. * @return a new Link.Builder. * @throws IllegalArgumentException if path is {@code null}. */ public static Builder fromPath(String path) { return fromUriBuilder(UriBuilder.fromPath(path)); } /** * Convenience method to build a link from a resource. Equivalent to * Link.fromUriBuilder({@link UriBuilder#fromResource UriBuilder.fromResource(resource)}). * Note that the link URI passed to the {@code Link.Builder} instance returned by this * method is relative. Should the link be built as absolute, a {@link Link.Builder#baseUri(URI) * base URI} has to be specified in the builder prior to building the new link instance. * For example, on a server side a {@link UriInfo#getBaseUri()} may be typically used to define * the base URI of a link created using this method. * * @param resource a root resource whose {@link javax.ws.rs.Path} value will be used * to initialize the builder. * @return a new {@link Link.Builder link builder} instance. * @throws IllegalArgumentException if resource is not annotated with {@link javax.ws.rs.Path} * or resource is {@code null}. * @see UriInfo#getBaseUri() */ public static Builder fromResource(Class resource) { return fromUriBuilder(UriBuilder.fromResource(resource)); } /** * Convenience method to build a link from a resource. Equivalent to * Link.fromUriBuilder({@link UriBuilder#fromMethod(Class, String) UriBuilder.fromMethod(resource, method)}). * Note that the link URI passed to the {@code Link.Builder} instance returned by this * method is relative. Should the link be built as absolute, a {@link Link.Builder#baseUri(URI) * base URI} has to be specified in the builder prior to building the new link instance. * For example, on a server side a {@link UriInfo#getBaseUri()} may be typically used to define * the base URI of a link created using this method. * * @param resource the resource containing the method. * @param method the name of the method whose {@link javax.ws.rs.Path} value will be used * to obtain the path to append. * @return the updated Link.Builder. * @throws IllegalArgumentException if resource or method is {@code null}, or there is more * than or less than one variant of the method annotated with * {@link javax.ws.rs.Path}. * @see UriInfo#getBaseUri() */ public static Builder fromMethod(Class resource, String method) { return fromUriBuilder(UriBuilder.fromMethod(resource, method)); } /** * Builder class for hypermedia links. * * @see Link * @since 2.0 */ public interface Builder { /** * Initialize builder using another link. Sets underlying URI and copies * all parameters. * * @param link other link from which to initialize. * @return the updated builder. */ public Builder link(Link link); /** * Initialize builder using another link represented as a string. Uses * simple parser to convert string representation into a link. *
         * link ::= '<' uri '>' (';' link-param)*
         * link-param ::= name '=' quoted-string
         * 
* * See RFC 5988 for more information. * * @param link other link in string representation. * @return the updated builder. * @throws IllegalArgumentException if string representation of URI is invalid. */ public Builder link(String link); /** * Set underlying URI template for the link being constructed. * * @param uri underlying URI for link * @return the updated builder. */ public Builder uri(URI uri); /** * Set underlying string representing URI template for the link being constructed. * * @param uri underlying URI for link. * @return the updated builder. * @throws IllegalArgumentException if string representation of URI is invalid. */ public Builder uri(String uri); /** * Set the base URI for resolution of relative URIs. If the underlying URI is already * absolute, the base URI is ignored. * * @param uri base URI for relative links. * @return the updated builder. * @see Link#fromPath(java.lang.String) * @see Link#fromResource(java.lang.Class) * @see Link#fromMethod(java.lang.Class, java.lang.String) */ public Builder baseUri(URI uri); /** * Set the base URI as a string for resolution of relative URIs. If the underlying URI * is already absolute, the base URI is ignored. * * @param uri base URI for relative links. * @return the updated builder. * @throws IllegalArgumentException if string representation of URI is invalid. * @see Link#fromPath(java.lang.String) * @see Link#fromResource(java.lang.Class) * @see Link#fromMethod(java.lang.Class, java.lang.String) */ public Builder baseUri(String uri); /** * Set underlying URI builder representing the URI template for the link being constructed. * * @param uriBuilder underlying URI builder. * @return the updated builder. */ public Builder uriBuilder(UriBuilder uriBuilder); /** * Convenience method to set a link relation. More than one {@code rel} value can * be specified by using one or more whitespace characters as delimiters * according to RFC 5988. The effect of calling this method is cumulative; * relations are appended using a single space character as separator. * * @param rel relation name. * @return the updated builder. * @throws IllegalArgumentException if the name is {@code null}. */ public Builder rel(String rel); /** * Convenience method to set a {@code title} on this link. * * @param title title parameter of this link. * @return the updated builder. * @throws IllegalArgumentException if the title is {@code null}. */ public Builder title(String title); /** * Convenience method to set a {@code type} on this link. * * @param type type parameter of this link. * @return the updated builder. * @throws IllegalArgumentException if the type is {@code null}. */ public Builder type(String type); /** * Set an arbitrary parameter on this link. Note that link parameters are those * defined in RFC 5988 and should not be confused with URI parameters which can * be specified when calling {@link #build(Object...)}. * * @param name the name of the parameter. * @param value the value set for the parameter. * @return the updated builder. * @throws IllegalArgumentException if either the name or value are {@code null}. */ public Builder param(String name, String value); /** * Finish building this link using the supplied values as URI parameters. * * The state of the builder is unaffected; this method may be called * multiple times on the same builder instance. * * @param values parameters used to build underlying URI. * @return newly built link. * @throws IllegalArgumentException if there are any URI template parameters * without a supplied value, or if a value is {@code null}. * @throws UriBuilderException if a URI cannot be constructed based on the * current state of the underlying URI builder. */ public Link build(Object... values); /** * Finish building this link using the supplied values as URI parameters * and relativize the result with respect to the supplied URI. * * If the underlying link is already relative or if it is absolute but does * not share a prefix with the supplied URI, this method is equivalent to calling * {@link Link.Builder#build(java.lang.Object[])}. Note that a base URI can * be set on a relative link using {@link Link.Builder#baseUri(java.net.URI)}. * The state of the builder is unaffected; this method may be called * multiple times on the same builder instance. * * @param uri URI used for relativization. * @param values parameters used to build underlying URI. * @return newly built link. * @throws IllegalArgumentException if there are any URI template parameters * without a supplied value, or if a value is {@code null}. * @throws UriBuilderException if a URI cannot be constructed based on the current * state of the underlying URI builder. * @see #baseUri(java.lang.String) * @see #baseUri(java.net.URI) */ public Link buildRelativized(URI uri, Object... values); } /** * Value type for {@link javax.ws.rs.core.Link} that can be marshalled and * unmarshalled by JAXB. * * @see javax.ws.rs.core.Link.JaxbAdapter * @since 2.0 */ public static class JaxbLink { private URI uri; private Map params; /** * Default constructor needed during unmarshalling. */ public JaxbLink() { } /** * Construct an instance from a URI and no parameters. * * @param uri underlying URI. */ public JaxbLink(URI uri) { this.uri = uri; } /** * Construct an instance from a URI and some parameters. * * @param uri underlying URI. * @param params parameters of this link. */ public JaxbLink(URI uri, Map params) { this.uri = uri; this.params = params; } /** * Get the underlying URI for this link. * * @return underlying URI. */ @XmlAttribute(name = "href") public URI getUri() { return uri; } /** * Get the parameter map for this link. * * @return parameter map. */ @XmlAnyAttribute public Map getParams() { if (params == null) { params = new HashMap(); } return params; } /** * Set the underlying URI for this link. * * This setter is needed for JAXB unmarshalling. */ void setUri(URI uri) { this.uri = uri; } /** * Set the parameter map for this link. * * This setter is needed for JAXB unmarshalling. */ void setParams(Map params) { this.params = params; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof JaxbLink)) return false; JaxbLink jaxbLink = (JaxbLink) o; if (uri != null ? !uri.equals(jaxbLink.uri) : jaxbLink.uri != null) { return false; } if (params == jaxbLink.params) { return true; } if (params == null) { // if this.params is 'null', consider other.params equal to empty return jaxbLink.params.isEmpty(); } if (jaxbLink.params == null) { // if other.params is 'null', consider this.params equal to empty return params.isEmpty(); } return params.equals(jaxbLink.params); } @Override public int hashCode() { int result = uri != null ? uri.hashCode() : 0; result = 31 * result + (params != null && !params.isEmpty() ? params.hashCode() : 0); return result; } } /** * An implementation of JAXB {@link javax.xml.bind.annotation.adapters.XmlAdapter} * that maps the JAX-RS {@link javax.ws.rs.core.Link} type to a value that can be * marshalled and unmarshalled by JAXB. The following example shows how to use * this adapter on a JAXB bean class: * *
     * @XmlRootElement
     * public class MyModel {
     *
     *   private Link link;
     *
     *   @XmlElement(name="link")
     *   @XmlJavaTypeAdapter(JaxbAdapter.class)
     *   public Link getLink() {
     *     return link;
     *   }
     *   ...
     * }
     * 
* * @see javax.ws.rs.core.Link.JaxbLink * @since 2.0 */ public static class JaxbAdapter extends XmlAdapter { /** * Convert a {@link JaxbLink} into a {@link Link}. * * @param v instance of type {@link JaxbLink}. * @return mapped instance of type {@link JaxbLink} */ @Override public Link unmarshal(JaxbLink v) { Link.Builder lb = Link.fromUri(v.getUri()); for (Entry e : v.getParams().entrySet()) { lb.param(e.getKey().getLocalPart(), e.getValue().toString()); } return lb.build(); } /** * Convert a {@link Link} into a {@link JaxbLink}. * * @param v instance of type {@link Link}. * @return mapped instance of type {@link JaxbLink}. */ @Override public JaxbLink marshal(Link v) { JaxbLink jl = new JaxbLink(v.getUri()); for (Entry e : v.getParams().entrySet()) { final String name = e.getKey(); jl.getParams().put(new QName("", name), e.getValue()); } return jl; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy