com.io7m.jwheatsheaf.api.JWFileChooserConfiguration Maven / Gradle / Ivy
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 extends Path> 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 extends Path> 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 extends JWFileImageSetType> 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 extends URL> 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 extends JWFileChooserFilterType> 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 extends Path> 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 extends Path> 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 extends Path> 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 extends JWFileImageSetType> 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 extends URL> 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 extends JWFileChooserFilterType> 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 extends JWFileChooserFilterType> 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 extends T> 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);
}
}
}
}