From 4e6ad698777d95f5faa39d73edfd9cde78cd23d9 Mon Sep 17 00:00:00 2001 From: io42630 Date: Fri, 1 Apr 2022 17:07:27 +0200 Subject: [PATCH] _ remove gui _ refactor readOrMakeStateFile() --- README.md | 25 ++ pom.xml | 132 +++++----- src/main/java/com/olexyn/ensync/Flow.java | 45 ++-- src/main/java/com/olexyn/ensync/LogUtil.java | 50 ++++ src/main/java/com/olexyn/ensync/Main.java | 49 ---- src/main/java/com/olexyn/ensync/MainApp.java | 34 +++ src/main/java/com/olexyn/ensync/Tools.java | 17 +- .../olexyn/ensync/artifacts/Constants.java | 7 + .../{MapOfSyncMaps.java => DataRoot.java} | 8 +- .../com/olexyn/ensync/artifacts/StateFile.kt | 19 ++ .../{SyncMap.java => SyncBundle.java} | 19 +- .../ensync/artifacts/SyncDirectory.java | 44 ++-- .../java/com/olexyn/ensync/ui/Bridge.java | 55 ---- .../java/com/olexyn/ensync/ui/Controller.java | 237 ------------------ src/main/java/com/olexyn/ensync/ui/UI.java | 27 -- src/main/resources/config.json | 10 +- .../com/olexyn/ensync/files/FileTest.java | 27 +- 17 files changed, 279 insertions(+), 526 deletions(-) create mode 100644 src/main/java/com/olexyn/ensync/LogUtil.java delete mode 100644 src/main/java/com/olexyn/ensync/Main.java create mode 100644 src/main/java/com/olexyn/ensync/MainApp.java create mode 100644 src/main/java/com/olexyn/ensync/artifacts/Constants.java rename src/main/java/com/olexyn/ensync/artifacts/{MapOfSyncMaps.java => DataRoot.java} (54%) create mode 100644 src/main/java/com/olexyn/ensync/artifacts/StateFile.kt rename src/main/java/com/olexyn/ensync/artifacts/{SyncMap.java => SyncBundle.java} (58%) delete mode 100644 src/main/java/com/olexyn/ensync/ui/Bridge.java delete mode 100644 src/main/java/com/olexyn/ensync/ui/Controller.java delete mode 100644 src/main/java/com/olexyn/ensync/ui/UI.java diff --git a/README.md b/README.md index cc8dce4..6af0711 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,31 @@

+#### Design Goals +* Least possible intrusion. + * work on top of a FS + * can be plugged / unpluggen anytime +* Sync, not redundancy, not backup + * if user deletes File on one system, it will be deleted on all systems +* Pretty simple rules: + * if same md5 keep older file + * if diff md5 keep newer file + * if created, create everywhere + * if deleted, delete everywhere + +#### Overview +``` +DataRoot a data root +\_ SyncBundle : a bundle of directories on the FS to be syncronized. + \_ SyncDirectory : a directory on the FS. + \_ SyncFile : a file on the FS. +``` + +#### StateFile +* Used for tracking of file deletions. +* Located in each `SyncDirectory\state.ensync` +* Contains ` ` for each file in the SyncDirectory. + #### Demo [![IMAGE ALT TEXT](http://img.youtube.com/vi/znR3jyM_4Ss/0.jpg)](https://youtu.be/znR3jyM_4Ss "ensync WIP Demo") diff --git a/pom.xml b/pom.xml index 0c834b9..c38ee5f 100644 --- a/pom.xml +++ b/pom.xml @@ -13,8 +13,12 @@ UTF-8 + 7.3.1 + ${vaadin.version} + false 1.11 1.11 + 1.6.20-RC2 @@ -24,74 +28,26 @@ 4.11 test - - - javafx - javafx.base - 11.0.2 - system - /home/user/app/javafx-sdk-11.0.2/lib/javafx.base.jar - - - - javafx - javafx.fxml - 11.0.2 - system - /home/user/app/javafx-sdk-11.0.2/lib/javafx.fxml.jar - - - - javafx - javafx.controls - 11.0.2 - system - /home/user/app/javafx-sdk-11.0.2/lib/javafx.controls.jar - - - - javafx - javafx.graphics - 11.0.2 - system - /home/user/app/javafx-sdk-11.0.2/lib/javafx.graphics.jar - - - - javafx - javafx.media - 11.0.2 - system - /home/user/app/javafx-sdk-11.0.2/lib/javafx.media.jar - - - - javafx - javafx.swing - 11.0.2 - system - /home/user/app/javafx-sdk-11.0.2/lib/javafx.swing.jar - - - - javafx - javafx.web - 11.0.2 - system - /home/user/app/javafx-sdk-11.0.2/lib/javafx.web.jar - - - javafx - javafx.swt - 11.0.2 - system - /home/user/app/javafx-sdk-11.0.2/lib/javafx-swt.jar + org.json + json + 20190722 - org.json - json - 20190722 + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} @@ -139,5 +95,51 @@ + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + diff --git a/src/main/java/com/olexyn/ensync/Flow.java b/src/main/java/com/olexyn/ensync/Flow.java index 170a6e6..dce1f0e 100644 --- a/src/main/java/com/olexyn/ensync/Flow.java +++ b/src/main/java/com/olexyn/ensync/Flow.java @@ -1,34 +1,36 @@ package com.olexyn.ensync; -import com.olexyn.ensync.artifacts.MapOfSyncMaps; +import com.olexyn.ensync.artifacts.DataRoot; +import com.olexyn.ensync.artifacts.StateFile; import com.olexyn.ensync.artifacts.SyncDirectory; -import com.olexyn.ensync.artifacts.SyncMap; +import com.olexyn.ensync.artifacts.SyncBundle; import java.io.File; import java.util.Map.Entry; +import java.util.logging.Logger; public class Flow implements Runnable { + private static final Logger LOGGER = LogUtil.get(Flow.class); + Tools tools = new Tools(); public long pollingPause = 200; - private String state; - public void run() { while (true) { - synchronized (MapOfSyncMaps.get()) { + synchronized(DataRoot.get()) { readOrMakeStateFile(); - for (Entry syncMapEntry : MapOfSyncMaps.get().entrySet()) { + for (Entry syncMapEntry : DataRoot.get().entrySet()) { for (Entry SDEntry : syncMapEntry.getValue().syncDirectories.entrySet()) { @@ -39,13 +41,13 @@ public class Flow implements Runnable { try { System.out.println("Pausing... for " + pollingPause + "ms."); Thread.sleep(pollingPause); - } catch (InterruptedException ignored) {} + } catch (InterruptedException ignored) { } } } private void doSyncDirectory(SyncDirectory SD) { - state = "READ"; + LOGGER.info("READ"); SD.readStateFromFS(); SD.listCreated = SD.makeListOfLocallyCreatedFiles(); @@ -56,36 +58,25 @@ public class Flow implements Runnable { SD.doDeleteOpsOnOtherSDs(); SD.doModifyOpsOnOtherSDs(); - SD.writeStateFile(SD.path); + SD.writeStateFile(new StateFile(SD.path)); } - public String getState() { - return state == null ? "NONE" : state; - } - /** * For every single SyncDirectory try to read it's StateFile.

* If the StateFile is missing, then create a StateFile. */ private void readOrMakeStateFile() { - for (var syncMapEntry : MapOfSyncMaps.get().entrySet()) { - SyncMap syncMap = syncMapEntry.getValue(); - state = syncMap.toString(); - - for (var stringSyncDirectoryEntry : syncMap.syncDirectories.entrySet()) { - SyncDirectory SD = stringSyncDirectoryEntry.getValue(); - String path = SD.path; - String stateFilePath = tools.stateFilePath(path); - - if (new File(stateFilePath).exists()) { - state = "READ-STATE-FILE-" + SD.readStateFile(); + DataRoot.get().values().forEach(syncBundle -> { + for (var sd : syncBundle.syncDirectories.values()) { + var stateFile = new StateFile(sd.path); + if (stateFile.exists()) { + LOGGER.info("READ-STATE-FILE-" + sd.readStateFile()); } else { - SD.writeStateFile(path); + sd.writeStateFile(new StateFile(sd.path)); } } - - } + }); } } diff --git a/src/main/java/com/olexyn/ensync/LogUtil.java b/src/main/java/com/olexyn/ensync/LogUtil.java new file mode 100644 index 0000000..0223066 --- /dev/null +++ b/src/main/java/com/olexyn/ensync/LogUtil.java @@ -0,0 +1,50 @@ +package com.olexyn.ensync; + + +import java.io.IOException; +import java.util.Date; +import java.util.logging.FileHandler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + + + +public class LogUtil { + + private static final String format = "[%1$tF %1$tT] [%4$-7s] %5$-120s [%2$s]\n"; + + public static Logger get(Class c) { + return get(c, Level.INFO); + } + + public static Logger get(Class c, Level level) { + System.setProperty("java.util.logging.SimpleFormatter.format", format); + Logger logger = Logger.getLogger(c.getName()); + try { + String dir = System.getProperty("user.dir") + "/log/main.log"; + FileHandler fh = new FileHandler(dir, true); + fh.setFormatter(new SimpleFormatter() { + @Override + public synchronized String format(LogRecord logRecord) { + String msg = logRecord.getMessage(); + return String.format(format, + new Date(logRecord.getMillis()), + logRecord.getSourceClassName() + " " + logRecord.getSourceMethodName(), + "", + logRecord.getLevel().getLocalizedName(), + msg + ); + } + }); + + logger.addHandler(fh); + logger.setLevel(level); + } catch (NullPointerException | IOException e) { + e.printStackTrace(); + } + return logger; + } + +} diff --git a/src/main/java/com/olexyn/ensync/Main.java b/src/main/java/com/olexyn/ensync/Main.java deleted file mode 100644 index 7d1517e..0000000 --- a/src/main/java/com/olexyn/ensync/Main.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.olexyn.ensync; - -import com.olexyn.ensync.artifacts.MapOfSyncMaps; -import com.olexyn.ensync.artifacts.SyncMap; -import com.olexyn.ensync.ui.UI; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - - -public class Main { - - final public static Thread UI_THREAD = new Thread(new UI(), "ui"); - final public static Thread FLOW_THREAD = new Thread(new Flow(), "flow"); - final private static Tools tools = new Tools(); - - public static void main(String[] args) { - - OperationMode operationMode = OperationMode.JSON; - - switch (operationMode) { - case JAVA_FX: - UI_THREAD.start(); - break; - case JSON: - String configPath = System.getProperty("user.dir") + "/src/main/resources/config.json"; - String configString = tools.fileToString(new File(configPath)); - JSONObject jsonMapOfSyncMaps = new JSONObject(configString).getJSONObject("jsonMapOfSyncMaps"); - for (String key : jsonMapOfSyncMaps.keySet()) { - SyncMap syncMap = new SyncMap(key); - for (Object jsonSyncDirPath : jsonMapOfSyncMaps.getJSONArray(key).toList()) { - syncMap.addDirectory(jsonSyncDirPath.toString()); - } - MapOfSyncMaps.get().put(key, syncMap); - } - break; - default: - } - - - FLOW_THREAD.start(); - } -} diff --git a/src/main/java/com/olexyn/ensync/MainApp.java b/src/main/java/com/olexyn/ensync/MainApp.java new file mode 100644 index 0000000..65675ff --- /dev/null +++ b/src/main/java/com/olexyn/ensync/MainApp.java @@ -0,0 +1,34 @@ +package com.olexyn.ensync; + +import com.olexyn.ensync.artifacts.DataRoot; +import com.olexyn.ensync.artifacts.SyncBundle; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; + + +public class MainApp { + + final public static Thread FLOW_THREAD = new Thread(new Flow(), "flow"); + final private static Tools tools = new Tools(); + + public static void main(String[] args) throws JSONException { + + String configPath = System.getProperty("user.dir") + "/src/main/resources/config.json"; + String configString = tools.fileToString(new File(configPath)); + JSONObject dataRoot = new JSONObject(configString).getJSONObject("dataRoot"); + for (String bundleKey : dataRoot.keySet()) { + SyncBundle syncBundle = new SyncBundle(bundleKey); + dataRoot.getJSONArray(bundleKey).toList() + .forEach( + directoryPath -> syncBundle.addDirectory(directoryPath.toString()) + ); + + DataRoot.get().put(bundleKey, syncBundle); + } + + FLOW_THREAD.start(); + } +} diff --git a/src/main/java/com/olexyn/ensync/Tools.java b/src/main/java/com/olexyn/ensync/Tools.java index 5c96cf7..f24fefa 100644 --- a/src/main/java/com/olexyn/ensync/Tools.java +++ b/src/main/java/com/olexyn/ensync/Tools.java @@ -125,19 +125,9 @@ public class Tools { * @param list StringBuilder */ public void writeStringListToFile(String path, List list) { - File file = new File(path); - File parent = new File(file.getParent()); - if (!parent.exists()) { - - x.execute(new String[]{"mkdir", - "-p", - parent.getPath()}); - } - - try { - BufferedWriter bw = new BufferedWriter(new FileWriter(new File(path))); - StringBuilder sb = stringListToSb(list); + var bw = new BufferedWriter(new FileWriter(path)); + var sb = stringListToSb(list); bw.write(sb.toString()); bw.close(); } catch (Exception e) { @@ -145,7 +135,4 @@ public class Tools { } } - public String stateFilePath(String path) { - return "/tmp/ensync/state" + path.replace("/", "-"); - } } diff --git a/src/main/java/com/olexyn/ensync/artifacts/Constants.java b/src/main/java/com/olexyn/ensync/artifacts/Constants.java new file mode 100644 index 0000000..3db0966 --- /dev/null +++ b/src/main/java/com/olexyn/ensync/artifacts/Constants.java @@ -0,0 +1,7 @@ +package com.olexyn.ensync.artifacts; + +public interface Constants { + + String STATE_FILE_NAME = "state.ensync"; + +} diff --git a/src/main/java/com/olexyn/ensync/artifacts/MapOfSyncMaps.java b/src/main/java/com/olexyn/ensync/artifacts/DataRoot.java similarity index 54% rename from src/main/java/com/olexyn/ensync/artifacts/MapOfSyncMaps.java rename to src/main/java/com/olexyn/ensync/artifacts/DataRoot.java index cd8f7ab..0ea04e7 100644 --- a/src/main/java/com/olexyn/ensync/artifacts/MapOfSyncMaps.java +++ b/src/main/java/com/olexyn/ensync/artifacts/DataRoot.java @@ -2,13 +2,13 @@ package com.olexyn.ensync.artifacts; import java.util.HashMap; -public class MapOfSyncMaps { +public class DataRoot { - private static HashMap mapOfSyncMaps; + private static HashMap mapOfSyncMaps; - private MapOfSyncMaps() {} + private DataRoot() {} - public static HashMap get() { + public static HashMap get() { if (mapOfSyncMaps == null) { mapOfSyncMaps = new HashMap<>(); diff --git a/src/main/java/com/olexyn/ensync/artifacts/StateFile.kt b/src/main/java/com/olexyn/ensync/artifacts/StateFile.kt new file mode 100644 index 0000000..59205fc --- /dev/null +++ b/src/main/java/com/olexyn/ensync/artifacts/StateFile.kt @@ -0,0 +1,19 @@ +package com.olexyn.ensync.artifacts + +import java.io.File + +class StateFile(val targetPath: String) { + + fun getPath(): String { + return targetPath + Constants.STATE_FILE_NAME + } + + private fun getFile(): File { + return File(getPath()) + } + + fun exists(): Boolean { + return getFile().exists(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/olexyn/ensync/artifacts/SyncMap.java b/src/main/java/com/olexyn/ensync/artifacts/SyncBundle.java similarity index 58% rename from src/main/java/com/olexyn/ensync/artifacts/SyncMap.java rename to src/main/java/com/olexyn/ensync/artifacts/SyncBundle.java index bec044c..24dac1f 100644 --- a/src/main/java/com/olexyn/ensync/artifacts/SyncMap.java +++ b/src/main/java/com/olexyn/ensync/artifacts/SyncBundle.java @@ -11,7 +11,7 @@ import java.util.Map; * A SyncMap is a map of SyncDirectories.
* It synchronizes the SyncDirectories it contains. */ -public class SyncMap { +public class SyncBundle { public String name; public Map syncDirectories = new HashMap<>(); @@ -19,22 +19,22 @@ public class SyncMap { Tools tools = new Tools(); /** - * @see SyncMap + * @see SyncBundle */ - public SyncMap(String name) { + public SyncBundle(String name) { this.name = name; } /** - * Creates a new Syncdirectory.

- * Adds the created SyncDirectory to this SyncMap. + * Creates a new SyncDirectory.

+ * Adds the created SyncDirectory to this SyncBundle. * - * @param realPath the path from which the SyncDirectory is created. + * @param path the path from which the SyncDirectory is created. * @see SyncDirectory */ - public void addDirectory(String realPath) { - if (new File(realPath).isDirectory()) { - syncDirectories.put(realPath, new SyncDirectory(realPath, this)); + public void addDirectory(String path) { + if (new File(path).isDirectory()) { + syncDirectories.put(path, new SyncDirectory(path, this)); } } @@ -42,5 +42,4 @@ public class SyncMap { syncDirectories.remove(realPath); } - } diff --git a/src/main/java/com/olexyn/ensync/artifacts/SyncDirectory.java b/src/main/java/com/olexyn/ensync/artifacts/SyncDirectory.java index 2d0c0ae..24f645a 100644 --- a/src/main/java/com/olexyn/ensync/artifacts/SyncDirectory.java +++ b/src/main/java/com/olexyn/ensync/artifacts/SyncDirectory.java @@ -1,24 +1,33 @@ package com.olexyn.ensync.artifacts; import com.olexyn.ensync.Execute; +import com.olexyn.ensync.Flow; +import com.olexyn.ensync.LogUtil; import com.olexyn.ensync.Tools; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.logging.Logger; /** * A SyncDirectory is a singular occurrence of a directory in the filesystems. */ public class SyncDirectory { + private static final Logger LOGGER = LogUtil.get(SyncDirectory.class); + private String flowState; private SyncDirectory thisSD = this; - private final SyncMap syncMap; + private final SyncBundle syncMap; public String path = null; public Map listCreated = new HashMap<>(); @@ -32,9 +41,9 @@ public class SyncDirectory { /** * Create a SyncDirectory from realPath. * - * @see SyncMap + * @see SyncBundle */ - public SyncDirectory(String path, SyncMap syncMap) { + public SyncDirectory(String path, SyncBundle syncMap) { this.path = path; this.syncMap = syncMap; @@ -70,7 +79,8 @@ public class SyncDirectory { */ public Map readStateFile() { Map filemap = new HashMap<>(); - List lines = tools.fileToLines(new File(tools.stateFilePath(path))); + var stateFile = new StateFile(path); + List lines = tools.fileToLines(new File(stateFile.getPath())); for (String line : lines) { // this is a predefined format: "modification-time path" @@ -162,22 +172,24 @@ public class SyncDirectory { * QUERY state of the filesystem at realPath. * WRITE the state of the filesystem to file. */ - public void writeStateFile(String path) { + public void writeStateFile(StateFile stateFile) { List outputList = new ArrayList<>(); - - Execute.TwoBr find = x.execute(new String[]{"find", - path}); - - List pathList = tools.brToListString(find.output); - - - for (String filePath : pathList) { - long lastModified = new File(filePath).lastModified(); - outputList.add("" + lastModified + " " + filePath); + try { + Files.walk(Paths.get(path)) + .filter(Files::isRegularFile) + .map(Path::toFile) + .filter(file -> !file.getName().equals(Constants.STATE_FILE_NAME)) + .forEach(file -> { + String relativePath = file.getAbsolutePath() + .replace(stateFile.getTargetPath(), ""); + outputList.add("" + file.lastModified() + " " + relativePath); + }); + } catch (IOException e) { + LOGGER.severe("Could walk the file tree : StateFile will be empty."); } - tools.writeStringListToFile(tools.stateFilePath(path), outputList); + tools.writeStringListToFile(stateFile.getPath(), outputList); } diff --git a/src/main/java/com/olexyn/ensync/ui/Bridge.java b/src/main/java/com/olexyn/ensync/ui/Bridge.java deleted file mode 100644 index dcf9960..0000000 --- a/src/main/java/com/olexyn/ensync/ui/Bridge.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.olexyn.ensync.ui; - - -import com.olexyn.ensync.artifacts.MapOfSyncMaps; -import com.olexyn.ensync.artifacts.SyncMap; - - -import java.io.File; - - - -/** - * Connect the Controller and the Flow - */ -public class Bridge { - - - void newCollection(String collectionName) { - - synchronized (MapOfSyncMaps.get()) { - MapOfSyncMaps.get().put(collectionName, new SyncMap(collectionName)); - } - } - - - void removeCollection(String collectionName) { - synchronized (MapOfSyncMaps.get()) { - MapOfSyncMaps.get().remove(collectionName); - } - } - - - void addDirectory(String collectionName, File diretory) { - synchronized (MapOfSyncMaps.get()) { - MapOfSyncMaps.get().get(collectionName).addDirectory(diretory.getAbsolutePath()); - } - //TODO pause syning when adding - } - - - /** - * This works, because a directory, which here is an unique ablsolute path, - * is only supposed to present once across entire SYNC. - */ - void removeDirectory(String directoryAbsolutePath) { - //TODO fix ConcurrentModificationException. This will possibly resolve further errors. - synchronized (MapOfSyncMaps.get()) { - for (var syncMap : MapOfSyncMaps.get().entrySet()) { - syncMap.getValue().removeDirectory(directoryAbsolutePath); - } - } - - - } -} diff --git a/src/main/java/com/olexyn/ensync/ui/Controller.java b/src/main/java/com/olexyn/ensync/ui/Controller.java deleted file mode 100644 index 55e8504..0000000 --- a/src/main/java/com/olexyn/ensync/ui/Controller.java +++ /dev/null @@ -1,237 +0,0 @@ -package com.olexyn.ensync.ui; - - -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.scene.control.TextField; -import javafx.scene.layout.GridPane; -import javafx.scene.text.Text; -import javafx.stage.DirectoryChooser; -import javafx.stage.Window; - -import java.io.File; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.ResourceBundle; - -/*** - * Controller class for JavaFX. Contains the application logic. - */ -public class Controller implements Initializable { - - - final static int COLUMN_COUNT = 5; // How many columns should the GridPane have? Adjust if necessary. - final static Text SPACE = new Text(""); // Placeholder - int collection_count = 0; - Bridge bridge = new Bridge(); - - @FXML - protected GridPane gridPane; - - @Override - public void initialize(URL url, ResourceBundle resourceBundle) { - - Text end = new Text(""); - end.setId("end"); - - Button newCollectionButton = new Button("New Collection"); - newCollectionButton.setId("newCollectionButton"); - newCollectionButton.setOnAction(event -> { this.newCollection();}); - - gridPane.add(end, 0, 0); - - List nodeList = new ArrayList<>(gridPane.getChildren()); - - List payload = Arrays.asList(new Text(""), new Text(""), new Text(""), new Text(""), newCollectionButton); - - - insertPayload(nodeList, payload, "end", 0); - redraw(gridPane, nodeList); - - - } - - - private void newCollection() { - - - - String collectionName = "name" + collection_count++; - - bridge.newCollection(collectionName); - - - TextField collectionStateTextField = new TextField(); - collectionStateTextField.setText("STATE"); - collectionStateTextField.setStyle("-fx-text-fill: green"); - collectionStateTextField.setDisable(true); - collectionStateTextField.setId("collectionStateTextField-" + collectionName); - - Button removeCollectionButton = new Button("Remove Collection"); - removeCollectionButton.setId("removeCollectionButton-" + collectionName); - removeCollectionButton.setOnAction(event -> { this.removeCollection(collectionName);}); - - TextField addDirectoryTextField = new TextField(); - addDirectoryTextField.setId("addDirectoryTextField-" + collectionName); - - Button addDirectoryButton = new Button("Add Directory"); - addDirectoryButton.setId("addDirectoryButton-" + collectionName); - addDirectoryButton.setOnAction(event -> { this.addDirectory(collectionName);}); - - - List nodeList = new ArrayList<>(gridPane.getChildren()); - - List payload = new ArrayList<>(); - payload.addAll(Arrays.asList(new Text(""), new Text(""), collectionStateTextField, new Text(""), removeCollectionButton)); - payload.addAll(Arrays.asList(addDirectoryTextField, new Text(""), new Text(""), new Text(""), addDirectoryButton)); - - insertPayload(nodeList, payload, "newCollectionButton", -4); - redraw(gridPane, nodeList); - } - - - - - /** - * For the order & number of Nodes see ui-design.png . - * Remove the "Remove-Collection-Line" and the consecutive lines until and including the "Add-Directory-Line". - * The !=null expression protects from Text("") placeholders, who have id==null. - */ - private void removeCollection(String collectionName) { - - bridge.removeCollection(collectionName); - - List nodeList = new ArrayList<>(gridPane.getChildren()); - - here: - for (Node node : nodeList) { - - if (node.getId() != null && node.getId().equals("removeCollectionButton-" + collectionName)) { - int i = nodeList.indexOf(node) - 4; - while (i < nodeList.size()) { - nodeList.remove(i); - - if (nodeList.get(i).getId() != null && nodeList.get(i).getId().equals("addDirectoryButton-" + collectionName)) { - nodeList.remove(i); - break here; - } - } - - } - } - - redraw(gridPane, nodeList); - } - - - /** - * - */ - private void addDirectory(String collectionName) { - // TODO throw error if other collection already contains absollutepath - Window stage = gridPane.getScene().getWindow(); - - final DirectoryChooser directoryChooser = new DirectoryChooser(); - directoryChooser.setTitle("Select Directory."); - directoryChooser.setInitialDirectory(new File(System.getProperty("user.home"))); - - File directory = directoryChooser.showDialog(stage); - - if (directory != null) { - - bridge.addDirectory(collectionName, directory); - - TextField directoryPathTextField = new TextField(); - directoryPathTextField.setText(directory.getAbsolutePath()); - directoryPathTextField.setDisable(true); - directoryPathTextField.setId("directoryPathTextField-" + directory.getAbsolutePath()); - - - - TextField directoryStateTextField = new TextField(); - directoryStateTextField.setText("STATE"); - directoryStateTextField.setStyle("-fx-text-fill: green"); - directoryStateTextField.setDisable(true); - directoryStateTextField.setId("directoryStateTextField-" + directory.getAbsolutePath()); - - Button removeDirectoryButton = new Button("Remove"); - removeDirectoryButton.setId("removeDirectoryButton-" + directory.getAbsolutePath()); - removeDirectoryButton.setOnAction(event -> { this.removeDirectory(directory.getAbsolutePath());}); - - - List nodeList = new ArrayList<>(gridPane.getChildren()); - List payload = Arrays.asList(directoryPathTextField, new Text(""), directoryStateTextField, new Text(""), removeDirectoryButton); - insertPayload(nodeList, payload, "addDirectoryTextField-" + collectionName, 0); - redraw(gridPane, nodeList); - } - - - } - - - /** - * Find the Node with @param id. - * Insert the contents of the @param payload starting from the last. - * This pushes the Node with @param id forward. - */ - private void insertPayload(List nodeList, List payload, String id, int offset) { - for (Node node : nodeList) { - - if (node.getId() != null && node.getId().equals(id)) { - int i = nodeList.indexOf(node) + offset; - - for (int j = payload.size() - 1; j >= 0; j--) { - nodeList.add(i, payload.get(j)); - } - break; - } - } - } - - - /** - * Clear the gridPane and redraw it with contents of nodeList. - */ - private void redraw(GridPane gridPane, List nodeList) { - gridPane.getChildren().clear(); - - int col = 0, row = 0; - - for (Node node : nodeList) { - if (nodeList.indexOf(node) % COLUMN_COUNT == 0) { - row++; - col = 0; - } - gridPane.add(node, col, row); - col++; - } - } - - - private void removeDirectory(String directoryAbsolutePath) { - - bridge.removeDirectory(directoryAbsolutePath); - - List nodeList = new ArrayList<>(gridPane.getChildren()); - - for (Node node : nodeList) { - - if (node.getId() != null && node.getId().equals("removeDirectoryButton-" +directoryAbsolutePath)) { - int i = nodeList.indexOf(node) - 4; - for (int j = 0; j < 5; j++) { - nodeList.remove(i); - } - break; - } - } - redraw(gridPane, nodeList); - } - - -} - - diff --git a/src/main/java/com/olexyn/ensync/ui/UI.java b/src/main/java/com/olexyn/ensync/ui/UI.java deleted file mode 100644 index 7f24ca3..0000000 --- a/src/main/java/com/olexyn/ensync/ui/UI.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.olexyn.ensync.ui; - -import javafx.application.Application; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.stage.Stage; - - -public class UI extends Application implements Runnable { - - @Override - public void start(Stage primaryStage) throws Exception { - // in IDEA add ";?.fxml;?.css" to File|Settings|Compiler settings - Parent root = FXMLLoader.load(getClass().getResource("/fxml/layout.fxml")); - Scene scene = new Scene(root, 500, 500); - - primaryStage.setTitle("EnSync"); - primaryStage.setScene(scene); - primaryStage.show(); - } - - @Override - public void run() { - UI.launch(); - } -} diff --git a/src/main/resources/config.json b/src/main/resources/config.json index 07f6f02..a43b93d 100644 --- a/src/main/resources/config.json +++ b/src/main/resources/config.json @@ -1,12 +1,8 @@ { - "jsonMapOfSyncMaps": { + "dataRoot": { "syncMap1": [ - "/home/user/test/a", - "/home/user/test/b" - ], - "syncMap2": [ - "/home/user/test/c", - "/home/user/test/d" + "P:\\ensync-test", + "C:\\Users\\user\\home\\ensync-test" ] } } diff --git a/src/test/java/com/olexyn/ensync/files/FileTest.java b/src/test/java/com/olexyn/ensync/files/FileTest.java index 4412065..331fd12 100644 --- a/src/test/java/com/olexyn/ensync/files/FileTest.java +++ b/src/test/java/com/olexyn/ensync/files/FileTest.java @@ -2,11 +2,10 @@ package com.olexyn.ensync.files; import com.olexyn.ensync.Execute; import com.olexyn.ensync.Flow; -import com.olexyn.ensync.OperationMode; import com.olexyn.ensync.Tools; -import com.olexyn.ensync.artifacts.MapOfSyncMaps; -import com.olexyn.ensync.artifacts.SyncMap; -import com.olexyn.ensync.ui.UI; +import com.olexyn.ensync.artifacts.DataRoot; +import com.olexyn.ensync.artifacts.SyncBundle; +import org.json.JSONException; import org.json.JSONObject; import org.junit.Assert; import org.junit.Test; @@ -24,7 +23,7 @@ public class FileTest { final public static Thread FLOW_THREAD = new Thread(new Flow(), "flow"); final private static Tools tools = new Tools(); - final private HashMap mapOfSyncMaps = MapOfSyncMaps.get(); + final private HashMap mapOfSyncMaps = DataRoot.get(); public long fileOpsPause = 800; public long assertPause = 4000; @@ -85,19 +84,19 @@ public class FileTest { * Simple means with a static test-config.json, thus no SyncMaps are added at runtime. */ @Test - public void doSimpleFileTests() { + public void doSimpleFileTests() throws JSONException { String configPath = System.getProperty("user.dir") + "/src/test/resources/test-config.json"; String configString = tools.fileToString(new File(configPath)); JSONObject jsonMapOfSyncMaps = new JSONObject(configString).getJSONObject("jsonMapOfSyncMaps"); - for (String key : jsonMapOfSyncMaps.keySet()) { - SyncMap syncMap = new SyncMap(key); - for (Object jsonSyncDirPath : jsonMapOfSyncMaps.getJSONArray(key).toList()) { - syncMap.addDirectory(jsonSyncDirPath.toString()); - } - MapOfSyncMaps.get().put(key, syncMap); - - } +// for (String key : jsonMapOfSyncMaps.keySet()) { +// SyncMap syncMap = new SyncMap(key); +// for (Object jsonSyncDirPath : jsonMapOfSyncMaps.getJSONArray(key).toList()) { +// syncMap.addDirectory(jsonSyncDirPath.toString()); +// } +// MapOfSyncMaps.get().put(key, syncMap); +// +// } FLOW_THREAD.start();