parent
cd5f7be740
commit
4e6ad69877
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.olexyn.ensync.artifacts;
|
||||
|
||||
public interface Constants {
|
||||
|
||||
String STATE_FILE_NAME = "state.ensync";
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -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<Node> nodeList = new ArrayList<>(gridPane.getChildren());
|
||||
|
||||
List<Node> 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<Node> nodeList = new ArrayList<>(gridPane.getChildren());
|
||||
|
||||
List<Node> 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<Node> 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<Node> nodeList = new ArrayList<>(gridPane.getChildren());
|
||||
List<Node> 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<Node> nodeList, List<Node> 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<Node> 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<Node> 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in new issue