001/**
002 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
003 *   This file is part of the LDP4j Project:
004 *     http://www.ldp4j.org/
005 *
006 *   Center for Open Middleware
007 *     http://www.centeropenmiddleware.com/
008 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
009 *   Copyright (C) 2014-2016 Center for Open Middleware.
010 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
011 *   Licensed under the Apache License, Version 2.0 (the "License");
012 *   you may not use this file except in compliance with the License.
013 *   You may obtain a copy of the License at
014 *
015 *             http://www.apache.org/licenses/LICENSE-2.0
016 *
017 *   Unless required by applicable law or agreed to in writing, software
018 *   distributed under the License is distributed on an "AS IS" BASIS,
019 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020 *   See the License for the specific language governing permissions and
021 *   limitations under the License.
022 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
023 *   Artifact    : org.ldp4j.framework:ldp4j-application-api:0.2.1
024 *   Bundle      : ldp4j-application-api-0.2.1.jar
025 * #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
026 */
027package org.ldp4j.application.session;
028
029import java.net.URI;
030import java.util.Objects;
031
032import org.ldp4j.application.spi.ResourceSnapshotResolver;
033import org.ldp4j.application.spi.RuntimeDelegate;
034
035/**
036 * Utility class for resolving the endpoints (URI) where the resources managed
037 * by the LDP4j framework are published, and for discovering which resources are
038 * addressed by a given URI.
039 */
040public final class SnapshotResolver {
041
042  /**
043   * Builder class for creating {@code SnapshotResolver} instances.
044   */
045  public static final class Builder {
046
047    private ReadSession session;
048    private URI canonicalBase;
049
050    private Builder() {
051    }
052
053    /**
054     * Define the canonical base URI to be used for the resolution of
055     * endpoints.
056     *
057     * @param base
058     *            the canonical base URI.
059     * @return this builder.
060     */
061    public Builder withCanonicalBase(URI base) {
062      this.canonicalBase = base;
063      return this;
064    }
065
066    /**
067     * Define the session to be used for the resolution of resource
068     * snapshots.
069     *
070     * @param session
071     *            the session
072     * @return this builder.
073     */
074    public Builder withReadSession(ReadSession session) {
075      this.session = session;
076      return this;
077    }
078
079    /**
080     * Return a configured snapshot resolver instance.
081     *
082     * @return a configured snapshot resolver instance
083     * @throws NullPointerException
084     *             if the canonical base URI or the session are null.
085     * @throws IllegalArgumentException
086     *             if the canonical base URI is not hierarchical and
087     *             absolute.
088     */
089    public SnapshotResolver build() {
090      return
091        new SnapshotResolver(
092          RuntimeDelegate.
093            getInstance().
094              createResourceResolver(
095                getCanonicalBase(),
096                Objects.requireNonNull(this.session,"Session cannot be null")));
097    }
098
099    private URI getCanonicalBase() {
100      Objects.requireNonNull(this.canonicalBase,"Canonical base cannot be null");
101      if(this.canonicalBase.isOpaque()) {
102        throw new IllegalArgumentException("Canonical base '"+this.canonicalBase+"' is not hierarchical");
103      }
104      if(!this.canonicalBase.isAbsolute()) {
105        throw new IllegalArgumentException("Canonical base '"+this.canonicalBase+"' is not absolute");
106      }
107      return this.canonicalBase;
108    }
109
110  }
111
112  private final ResourceSnapshotResolver resolver;
113
114  private SnapshotResolver(ResourceSnapshotResolver resolver) {
115    this.resolver = resolver;
116  }
117
118  /**
119   * Return the URI used to publish a resource.
120   *
121   * @param snapshot
122   *            the snapshot of the resource that is to be resolved.
123   * @throws SnapshotResolutionException
124   *             if the snapshot cannot be resolved to a URI.
125   * @return the URI used to published the resource that represents the
126   *         snapshot.
127   */
128  public URI toURI(ResourceSnapshot snapshot) {
129    return this.resolver.resolve(snapshot);
130  }
131
132  /**
133   * Return a snapshot of the resource published at a given URI.
134   *
135   * @param endpoint
136   *            the URI that is to be resolved.
137   * @throws SnapshotResolutionException
138   *             if the URI cannot be resolved to a resource snapshot.
139   * @return a snapshot of the resource that is published at the specified
140   *         endpoint.
141   */
142  public ResourceSnapshot fromURI(URI endpoint) {
143    return this.resolver.resolve(endpoint);
144  }
145
146  /**
147   * Create a {@code Builder} instance.
148   * @return a {@code Builder} instance.
149   */
150  public static Builder builder() {
151    return new Builder();
152  }
153
154}