diff --git a/README.md b/README.md index f5c2d03..4161433 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,8 @@ Sync files across directories. - To do so .listDeleted would need to be a field of Dir - And the .lists of every dir would need to be calculated before any deletion took place. - Check if the reduced reobustness is worth the prettier solution. - - File is created in DirA - - Sync creates the file in DirB + - File is created in DirB + - Sync creates the file in DirA - Sync creates the file in DirB - this means the file in DirB is overwritten with `cp` for no reason. - implement a check to prevent this. \ No newline at end of file diff --git a/src/com/olexyn/ensync/Flow.java b/src/com/olexyn/ensync/Flow.java index 847e3c4..d95a968 100644 --- a/src/com/olexyn/ensync/Flow.java +++ b/src/com/olexyn/ensync/Flow.java @@ -38,7 +38,7 @@ public class Flow { String stateFilePath = syncDirectory.stateFilePath(path); if (new File(stateFilePath).exists()) { - syncDirectory.readStateFile(syncDirectory.path); + syncDirectory.readStateFile(); } else { syncDirectory.writeStateFile(path); } @@ -53,11 +53,11 @@ public class Flow { String path = syncDirectory.path; - syncDirectory.readState(path); + syncDirectory.readState(); - syncDirectory.makeListCreated(path); - syncDirectory.makeListDeleted(path); - syncDirectory.makeListModified(path); + syncDirectory.makeListCreated(); + syncDirectory.makeListDeleted(); + syncDirectory.makeListModified(); syncDirectory.doCreate(); syncDirectory.doDelete(); diff --git a/src/com/olexyn/ensync/artifacts/SyncDirectory.java b/src/com/olexyn/ensync/artifacts/SyncDirectory.java index 30abcd7..831a488 100644 --- a/src/com/olexyn/ensync/artifacts/SyncDirectory.java +++ b/src/com/olexyn/ensync/artifacts/SyncDirectory.java @@ -40,7 +40,7 @@ public class SyncDirectory { /** * NOTE that the SFile().lastModifiedOld is not set here, so it is 0 by default. */ - public Map readState(String path) { + public Map readState() { Map filemap = new HashMap<>(); Execute.TwoBr find = x.execute(new String[]{"find", @@ -64,7 +64,7 @@ public class SyncDirectory { /** * READ the contents of StateFile to Map. */ - public Map readStateFile(String path) { + public Map readStateFile() { Map filemap = new HashMap<>(); List lines = tools.fileToLines(new File(stateFilePath(path))); @@ -76,7 +76,7 @@ public class SyncDirectory { String sFilePath = line.replace(modTimeString + " ", ""); SyncFile sfile = new SyncFile(sFilePath); - sfile.setLastModifiedOld(modTime); + sfile.setStateFileTime(modTime); filemap.put(sFilePath, sfile); } @@ -92,10 +92,10 @@ public class SyncDirectory { * * @return */ - public void makeListCreated(String path) { + public void makeListCreated() { listCreated = new ArrayList<>(); - Map fromA = readState(path); - Map substractB = readStateFile(path); + Map fromA = readState(); + Map substractB = readStateFile(); listCreated = tools.mapMinus(fromA, substractB); } @@ -112,10 +112,10 @@ public class SyncDirectory { * * @return */ - public void makeListDeleted(String path) { + public void makeListDeleted() { listDeleted = new ArrayList<>(); - Map fromA = readStateFile(path); - Map substractB = readState(path); + Map fromA = readStateFile(); + Map substractB = readState(); listDeleted = tools.mapMinus(fromA, substractB); @@ -128,12 +128,12 @@ public class SyncDirectory { * * @return */ - public void makeListModified(String path) { + public void makeListModified() { listModified = new ArrayList<>(); - Map oldMap = readStateFile(path); + Map oldMap = readStateFile(); - for (Map.Entry newFileEntry : readState(path).entrySet()) { + for (Map.Entry newFileEntry : readState().entrySet()) { // If KEY exists in OLD , thus FILE was NOT created. String newFileKey = newFileEntry.getKey(); @@ -144,7 +144,7 @@ public class SyncDirectory { long lastModifiedNew = newFile.lastModified(); - long lastModifiedOld = oldMap.get(newFileKey).lastModifiedOld(); + long lastModifiedOld = oldMap.get(newFileKey).stateFileTime(); if (lastModifiedNew > lastModifiedOld) { listModified.add(newFile); @@ -178,61 +178,114 @@ public class SyncDirectory { } - public void doCreate() { + private class Info { + + private String relativePath = null; + private String thisFilePath = null; + private String otherFilePath = null; + private File otherFile = null; + private String otherParentPath = null; + private File otherParentFile = null; + private long thisStateFileTime = 0; + private long thisTimeModified = 0; + private long otherTimeModified = 0; + + + private Info(SyncDirectory thisSD, + SyncFile sFile, + SyncDirectory otherSD) { + // Example: + // syncDirectory /foo + // otherSyncDirectory /bar + // createdFile /foo/hello/created-file.gif + // relativePath /hello/created-file.gif + this.relativePath = sFile.getPath().replace(thisSD.path, ""); + this.thisFilePath = sFile.getPath(); + this.otherFilePath = otherSD.path + relativePath; + this.otherFile = new File(otherFilePath); + + this.otherParentPath = otherFile.getParent(); + this.otherParentFile = new File(otherParentPath); + + if (thisSD.readStateFile().get(thisFilePath) != null) { + this.thisStateFileTime = thisSD.readStateFile().get(thisFilePath).stateFileTime(); + } else { + // thisFile does not exist in StateFile, a value of 0 can be seen as equal to "never existed". + this.thisStateFileTime = 0; + } + this.thisTimeModified = sFile.lastModified(); - for (File createdFile : listCreated) { - for (Map.Entry otherEntry : syncEntity.syncDirectories.entrySet()) { - SyncDirectory otherSyncDirectory = otherEntry.getValue(); + if (otherFile.exists()) { - if (!this.equals(otherSyncDirectory)) { - // Example: - // syncDirectory /foo - // otherSyncDirectory /bar - // createdFile /foo/hello/created-file.gif - // relativePath /hello/created-file.gif - String relativePath = createdFile.getPath().replace(this.path, ""); - String targetPath = otherSyncDirectory.path + relativePath; - String targetParentPath = new File(targetPath).getParent(); - if (!new File(targetParentPath).exists()) { - String[] cmd = new String[]{"mkdir", - "-p", - targetParentPath}; - x.execute(cmd); - } + this.otherTimeModified = otherFile.lastModified(); - String[] cmd = new String[]{"cp", - createdFile.getPath(), - otherSyncDirectory.path + relativePath}; - x.execute(cmd); + } else { + if (otherSD.readStateFile().get(otherFilePath) != null) { + this.otherTimeModified = otherSD.readStateFile().get(otherFilePath).stateFileTime(); + } else { + this.otherTimeModified = 0; } } } + + } + public void doCreate() { + + for (SyncFile createdFile : listCreated) { + + if (createdFile.isFile()) { + + for (Map.Entry otherEntry : syncEntity.syncDirectories.entrySet()) { + SyncDirectory otherSyncDirectory = otherEntry.getValue(); + + if (!this.equals(otherSyncDirectory)) { + + Info info = new Info(this, createdFile, otherSyncDirectory); + + createFile(info); + } + } + } + } + } + + + /** + * + */ public void doDelete() { - for (File deletedFile : listDeleted) { + for (SyncFile deletedFile : listDeleted) { + for (Map.Entry otherEntry : syncEntity.syncDirectories.entrySet()) { SyncDirectory otherSyncDirectory = otherEntry.getValue(); if (!this.equals(otherSyncDirectory)) { - String relativePath = deletedFile.getPath().replace(this.path, ""); - String[] cmd = new String[]{"rm", - "-r", - otherSyncDirectory.path + relativePath}; - x.execute(cmd); - } - } - } + Info info = new Info(this, deletedFile, otherSyncDirectory); + if (info.otherFile.isFile()) { + // if the otherFile was created with ensync it will have the == TimeModified. + if (info.thisStateFileTime >= info.otherTimeModified) { + String[] cmd = new String[]{"rm", + "-r", + info.otherFilePath}; + x.execute(cmd); + } + } + } + } + } } + public void doModify() { for (SyncFile modifiedFile : this.listModified) { @@ -244,32 +297,10 @@ public class SyncDirectory { if (!this.equals(otherSyncDirectory)) { - String relativePath = modifiedFile.getPath().replace(this.path, ""); - - - String otherFilePath = otherSyncDirectory.path + relativePath; - SyncFile otherFile = new SyncFile(otherFilePath); - - if (otherFile.exists()) { - if (modifiedFile.lastModified() > otherFile.lastModified()) { - // IF both Files exist, and this File NEWER -> UPDATE the other File - String[] cmd = new String[]{"cp", - modifiedFile.getPath(), - otherFilePath}; - x.execute(cmd); - } - } else { - // IF other file does NOT exist -> UPDATE (i.e. create) the other File - String[] cmd = new String[]{"mkdir", - "-p", - otherFilePath}; - x.execute(cmd); + Info info = new Info(this, modifiedFile, otherSyncDirectory); - cmd = new String[]{"cp", - modifiedFile.getPath(), - otherFilePath}; - x.execute(cmd); - } + + createFile(info); } @@ -282,4 +313,20 @@ public class SyncDirectory { } + private void createFile(Info info) { + if (!info.otherFile.exists() || info.thisTimeModified > info.otherTimeModified) { + if (!info.otherParentFile.exists()) { + String[] cmd = new String[]{"mkdir", + "-p", + info.otherParentPath}; + x.execute(cmd); + } + String[] cmd = new String[]{"cp", + "-p", + info.thisFilePath, + info.otherFilePath}; + x.execute(cmd); + } + } + } diff --git a/src/com/olexyn/ensync/artifacts/SyncFile.java b/src/com/olexyn/ensync/artifacts/SyncFile.java index e729530..6c3968e 100644 --- a/src/com/olexyn/ensync/artifacts/SyncFile.java +++ b/src/com/olexyn/ensync/artifacts/SyncFile.java @@ -6,7 +6,8 @@ public class SyncFile extends File { // Very IMPORTANT field. Allows to store lastModified as it is stored in the StateFile. - private long lastModifiedOld = 0; + private long stateFileTime = 0; + public SyncFile(String pathname) { @@ -15,12 +16,16 @@ public class SyncFile extends File { - public long lastModifiedOld(){ - return lastModifiedOld; + public long stateFileTime(){ + return stateFileTime; } - public void setLastModifiedOld(long value){ - lastModifiedOld = value; + public void setStateFileTime(long value){ + stateFileTime = value; } + + + + } diff --git a/src/com/olexyn/ensync/file-ops-covered-vs-missing.png b/src/com/olexyn/ensync/file-ops-covered-vs-missing.png index 237c454..1080cb8 100644 Binary files a/src/com/olexyn/ensync/file-ops-covered-vs-missing.png and b/src/com/olexyn/ensync/file-ops-covered-vs-missing.png differ diff --git a/src/com/olexyn/ensync/file-ops-covered-vs-missing.uxf b/src/com/olexyn/ensync/file-ops-covered-vs-missing.uxf index f0ebaa8..46a0051 100644 --- a/src/com/olexyn/ensync/file-ops-covered-vs-missing.uxf +++ b/src/com/olexyn/ensync/file-ops-covered-vs-missing.uxf @@ -4,31 +4,31 @@ UMLObject - 700 - 720 - 110 + 890 + 380 + 150 40 - Directory B + otherDirectory UMLObject - 700 - 680 - 110 + 890 + 340 + 150 40 - Directory A + this.Directory UMLObject - 700 - 530 - 110 + 980 + 280 + 90 40 Delete @@ -39,9 +39,9 @@ group=1 UMLObject - 700 - 570 - 110 + 1070 + 280 + 90 40 Create @@ -52,9 +52,9 @@ group=1 UMLObject - 700 - 610 - 110 + 1160 + 280 + 90 40 Modify @@ -65,305 +65,379 @@ group=1 UMLState - 850 - 830 + 1050 + 340 70 40 - YES -bg=green + File +bg=red +group=2 + + + + UMLObject + + 890 + 280 + 90 + 40 + + Unchanged +bg=white +group=1 UMLState - 850 - 720 + 1120 + 380 70 40 - File + File +group=2 UMLState - 940 - 720 + 1050 + 380 70 40 File -bg=red +bg=red +group=2 UMLState - 1300 - 830 + 1120 + 340 70 40 - NO -bg=red + File +bg=red +group=2 - UMLObject + UMLState - 700 - 490 - 110 + 1410 + 340 + 70 40 - Unchanged -bg=white -group=1 + File +bg=green +group=3 UMLState - 850 - 680 + 1410 + 380 70 40 - File + File +group=3 UMLState - 940 - 680 + 1340 + 380 70 40 - File + File +bg=green +group=3 UMLState - 1030 - 720 + 1340 + 340 70 40 File -bg=red +bg=green +group=3 UMLState - 1030 - 680 + 1700 + 340 70 40 File -bg=red +bg=yellow +group=4 UMLState - 1120 - 720 + 1700 + 380 + 70 + 40 + + File +group=4 + + + + UMLState + + 1630 + 380 70 40 File -bg=green +bg=yellow +group=4 UMLState - 1120 - 680 + 1630 + 340 70 40 - File + File +bg=yellow +group=4 UMLState - 1210 - 720 + 1190 + 340 70 40 File -bg=green +bg=red +group=2 UMLState - 1210 - 680 + 1190 + 380 70 40 File -bg=green +bg=green +group=2 UMLState - 1300 - 720 + 1260 + 340 70 40 File -bg=yellow +bg=red +group=2 UMLState - 1300 - 680 + 1260 + 380 70 40 - File + File +bg=yellow +group=2 UMLState - 1390 - 720 + 1550 + 340 70 40 File -bg=yellow +bg=green +group=3 UMLState - 1390 - 680 + 1550 + 380 70 40 File -bg=yellow +bg=yellow +group=3 + + + + UMLState + + 1050 + 440 + 70 + 40 + + do +nothing + + + + UMLState + + 1120 + 440 + 790 + 40 + + cp if newer + try: time deletet = last time present in StateFile, else time deleted = 0 (~never existed) +halign=left UMLState 1480 - 680 + 380 70 40 File -bg=red +bg=red +group=3 UMLState 1480 - 720 + 340 70 40 File -bg=green +bg=green +group=3 UMLState - 1570 - 680 + 1770 + 340 70 40 File -bg=red +bg=yellow +group=4 UMLState - 1570 - 720 + 1840 + 380 70 40 File -bg=yellow +bg=green +group=4 UMLState - 1660 - 680 + 1840 + 340 70 40 File -bg=green +bg=yellow +group=4 UMLState - 1660 - 720 + 1770 + 380 70 40 File -bg=yellow +bg=red +group=4 - UMLNote + UMLObject - 830 - 490 - 150 - 80 + 1050 + 510 + 70 + 40 - 2^4 = 16 -however only 10 -because 6 are symmetrical. -bg=white + YES +bg=green UMLObject - 700 - 830 - 110 + 1340 + 510 + 70 40 - Covered? + YES +bg=green - UMLState + UMLObject - 940 - 830 + 1410 + 510 70 40 @@ -372,10 +446,10 @@ bg=green - UMLState + UMLObject 1120 - 830 + 510 70 40 @@ -383,76 +457,406 @@ bg=green bg=green + + UMLObject + + 880 + 760 + 150 + 40 + + otherDirectory + + + + UMLObject + + 880 + 670 + 150 + 40 + + this.Directory + + UMLState - 1390 - 830 + 1340 + 670 70 40 - NO + File bg=red UMLState - 1570 - 830 + 1250 + 770 70 40 - NO -bg=red + File +bg=green UMLState - 1660 - 830 + 1090 + 670 70 40 - NO -bg=red + File + + + + UMLObject + + 1490 + 670 + 80 + 140 + + result + + + + UMLObject + + 1170 + 670 + 70 + 140 + + time +of +last +lool + + + + UMLState + + 1580 + 770 + 70 + 40 + + File +bg=green + + + + UMLState + + 1580 + 670 + 70 + 40 + + File +bg=green + + + + UMLObject + + 890 + 1040 + 150 + 40 + + otherDirectory + + + + UMLObject + + 890 + 950 + 150 + 40 + + this.Directory UMLState - 1210 - 830 + 1470 + 950 70 40 - NO + File bg=red UMLState - 1480 - 830 + 1180 + 1050 + 70 + 40 + + File +bg=green + + + + UMLState + + 1100 + 950 70 40 - NO + File + + + + UMLObject + + 1630 + 950 + 80 + 140 + + result + + + + UMLObject + + 1270 + 950 + 70 + 140 + + time +of +last +lool + + + + UMLState + + 1720 + 950 + 70 + 40 + + File bg=red UMLState - 1030 - 830 + 1720 + 1050 70 40 - NO + File bg=red + + UMLObject + + 880 + 600 + 720 + 30 + + Deleted Files are tracked by their last existance in a StateFile. + + + + UMLObject + + 1190 + 510 + 70 + 40 + + YES +bg=green + + + + UMLObject + + 1260 + 510 + 70 + 40 + + YES +bg=green + + + + UMLState + + 1360 + 950 + 70 + 40 + + File +bg=green + + + + UMLState + + 1360 + 1050 + 70 + 40 + + File +bg=green + + + + UMLObject + + 1560 + 950 + 70 + 140 + + current +loop + + + + UMLObject + + 1420 + 670 + 70 + 140 + + current +loop + + + + Relation + + 1110 + 640 + 280 + 50 + + lt=- + 10.0;30.0;10.0;10.0;260.0;10.0;260.0;30.0 + + + Relation + + 1380 + 900 + 140 + 70 + + lt=<- +comprison >= + 10.0;50.0;10.0;20.0;120.0;20.0;120.0;50.0 + + + UMLObject + + 1480 + 510 + 70 + 40 + + RED +bg=gray + + + + UMLObject + + 1550 + 510 + 70 + 40 + + YES +bg=green + + + + UMLObject + + 1630 + 510 + 70 + 40 + + YES +bg=green + + + + UMLObject + + 1700 + 510 + 70 + 40 + + YES +bg=green + + + + UMLObject + + 1770 + 510 + 70 + 40 + + RED +bg=gray + + + + UMLObject + + 1840 + 510 + 70 + 40 + + RED +bg=gray + + + + Relation + + 1110 + 700 + 200 + 160 + + lt=<- +comprison >= + 10.0;10.0;10.0;140.0;180.0;140.0;180.0;110.0 +