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

com.io7m.jwheatsheaf.api.JWFileChooserConfiguration Maven / Gradle / Ivy

There is a newer version: 4.0.0
Show newest version
package com.io7m.jwheatsheaf.api;

import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * The configuration information used to instantiate file choosers.
 * File choosers have a wide range of configurable properties. The only
 * mandatory configuration parameter is the {@link #fileSystem()}, because
 * this defines the initial filesystem used for file selection.
 */
@SuppressWarnings({"all"})
public final class JWFileChooserConfiguration
    implements JWFileChooserConfigurationType {
  private final List recentFiles;
  private final FileSystem fileSystem;
  private final Path initialDirectory;
  private final JWFileImageSetType fileImageSet;
  private final URL cssStylesheet;
  private final List fileFilters;
  private final boolean allowDirectoryCreation;
  private final DateTimeFormatter fileTimeFormatter;
  private final JWFileSizeFormatterType fileSizeFormatter;
  private final JWFileChooserAction action;

  private JWFileChooserConfiguration(JWFileChooserConfiguration.Builder builder) {
    this.recentFiles = createUnmodifiableList(true, builder.recentFiles);
    this.fileSystem = builder.fileSystem;
    this.initialDirectory = builder.initialDirectory;
    this.fileImageSet = builder.fileImageSet;
    this.cssStylesheet = builder.cssStylesheet;
    this.fileFilters = createUnmodifiableList(true, builder.fileFilters);
    if (builder.allowDirectoryCreationIsSet()) {
      initShim.setAllowDirectoryCreation(builder.allowDirectoryCreation);
    }
    if (builder.fileTimeFormatter != null) {
      initShim.setFileTimeFormatter(builder.fileTimeFormatter);
    }
    if (builder.fileSizeFormatter != null) {
      initShim.setFileSizeFormatter(builder.fileSizeFormatter);
    }
    if (builder.action != null) {
      initShim.setAction(builder.action);
    }
    this.allowDirectoryCreation = initShim.allowDirectoryCreation();
    this.fileTimeFormatter = initShim.fileTimeFormatter();
    this.fileSizeFormatter = initShim.fileSizeFormatter();
    this.action = initShim.action();
    this.initShim = null;
  }

  private JWFileChooserConfiguration(
      List recentFiles,
      FileSystem fileSystem,
      Path initialDirectory,
      JWFileImageSetType fileImageSet,
      URL cssStylesheet,
      List fileFilters,
      boolean allowDirectoryCreation,
      DateTimeFormatter fileTimeFormatter,
      JWFileSizeFormatterType fileSizeFormatter,
      JWFileChooserAction action) {
    this.recentFiles = recentFiles;
    this.fileSystem = fileSystem;
    this.initialDirectory = initialDirectory;
    this.fileImageSet = fileImageSet;
    this.cssStylesheet = cssStylesheet;
    this.fileFilters = fileFilters;
    this.allowDirectoryCreation = allowDirectoryCreation;
    this.fileTimeFormatter = fileTimeFormatter;
    this.fileSizeFormatter = fileSizeFormatter;
    this.action = action;
    this.initShim = null;
  }

  private static final byte STAGE_INITIALIZING = -1;
  private static final byte STAGE_UNINITIALIZED = 0;
  private static final byte STAGE_INITIALIZED = 1;
  private transient volatile InitShim initShim = new InitShim();

  private final class InitShim {
    private byte allowDirectoryCreationBuildStage = STAGE_UNINITIALIZED;
    private boolean allowDirectoryCreation;

    boolean allowDirectoryCreation() {
      if (allowDirectoryCreationBuildStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage());
      if (allowDirectoryCreationBuildStage == STAGE_UNINITIALIZED) {
        allowDirectoryCreationBuildStage = STAGE_INITIALIZING;
        this.allowDirectoryCreation = allowDirectoryCreationInitialize();
        allowDirectoryCreationBuildStage = STAGE_INITIALIZED;
      }
      return this.allowDirectoryCreation;
    }

    void setAllowDirectoryCreation(boolean allowDirectoryCreation) {
      this.allowDirectoryCreation = allowDirectoryCreation;
      allowDirectoryCreationBuildStage = STAGE_INITIALIZED;
    }

    private byte fileTimeFormatterBuildStage = STAGE_UNINITIALIZED;
    private DateTimeFormatter fileTimeFormatter;

    DateTimeFormatter fileTimeFormatter() {
      if (fileTimeFormatterBuildStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage());
      if (fileTimeFormatterBuildStage == STAGE_UNINITIALIZED) {
        fileTimeFormatterBuildStage = STAGE_INITIALIZING;
        this.fileTimeFormatter = Objects.requireNonNull(fileTimeFormatterInitialize(), "fileTimeFormatter");
        fileTimeFormatterBuildStage = STAGE_INITIALIZED;
      }
      return this.fileTimeFormatter;
    }

    void setFileTimeFormatter(DateTimeFormatter fileTimeFormatter) {
      this.fileTimeFormatter = fileTimeFormatter;
      fileTimeFormatterBuildStage = STAGE_INITIALIZED;
    }

    private byte fileSizeFormatterBuildStage = STAGE_UNINITIALIZED;
    private JWFileSizeFormatterType fileSizeFormatter;

    JWFileSizeFormatterType fileSizeFormatter() {
      if (fileSizeFormatterBuildStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage());
      if (fileSizeFormatterBuildStage == STAGE_UNINITIALIZED) {
        fileSizeFormatterBuildStage = STAGE_INITIALIZING;
        this.fileSizeFormatter = Objects.requireNonNull(fileSizeFormatterInitialize(), "fileSizeFormatter");
        fileSizeFormatterBuildStage = STAGE_INITIALIZED;
      }
      return this.fileSizeFormatter;
    }

    void setFileSizeFormatter(JWFileSizeFormatterType fileSizeFormatter) {
      this.fileSizeFormatter = fileSizeFormatter;
      fileSizeFormatterBuildStage = STAGE_INITIALIZED;
    }

    private byte actionBuildStage = STAGE_UNINITIALIZED;
    private JWFileChooserAction action;

    JWFileChooserAction action() {
      if (actionBuildStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage());
      if (actionBuildStage == STAGE_UNINITIALIZED) {
        actionBuildStage = STAGE_INITIALIZING;
        this.action = Objects.requireNonNull(actionInitialize(), "action");
        actionBuildStage = STAGE_INITIALIZED;
      }
      return this.action;
    }

    void setAction(JWFileChooserAction action) {
      this.action = action;
      actionBuildStage = STAGE_INITIALIZED;
    }

    private String formatInitCycleMessage() {
      List attributes = new ArrayList<>();
      if (allowDirectoryCreationBuildStage == STAGE_INITIALIZING) attributes.add("allowDirectoryCreation");
      if (fileTimeFormatterBuildStage == STAGE_INITIALIZING) attributes.add("fileTimeFormatter");
      if (fileSizeFormatterBuildStage == STAGE_INITIALIZING) attributes.add("fileSizeFormatter");
      if (actionBuildStage == STAGE_INITIALIZING) attributes.add("action");
      return "Cannot build JWFileChooserConfiguration, attribute initializers form cycle " + attributes;
    }
  }

  private boolean allowDirectoryCreationInitialize() {
    return JWFileChooserConfigurationType.super.allowDirectoryCreation();
  }

  private DateTimeFormatter fileTimeFormatterInitialize() {
    return JWFileChooserConfigurationType.super.fileTimeFormatter();
  }

  private JWFileSizeFormatterType fileSizeFormatterInitialize() {
    return JWFileChooserConfigurationType.super.fileSizeFormatter();
  }

  private JWFileChooserAction actionInitialize() {
    return JWFileChooserConfigurationType.super.action();
  }

  /**
   * @return The list of recent files to be shown in the file chooser
   */
  @Override
  public List recentFiles() {
    return recentFiles;
  }

  /**
   * @return The file system traversed by the file chooser
   */
  @Override
  public FileSystem fileSystem() {
    return fileSystem;
  }

  /**
   * @return The starting directory
   */
  @Override
  public Optional initialDirectory() {
    return Optional.ofNullable(initialDirectory);
  }

  /**
   * The image set used to select images for the file chooser UI. If no
   * set is specified here, a default set of images and icons will be used.
   * @return An image set
   */
  @Override
  public Optional fileImageSet() {
    return Optional.ofNullable(fileImageSet);
  }

  /**
   * The CSS stylesheet that will be added to the file chooser UI.
   * @return The URL of the CSS stylesheet
   */
  @Override
  public Optional cssStylesheet() {
    return Optional.ofNullable(cssStylesheet);
  }

  /**
   * @return The list of file filters
   */
  @Override
  public List fileFilters() {
    return fileFilters;
  }

  /**
   * @return {@code true} if the UI will allow the creation of directories
   */
  @Override
  public boolean allowDirectoryCreation() {
    InitShim shim = this.initShim;
    return shim != null
        ? shim.allowDirectoryCreation()
        : this.allowDirectoryCreation;
  }

  /**
   * @return The date/time formatter used to display file times
   */
  @Override
  public DateTimeFormatter fileTimeFormatter() {
    InitShim shim = this.initShim;
    return shim != null
        ? shim.fileTimeFormatter()
        : this.fileTimeFormatter;
  }

  /**
   * @return The formatter used to display file sizes
   */
  @Override
  public JWFileSizeFormatterType fileSizeFormatter() {
    InitShim shim = this.initShim;
    return shim != null
        ? shim.fileSizeFormatter()
        : this.fileSizeFormatter;
  }

  /**
   * @return The action that the user is performing
   */
  @Override
  public JWFileChooserAction action() {
    InitShim shim = this.initShim;
    return shim != null
        ? shim.action()
        : this.action;
  }

  /**
   * Copy the current immutable object with elements that replace the content of {@link JWFileChooserConfigurationType#recentFiles() recentFiles}.
   * @param elements The elements to set
   * @return A modified copy of {@code this} object
   */
  public final JWFileChooserConfiguration withRecentFiles(Path... elements) {
    List newValue = createUnmodifiableList(false, createSafeList(Arrays.asList(elements), true, false));
    return validate(new JWFileChooserConfiguration(
        newValue,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object with elements that replace the content of {@link JWFileChooserConfigurationType#recentFiles() recentFiles}.
   * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
   * @param elements An iterable of recentFiles elements to set
   * @return A modified copy of {@code this} object
   */
  public final JWFileChooserConfiguration withRecentFiles(Iterable elements) {
    if (this.recentFiles == elements) return this;
    List newValue = createUnmodifiableList(false, createSafeList(elements, true, false));
    return validate(new JWFileChooserConfiguration(
        newValue,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting a value for the {@link JWFileChooserConfigurationType#fileSystem() fileSystem} attribute.
   * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for fileSystem
   * @return A modified copy of the {@code this} object
   */
  public final JWFileChooserConfiguration withFileSystem(FileSystem value) {
    if (this.fileSystem == value) return this;
    FileSystem newValue = Objects.requireNonNull(value, "fileSystem");
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        newValue,
        this.initialDirectory,
        this.fileImageSet,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting a present value for the optional {@link JWFileChooserConfigurationType#initialDirectory() initialDirectory} attribute.
   * @param value The value for initialDirectory
   * @return A modified copy of {@code this} object
   */
  public final JWFileChooserConfiguration withInitialDirectory(Path value) {
    Path newValue = Objects.requireNonNull(value, "initialDirectory");
    if (this.initialDirectory == newValue) return this;
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        newValue,
        this.fileImageSet,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting an optional value for the {@link JWFileChooserConfigurationType#initialDirectory() initialDirectory} attribute.
   * A shallow reference equality check is used on unboxed optional value to prevent copying of the same value by returning {@code this}.
   * @param optional A value for initialDirectory
   * @return A modified copy of {@code this} object
   */
  @SuppressWarnings("unchecked") // safe covariant cast
  public final JWFileChooserConfiguration withInitialDirectory(Optional optional) {
    Path value = optional.orElse(null);
    if (this.initialDirectory == value) return this;
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        value,
        this.fileImageSet,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting a present value for the optional {@link JWFileChooserConfigurationType#fileImageSet() fileImageSet} attribute.
   * @param value The value for fileImageSet
   * @return A modified copy of {@code this} object
   */
  public final JWFileChooserConfiguration withFileImageSet(JWFileImageSetType value) {
    JWFileImageSetType newValue = Objects.requireNonNull(value, "fileImageSet");
    if (this.fileImageSet == newValue) return this;
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        newValue,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting an optional value for the {@link JWFileChooserConfigurationType#fileImageSet() fileImageSet} attribute.
   * A shallow reference equality check is used on unboxed optional value to prevent copying of the same value by returning {@code this}.
   * @param optional A value for fileImageSet
   * @return A modified copy of {@code this} object
   */
  @SuppressWarnings("unchecked") // safe covariant cast
  public final JWFileChooserConfiguration withFileImageSet(Optional optional) {
    JWFileImageSetType value = optional.orElse(null);
    if (this.fileImageSet == value) return this;
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        value,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting a present value for the optional {@link JWFileChooserConfigurationType#cssStylesheet() cssStylesheet} attribute.
   * @param value The value for cssStylesheet
   * @return A modified copy of {@code this} object
   */
  public final JWFileChooserConfiguration withCssStylesheet(URL value) {
    URL newValue = Objects.requireNonNull(value, "cssStylesheet");
    if (this.cssStylesheet == newValue) return this;
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        newValue,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting an optional value for the {@link JWFileChooserConfigurationType#cssStylesheet() cssStylesheet} attribute.
   * A shallow reference equality check is used on unboxed optional value to prevent copying of the same value by returning {@code this}.
   * @param optional A value for cssStylesheet
   * @return A modified copy of {@code this} object
   */
  @SuppressWarnings("unchecked") // safe covariant cast
  public final JWFileChooserConfiguration withCssStylesheet(Optional optional) {
    URL value = optional.orElse(null);
    if (this.cssStylesheet == value) return this;
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        value,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object with elements that replace the content of {@link JWFileChooserConfigurationType#fileFilters() fileFilters}.
   * @param elements The elements to set
   * @return A modified copy of {@code this} object
   */
  public final JWFileChooserConfiguration withFileFilters(JWFileChooserFilterType... elements) {
    List newValue = createUnmodifiableList(false, createSafeList(Arrays.asList(elements), true, false));
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        this.cssStylesheet,
        newValue,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object with elements that replace the content of {@link JWFileChooserConfigurationType#fileFilters() fileFilters}.
   * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
   * @param elements An iterable of fileFilters elements to set
   * @return A modified copy of {@code this} object
   */
  public final JWFileChooserConfiguration withFileFilters(Iterable elements) {
    if (this.fileFilters == elements) return this;
    List newValue = createUnmodifiableList(false, createSafeList(elements, true, false));
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        this.cssStylesheet,
        newValue,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting a value for the {@link JWFileChooserConfigurationType#allowDirectoryCreation() allowDirectoryCreation} attribute.
   * A value equality check is used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for allowDirectoryCreation
   * @return A modified copy of the {@code this} object
   */
  public final JWFileChooserConfiguration withAllowDirectoryCreation(boolean value) {
    if (this.allowDirectoryCreation == value) return this;
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        this.cssStylesheet,
        this.fileFilters,
        value,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting a value for the {@link JWFileChooserConfigurationType#fileTimeFormatter() fileTimeFormatter} attribute.
   * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for fileTimeFormatter
   * @return A modified copy of the {@code this} object
   */
  public final JWFileChooserConfiguration withFileTimeFormatter(DateTimeFormatter value) {
    if (this.fileTimeFormatter == value) return this;
    DateTimeFormatter newValue = Objects.requireNonNull(value, "fileTimeFormatter");
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        newValue,
        this.fileSizeFormatter,
        this.action));
  }

  /**
   * Copy the current immutable object by setting a value for the {@link JWFileChooserConfigurationType#fileSizeFormatter() fileSizeFormatter} attribute.
   * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for fileSizeFormatter
   * @return A modified copy of the {@code this} object
   */
  public final JWFileChooserConfiguration withFileSizeFormatter(JWFileSizeFormatterType value) {
    if (this.fileSizeFormatter == value) return this;
    JWFileSizeFormatterType newValue = Objects.requireNonNull(value, "fileSizeFormatter");
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        newValue,
        this.action));
  }

  /**
   * Copy the current immutable object by setting a value for the {@link JWFileChooserConfigurationType#action() action} attribute.
   * A value equality check is used to prevent copying of the same value by returning {@code this}.
   * @param value A new value for action
   * @return A modified copy of the {@code this} object
   */
  public final JWFileChooserConfiguration withAction(JWFileChooserAction value) {
    if (this.action == value) return this;
    JWFileChooserAction newValue = Objects.requireNonNull(value, "action");
    if (this.action.equals(newValue)) return this;
    return validate(new JWFileChooserConfiguration(
        this.recentFiles,
        this.fileSystem,
        this.initialDirectory,
        this.fileImageSet,
        this.cssStylesheet,
        this.fileFilters,
        this.allowDirectoryCreation,
        this.fileTimeFormatter,
        this.fileSizeFormatter,
        newValue));
  }

  /**
   * This instance is equal to all instances of {@code JWFileChooserConfiguration} that have equal attribute values.
   * @return {@code true} if {@code this} is equal to {@code another} instance
   */
  @Override
  public boolean equals(Object another) {
    if (this == another) return true;
    return another instanceof JWFileChooserConfiguration
        && equalTo((JWFileChooserConfiguration) another);
  }

  private boolean equalTo(JWFileChooserConfiguration another) {
    return recentFiles.equals(another.recentFiles)
        && fileSystem.equals(another.fileSystem)
        && Objects.equals(initialDirectory, another.initialDirectory)
        && Objects.equals(fileImageSet, another.fileImageSet)
        && Objects.equals(cssStylesheet, another.cssStylesheet)
        && fileFilters.equals(another.fileFilters)
        && allowDirectoryCreation == another.allowDirectoryCreation
        && fileTimeFormatter.equals(another.fileTimeFormatter)
        && fileSizeFormatter.equals(another.fileSizeFormatter)
        && action.equals(another.action);
  }

  /**
   * Computes a hash code from attributes: {@code recentFiles}, {@code fileSystem}, {@code initialDirectory}, {@code fileImageSet}, {@code cssStylesheet}, {@code fileFilters}, {@code allowDirectoryCreation}, {@code fileTimeFormatter}, {@code fileSizeFormatter}, {@code action}.
   * @return hashCode value
   */
  @Override
  public int hashCode() {
    int h = 5381;
    h += (h << 5) + recentFiles.hashCode();
    h += (h << 5) + fileSystem.hashCode();
    h += (h << 5) + Objects.hashCode(initialDirectory);
    h += (h << 5) + Objects.hashCode(fileImageSet);
    h += (h << 5) + Objects.hashCode(cssStylesheet);
    h += (h << 5) + fileFilters.hashCode();
    h += (h << 5) + Boolean.hashCode(allowDirectoryCreation);
    h += (h << 5) + fileTimeFormatter.hashCode();
    h += (h << 5) + fileSizeFormatter.hashCode();
    h += (h << 5) + action.hashCode();
    return h;
  }

  /**
   * Prints the immutable value {@code JWFileChooserConfiguration} with attribute values.
   * @return A string representation of the value
   */
  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder("JWFileChooserConfiguration{");
    builder.append("recentFiles=").append(recentFiles);
    builder.append(", ");
    builder.append("fileSystem=").append(fileSystem);
    if (initialDirectory != null) {
      builder.append(", ");
      builder.append("initialDirectory=").append(initialDirectory);
    }
    if (fileImageSet != null) {
      builder.append(", ");
      builder.append("fileImageSet=").append(fileImageSet);
    }
    if (cssStylesheet != null) {
      builder.append(", ");
      builder.append("cssStylesheet=").append(cssStylesheet);
    }
    builder.append(", ");
    builder.append("fileFilters=").append(fileFilters);
    builder.append(", ");
    builder.append("allowDirectoryCreation=").append(allowDirectoryCreation);
    builder.append(", ");
    builder.append("fileTimeFormatter=").append(fileTimeFormatter);
    builder.append(", ");
    builder.append("fileSizeFormatter=").append(fileSizeFormatter);
    builder.append(", ");
    builder.append("action=").append(action);
    return builder.append("}").toString();
  }

  private static JWFileChooserConfiguration validate(JWFileChooserConfiguration instance) {
    instance.checkPreconditions();
    return instance;
  }

  /**
   * Creates an immutable copy of a {@link JWFileChooserConfigurationType} value.
   * Uses accessors to get values to initialize the new immutable instance.
   * If an instance is already immutable, it is returned as is.
   * @param instance The instance to copy
   * @return A copied immutable JWFileChooserConfiguration instance
   */
  public static JWFileChooserConfiguration copyOf(JWFileChooserConfigurationType instance) {
    if (instance instanceof JWFileChooserConfiguration) {
      return (JWFileChooserConfiguration) instance;
    }
    return JWFileChooserConfiguration.builder()
        .from(instance)
        .build();
  }

  /**
   * Creates a builder for {@link JWFileChooserConfiguration JWFileChooserConfiguration}.
   * 
   * JWFileChooserConfiguration.builder()
   *    .addRecentFiles|addAllRecentFiles(java.nio.file.Path) // {@link JWFileChooserConfigurationType#recentFiles() recentFiles} elements
   *    .setFileSystem(java.nio.file.FileSystem) // required {@link JWFileChooserConfigurationType#fileSystem() fileSystem}
   *    .setInitialDirectory(java.nio.file.Path) // optional {@link JWFileChooserConfigurationType#initialDirectory() initialDirectory}
   *    .setFileImageSet(com.io7m.jwheatsheaf.api.JWFileImageSetType) // optional {@link JWFileChooserConfigurationType#fileImageSet() fileImageSet}
   *    .setCssStylesheet(java.net.URL) // optional {@link JWFileChooserConfigurationType#cssStylesheet() cssStylesheet}
   *    .addFileFilters|addAllFileFilters(com.io7m.jwheatsheaf.api.JWFileChooserFilterType) // {@link JWFileChooserConfigurationType#fileFilters() fileFilters} elements
   *    .setAllowDirectoryCreation(boolean) // optional {@link JWFileChooserConfigurationType#allowDirectoryCreation() allowDirectoryCreation}
   *    .setFileTimeFormatter(java.time.format.DateTimeFormatter) // optional {@link JWFileChooserConfigurationType#fileTimeFormatter() fileTimeFormatter}
   *    .setFileSizeFormatter(com.io7m.jwheatsheaf.api.JWFileSizeFormatterType) // optional {@link JWFileChooserConfigurationType#fileSizeFormatter() fileSizeFormatter}
   *    .setAction(com.io7m.jwheatsheaf.api.JWFileChooserAction) // optional {@link JWFileChooserConfigurationType#action() action}
   *    .build();
   * 
* @return A new JWFileChooserConfiguration builder */ public static JWFileChooserConfiguration.Builder builder() { return new JWFileChooserConfiguration.Builder(); } /** * Builds instances of type {@link JWFileChooserConfiguration JWFileChooserConfiguration}. * Initialize attributes and then invoke the {@link #build()} method to create an * immutable instance. *

{@code Builder} is not thread-safe and generally should not be stored in a field or collection, * but instead used immediately to create instances. */ public static final class Builder { private static final long INIT_BIT_FILE_SYSTEM = 0x1L; private static final long OPT_BIT_ALLOW_DIRECTORY_CREATION = 0x1L; private long initBits = 0x1L; private long optBits; private List recentFiles = new ArrayList(); private FileSystem fileSystem; private Path initialDirectory; private JWFileImageSetType fileImageSet; private URL cssStylesheet; private List fileFilters = new ArrayList(); private boolean allowDirectoryCreation; private DateTimeFormatter fileTimeFormatter; private JWFileSizeFormatterType fileSizeFormatter; private JWFileChooserAction action; private Builder() { } /** * Fill a builder with attribute values from the provided {@code JWFileChooserConfigurationType} instance. * Regular attribute values will be replaced with those from the given instance. * Absent optional values will not replace present values. * Collection elements and entries will be added, not replaced. * @param instance The instance from which to copy values * @return {@code this} builder for use in a chained invocation */ public final Builder from(JWFileChooserConfigurationType instance) { Objects.requireNonNull(instance, "instance"); addAllRecentFiles(instance.recentFiles()); setFileSystem(instance.fileSystem()); Optional initialDirectoryOptional = instance.initialDirectory(); if (initialDirectoryOptional.isPresent()) { setInitialDirectory(initialDirectoryOptional); } Optional fileImageSetOptional = instance.fileImageSet(); if (fileImageSetOptional.isPresent()) { setFileImageSet(fileImageSetOptional); } Optional cssStylesheetOptional = instance.cssStylesheet(); if (cssStylesheetOptional.isPresent()) { setCssStylesheet(cssStylesheetOptional); } addAllFileFilters(instance.fileFilters()); setAllowDirectoryCreation(instance.allowDirectoryCreation()); setFileTimeFormatter(instance.fileTimeFormatter()); setFileSizeFormatter(instance.fileSizeFormatter()); setAction(instance.action()); return this; } /** * Adds one element to {@link JWFileChooserConfigurationType#recentFiles() recentFiles} list. * @param element A recentFiles element * @return {@code this} builder for use in a chained invocation */ public final Builder addRecentFiles(Path element) { this.recentFiles.add(Objects.requireNonNull(element, "recentFiles element")); return this; } /** * Adds elements to {@link JWFileChooserConfigurationType#recentFiles() recentFiles} list. * @param elements An array of recentFiles elements * @return {@code this} builder for use in a chained invocation */ public final Builder addRecentFiles(Path... elements) { for (Path element : elements) { this.recentFiles.add(Objects.requireNonNull(element, "recentFiles element")); } return this; } /** * Sets or replaces all elements for {@link JWFileChooserConfigurationType#recentFiles() recentFiles} list. * @param elements An iterable of recentFiles elements * @return {@code this} builder for use in a chained invocation */ public final Builder setRecentFiles(Iterable elements) { this.recentFiles.clear(); return addAllRecentFiles(elements); } /** * Adds elements to {@link JWFileChooserConfigurationType#recentFiles() recentFiles} list. * @param elements An iterable of recentFiles elements * @return {@code this} builder for use in a chained invocation */ public final Builder addAllRecentFiles(Iterable elements) { for (Path element : elements) { this.recentFiles.add(Objects.requireNonNull(element, "recentFiles element")); } return this; } /** * Initializes the value for the {@link JWFileChooserConfigurationType#fileSystem() fileSystem} attribute. * @param fileSystem The value for fileSystem * @return {@code this} builder for use in a chained invocation */ public final Builder setFileSystem(FileSystem fileSystem) { this.fileSystem = Objects.requireNonNull(fileSystem, "fileSystem"); initBits &= ~INIT_BIT_FILE_SYSTEM; return this; } /** * Initializes the optional value {@link JWFileChooserConfigurationType#initialDirectory() initialDirectory} to initialDirectory. * @param initialDirectory The value for initialDirectory * @return {@code this} builder for chained invocation */ public final Builder setInitialDirectory(Path initialDirectory) { this.initialDirectory = Objects.requireNonNull(initialDirectory, "initialDirectory"); return this; } /** * Initializes the optional value {@link JWFileChooserConfigurationType#initialDirectory() initialDirectory} to initialDirectory. * @param initialDirectory The value for initialDirectory * @return {@code this} builder for use in a chained invocation */ public final Builder setInitialDirectory(Optional initialDirectory) { this.initialDirectory = initialDirectory.orElse(null); return this; } /** * Initializes the optional value {@link JWFileChooserConfigurationType#fileImageSet() fileImageSet} to fileImageSet. * @param fileImageSet The value for fileImageSet * @return {@code this} builder for chained invocation */ public final Builder setFileImageSet(JWFileImageSetType fileImageSet) { this.fileImageSet = Objects.requireNonNull(fileImageSet, "fileImageSet"); return this; } /** * Initializes the optional value {@link JWFileChooserConfigurationType#fileImageSet() fileImageSet} to fileImageSet. * @param fileImageSet The value for fileImageSet * @return {@code this} builder for use in a chained invocation */ public final Builder setFileImageSet(Optional fileImageSet) { this.fileImageSet = fileImageSet.orElse(null); return this; } /** * Initializes the optional value {@link JWFileChooserConfigurationType#cssStylesheet() cssStylesheet} to cssStylesheet. * @param cssStylesheet The value for cssStylesheet * @return {@code this} builder for chained invocation */ public final Builder setCssStylesheet(URL cssStylesheet) { this.cssStylesheet = Objects.requireNonNull(cssStylesheet, "cssStylesheet"); return this; } /** * Initializes the optional value {@link JWFileChooserConfigurationType#cssStylesheet() cssStylesheet} to cssStylesheet. * @param cssStylesheet The value for cssStylesheet * @return {@code this} builder for use in a chained invocation */ public final Builder setCssStylesheet(Optional cssStylesheet) { this.cssStylesheet = cssStylesheet.orElse(null); return this; } /** * Adds one element to {@link JWFileChooserConfigurationType#fileFilters() fileFilters} list. * @param element A fileFilters element * @return {@code this} builder for use in a chained invocation */ public final Builder addFileFilters(JWFileChooserFilterType element) { this.fileFilters.add(Objects.requireNonNull(element, "fileFilters element")); return this; } /** * Adds elements to {@link JWFileChooserConfigurationType#fileFilters() fileFilters} list. * @param elements An array of fileFilters elements * @return {@code this} builder for use in a chained invocation */ public final Builder addFileFilters(JWFileChooserFilterType... elements) { for (JWFileChooserFilterType element : elements) { this.fileFilters.add(Objects.requireNonNull(element, "fileFilters element")); } return this; } /** * Sets or replaces all elements for {@link JWFileChooserConfigurationType#fileFilters() fileFilters} list. * @param elements An iterable of fileFilters elements * @return {@code this} builder for use in a chained invocation */ public final Builder setFileFilters(Iterable elements) { this.fileFilters.clear(); return addAllFileFilters(elements); } /** * Adds elements to {@link JWFileChooserConfigurationType#fileFilters() fileFilters} list. * @param elements An iterable of fileFilters elements * @return {@code this} builder for use in a chained invocation */ public final Builder addAllFileFilters(Iterable elements) { for (JWFileChooserFilterType element : elements) { this.fileFilters.add(Objects.requireNonNull(element, "fileFilters element")); } return this; } /** * Initializes the value for the {@link JWFileChooserConfigurationType#allowDirectoryCreation() allowDirectoryCreation} attribute. *

If not set, this attribute will have a default value as returned by the initializer of {@link JWFileChooserConfigurationType#allowDirectoryCreation() allowDirectoryCreation}. * @param allowDirectoryCreation The value for allowDirectoryCreation * @return {@code this} builder for use in a chained invocation */ public final Builder setAllowDirectoryCreation(boolean allowDirectoryCreation) { this.allowDirectoryCreation = allowDirectoryCreation; optBits |= OPT_BIT_ALLOW_DIRECTORY_CREATION; return this; } /** * Initializes the value for the {@link JWFileChooserConfigurationType#fileTimeFormatter() fileTimeFormatter} attribute. *

If not set, this attribute will have a default value as returned by the initializer of {@link JWFileChooserConfigurationType#fileTimeFormatter() fileTimeFormatter}. * @param fileTimeFormatter The value for fileTimeFormatter * @return {@code this} builder for use in a chained invocation */ public final Builder setFileTimeFormatter(DateTimeFormatter fileTimeFormatter) { this.fileTimeFormatter = Objects.requireNonNull(fileTimeFormatter, "fileTimeFormatter"); return this; } /** * Initializes the value for the {@link JWFileChooserConfigurationType#fileSizeFormatter() fileSizeFormatter} attribute. *

If not set, this attribute will have a default value as returned by the initializer of {@link JWFileChooserConfigurationType#fileSizeFormatter() fileSizeFormatter}. * @param fileSizeFormatter The value for fileSizeFormatter * @return {@code this} builder for use in a chained invocation */ public final Builder setFileSizeFormatter(JWFileSizeFormatterType fileSizeFormatter) { this.fileSizeFormatter = Objects.requireNonNull(fileSizeFormatter, "fileSizeFormatter"); return this; } /** * Initializes the value for the {@link JWFileChooserConfigurationType#action() action} attribute. *

If not set, this attribute will have a default value as returned by the initializer of {@link JWFileChooserConfigurationType#action() action}. * @param action The value for action * @return {@code this} builder for use in a chained invocation */ public final Builder setAction(JWFileChooserAction action) { this.action = Objects.requireNonNull(action, "action"); return this; } /** * Builds a new {@link JWFileChooserConfiguration JWFileChooserConfiguration}. * @return An immutable instance of JWFileChooserConfiguration * @throws java.lang.IllegalStateException if any required attributes are missing */ public JWFileChooserConfiguration build() { if (initBits != 0) { throw new IllegalStateException(formatRequiredAttributesMessage()); } return JWFileChooserConfiguration.validate(new JWFileChooserConfiguration(this)); } private boolean allowDirectoryCreationIsSet() { return (optBits & OPT_BIT_ALLOW_DIRECTORY_CREATION) != 0; } private String formatRequiredAttributesMessage() { List attributes = new ArrayList<>(); if ((initBits & INIT_BIT_FILE_SYSTEM) != 0) attributes.add("fileSystem"); return "Cannot build JWFileChooserConfiguration, some of required attributes are not set " + attributes; } } private static List createSafeList(Iterable iterable, boolean checkNulls, boolean skipNulls) { ArrayList list; if (iterable instanceof Collection) { int size = ((Collection) iterable).size(); if (size == 0) return Collections.emptyList(); list = new ArrayList<>(); } else { list = new ArrayList<>(); } for (T element : iterable) { if (skipNulls && element == null) continue; if (checkNulls) Objects.requireNonNull(element, "element"); list.add(element); } return list; } private static List createUnmodifiableList(boolean clone, List list) { switch(list.size()) { case 0: return Collections.emptyList(); case 1: return Collections.singletonList(list.get(0)); default: if (clone) { return Collections.unmodifiableList(new ArrayList<>(list)); } else { if (list instanceof ArrayList) { ((ArrayList) list).trimToSize(); } return Collections.unmodifiableList(list); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy