io.spring.initializr.metadata.Link.java Source code

Java tutorial

Introduction

Here is the source code for io.spring.initializr.metadata.Link.java

Source

/*
 * 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);
    }

}