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

eu.binjr.common.preferences.ObservablePreferenceFactory Maven / Gradle / Ivy

There is a newer version: 3.20.1
Show newest version

/*
 *    Copyright 2019-2022 Frederic Thevenet
 *
 *    Licensed 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 eu.binjr.common.preferences;

import eu.binjr.common.logging.Logger;
import javafx.beans.property.*;

import java.net.URI;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import java.util.function.Function;
import java.util.prefs.Preferences;
import java.util.stream.Collectors;

/**
 * A factory to create and manage preferences exposed as {@link Property} and backed by {@link Preferences}
 *
 * @author Frederic Thevenet
 */
public class ObservablePreferenceFactory extends ReloadableItemStore> {
    private static final Logger logger = Logger.create(ObservablePreferenceFactory.class);

    public ObservablePreferenceFactory(String backingStoreKey) {
        super(backingStoreKey);
    }

    public ObservablePreference booleanPreference(String key, Boolean defaultValue) {
        var p = new ObservablePreference<>(Boolean.class, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(Boolean value) {
                return new SimpleBooleanProperty(value);
            }

            @Override
            protected Boolean loadFromBackend() {
                return getBackingStore().getBoolean(getKey(), getDefaultValue());
            }

            @Override
            protected void saveToBackend(Boolean value) {
                getBackingStore().putBoolean(getKey(), value);
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public ObservablePreference obfuscatedStringPreference(String key, String defaultValue) {
        var p = new ObservablePreference<>(ObfuscatedString.class, key, ObfuscatedString.of(defaultValue), backingStore) {
            @Override
            protected Property makeProperty(ObfuscatedString value) {
                return new SimpleObjectProperty<>(value);
            }

            @Override
            protected ObfuscatedString loadFromBackend() {
                return new ObfuscatedString(getBackingStore().get(getKey(), getDefaultValue().getObfuscated()));
            }

            @Override
            protected void saveToBackend(ObfuscatedString value) {
                getBackingStore().put(getKey(), value.getObfuscated());
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }


    public ObservablePreference stringPreference(String key, String defaultValue) {
        var p = new ObservablePreference<>(String.class, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(String value) {
                return new SimpleStringProperty(value);
            }

            @Override
            protected String loadFromBackend() {
                return getBackingStore().get(getKey(), getDefaultValue());
            }

            @Override
            protected void saveToBackend(String value) {
                getBackingStore().put(getKey(), value);
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public ObservablePreference integerPreference(String key, Integer defaultValue) {
        var p = new ObservablePreference<>(Number.class, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(Number value) {
                return new SimpleIntegerProperty(value.intValue());
            }

            @Override
            protected Integer loadFromBackend() {
                return getBackingStore().getInt(getKey(), getDefaultValue().intValue());
            }

            @Override
            protected void saveToBackend(Number value) {
                getBackingStore().putInt(getKey(), value.intValue());
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public ObservablePreference zoneDateTimePreference(String key, ZonedDateTime defaultValue) {
        var p = new ObservablePreference<>(ZonedDateTime.class, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(ZonedDateTime value) {
                return new SimpleObjectProperty<>(value);
            }

            @Override
            protected ZonedDateTime loadFromBackend() {
                return ZonedDateTime.parse(getBackingStore().get(getKey(),
                                getDefaultValue().format(DateTimeFormatter.ISO_ZONED_DATE_TIME)),
                        DateTimeFormatter.ISO_ZONED_DATE_TIME);
            }

            @Override
            protected void saveToBackend(ZonedDateTime value) {
                getBackingStore().put(getKey(), value.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public ObservablePreference localDateTimePreference(String key, LocalDateTime defaultValue) {
        var p = new ObservablePreference<>(LocalDateTime.class, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(LocalDateTime value) {
                return new SimpleObjectProperty<>(value);
            }

            @Override
            protected LocalDateTime loadFromBackend() {
                return LocalDateTime.parse(getBackingStore().get(getKey(),
                                getDefaultValue().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)),
                        DateTimeFormatter.ISO_LOCAL_DATE_TIME);
            }

            @Override
            protected void saveToBackend(LocalDateTime value) {
                getBackingStore().put(getKey(), value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public ObservablePreference longPreference(String key, Long defaultValue) {
        var p = new ObservablePreference<>(Number.class, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(Number value) {
                return new SimpleLongProperty(value.longValue());
            }

            @Override
            protected Long loadFromBackend() {
                return getBackingStore().getLong(getKey(), getDefaultValue().longValue());
            }

            @Override
            protected void saveToBackend(Number value) {
                getBackingStore().putLong(getKey(), value.longValue());
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public ObservablePreference doublePreference(String key, Double defaultValue) {
        var p = new ObservablePreference<>(Number.class, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(Number value) {
                return new SimpleDoubleProperty(value.doubleValue());
            }

            @Override
            protected Double loadFromBackend() {
                return getBackingStore().getDouble(getKey(), getDefaultValue().doubleValue());
            }

            @Override
            protected void saveToBackend(Number value) {
                getBackingStore().putDouble(getKey(), value.doubleValue());
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public ObservablePreference pathPreference(String key, Path defaultValue) {
        var p = new ObservablePreference<>(Path.class, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(Path value) {
                return new SimpleObjectProperty<>(value);
            }

            @Override
            protected Path loadFromBackend() {
                return Path.of(getBackingStore().get(getKey(), getDefaultValue().toString()));
            }

            @Override
            protected void saveToBackend(Path value) {
                getBackingStore().put(getKey(), value.toString());
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public ObservablePreference uriPreference(String key, URI defaultValue) {
        var p = new ObservablePreference<>(URI.class, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(URI value) {
                return new SimpleObjectProperty<>(value);
            }

            @Override
            protected URI loadFromBackend() {
                return URI.create(getBackingStore().get(getKey(), getDefaultValue().toString()));
            }

            @Override
            protected void saveToBackend(URI value) {
                getBackingStore().put(getKey(), value.toString());
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public > ObservablePreference enumPreference(Class type, String key, E defaultValue) {
        var p = new ObservablePreference<>(type, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(E value) {
                return new SimpleObjectProperty<>(value);
            }

            @Override
            protected E loadFromBackend() {
                return Enum.valueOf(getInnerType(), getBackingStore().get(getKey(), getDefaultValue().name()));
            }

            @Override
            protected void saveToBackend(E value) {
                getBackingStore().put(getKey(), value.name());
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    public  ObservablePreference objectPreference(Class type,
                                                        String key,
                                                        T defaultValue,
                                                        Function convertToString,
                                                        Function parseFromString) {
        var p = new ObservablePreference<>(type, key, defaultValue, backingStore) {
            @Override
            protected Property makeProperty(T value) {
                return new SimpleObjectProperty<>(value);
            }

            @Override
            protected T loadFromBackend() {
                return parseFromString.apply(getBackingStore().get(getKey(), convertToString.apply(getDefaultValue())));
            }

            @Override
            protected void saveToBackend(T value) {
                getBackingStore().put(getKey(), convertToString.apply(value));
            }
        };
        storedItems.put(p.getKey(), p);
        return p;
    }

    @SuppressWarnings("unchecked")
    public  Optional> getByName(String name, Class type) {
        var p = storedItems.get(name);
        if (p == null || !type.isAssignableFrom(p.getInnerType())) {
            return Optional.empty();
        }
        return Optional.of((ObservablePreference) p);
    }

    @Override

    public String toString() {
        return storedItems.values().stream().map(p -> p.getKey() + "=" + p.get()).collect(Collectors.joining("\n"));
    }

}