Simplifed the flow. Some bugs present.

pull/1/head
Ivan Olexyn 5 years ago
parent 462bd11a75
commit 21ab7839e3

@ -29,6 +29,7 @@ Sync files across directories.
### Issues <a name="issues"></a> ### Issues <a name="issues"></a>
- Have Map entries be remove, once file ops is performed.
- Create a parallel Thread for each SyncEnity. - Create a parallel Thread for each SyncEnity.
- Add support for modification dates. - Add support for modification dates.
- And thereby eventually support 10 out of 10 file operation types. - And thereby eventually support 10 out of 10 file operation types.

@ -1,13 +0,0 @@
package com.olexyn.ensync;
import java.util.List;
public class Core {
public Core(){
}
}

@ -0,0 +1,76 @@
package com.olexyn.ensync;
import com.olexyn.ensync.artifacts.SyncDirectory;
import com.olexyn.ensync.artifacts.SyncEntity;
import com.olexyn.ensync.artifacts.SyncFile;
import java.io.File;
import java.util.List;
import java.util.Map;
public class Flow {
public Flow(){
}
public void start() {
File asdf = new File("/home/user/");
System.out.println(asdf.lastModified());
Tools tools = new Tools();
Execute x = new Execute();
SyncEntity syncEntity = new SyncEntity("test");
syncEntity.addDirectory("/home/user/test/a");
syncEntity.addDirectory("/home/user/test/b");
//syncEntity.addDirectory("/home/user/test/c");
for (Map.Entry<String, SyncDirectory> entry : syncEntity.syncDirectories.entrySet()) {
SyncDirectory syncDirectory = entry.getValue();
String path = syncDirectory.path;
String stateFilePath = syncDirectory.stateFilePath(path);
if (new File(stateFilePath).exists()) {
syncDirectory.readStateFile(syncDirectory.path);
} else {
syncDirectory.writeStateFile(path);
}
}
while (true) {
for (Map.Entry<String, SyncDirectory> entry : syncEntity.syncDirectories.entrySet()) {
SyncDirectory syncDirectory = entry.getValue();
String path = syncDirectory.path;
syncDirectory.readState(path);
List<SyncFile> listCreated = syncDirectory.makeListCreated(path);
List<SyncFile> listDeleted = syncDirectory.makeListDeleted(path);
List<SyncFile> listModified = syncDirectory.makeListModified(path);
syncDirectory.doCreate(listCreated);
syncDirectory.doDelete(listDeleted);
syncDirectory.doModify(listModified);
syncDirectory.writeStateFile(path);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}}
}
}

@ -1,71 +1,16 @@
package com.olexyn.ensync; package com.olexyn.ensync;
import com.olexyn.ensync.artifacts.SyncDirectory;
import com.olexyn.ensync.artifacts.SyncEntity;
import java.util.*;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
new Flow().start();
Tools tools = new Tools();
Execute x = new Execute();
SyncEntity syncEntity = new SyncEntity("test");
syncEntity.addDirectory("/home/user/test/a");
syncEntity.addDirectory("/home/user/test/b");
//syncEntity.addDirectory("/home/user/test/c");
int br1 = 0;
while (true) {
for (Map.Entry<String, SyncDirectory> entry : syncEntity.syncDirectories.entrySet()) {
SyncDirectory syncDirectory = entry.getValue();
syncDirectory.updateStateFileNew();
syncDirectory.updatePoolNew();
syncDirectory.getListCreated();
syncDirectory.getListDeleted();
//
syncDirectory.doSyncOps();
//
// WARNING:
// Be very carefull when to update the StateFileOld
// i.e. you create a File and update StateFileOld without updating
// -> create newFile -> update StateFileNew-> getListCreated contains newFile -> addToMapCreated -> create copies as needed -> updateStateFileOld -> OK
// -> create newFile -> update StateFileOld -> getListDeletd contains newFile -> VERY BAD
//
syncDirectory.updateStateFileNew();
syncDirectory.updatePoolNew();
syncDirectory.updateStateFileOld();
syncDirectory.updatePoolOld();
}
//Map<String,File> mapCreated = syncEntity.getMapCreated();
//Map<String,File> mapDeleted = syncEntity.getMapDeleted();
int br = 0;
try {Thread.sleep(1000);}
catch (InterruptedException e){
}
}
} }
} }

@ -1,13 +1,11 @@
package com.olexyn.ensync; package com.olexyn.ensync;
import java.io.BufferedReader; import com.olexyn.ensync.artifacts.SyncFile;
import java.io.File;
import java.io.IOException; import java.io.*;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.*; import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Tools { public class Tools {
@ -18,25 +16,15 @@ public class Tools {
} }
/** /**
* Convert BufferedReader to String.
* *
* @param br BufferedReader
* @return String
*/ */
public void rsync(String param,
String source,
String destination) {
//
BufferedReader foo = x.execute(new String[]{"rsync",
param,
source,
destination}).output;
}
public String getConf() {
BufferedReader output = x.execute(new String[]{"cat",
System.getProperty("user.dir") + "/src/com/olexyn/ensync/sync.conf"}).output;
return brToString(output);
}
public String brToString(BufferedReader br) { public String brToString(BufferedReader br) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Object[] br_array = br.lines().toArray(); Object[] br_array = br.lines().toArray();
@ -46,30 +34,23 @@ public class Tools {
return sb.toString(); return sb.toString();
} }
/** /**
* StateFile -> FilePool * Convert BufferedReader to List of Strings.
*
* @param br BufferedReader
* @return List
*/ */
public Map<String, File> fileToPool(File file, public List<String> brToListString(BufferedReader br) {
String type) { List<String> list = new ArrayList<>();
List<String> lines = fileToLines(file); Object[] br_array = br.lines().toArray();
return linesToFilePool(lines, type); for (int i = 0; i < br_array.length; i++) {
list.add(br_array[i].toString());
}
return list;
} }
/**
* CREATE a StateFile from realPath. <p>
* WRITE the StateFle to stateFilePath.
* @param realPath the path of the directory the StateFile is created for.
* @param stateFilePath the desired path for the created Statefile.
*/
public File generateStateFile(String realPath, String stateFilePath) {
String[] cmd = new String[]{System.getProperty("user.dir") + "/src/com/olexyn/ensync/shell/toFile.sh",
"find",
realPath,
stateFilePath};
x.execute(cmd);
return new File(realPath);
}
public List<String> fileToLines(File file) { public List<String> fileToLines(File file) {
@ -84,32 +65,19 @@ public class Tools {
} }
public Map<String, File> linesToFilePool(List<String> lines,
String type) {
Map<String, File> filepool = new HashMap<>();
for (String line : lines) {
File file = new File(line);
if (type.equals("all") || type.equals("dir") && file.isDirectory() || type.equals("file") && file.isFile()) { public List<SyncFile> mapMinus(Map<String, SyncFile> fromA,
filepool.put(line, file); Map<String, SyncFile> substractB) {
}
}
return filepool;
}
public List<File> mapMinus(Map<String, File> fromA,
Map<String, File> substractB) {
List<File> difference = new ArrayList<>(); List<SyncFile> difference = new ArrayList<>();
Iterator iterator = fromA.entrySet().iterator(); Iterator iterator = fromA.entrySet().iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next(); Map.Entry entry = (Map.Entry) iterator.next();
String key = (String) entry.getKey(); String key = (String) entry.getKey();
File file = fromA.get(key); SyncFile file = fromA.get(key);
if (fromA.containsKey(key) && !substractB.containsKey(key)) { if (fromA.containsKey(key) && !substractB.containsKey(key)) {
@ -120,4 +88,51 @@ public class Tools {
} }
return difference; return difference;
} }
public StringBuilder stringListToSb(List<String> list) {
StringBuilder sb = new StringBuilder();
for (String line : list) {
sb.append(line + "\n");
}
return sb;
}
/**
* Write sb to file at path .
*
* @param path <i>String</i>
* @param sb <i>StringBuilder</i>
*/
public void writeSbToFile(String path,
StringBuilder sb) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(path)));
bw.write(sb.toString());
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Write List of String to file at path .
*
* @param path <i>String</i>
* @param list <i>StringBuilder</i>
*/
public void writeStringListToFile(String path,
List<String> list) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(path)));
StringBuilder sb = stringListToSb(list);
bw.write(sb.toString());
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} }

@ -0,0 +1,36 @@
package com.olexyn.ensync.artifacts;
import java.util.Map;
public class Data {
Map<String, Map<String, SyncFile>> database;
public Data(){
}
}

@ -1,29 +0,0 @@
package com.olexyn.ensync.artifacts;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class StateFile {
private final String[] types = new String[]{ "OLD" , "NEW"};
public String stateFilePath;
public File stateFileOld;
private Map<String, File> poolOld = new HashMap<>();
public StateFile(){
}
public void update(){
}
}

@ -8,22 +8,12 @@ import java.util.*;
public class SyncDirectory { public class SyncDirectory {
public String realPath;
public String stateFileBasePath;
public String stateFileOldPath;
public String stateFileNewPath;
public File stateFileOld;
public File stateFileNew;
private Map<String, File> poolOld = new HashMap<>();
private Map<String, File> poolNew = new HashMap<>();
private List<File> listCreated = new ArrayList<>();
private List<File> listDeleted = new ArrayList<>();
private SyncEntity syncEntity; private SyncEntity syncEntity;
public String path= null;
private String state = null;
// For an explanation of what the STATES mean, see the flow.png
private final List<String> STATES = new ArrayList<>(Arrays.asList( "NEW-1", "LIST-1" , "LIST-2" , "SYNC-1" , "NEW-2", "OLD-1"));
Tools tools = new Tools(); Tools tools = new Tools();
Execute x = new Execute(); Execute x = new Execute();
@ -31,153 +21,147 @@ public class SyncDirectory {
/** /**
* Create a SyncDirectory from realPath. * Create a SyncDirectory from realPath.
* *
* @param realPath
* @see SyncEntity * @see SyncEntity
*/ */
public SyncDirectory(String realPath, SyncEntity syncEntity) { public SyncDirectory(String path , SyncEntity syncEntity) {
this.realPath = realPath; this.path = path;
stateFileBasePath = "/tmp/find" + this.realPath.replace("/", "-");
stateFileOldPath = stateFileBasePath + "-old";
stateFileNewPath = stateFileBasePath + "-new";
stateFileOld = getStateFileOld();
stateFileNew = getStateFileNew();
poolOld = getPoolOld();
poolNew = getPoolNew();
this.syncEntity = syncEntity; this.syncEntity = syncEntity;
} }
/** /**
* IF NOT EXISTS the StateFileOld for this SyncDirectory,<p> * NOTE that the SFile().lastModifiedOld is not set here, so it is 0 by default.
* - THEN create the File on Disk.
*
* @return the StateFileOld.
*/ */
public File getStateFileOld() { public Map<String, SyncFile> readState(String path) {
stateFileOld = new File(stateFileOldPath); Map<String, SyncFile> filemap = new HashMap<>();
if (!stateFileOld.exists()) {
stateFileOld = tools.generateStateFile(realPath, stateFileOldPath); Execute.TwoBr find = x.execute(new String[]{"find",
path});
List<String> pathList = tools.brToListString(find.output);
for (String filePath : pathList) {
filemap.put(filePath, new SyncFile(filePath));
} }
return stateFileOld;
return filemap;
} }
/** /**
* READ directory contents.<p> * READ the contents of StateFile to Map.
* WRITE a new StateFileNew to Disk. This is IMPORTANT in order to make sure that StateFileOld is NEVER newer than StateFileNew.<p>
* WRITE a new StateFileOld to Disk.
*/ */
public void updateStateFileOld() { public Map<String, SyncFile> readStateFile(String path) {
// Map<String, SyncFile> filemap = new HashMap<>();
if (state.equals(STATES.get(4))){ List<String> lines = tools.fileToLines(new File(stateFilePath(path)));
state = STATES.get(5);
} else {
return ;
}
tools.generateStateFile(realPath, stateFileOldPath);
}
public File getStateFileNew() { for (String line : lines) {
stateFileNew = new File(stateFileNewPath); // this is a predefined format: "modification-time path"
if (!stateFileNew.exists()) { String modTimeString = line.split("")[0];
stateFileNew = tools.generateStateFile(realPath, stateFileNewPath); long modTime = Long.parseLong(modTimeString);
String sFilePath = line.replace(modTimeString + "", "");
SyncFile sfile = new SyncFile(sFilePath);
sfile.setLastModifiedOld(modTime);
filemap.put(line, sfile);
} }
return stateFileNew;
return filemap;
} }
/** /**
* READ directory contents.<p> * Compare the OLD and NEW pools.
* WRITE a new StateFileNew Disk. *
* @return
*/ */
public void updateStateFileNew() { public List<SyncFile> makeListCreated(String path) {
//
if (state == null || state.equals(STATES.get(5))){
state = STATES.get(0);
}else if (state.equals(STATES.get(3))){
state = STATES.get(4);
} else {
return;
}
return tools.mapMinus(readState(path), readStateFile(path));
}
tools.generateStateFile(realPath, stateFileNewPath); public String stateFilePath(String path) {
return "/tmp/ensync/state" + path.replace("/", "-");
}
} /**
* Compare the OLD and NEW pools.
*
* @return
*/
public List<SyncFile> makeListDeleted(String path) {
public Map<String, File> getPoolOld() { return tools.mapMinus(readStateFile(path), readState(path));
if (poolOld.isEmpty()) {
updatePoolOld();
}
return poolOld;
} }
/** /**
* UPDATE PoolOld FROM contents of StateFileOld. * Compare the OLD and NEW pools.
*
* @return
*/ */
public void updatePoolOld() { public List<SyncFile> makeListModified(String path) {
poolOld = tools.fileToPool(getStateFileOld(), "all"); List<SyncFile> listModified = new ArrayList<>();
Map<String, SyncFile> oldMap = readStateFile(path);
} for (Map.Entry<String, SyncFile> newFileEntry : readState(path).entrySet()) {
// If KEY exists in OLD , thus FILE was NOT created.
String newFileKey = newFileEntry.getKey();
SyncFile newFile = newFileEntry.getValue();
if (oldMap.containsKey(newFileKey)) {
long lastModifiedNew = newFile.lastModified();
public Map<String, File> getPoolNew() { long lastModifiedOld = oldMap.get(newFileKey).lastModifiedOld();
if (poolNew.isEmpty()) {
updatePoolNew(); if (lastModifiedNew > lastModifiedOld) {
listModified.add(newFile);
}
} }
return poolNew;
} }
return listModified;
}
/** /**
* UPDATE PoolNew FROM contents of StateFileNew. * QUERY state of the filesystem at realPath.
* WRITE the state of the filesystem to file.
*/ */
public void updatePoolNew() { public void writeStateFile(String path) {
poolNew = tools.fileToPool(getStateFileNew(), "all"); List<String> outputList = new ArrayList<>();
}
public List<File> getListCreated() {
if (state.equals(STATES.get(0))){
state = STATES.get(1);
} else {
return null;
}
updateListCreated();
return listCreated;
}
public void updateListCreated(){ Execute.TwoBr find = x.execute(new String[]{"find",
path});
listCreated = tools.mapMinus(getPoolNew(), getPoolOld()); List<String> pathList = tools.brToListString(find.output);
}
public List<File> getListDeleted() {
if (state.equals(STATES.get(1))){
state = STATES.get(2);
} else {
return null;
}
listDeleted = tools.mapMinus(getPoolOld(), getPoolNew());
return listDeleted; for (String filePath : pathList) {
long lastModified = new File(filePath).lastModified();
outputList.add("" + lastModified + " " + filePath);
} }
public void doSyncOps(){ tools.writeStringListToFile(stateFilePath(path), outputList);
if (state.equals(STATES.get(2))){
state = STATES.get(3);
} else {
return ;
} }
public void doCreate(List<SyncFile> listCreated){
for (File createdFile : listCreated) { for (File createdFile : listCreated) {
@ -190,8 +174,8 @@ public class SyncDirectory {
// otherSyncDirectory /bar // otherSyncDirectory /bar
// createdFile /foo/hello/created-file.gif // createdFile /foo/hello/created-file.gif
// relativePath /hello/created-file.gif // relativePath /hello/created-file.gif
String relativePath = createdFile.getPath().replace(this.realPath, ""); String relativePath = createdFile.getPath().replace(this.path, "");
String targetPath = otherSyncDirectory.realPath + relativePath; String targetPath = otherSyncDirectory.path + relativePath;
String targetParentPath = new File(targetPath).getParent(); String targetParentPath = new File(targetPath).getParent();
if (!new File(targetParentPath).exists()) { if (!new File(targetParentPath).exists()) {
String[] cmd = new String[]{"mkdir", String[] cmd = new String[]{"mkdir",
@ -202,28 +186,44 @@ public class SyncDirectory {
String[] cmd = new String[]{"cp", String[] cmd = new String[]{"cp",
createdFile.getPath(), createdFile.getPath(),
otherSyncDirectory.realPath + relativePath}; otherSyncDirectory.path + relativePath};
x.execute(cmd); x.execute(cmd);
} }
} }
} }
}
public void doDelete(List<SyncFile> listDeleted){
//
for (File deletedFile : listDeleted) { for (File deletedFile : listDeleted) {
for (Map.Entry<String, SyncDirectory> otherEntry : syncEntity.syncDirectories.entrySet()) { for (Map.Entry<String, SyncDirectory> otherEntry : syncEntity.syncDirectories.entrySet()) {
SyncDirectory otherSyncDirectory = otherEntry.getValue(); SyncDirectory otherSyncDirectory = otherEntry.getValue();
if (!this.equals(otherSyncDirectory)) { if (!this.equals(otherSyncDirectory)) {
String relativePath = deletedFile.getPath().replace(this.realPath, ""); String relativePath = deletedFile.getPath().replace(this.path, "");
String[] cmd = new String[]{"rm", "-r", String[] cmd = new String[]{"rm",
otherSyncDirectory.realPath + relativePath}; "-r",
otherSyncDirectory.path + relativePath};
x.execute(cmd); x.execute(cmd);
} }
} }
} }
} }
public void doModify(List<SyncFile> listModified) {
}
} }

@ -0,0 +1,26 @@
package com.olexyn.ensync.artifacts;
import java.io.File;
public class SyncFile extends File {
// Very IMPORTANT field. Allows to store lastModified as it is stored in the StateFile.
private long lastModifiedOld = 0;
public SyncFile(String pathname) {
super(pathname);
}
public long lastModifiedOld(){
return lastModifiedOld;
}
public void setLastModifiedOld(long value){
lastModifiedOld = value;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 44 KiB

@ -4,8 +4,8 @@
<element> <element>
<id>UMLClass</id> <id>UMLClass</id>
<coordinates> <coordinates>
<x>1350</x> <x>1230</x>
<y>1220</y> <y>620</y>
<w>130</w> <w>130</w>
<h>60</h> <h>60</h>
</coordinates> </coordinates>
@ -18,8 +18,8 @@ group=1</panel_attributes>
<element> <element>
<id>UMLClass</id> <id>UMLClass</id>
<coordinates> <coordinates>
<x>1480</x> <x>1360</x>
<y>1220</y> <y>620</y>
<w>130</w> <w>130</w>
<h>30</h> <h>30</h>
</coordinates> </coordinates>
@ -32,8 +32,8 @@ group=1</panel_attributes>
<element> <element>
<id>UMLClass</id> <id>UMLClass</id>
<coordinates> <coordinates>
<x>1480</x> <x>1360</x>
<y>1250</y> <y>650</y>
<w>130</w> <w>130</w>
<h>30</h> <h>30</h>
</coordinates> </coordinates>
@ -45,8 +45,8 @@ group=1</panel_attributes>
<element> <element>
<id>UMLClass</id> <id>UMLClass</id>
<coordinates> <coordinates>
<x>1350</x> <x>1230</x>
<y>1040</y> <y>520</y>
<w>130</w> <w>130</w>
<h>30</h> <h>30</h>
</coordinates> </coordinates>
@ -59,8 +59,8 @@ group=2</panel_attributes>
<element> <element>
<id>UMLClass</id> <id>UMLClass</id>
<coordinates> <coordinates>
<x>1480</x> <x>1360</x>
<y>1040</y> <y>520</y>
<w>130</w> <w>130</w>
<h>60</h> <h>60</h>
</coordinates> </coordinates>
@ -73,8 +73,8 @@ group=2</panel_attributes>
<element> <element>
<id>UMLClass</id> <id>UMLClass</id>
<coordinates> <coordinates>
<x>1350</x> <x>1230</x>
<y>1070</y> <y>550</y>
<w>130</w> <w>130</w>
<h>30</h> <h>30</h>
</coordinates> </coordinates>
@ -86,8 +86,8 @@ group=2</panel_attributes>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1090</x> <x>1040</x>
<y>870</y> <y>430</y>
<w>120</w> <w>120</w>
<h>40</h> <h>40</h>
</coordinates> </coordinates>
@ -99,8 +99,8 @@ halign=left</panel_attributes>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1090</x> <x>1040</x>
<y>1060</y> <y>530</y>
<w>120</w> <w>120</w>
<h>40</h> <h>40</h>
</coordinates> </coordinates>
@ -112,8 +112,8 @@ halign=left</panel_attributes>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1090</x> <x>1040</x>
<y>1240</y> <y>630</y>
<w>120</w> <w>120</w>
<h>40</h> <h>40</h>
</coordinates> </coordinates>
@ -125,30 +125,30 @@ halign=left</panel_attributes>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1130</x> <x>1090</x>
<y>990</y> <y>500</y>
<w>30</w> <w>30</w>
<h>90</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;70.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1120</x> <x>1090</x>
<y>1170</y> <y>600</y>
<w>50</w> <w>30</w>
<h>90</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>30.0;70.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1090</x> <x>1040</x>
<y>1380</y> <y>830</y>
<w>120</w> <w>120</w>
<h>40</h> <h>40</h>
</coordinates> </coordinates>
@ -161,43 +161,43 @@ style=wordwrap</panel_attributes>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1140</x> <x>1090</x>
<y>1320</y> <y>800</y>
<w>60</w> <w>30</w>
<h>80</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>40.0;60.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1120</x> <x>1090</x>
<y>1090</y> <y>560</y>
<w>50</w> <w>30</w>
<h>90</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;70.0;30.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>UMLClass</id> <id>UMLClass</id>
<coordinates> <coordinates>
<x>840</x> <x>940</x>
<y>840</y> <y>390</y>
<w>820</w> <w>590</w>
<h>1090</h> <h>810</h>
</coordinates> </coordinates>
<panel_attributes>For Each SyncDirectory <panel_attributes>For Each SyncDirectory
halign=left halign=right
layer=-1</panel_attributes> layer=-1</panel_attributes>
<additional_attributes/> <additional_attributes/>
</element> </element>
<element> <element>
<id>UMLClass</id> <id>UMLClass</id>
<coordinates> <coordinates>
<x>1340</x> <x>1220</x>
<y>1030</y> <y>510</y>
<w>280</w> <w>280</w>
<h>80</h> <h>80</h>
</coordinates> </coordinates>
@ -210,30 +210,30 @@ group=2</panel_attributes>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1200</x> <x>1150</x>
<y>1240</y> <y>640</y>
<w>160</w> <w>90</w>
<h>40</h> <h>30</h>
</coordinates> </coordinates>
<panel_attributes>lt=.</panel_attributes> <panel_attributes>lt=.</panel_attributes>
<additional_attributes>140.0;10.0;10.0;20.0</additional_attributes> <additional_attributes>70.0;10.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1150</x> <x>1090</x>
<y>800</y> <y>370</y>
<w>30</w> <w>30</w>
<h>90</h> <h>80</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;70.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;60.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>UMLSpecialState</id> <id>UMLSpecialState</id>
<coordinates> <coordinates>
<x>1150</x> <x>1090</x>
<y>790</y> <y>360</y>
<w>20</w> <w>20</w>
<h>20</h> <h>20</h>
</coordinates> </coordinates>
@ -243,8 +243,8 @@ group=2</panel_attributes>
<element> <element>
<id>UMLSpecialState</id> <id>UMLSpecialState</id>
<coordinates> <coordinates>
<x>1150</x> <x>1090</x>
<y>1970</y> <y>1220</y>
<w>20</w> <w>20</w>
<h>20</h> <h>20</h>
</coordinates> </coordinates>
@ -254,30 +254,30 @@ group=2</panel_attributes>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1130</x> <x>1090</x>
<y>1500</y> <y>900</y>
<w>50</w> <w>30</w>
<h>90</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>30.0;70.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1150</x> <x>1090</x>
<y>1900</y> <y>1170</y>
<w>30</w> <w>30</w>
<h>90</h> <h>70</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;70.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;50.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1070</x> <x>1040</x>
<y>1720</y> <y>1030</y>
<w>120</w> <w>120</w>
<h>50</h> <h>50</h>
</coordinates> </coordinates>
@ -290,9 +290,9 @@ style=wordwrap</panel_attributes>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1100</x> <x>1030</x>
<y>1160</y> <y>590</y>
<w>150</w> <w>140</w>
<h>20</h> <h>20</h>
</coordinates> </coordinates>
<panel_attributes>State 1 : LIST-1 <panel_attributes>State 1 : LIST-1
@ -302,8 +302,8 @@ bg=orange</panel_attributes>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1070</x> <x>1040</x>
<y>1570</y> <y>930</y>
<w>120</w> <w>120</w>
<h>40</h> <h>40</h>
</coordinates> </coordinates>
@ -316,32 +316,32 @@ style=wordwrap</panel_attributes>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1110</x> <x>1030</x>
<y>1490</y> <y>890</y>
<w>160</w> <w>140</w>
<h>20</h> <h>20</h>
</coordinates> </coordinates>
<panel_attributes>State 3 : SYNC-1 <panel_attributes>State 4 : SYNC-1
bg=orange</panel_attributes> bg=orange</panel_attributes>
<additional_attributes/> <additional_attributes/>
</element> </element>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1110</x> <x>1030</x>
<y>1640</y> <y>990</y>
<w>150</w> <w>140</w>
<h>20</h> <h>20</h>
</coordinates> </coordinates>
<panel_attributes>State 4 : NEW-2 <panel_attributes>State 5 : NEW-2
bg=orange</panel_attributes> bg=orange</panel_attributes>
<additional_attributes/> <additional_attributes/>
</element> </element>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1110</x> <x>1030</x>
<y>980</y> <y>490</y>
<w>140</w> <w>140</w>
<h>20</h> <h>20</h>
</coordinates> </coordinates>
@ -352,31 +352,31 @@ bg=orange</panel_attributes>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1120</x> <x>1030</x>
<y>1790</y> <y>1100</y>
<w>140</w> <w>140</w>
<h>20</h> <h>20</h>
</coordinates> </coordinates>
<panel_attributes>State 5 : OLD-1 <panel_attributes>State 6 : OLD-1
bg=orange</panel_attributes> bg=orange</panel_attributes>
<additional_attributes/> <additional_attributes/>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1130</x> <x>1090</x>
<y>1650</y> <y>1000</y>
<w>40</w> <w>30</w>
<h>90</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>20.0;70.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>UMLSpecialState</id> <id>UMLSpecialState</id>
<coordinates> <coordinates>
<x>1140</x> <x>1080</x>
<y>1870</y> <y>1140</y>
<w>40</w> <w>40</w>
<h>40</h> <h>40</h>
</coordinates> </coordinates>
@ -386,41 +386,41 @@ bg=orange</panel_attributes>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1150</x> <x>1090</x>
<y>1800</y> <y>1110</y>
<w>30</w> <w>30</w>
<h>90</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;70.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>920</x> <x>970</x>
<y>880</y> <y>440</y>
<w>240</w> <w>130</w>
<h>1030</h> <h>740</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>170.0;10.0;20.0;260.0;10.0;1010.0;220.0;1010.0</additional_attributes> <additional_attributes>70.0;10.0;10.0;10.0;10.0;720.0;110.0;720.0</additional_attributes>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1130</x> <x>1090</x>
<y>900</y> <y>460</y>
<w>40</w> <w>30</w>
<h>100</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;80.0;20.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>UMLClass</id> <id>UMLClass</id>
<coordinates> <coordinates>
<x>1340</x> <x>1220</x>
<y>1210</y> <y>610</y>
<w>280</w> <w>280</w>
<h>80</h> <h>80</h>
</coordinates> </coordinates>
@ -433,20 +433,20 @@ group=1</panel_attributes>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1200</x> <x>1150</x>
<y>1060</y> <y>540</y>
<w>160</w> <w>90</w>
<h>40</h> <h>30</h>
</coordinates> </coordinates>
<panel_attributes>lt=.</panel_attributes> <panel_attributes>lt=.</panel_attributes>
<additional_attributes>10.0;20.0;140.0;10.0</additional_attributes> <additional_attributes>10.0;10.0;70.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>UMLState</id> <id>UMLState</id>
<coordinates> <coordinates>
<x>1120</x> <x>1030</x>
<y>1310</y> <y>690</y>
<w>160</w> <w>140</w>
<h>20</h> <h>20</h>
</coordinates> </coordinates>
<panel_attributes>State 2 : LIST-2 <panel_attributes>State 2 : LIST-2
@ -456,45 +456,92 @@ bg=orange</panel_attributes>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1140</x> <x>1090</x>
<y>1270</y> <y>660</y>
<w>30</w> <w>30</w>
<h>60</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;40.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1140</x> <x>1090</x>
<y>1760</y> <y>1070</y>
<w>40</w> <w>30</w>
<h>50</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>20.0;30.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1110</x> <x>1090</x>
<y>1600</y> <y>960</y>
<w>50</w> <w>30</w>
<h>60</h> <h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>30.0;40.0;10.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
<element> <element>
<id>Relation</id> <id>Relation</id>
<coordinates> <coordinates>
<x>1130</x> <x>1090</x>
<y>1410</y> <y>860</y>
<w>60</w> <w>30</w>
<h>100</h> <h>50</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element>
<element>
<id>UMLState</id>
<coordinates>
<x>1030</x>
<y>790</y>
<w>140</w>
<h>20</h>
</coordinates>
<panel_attributes>State 3 : LIST-3
bg=orange</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>UMLState</id>
<coordinates>
<x>1040</x>
<y>730</y>
<w>120</w>
<h>40</h>
</coordinates>
<panel_attributes>get
ListModified
halign=left</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>1090</x>
<y>760</y>
<w>30</w>
<h>50</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>1090</x>
<y>700</y>
<w>30</w>
<h>50</h>
</coordinates> </coordinates>
<panel_attributes>lt=&lt;-</panel_attributes> <panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>10.0;80.0;40.0;10.0</additional_attributes> <additional_attributes>10.0;30.0;10.0;10.0</additional_attributes>
</element> </element>
</diagram> </diagram>

Loading…
Cancel
Save