mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 23:20:23 +00:00
Add dynamic tunnels
This commit is contained in:
parent
a218f9ac35
commit
c8cf6aa3fb
28 changed files with 124 additions and 178 deletions
|
@ -55,7 +55,15 @@ public class StoreCreationBarComp extends SimpleComp {
|
|||
.shortcut(new KeyCodeCombination(KeyCode.D, KeyCombination.SHORTCUT_DOWN))
|
||||
.apply(new FancyTooltipAugment<>("addDatabase"));
|
||||
|
||||
var box = new VerticalComp(List.of(newHostStore, newShellStore, newStreamStore, newDbStore))
|
||||
var newTunnelStore = new ButtonComp(AppI18n.observable("addTunnel"), new FontIcon("mdi2v-vector-polyline-plus"), () -> {
|
||||
GuiDsStoreCreator.showCreation(
|
||||
v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.TUNNEL));
|
||||
})
|
||||
.styleClass(Styles.FLAT)
|
||||
.shortcut(new KeyCodeCombination(KeyCode.T, KeyCombination.SHORTCUT_DOWN))
|
||||
.apply(new FancyTooltipAugment<>("addTunnel"));
|
||||
|
||||
var box = new VerticalComp(List.of(newHostStore, newShellStore, newStreamStore, newDbStore, newTunnelStore))
|
||||
.apply(struc -> struc.get().setFillWidth(true));
|
||||
box.apply(s -> AppFont.medium(s.get()));
|
||||
var bar = box.createRegion();
|
||||
|
|
|
@ -197,6 +197,7 @@ public class StoreEntryWrapper implements StorageFilter.Filterable {
|
|||
found.createAction(entry.getStore().asNeeded()).execute();
|
||||
} else if (getEntry().getStore() instanceof FixedHierarchyStore) {
|
||||
refreshWithChildrenAsync();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import lombok.experimental.FieldDefaults;
|
|||
@AllArgsConstructor
|
||||
public class DataStoreSelectorComp extends Comp<CompStructure<Button>> {
|
||||
|
||||
DataStoreProvider.DataCategory category;
|
||||
DataStoreProvider.DisplayCategory category;
|
||||
Property<DataStore> chosenStore;
|
||||
|
||||
@Override
|
||||
|
@ -34,7 +34,7 @@ public class DataStoreSelectorComp extends Comp<CompStructure<Button>> {
|
|||
"inProgress",
|
||||
null,
|
||||
null,
|
||||
v -> v.getCategory().equals(category),
|
||||
v -> v.getDisplayCategory().equals(category),
|
||||
entry -> {
|
||||
chosenStore.setValue(entry.getStore());
|
||||
},
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
package io.xpipe.app.comp.store;
|
||||
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.DataSourceProvider;
|
||||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.TabPaneComp;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class DsDbStoreChooserComp extends SimpleComp {
|
||||
|
||||
private final Property<DataStore> input;
|
||||
private final ObservableValue<DataSourceProvider<?>> provider;
|
||||
|
||||
public DsDbStoreChooserComp(Property<DataStore> input, ObservableValue<DataSourceProvider<?>> provider) {
|
||||
this.input = input;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var filter = Bindings.createObjectBinding(
|
||||
() -> (Predicate<DataStoreEntry>) e -> {
|
||||
if (provider.getValue() == null) {
|
||||
return e.getProvider().getCategory() == DataStoreProvider.DataCategory.DATABASE;
|
||||
}
|
||||
|
||||
return provider.getValue().couldSupportStore(e.getStore());
|
||||
},
|
||||
provider);
|
||||
|
||||
var connections = new TabPaneComp.Entry(
|
||||
AppI18n.observable("savedConnections"),
|
||||
"mdi2m-monitor",
|
||||
NamedStoreChoiceComp.create(filter, input, DataStoreProvider.DataCategory.DATABASE)
|
||||
.styleClass("store-local-file-chooser"));
|
||||
|
||||
var pane = new TabPaneComp(new SimpleObjectProperty<>(connections), List.of(connections));
|
||||
pane.apply(s -> AppFont.normal(s.get()));
|
||||
return pane.createRegion();
|
||||
}
|
||||
}
|
|
@ -121,7 +121,7 @@ public class DsStreamStoreChoiceComp extends SimpleComp implements Validatable {
|
|||
var other = new TabPaneComp.Entry(
|
||||
AppI18n.observable("other"),
|
||||
"mdrmz-web_asset",
|
||||
new DataStoreSelectorComp(DataStoreProvider.DataCategory.STREAM, otherStore));
|
||||
new DataStoreSelectorComp(DataStoreProvider.DisplayCategory.HOST, otherStore));
|
||||
|
||||
var selectedTab = new SimpleObjectProperty<TabPaneComp.Entry>();
|
||||
if (localStore.get() != null) {
|
||||
|
|
|
@ -105,11 +105,11 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
|
|||
v -> true,
|
||||
newE -> {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
e.applyChanges(newE);
|
||||
if (!DataStorage.get().getStoreEntries().contains(e)) {
|
||||
DataStorage.get().addStoreEntry(e);
|
||||
} else {
|
||||
DataStorage.get().updateEntry(e, newE);
|
||||
}
|
||||
DataStorage.get().refresh();
|
||||
});
|
||||
},
|
||||
true);
|
||||
|
|
|
@ -146,7 +146,7 @@ public class NamedStoreChoiceComp extends SimpleComp implements Validatable {
|
|||
var text = new LabelComp(AppI18n.observable("noMatchingStoreFound"))
|
||||
.apply(struc -> VBox.setVgrow(struc.get(), Priority.ALWAYS));
|
||||
var addButton = new ButtonComp(AppI18n.observable("addStore"), null, () -> {
|
||||
GuiDsStoreCreator.showCreation(v -> v.getCategory().equals(category));
|
||||
// GuiDsStoreCreator.showCreation(v -> v.getCategory().equals(category));
|
||||
});
|
||||
var notice = new VerticalComp(List.of(text, addButton))
|
||||
.apply(struc -> {
|
||||
|
|
|
@ -195,6 +195,10 @@ public class AppI18n {
|
|||
}
|
||||
|
||||
public String getMarkdownDocumentation(String name) {
|
||||
if (!markdownDocumentations.containsKey(name)) {
|
||||
TrackEvent.withWarn("Markdown documentation for key " + name + " not found").handle();
|
||||
}
|
||||
|
||||
return markdownDocumentations.getOrDefault(name, "");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.app.core.mode;
|
||||
|
||||
import io.xpipe.app.core.*;
|
||||
import io.xpipe.app.ext.DataStoreProviders;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.ErrorHandler;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
|
@ -105,6 +106,11 @@ public abstract class OperationMode {
|
|||
setup(args);
|
||||
LauncherCommand.runLauncher(usedArgs);
|
||||
inStartup = false;
|
||||
postInit(args);
|
||||
}
|
||||
|
||||
public static void postInit(String[] args) {
|
||||
DataStoreProviders.postInit(AppExtensionManager.getInstance().getExtendedLayer());
|
||||
}
|
||||
|
||||
public static boolean isInStartup() {
|
||||
|
|
|
@ -15,12 +15,12 @@ public class StoreProviderListExchangeImpl extends StoreProviderListExchange
|
|||
|
||||
@Override
|
||||
public Response handleRequest(BeaconHandler handler, Request msg) {
|
||||
var categories = DataStoreProvider.DataCategory.values();
|
||||
var categories = DataStoreProvider.DisplayCategory.values();
|
||||
var all = DataStoreProviders.getAll();
|
||||
var map = Arrays.stream(categories)
|
||||
.collect(Collectors.toMap(category -> getName(category), category -> all.stream()
|
||||
.filter(dataStoreProvider ->
|
||||
dataStoreProvider.getCategory().equals(category))
|
||||
dataStoreProvider.getDisplayCategory().equals(category))
|
||||
.map(p -> ProviderEntry.builder()
|
||||
.id(p.getId())
|
||||
.description(p.getDisplayDescription())
|
||||
|
@ -31,7 +31,7 @@ public class StoreProviderListExchangeImpl extends StoreProviderListExchange
|
|||
return Response.builder().entries(map).build();
|
||||
}
|
||||
|
||||
private String getName(DataStoreProvider.DataCategory category) {
|
||||
private String getName(DataStoreProvider.DisplayCategory category) {
|
||||
return category.name().substring(0, 1).toUpperCase()
|
||||
+ category.name().substring(1).toLowerCase();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ public interface DataStoreProvider {
|
|||
}
|
||||
|
||||
default void validate() {
|
||||
getCategory();
|
||||
for (Class<?> storeClass : getStoreClasses()) {
|
||||
if (!JacksonizedValue.class.isAssignableFrom(storeClass)) {
|
||||
throw new ExtensionException(
|
||||
|
@ -34,6 +33,8 @@ public interface DataStoreProvider {
|
|||
}
|
||||
}
|
||||
|
||||
default void preAdd(DataStore store) {}
|
||||
|
||||
default Comp<?> customDisplay(StoreSection s) {
|
||||
return new StandardStoreEntryComp(s.getWrapper(), null);
|
||||
}
|
||||
|
@ -90,27 +91,7 @@ public interface DataStoreProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
default DataCategory getCategory() {
|
||||
var c = getStoreClasses().get(0);
|
||||
if (StreamDataStore.class.isAssignableFrom(c)) {
|
||||
return DataCategory.STREAM;
|
||||
}
|
||||
|
||||
if (FileSystem.class.isAssignableFrom(c) || ShellStore.class.isAssignableFrom(c)) {
|
||||
return DataCategory.SHELL;
|
||||
}
|
||||
|
||||
throw new ExtensionException("Provider " + getId() + " has no set category");
|
||||
}
|
||||
|
||||
default DisplayCategory getDisplayCategory() {
|
||||
var category = getCategory();
|
||||
if (category.equals(DataCategory.SHELL)) {
|
||||
return DisplayCategory.HOST;
|
||||
}
|
||||
if (category.equals(DataCategory.DATABASE)) {
|
||||
return DisplayCategory.DATABASE;
|
||||
}
|
||||
return DisplayCategory.OTHER;
|
||||
}
|
||||
|
||||
|
@ -130,19 +111,26 @@ public interface DataStoreProvider {
|
|||
return true;
|
||||
}
|
||||
|
||||
default void postInit(){
|
||||
}
|
||||
|
||||
default void storageInit() throws Exception {}
|
||||
|
||||
default boolean isShareable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
String queryInformationString(DataStore store, int length) throws Exception;
|
||||
default String queryInformationString(DataStore store, int length) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
default String queryInvalidInformationString(DataStore store, int length) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
String toSummaryString(DataStore store, int length);
|
||||
default String toSummaryString(DataStore store, int length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default String i18n(String key) {
|
||||
return AppI18n.get(getId() + "." + key);
|
||||
|
@ -205,6 +193,7 @@ public interface DataStoreProvider {
|
|||
DATABASE,
|
||||
SHELL,
|
||||
COMMAND,
|
||||
TUNNEL,
|
||||
OTHER
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ public class DataStoreProviders {
|
|||
if (ALL == null) {
|
||||
ALL = ServiceLoader.load(layer, DataStoreProvider.class).stream()
|
||||
.map(ServiceLoader.Provider::get)
|
||||
.sorted(Comparator.comparing(DataStoreProvider::getId))
|
||||
.collect(Collectors.toList());
|
||||
ALL.removeIf(p -> {
|
||||
try {
|
||||
|
@ -35,6 +34,20 @@ public class DataStoreProviders {
|
|||
}
|
||||
}
|
||||
|
||||
public static void postInit(ModuleLayer layer) {
|
||||
ALL = ServiceLoader.load(layer, DataStoreProvider.class).stream()
|
||||
.map(ServiceLoader.Provider::get)
|
||||
.sorted(Comparator.comparing(DataStoreProvider::getId))
|
||||
.collect(Collectors.toList());
|
||||
ALL.forEach(p -> {
|
||||
try {
|
||||
p.postInit();
|
||||
} catch (Throwable e) {
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Optional<DataStoreProvider> byName(String name) {
|
||||
if (ALL == null) {
|
||||
throw new IllegalStateException("Not initialized");
|
||||
|
|
|
@ -42,6 +42,11 @@ public class DataStateProviderImpl extends DataStateProvider {
|
|||
return c.cast(result);
|
||||
}
|
||||
|
||||
public boolean isInStorage(DataStore store) {
|
||||
var entry = DataStorage.get().getStoreEntryIfPresent(store);
|
||||
return entry.isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getInternalStreamStore(UUID id) {
|
||||
return DataStorage.get().getInternalStreamPath(id);
|
||||
|
|
|
@ -92,6 +92,7 @@ public abstract class DataStorage {
|
|||
Collections.reverse(ordered);
|
||||
|
||||
synchronized (this) {
|
||||
ordered.forEach(entry -> entry.finalizeEntry());
|
||||
this.storeEntries.removeAll(ordered);
|
||||
this.listeners.forEach(l -> l.onStoreRemove(ordered.toArray(DataStoreEntry[]::new)));
|
||||
}
|
||||
|
@ -213,6 +214,12 @@ public abstract class DataStorage {
|
|||
}
|
||||
}
|
||||
|
||||
public void updateEntry(DataStoreEntry entry, DataStoreEntry newEntry) {
|
||||
newEntry.finalizeEntry();
|
||||
entry.applyChanges(newEntry);
|
||||
entry.initializeEntry();
|
||||
}
|
||||
|
||||
public void refreshAsync(DataStoreEntry element, boolean deep) {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
try {
|
||||
|
@ -233,6 +240,8 @@ public abstract class DataStorage {
|
|||
}
|
||||
|
||||
public void addStoreEntry(@NonNull DataStoreEntry e) {
|
||||
e.getProvider().preAdd(e.getStore());
|
||||
|
||||
synchronized (this) {
|
||||
e.setDirectory(getStoresDir().resolve(e.getUuid().toString()));
|
||||
this.storeEntries.add(e);
|
||||
|
@ -241,16 +250,22 @@ public abstract class DataStorage {
|
|||
save();
|
||||
|
||||
this.listeners.forEach(l -> l.onStoreAdd(e));
|
||||
e.initializeEntry();
|
||||
}
|
||||
|
||||
public void addStoreEntries(@NonNull DataStoreEntry... es) {
|
||||
synchronized (this) {
|
||||
for (DataStoreEntry e : es) {
|
||||
e.getProvider().preAdd(e.getStore());
|
||||
|
||||
e.setDirectory(getStoresDir().resolve(e.getUuid().toString()));
|
||||
this.storeEntries.add(e);
|
||||
propagateUpdate(e);
|
||||
}
|
||||
this.listeners.forEach(l -> l.onStoreAdd(es));
|
||||
for (DataStoreEntry e : es) {
|
||||
e.initializeEntry();
|
||||
}
|
||||
}
|
||||
save();
|
||||
}
|
||||
|
@ -284,6 +299,7 @@ public abstract class DataStorage {
|
|||
}
|
||||
|
||||
public void deleteStoreEntry(@NonNull DataStoreEntry store) {
|
||||
store.finalizeEntry();
|
||||
synchronized (this) {
|
||||
this.storeEntries.remove(store);
|
||||
}
|
||||
|
@ -298,13 +314,6 @@ public abstract class DataStorage {
|
|||
|
||||
public abstract void load();
|
||||
|
||||
public void refresh() {
|
||||
getStoreEntries().forEach(entry -> {
|
||||
entry.simpleRefresh();
|
||||
});
|
||||
save();
|
||||
}
|
||||
|
||||
public abstract void save();
|
||||
|
||||
public synchronized Optional<DataStoreEntry> getStoreEntry(UUID id) {
|
||||
|
|
|
@ -288,6 +288,36 @@ public class DataStoreEntry extends StorageElement {
|
|||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void initializeEntry() {
|
||||
try {
|
||||
state = State.VALIDATING;
|
||||
listeners.forEach(l -> l.onUpdate());
|
||||
store.initializeValidate();
|
||||
state = State.COMPLETE_AND_VALID;
|
||||
} catch (Exception e) {
|
||||
state = State.COMPLETE_BUT_INVALID;
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
} finally {
|
||||
propagateUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void finalizeEntry() {
|
||||
try {
|
||||
state = State.VALIDATING;
|
||||
listeners.forEach(l -> l.onUpdate());
|
||||
store.finalizeValidate();
|
||||
state = State.COMPLETE_AND_VALID;
|
||||
} catch (Exception e) {
|
||||
state = State.COMPLETE_BUT_INVALID;
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
} finally {
|
||||
propagateUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldSave() {
|
||||
return getStore() == null || getStore().shouldSave();
|
||||
|
|
|
@ -42,6 +42,12 @@ public class OptionsBuilder {
|
|||
entries.add(entry);
|
||||
}
|
||||
|
||||
public OptionsBuilder sub(OptionsBuilder builder) {
|
||||
props.addAll(builder.props);
|
||||
pushComp(builder.buildComp());
|
||||
return this;
|
||||
}
|
||||
|
||||
public OptionsBuilder addTitle(String titleKey) {
|
||||
finishCurrent();
|
||||
entries.add(new OptionsComp.Entry(
|
||||
|
|
|
@ -42,6 +42,7 @@ clean=Clean
|
|||
refresh=Refresh
|
||||
remove=Remove
|
||||
addDatabase=Add Database ...
|
||||
addTunnel=Add Tunnel ...
|
||||
addHost=Add Remote Host ...
|
||||
addShell=Add Environment ...
|
||||
addCommand=Add Command ...
|
||||
|
|
|
@ -116,7 +116,6 @@ noMatchingSourceFound=No matching source found
|
|||
addSource=Add Source
|
||||
edit=Edit
|
||||
addStream=Add File
|
||||
addDatabase=Add Database
|
||||
pipeStream=Pipe File
|
||||
pipeDatabase=Pipe Database
|
||||
transfer=Transfer
|
||||
|
|
|
@ -9,13 +9,10 @@ import lombok.Getter;
|
|||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@JsonTypeName("internalStream")
|
||||
|
@ -35,20 +32,10 @@ public class InternalStreamStore extends JacksonizedValue implements StreamDataS
|
|||
return DataFlow.INPUT_OUTPUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> determineDefaultName() {
|
||||
return Optional.of(uuid.toString());
|
||||
}
|
||||
|
||||
private Path getFile() {
|
||||
return DataStateProvider.get().getInternalStreamStore(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Instant> determineLastModified() throws IOException {
|
||||
return Optional.of(Files.getLastModifiedTime(getFile()).toInstant());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInput() throws Exception {
|
||||
return Files.newInputStream(getFile());
|
||||
|
|
|
@ -5,11 +5,7 @@ import com.fasterxml.jackson.annotation.JsonTypeName;
|
|||
import io.xpipe.core.store.DataStore;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
@JsonTypeName("localDir")
|
||||
@EqualsAndHashCode
|
||||
|
@ -22,21 +18,6 @@ public class LocalDirectoryDataStore implements DataStore {
|
|||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> determineDefaultName() {
|
||||
return Optional.of(file.getFileName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Instant> determineLastModified() {
|
||||
try {
|
||||
var l = Files.getLastModifiedTime(file);
|
||||
return Optional.of(l.toInstant());
|
||||
} catch (IOException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return file;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,6 @@ import lombok.Getter;
|
|||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A store that refers to another store in the XPipe storage.
|
||||
* The referenced store has to be resolved by the caller manually, as this class does not act as a resolver.
|
||||
|
@ -36,13 +33,4 @@ public final class NamedStore implements DataStore {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> determineDefaultName() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Instant> determineLastModified() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,6 @@ import io.xpipe.core.impl.StdinDataStore;
|
|||
import io.xpipe.core.impl.StdoutDataStore;
|
||||
import io.xpipe.core.source.DataSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A data store represents some form of a location where data is stored, e.g. a file or a database.
|
||||
* It does not contain any information on what data is stored,
|
||||
|
@ -77,6 +73,10 @@ public interface DataStore {
|
|||
*/
|
||||
default void validate() throws Exception {}
|
||||
|
||||
default void initializeValidate() throws Exception {}
|
||||
|
||||
default void finalizeValidate() throws Exception {}
|
||||
|
||||
default void checkComplete() throws Exception {}
|
||||
|
||||
default boolean delete() {
|
||||
|
@ -90,19 +90,4 @@ public interface DataStore {
|
|||
default <DS extends DataStore> DS asNeeded() {
|
||||
return (DS) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines on optional default name for this data store that is
|
||||
* used when determining a suitable default name for a data source.
|
||||
*/
|
||||
default Optional<String> determineDefaultName() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the last modified of this data store if this data store supports it.
|
||||
*/
|
||||
default Optional<Instant> determineLastModified() throws IOException {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents a store that has a filename.
|
||||
* Note that this does not only apply to file stores but any other store as well that has some kind of file name.
|
||||
*/
|
||||
public interface FilenameStore extends DataStore {
|
||||
|
||||
@Override
|
||||
default Optional<String> determineDefaultName() {
|
||||
var n = getFileName();
|
||||
var i = n.lastIndexOf('.');
|
||||
return Optional.of(i != -1 ? n.substring(0, i) : n);
|
||||
}
|
||||
|
||||
default String getFileExtension() {
|
||||
var split = getFileName().split("[\\\\.]");
|
||||
if (split.length == 0) {
|
||||
|
|
|
@ -6,6 +6,10 @@ import java.util.function.Supplier;
|
|||
|
||||
public interface StatefulDataStore extends DataStore {
|
||||
|
||||
default boolean isInStorage() {
|
||||
return DataStateProvider.get().isInStorage(this);
|
||||
}
|
||||
|
||||
default <T> T getState(String key, Class<T> c, T def) {
|
||||
return DataStateProvider.get().getState(this, key, c, () -> def);
|
||||
}
|
||||
|
|
|
@ -25,5 +25,7 @@ public abstract class DataStateProvider {
|
|||
|
||||
public abstract <T> T getState(DataStore store, String key, Class<T> c, Supplier<T> def);
|
||||
|
||||
public abstract boolean isInStorage(DataStore store);
|
||||
|
||||
public abstract Path getInternalStreamStore(UUID id);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.nio.charset.Charset;
|
|||
import java.nio.charset.IllegalCharsetNameException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@JsonTypeName("http")
|
||||
@SuperBuilder
|
||||
|
@ -101,11 +100,6 @@ public class HttpStore extends JacksonizedValue implements StreamDataStore, Stat
|
|||
Validators.nonNull(headers, "Headers");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> determineDefaultName() {
|
||||
return Optional.ofNullable(getURL().getHost());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() throws Exception {
|
||||
var client = createClient();
|
||||
|
|
|
@ -70,11 +70,6 @@ public class InMemoryStoreProvider implements DataStoreProvider {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataCategory getCategory() {
|
||||
return DataCategory.STREAM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStore defaultStore() {
|
||||
return new InMemoryStore(new byte[0]);
|
||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
|||
1.3.2
|
||||
1.4.0
|
Loading…
Reference in a new issue