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

com.ionoscloud.s3.BaseArgs Maven / Gradle / Ivy

The newest version!
package com.ionoscloud.s3;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

/** Base argument class. */
public abstract class BaseArgs {
  protected Multimap extraHeaders =
      Multimaps.unmodifiableMultimap(HashMultimap.create());
  protected Multimap extraQueryParams =
      Multimaps.unmodifiableMultimap(HashMultimap.create());

  public Multimap extraHeaders() {
    return extraHeaders;
  }

  public Multimap extraQueryParams() {
    return extraQueryParams;
  }

  /** Base builder which builds arguments. */
  public abstract static class Builder, A extends BaseArgs> {
    protected List> operations;

    protected abstract void validate(A args);

    protected void validateNotNull(Object arg, String argName) {
      if (arg == null) {
        throw new IllegalArgumentException(argName + " must not be null.");
      }
    }

    protected void validateNotEmptyString(String arg, String argName) {
      validateNotNull(arg, argName);
      if (arg.isEmpty()) {
        throw new IllegalArgumentException(argName + " must be a non-empty string.");
      }
    }

    protected void validateNullOrNotEmptyString(String arg, String argName) {
      if (arg != null && arg.isEmpty()) {
        throw new IllegalArgumentException(argName + " must be a non-empty string.");
      }
    }

    protected void validateNullOrPositive(Number arg, String argName) {
      if (arg != null && arg.longValue() < 0) {
        throw new IllegalArgumentException(argName + " cannot be non-negative.");
      }
    }

    public Builder() {
      this.operations = new ArrayList<>();
    }

    protected Multimap copyMultimap(Multimap multimap) {
      Multimap multimapCopy = HashMultimap.create();
      if (multimap != null) {
        multimapCopy.putAll(multimap);
      }
      return Multimaps.unmodifiableMultimap(multimapCopy);
    }

    protected Multimap toMultimap(Map map) {
      Multimap multimap = HashMultimap.create();
      if (map != null) {
        multimap.putAll(Multimaps.forMap(map));
      }
      return Multimaps.unmodifiableMultimap(multimap);
    }

    @SuppressWarnings("unchecked") // Its safe to type cast to B as B extends this class.
    public B extraHeaders(Multimap headers) {
      final Multimap extraHeaders = copyMultimap(headers);
      operations.add(args -> args.extraHeaders = extraHeaders);
      return (B) this;
    }

    @SuppressWarnings("unchecked") // Its safe to type cast to B as B extends this class.
    public B extraQueryParams(Multimap queryParams) {
      final Multimap extraQueryParams = copyMultimap(queryParams);
      operations.add(args -> args.extraQueryParams = extraQueryParams);
      return (B) this;
    }

    @SuppressWarnings("unchecked") // Its safe to type cast to B as B extends this class.
    public B extraHeaders(Map headers) {
      final Multimap extraHeaders = toMultimap(headers);
      operations.add(args -> args.extraHeaders = extraHeaders);
      return (B) this;
    }

    @SuppressWarnings("unchecked") // Its safe to type cast to B as B extends this class.
    public B extraQueryParams(Map queryParams) {
      final Multimap extraQueryParams = toMultimap(queryParams);
      operations.add(args -> args.extraQueryParams = extraQueryParams);
      return (B) this;
    }

    @SuppressWarnings("unchecked") // safe as B will always be the builder of the current args class
    private A newInstance() {
      try {
        for (Constructor constructor :
            this.getClass().getEnclosingClass().getDeclaredConstructors()) {
          if (constructor.getParameterCount() == 0) {
            return (A) constructor.newInstance();
          }
        }

        throw new RuntimeException(
            this.getClass().getEnclosingClass() + " must have no argument constructor");
      } catch (InstantiationException
          | IllegalAccessException
          | InvocationTargetException
          | SecurityException e) {
        // Args class must have no argument constructor with at least protected access.
        throw new RuntimeException(e);
      }
    }

    /** Creates derived Args class with each attribute populated. */
    public A build() throws IllegalArgumentException {
      A args = newInstance();
      operations.forEach(operation -> operation.accept(args));
      validate(args);
      return args;
    }
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof BaseArgs)) return false;
    BaseArgs baseArgs = (BaseArgs) o;
    return Objects.equals(extraHeaders, baseArgs.extraHeaders)
        && Objects.equals(extraQueryParams, baseArgs.extraQueryParams);
  }

  @Override
  public int hashCode() {
    return Objects.hash(extraHeaders, extraQueryParams);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy