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

org.openqa.selenium.docker.internal.Reference Maven / Gradle / Ivy

// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you 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 org.openqa.selenium.docker.internal;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.Beta;
import org.openqa.selenium.docker.DockerException;
import org.openqa.selenium.internal.Require;

import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Beta
public class Reference {

  private static final String DEFAULT_DOMAIN = "docker.io";
  private static final String DEFAULT_REPO = "library";
  private static final String DEFAULT_TAG = "latest";

  // Capturing groups used in patterns below
  private static final String DOMAIN = "([\\w\\d-_.]+?(:(\\d+))?)";
  private static final String REPO = "([\\w\\d-_.]+?)";
  private static final String NAME = "([\\w\\d-_.]+?)";
  private static final String TAG = "([\\w\\d-_.]+?)";
  private static final String DIGEST = "(sha256:[A-Fa-f0-9]{64})";

  // name -> {domain: "docker.io", repository: "repository", name: name, tag: "latest", digest: null}
  // name:tag -> {domain: "docker.io", repository: "repository", name: name, tag: tag, digest: null}
  // name@digest -> {domain: "docker.io", repository: "repository", name: name, tag: null, digest: digest}
  // repository/name -> {domain: "docker.io", repository: repository, name: name, tag: "latest", digest: null}
  // repository/name:tag -> {domain: "docker.io", repository: repository, name: name, tag: tag, digest: null}
  // repository/name@digest -> {domain: "docker.io", repository: repository, name: name, tag: null, digest: digest}
  // domain/repository/name:tag -> {domain: "domain", repository: repository, name: name, tag: tag, digest: null}
  // domain:port/repository/name@digest -> {domain: "domain:port", repository: repository, name: name, tag: tag, digest: null}
  private static final Map> PATTERNS = ImmutableMap.>builder()
    .put(Pattern.compile(TAG), m -> new Reference(DEFAULT_DOMAIN, DEFAULT_REPO, m.group(1), DEFAULT_TAG, null))
    .put(Pattern.compile(String.format("%s:%s", NAME, TAG)), m -> new Reference(DEFAULT_DOMAIN, DEFAULT_REPO, m.group(1), m.group(2), null))
    .put(Pattern.compile(String.format("%s/%s", REPO, NAME)), m -> new Reference(DEFAULT_DOMAIN, m.group(1), m.group(2), DEFAULT_TAG, null))
    .put(Pattern.compile(String.format("%s@%s", NAME, DIGEST)), m -> new Reference(DEFAULT_DOMAIN, DEFAULT_REPO, m.group(1), null, m.group(2)))
    .put(Pattern.compile(String.format("%s/%s:%s", REPO, NAME, TAG)), m -> new Reference(DEFAULT_DOMAIN, m.group(1), m.group(2), m.group(3), null))
    .put(Pattern.compile(String.format("%s/%s@%s", REPO, NAME, DIGEST)), m -> new Reference(DEFAULT_DOMAIN, m.group(1), m.group(2), null, m.group(3)))
    .put(Pattern.compile(String.format("%s/%s/%s", DOMAIN, REPO, NAME)), m -> new Reference(m.group(1), m.group(4), m.group(5), DEFAULT_TAG, null))
    .put(Pattern.compile(String.format("%s/%s/%s:%s", DOMAIN, REPO, NAME, TAG)), m -> new Reference(m.group(1), m.group(4), m.group(5), m.group(6), null))
    .build();

  private final String domain;
  private final String repository;
  private final String name;
  private final String tag;
  private final String digest;

  @VisibleForTesting
  Reference(String domain, String repository, String name, String tag, String digest) {
    this.domain = Require.nonNull("Domain", domain);
    this.repository = Require.nonNull("Repository", repository);
    this.name = Require.nonNull("Name", name);
    this.tag = tag;
    this.digest = digest;
  }

  public String getDomain() {
    return domain;
  }

  public String getRepository() {
    return repository;
  }

  public String getName() {
    return name;
  }

  public String getTag() {
    return tag;
  }

  public String getDigest() {
    return digest;
  }

  public String getFamiliarName() {
    StringBuilder familiar = new StringBuilder();

    if (!DEFAULT_DOMAIN.equals(domain)) {
      familiar.append(domain).append("/");
    }

    if (!DEFAULT_REPO.equals(repository)) {
      familiar.append(repository).append("/");
    }

    familiar.append(name);

    if (digest != null) {
      familiar.append("@").append(digest);
    } else if (tag != null) {
      familiar.append(":").append(tag);
    } else {
      throw new DockerException("Unable to form familiar name: " + this);
    }

    return familiar.toString();
  }

  public static Reference parse(String input) {
    Require.nonNull("Reference to parse", input);

    for (Map.Entry> entry : PATTERNS.entrySet()) {
      Matcher matcher = entry.getKey().matcher(input);
      if (matcher.matches()) {
        return entry.getValue().apply(matcher);
      }
    }

    throw new DockerException("Unable to parse: " + input);
  }

  @Override
  public String toString() {
    return "Reference{" +
      "domain='" + domain + '\'' +
      ", repository='" + repository + '\'' +
      ", name='" + name + '\'' +
      ", tag='" + tag + '\'' +
      ", digest='" + digest + '\'' +
      '}';
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof Reference)) {
      return false;
    }

    Reference that = (Reference) o;
    return this.domain.equals(that.domain) &&
      this.repository.equals(that.repository) &&
      this.name.equals(that.name) &&
      Objects.equals(tag, that.tag) &&
      Objects.equals(digest, that.digest);
  }

  @Override
  public int hashCode() {
    return Objects.hash(domain, repository, name, tag, digest);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy