Properly implement storage directory switching

This commit is contained in:
crschnick
2023-07-09 11:39:23 +00:00
parent 4c08385098
commit b2d685f523
7 changed files with 40 additions and 75 deletions

View File

@@ -205,24 +205,19 @@ public class AppPrefs {
private final BooleanProperty confirmDeletions = typed(new SimpleBooleanProperty(true), Boolean.class);
// External startup behaviour
// ==========================
private final ObjectProperty<Path> internalStorageDirectory =
// Storage
// =======
private final ObjectProperty<Path> storageDirectory =
typed(new SimpleObjectProperty<>(DEFAULT_STORAGE_DIR), Path.class);
private final ObjectProperty<Path> effectiveStorageDirectory = STORAGE_DIR_FIXED
? new SimpleObjectProperty<>(AppProperties.get().getDataDir().resolve("storage"))
: internalStorageDirectory;
private final StringField storageDirectoryControl = PrefFields.ofPath(effectiveStorageDirectory)
.editable(!STORAGE_DIR_FIXED)
private final StringField storageDirectoryControl = PrefFields.ofPath(storageDirectory)
.validate(
CustomValidators.absolutePath(),
CustomValidators.directory(),
CustomValidators.emptyStorageDirectory());
private final ObjectProperty<String> internalLogLevel =
typed(new SimpleObjectProperty<>(DEFAULT_LOG_LEVEL), String.class);
CustomValidators.directory());
// Log level
// =========
private final ObjectProperty<String> internalLogLevel =
typed(new SimpleObjectProperty<>(DEFAULT_LOG_LEVEL), String.class);
private final ObjectProperty<String> effectiveLogLevel = LOG_LEVEL_FIXED
? new SimpleObjectProperty<>(System.getProperty(LOG_LEVEL_PROP).toLowerCase())
: internalLogLevel;
@@ -230,6 +225,7 @@ public class AppPrefs {
logLevelList, effectiveLogLevel)
.editable(!LOG_LEVEL_FIXED)
.render(() -> new SimpleComboBoxControl<>());
// Developer mode
// ==============
private final BooleanProperty internalDeveloperMode = typed(new SimpleBooleanProperty(false), Boolean.class);
@@ -335,7 +331,7 @@ public class AppPrefs {
}
public ObservableValue<Path> storageDirectory() {
return effectiveStorageDirectory;
return storageDirectory;
}
public ReadOnlyProperty<String> logLevel() {
@@ -535,9 +531,9 @@ public class AppPrefs {
automaticallyCheckForUpdatesField,
automaticallyCheckForUpdates),
Setting.of("updateToPrereleases", checkForPrereleasesField, checkForPrereleases)),
Group.of(
group(
"advanced",
Setting.of("storageDirectory", storageDirectoryControl, internalStorageDirectory),
STORAGE_DIR_FIXED ? null : Setting.of("storageDirectory", storageDirectoryControl, storageDirectory),
Setting.of("logLevel", logLevelField, internalLogLevel),
Setting.of("developerMode", developerModeField, internalDeveloperMode))),
Category.of(
@@ -602,6 +598,10 @@ public class AppPrefs {
return AppPreferencesFx.of(cats);
}
private Group group(String name, Setting<?,?>... settings) {
return Group.of(name, Arrays.stream(settings).filter(setting -> setting != null).toArray(Setting[]::new));
}
private class PrefsHandlerImpl implements PrefsHandler {
private final List<Category> categories;

View File

@@ -3,7 +3,6 @@ package io.xpipe.app.prefs;
import com.dlsc.formsfx.model.validators.CustomValidator;
import com.dlsc.formsfx.model.validators.Validator;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -30,25 +29,4 @@ public class CustomValidators {
},
"notADirectory");
}
public static Validator<String> emptyStorageDirectory() {
return CustomValidator.forPredicate(
(String s) -> {
var p = Path.of(s);
if (AppPrefs.get() == null) {
return true;
}
if (p.equals(AppPrefs.get().storageDirectory().getValue())) {
return true;
}
try {
return Files.list(p).findAny().isEmpty();
} catch (IOException ignored) {
return false;
}
},
"notAnEmptyDirectory");
}
}

View File

@@ -3,34 +3,39 @@ package io.xpipe.app.prefs;
import com.dlsc.formsfx.model.structure.StringField;
import com.dlsc.preferencesfx.formsfx.view.controls.SimpleChooserControl;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.fxcomps.util.PlatformThread;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.util.StringConverter;
import java.nio.file.Path;
import java.util.Objects;
public class PrefFields {
public static StringField ofPath(ObjectProperty<Path> fileProperty) {
StringProperty stringProperty = new SimpleStringProperty();
stringProperty.bindBidirectional(fileProperty, new StringConverter<>() {
@Override
public String toString(Path file) {
if (Objects.isNull(file)) {
return "";
}
return file.toString();
}
StringProperty stringProperty = new SimpleStringProperty(fileProperty.getValue().toString());
@Override
public Path fromString(String value) {
return Path.of(value);
}
// Prevent garbage collection of this due to how preferencesfx handles properties via bindings
BindingsHelper.linkPersistently(fileProperty, stringProperty);
stringProperty.addListener((observable, oldValue, newValue) -> {
fileProperty.setValue(newValue != null ? Path.of(newValue) : null);
});
fileProperty.addListener((observable, oldValue, newValue) -> {
PlatformThread.runLaterIfNeeded(() -> {
stringProperty.setValue(newValue != null ? newValue.toString() : "");
});
});
return StringField.ofStringType(stringProperty)
.render(() -> new SimpleChooserControl(
AppI18n.get("browse"), fileProperty.getValue().toFile(), true));
.render(() -> {
var c = new SimpleChooserControl(
AppI18n.get("browse"), fileProperty.getValue().toFile(), true);
c.setMinWidth(600);
c.setPrefWidth(600);
return c;
});
}
}

View File

@@ -145,10 +145,6 @@ public abstract class DataStorage {
}
}
protected Path getSourcesDir() {
return dir.resolve("sources");
}
protected Path getStoresDir() {
return dir.resolve("stores");
}

View File

@@ -17,14 +17,10 @@ public class ImpersistentStorage extends DataStorage {
@Override
public void save() {
var sourcesDir = getSourcesDir();
var storesDir = getStoresDir();
TrackEvent.info("Storage persistence is disabled. Deleting storage contents ...");
try {
if (Files.exists(sourcesDir)) {
FileUtils.cleanDirectory(sourcesDir.toFile());
}
if (Files.exists(storesDir)) {
FileUtils.cleanDirectory(storesDir.toFile());
}

View File

@@ -24,8 +24,6 @@ public class StandardStorage extends DataStorage {
}
private void deleteLeftovers() {
var entriesDir = getSourcesDir().resolve("entries");
var collectionsDir = getSourcesDir().resolve("collections");
var storesDir = getStoresDir();
// Delete leftover directories in entries dir
@@ -63,14 +61,10 @@ public class StandardStorage extends DataStorage {
public synchronized void load() {
var newSession = isNewSession();
var entriesDir = getSourcesDir().resolve("entries");
var collectionsDir = getSourcesDir().resolve("collections");
var storesDir = getStoresDir();
var streamsDir = getStreamsDir();
try {
FileUtils.forceMkdir(entriesDir.toFile());
FileUtils.forceMkdir(collectionsDir.toFile());
FileUtils.forceMkdir(storesDir.toFile());
FileUtils.forceMkdir(streamsDir.toFile());
} catch (Exception e) {
@@ -120,14 +114,10 @@ public class StandardStorage extends DataStorage {
}
public synchronized void save() {
var entriesDir = getSourcesDir().resolve("entries");
var collectionsDir = getSourcesDir().resolve("collections");
try {
FileUtils.forceMkdir(entriesDir.toFile());
FileUtils.forceMkdir(collectionsDir.toFile());
FileUtils.forceMkdir(getStoresDir().toFile());
} catch (Exception e) {
ErrorEvent.fromThrowable(e).terminal(true).build().handle();
ErrorEvent.fromThrowable(e).description("Unable to create storage directory " + getStoresDir()).terminal(true).build().handle();
}
// Save stores