Java tutorial
/* * Copyright 2012-2017 the original author or authors. * * Licensed 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 io.spring.initializr.metadata; import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; /** * Metadata for a link. Each link has a "relation" that potentially attaches a strong * semantic to the nature of the link. The URI of the link itself can be templated by * including variables in the form `{variableName}`. * <p> * An actual {@code URI} can be generated using {@code expand}, providing a mapping for * those variables. * * @author Dave Syer * @author Stephane Nicoll */ public class Link { private static final Pattern VARIABLE_REGEX = Pattern.compile("\\{(\\w+)\\}"); /** * The relation of the link. */ private String rel; /** * The URI the link is pointing to. */ private String href; /** * Specify if the URI is templated. */ @JsonInclude(JsonInclude.Include.NON_DEFAULT) private boolean templated; @JsonIgnore private final Set<String> templateVariables = new LinkedHashSet<>(); /** * A description of the link. */ @JsonInclude(JsonInclude.Include.NON_NULL) private String description; public Link() { } private Link(String rel, String href) { this(rel, href, null); } private Link(String rel, String href, String description) { this.rel = rel; this.href = href; this.description = description; } private Link(String rel, String href, boolean templated) { this(rel, href); this.templated = templated; } public String getRel() { return rel; } public void setRel(String rel) { this.rel = rel; } public boolean isTemplated() { return templated; } public void setTemplated(boolean templated) { this.templated = templated; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getHref() { return href; } public Set<String> getTemplateVariables() { return Collections.unmodifiableSet(templateVariables); } public void setHref(String href) { this.href = href; } public void resolve() { if (rel == null) { throw new InvalidInitializrMetadataException("Invalid link " + this + ": rel attribute is mandatory"); } if (href == null) { throw new InvalidInitializrMetadataException("Invalid link " + this + ": href attribute is mandatory"); } Matcher matcher = VARIABLE_REGEX.matcher(href); while (matcher.find()) { String variable = matcher.group(1); this.templateVariables.add(variable); } this.templated = !this.templateVariables.isEmpty(); } /** * Expand the link using the specified parameters. * @param parameters the parameters value * @return an URI where all variables have been expanded */ public URI expand(Map<String, String> parameters) { AtomicReference<String> result = new AtomicReference<>(href); templateVariables.forEach(var -> { Object value = parameters.get(var); if (value == null) { throw new IllegalArgumentException( "Could not expand " + href + ", missing value for '" + var + "'"); } result.set(result.get().replace("{" + var + "}", value.toString())); }); try { return new URI(result.get()); } catch (URISyntaxException e) { throw new IllegalStateException("Invalid URL", e); } } public static Link create(String rel, String href) { return new Link(rel, href); } public static Link create(String rel, String href, String description) { return new Link(rel, href, description); } public static Link create(String rel, String href, boolean templated) { return new Link(rel, href, templated); } }