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>
- Have Map entries be remove, once file ops is performed.
- Create a parallel Thread for each SyncEnity.
- Add support for modification dates.
- 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;
import com.olexyn.ensync.artifacts.SyncDirectory;
import com.olexyn.ensync.artifacts.SyncEntity;
import java.util.*;
public class Main {
public static void main(String[] args) {
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();
new Flow().start();
}
//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;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import com.olexyn.ensync.artifacts.SyncFile;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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) {
StringBuilder sb = new StringBuilder();
Object[] br_array = br.lines().toArray();
@ -46,30 +34,23 @@ public class Tools {
return sb.toString();
}
/**
* StateFile -> FilePool
* Convert BufferedReader to List of Strings.
*
* @param br BufferedReader
* @return List
*/
public Map<String, File> fileToPool(File file,
String type) {
List<String> lines = fileToLines(file);
return linesToFilePool(lines, type);
public List<String> brToListString(BufferedReader br) {
List<String> list = new ArrayList<>();
Object[] br_array = br.lines().toArray();
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) {
@ -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()) {
filepool.put(line, file);
}
}
return filepool;
}
public List<File> mapMinus(Map<String, File> fromA,
Map<String, File> substractB) {
public List<SyncFile> mapMinus(Map<String, SyncFile> fromA,
Map<String, SyncFile> substractB) {
List<File> difference = new ArrayList<>();
List<SyncFile> difference = new ArrayList<>();
Iterator iterator = fromA.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
String key = (String) entry.getKey();
File file = fromA.get(key);
SyncFile file = fromA.get(key);
if (fromA.containsKey(key) && !substractB.containsKey(key)) {
@ -120,4 +88,51 @@ public class Tools {
}
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 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;
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();
Execute x = new Execute();
@ -31,153 +21,147 @@ public class SyncDirectory {
/**
* Create a SyncDirectory from realPath.
*
* @param realPath
* @see SyncEntity
*/
public SyncDirectory(String realPath, SyncEntity syncEntity) {
public SyncDirectory(String path , SyncEntity syncEntity) {
this.realPath = realPath;
stateFileBasePath = "/tmp/find" + this.realPath.replace("/", "-");
stateFileOldPath = stateFileBasePath + "-old";
stateFileNewPath = stateFileBasePath + "-new";
stateFileOld = getStateFileOld();
stateFileNew = getStateFileNew();
poolOld = getPoolOld();
poolNew = getPoolNew();
this.path = path;
this.syncEntity = syncEntity;
}
/**
* IF NOT EXISTS the StateFileOld for this SyncDirectory,<p>
* - THEN create the File on Disk.
*
* @return the StateFileOld.
* NOTE that the SFile().lastModifiedOld is not set here, so it is 0 by default.
*/
public File getStateFileOld() {
stateFileOld = new File(stateFileOldPath);
if (!stateFileOld.exists()) {
stateFileOld = tools.generateStateFile(realPath, stateFileOldPath);
public Map<String, SyncFile> readState(String path) {
Map<String, SyncFile> filemap = new HashMap<>();
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>
* 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.
* READ the contents of StateFile to Map.
*/
public void updateStateFileOld() {
//
if (state.equals(STATES.get(4))){
state = STATES.get(5);
} else {
return ;
}
tools.generateStateFile(realPath, stateFileOldPath);
}
public Map<String, SyncFile> readStateFile(String path) {
Map<String, SyncFile> filemap = new HashMap<>();
List<String> lines = tools.fileToLines(new File(stateFilePath(path)));
public File getStateFileNew() {
stateFileNew = new File(stateFileNewPath);
if (!stateFileNew.exists()) {
stateFileNew = tools.generateStateFile(realPath, stateFileNewPath);
for (String line : lines) {
// this is a predefined format: "modification-time path"
String modTimeString = line.split("")[0];
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>
* WRITE a new StateFileNew Disk.
* Compare the OLD and NEW pools.
*
* @return
*/
public void updateStateFileNew() {
//
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;
}
public List<SyncFile> makeListCreated(String path) {
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() {
if (poolOld.isEmpty()) {
updatePoolOld();
}
return poolOld;
return tools.mapMinus(readStateFile(path), readState(path));
}
/**
* 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() {
if (poolNew.isEmpty()) {
updatePoolNew();
long lastModifiedOld = oldMap.get(newFileKey).lastModifiedOld();
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() {
poolNew = tools.fileToPool(getStateFileNew(), "all");
public void writeStateFile(String path) {
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(){
if (state.equals(STATES.get(2))){
state = STATES.get(3);
} else {
return ;
tools.writeStringListToFile(stateFilePath(path), outputList);
}
public void doCreate(List<SyncFile> listCreated){
for (File createdFile : listCreated) {
@ -190,8 +174,8 @@ public class SyncDirectory {
// otherSyncDirectory /bar
// createdFile /foo/hello/created-file.gif
// relativePath /hello/created-file.gif
String relativePath = createdFile.getPath().replace(this.realPath, "");
String targetPath = otherSyncDirectory.realPath + relativePath;
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",
@ -202,28 +186,44 @@ public class SyncDirectory {
String[] cmd = new String[]{"cp",
createdFile.getPath(),
otherSyncDirectory.realPath + relativePath};
otherSyncDirectory.path + relativePath};
x.execute(cmd);
}
}
}
}
public void doDelete(List<SyncFile> listDeleted){
//
for (File deletedFile : listDeleted) {
for (Map.Entry<String, SyncDirectory> otherEntry : syncEntity.syncDirectories.entrySet()) {
SyncDirectory otherSyncDirectory = otherEntry.getValue();
if (!this.equals(otherSyncDirectory)) {
String relativePath = deletedFile.getPath().replace(this.realPath, "");
String[] cmd = new String[]{"rm", "-r",
otherSyncDirectory.realPath + relativePath};
String relativePath = deletedFile.getPath().replace(this.path, "");
String[] cmd = new String[]{"rm",
"-r",
otherSyncDirectory.path + relativePath};
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>
<id>UMLClass</id>
<coordinates>
<x>1350</x>
<y>1220</y>
<x>1230</x>
<y>620</y>
<w>130</w>
<h>60</h>
</coordinates>
@ -18,8 +18,8 @@ group=1</panel_attributes>
<element>
<id>UMLClass</id>
<coordinates>
<x>1480</x>
<y>1220</y>
<x>1360</x>
<y>620</y>
<w>130</w>
<h>30</h>
</coordinates>
@ -32,8 +32,8 @@ group=1</panel_attributes>
<element>
<id>UMLClass</id>
<coordinates>
<x>1480</x>
<y>1250</y>
<x>1360</x>
<y>650</y>
<w>130</w>
<h>30</h>
</coordinates>
@ -45,8 +45,8 @@ group=1</panel_attributes>
<element>
<id>UMLClass</id>
<coordinates>
<x>1350</x>
<y>1040</y>
<x>1230</x>
<y>520</y>
<w>130</w>
<h>30</h>
</coordinates>
@ -59,8 +59,8 @@ group=2</panel_attributes>
<element>
<id>UMLClass</id>
<coordinates>
<x>1480</x>
<y>1040</y>
<x>1360</x>
<y>520</y>
<w>130</w>
<h>60</h>
</coordinates>
@ -73,8 +73,8 @@ group=2</panel_attributes>
<element>
<id>UMLClass</id>
<coordinates>
<x>1350</x>
<y>1070</y>
<x>1230</x>
<y>550</y>
<w>130</w>
<h>30</h>
</coordinates>
@ -86,8 +86,8 @@ group=2</panel_attributes>
<element>
<id>UMLState</id>
<coordinates>
<x>1090</x>
<y>870</y>
<x>1040</x>
<y>430</y>
<w>120</w>
<h>40</h>
</coordinates>
@ -99,8 +99,8 @@ halign=left</panel_attributes>
<element>
<id>UMLState</id>
<coordinates>
<x>1090</x>
<y>1060</y>
<x>1040</x>
<y>530</y>
<w>120</w>
<h>40</h>
</coordinates>
@ -112,8 +112,8 @@ halign=left</panel_attributes>
<element>
<id>UMLState</id>
<coordinates>
<x>1090</x>
<y>1240</y>
<x>1040</x>
<y>630</y>
<w>120</w>
<h>40</h>
</coordinates>
@ -125,30 +125,30 @@ halign=left</panel_attributes>
<element>
<id>Relation</id>
<coordinates>
<x>1130</x>
<y>990</y>
<x>1090</x>
<y>500</y>
<w>30</w>
<h>90</h>
<h>50</h>
</coordinates>
<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>
<id>Relation</id>
<coordinates>
<x>1120</x>
<y>1170</y>
<w>50</w>
<h>90</h>
<x>1090</x>
<y>600</y>
<w>30</w>
<h>50</h>
</coordinates>
<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>
<id>UMLState</id>
<coordinates>
<x>1090</x>
<y>1380</y>
<x>1040</x>
<y>830</y>
<w>120</w>
<h>40</h>
</coordinates>
@ -161,43 +161,43 @@ style=wordwrap</panel_attributes>
<element>
<id>Relation</id>
<coordinates>
<x>1140</x>
<y>1320</y>
<w>60</w>
<h>80</h>
<x>1090</x>
<y>800</y>
<w>30</w>
<h>50</h>
</coordinates>
<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>
<id>Relation</id>
<coordinates>
<x>1120</x>
<y>1090</y>
<w>50</w>
<h>90</h>
<x>1090</x>
<y>560</y>
<w>30</w>
<h>50</h>
</coordinates>
<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>
<id>UMLClass</id>
<coordinates>
<x>840</x>
<y>840</y>
<w>820</w>
<h>1090</h>
<x>940</x>
<y>390</y>
<w>590</w>
<h>810</h>
</coordinates>
<panel_attributes>For Each SyncDirectory
halign=left
halign=right
layer=-1</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>1340</x>
<y>1030</y>
<x>1220</x>
<y>510</y>
<w>280</w>
<h>80</h>
</coordinates>
@ -210,30 +210,30 @@ group=2</panel_attributes>
<element>
<id>Relation</id>
<coordinates>
<x>1200</x>
<y>1240</y>
<w>160</w>
<h>40</h>
<x>1150</x>
<y>640</y>
<w>90</w>
<h>30</h>
</coordinates>
<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>
<id>Relation</id>
<coordinates>
<x>1150</x>
<y>800</y>
<x>1090</x>
<y>370</y>
<w>30</w>
<h>90</h>
<h>80</h>
</coordinates>
<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>
<id>UMLSpecialState</id>
<coordinates>
<x>1150</x>
<y>790</y>
<x>1090</x>
<y>360</y>
<w>20</w>
<h>20</h>
</coordinates>
@ -243,8 +243,8 @@ group=2</panel_attributes>
<element>
<id>UMLSpecialState</id>
<coordinates>
<x>1150</x>
<y>1970</y>
<x>1090</x>
<y>1220</y>
<w>20</w>
<h>20</h>
</coordinates>
@ -254,30 +254,30 @@ group=2</panel_attributes>
<element>
<id>Relation</id>
<coordinates>
<x>1130</x>
<y>1500</y>
<w>50</w>
<h>90</h>
<x>1090</x>
<y>900</y>
<w>30</w>
<h>50</h>
</coordinates>
<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>
<id>Relation</id>
<coordinates>
<x>1150</x>
<y>1900</y>
<x>1090</x>
<y>1170</y>
<w>30</w>
<h>90</h>
<h>70</h>
</coordinates>
<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>
<id>UMLState</id>
<coordinates>
<x>1070</x>
<y>1720</y>
<x>1040</x>
<y>1030</y>
<w>120</w>
<h>50</h>
</coordinates>
@ -290,9 +290,9 @@ style=wordwrap</panel_attributes>
<element>
<id>UMLState</id>
<coordinates>
<x>1100</x>
<y>1160</y>
<w>150</w>
<x>1030</x>
<y>590</y>
<w>140</w>
<h>20</h>
</coordinates>
<panel_attributes>State 1 : LIST-1
@ -302,8 +302,8 @@ bg=orange</panel_attributes>
<element>
<id>UMLState</id>
<coordinates>
<x>1070</x>
<y>1570</y>
<x>1040</x>
<y>930</y>
<w>120</w>
<h>40</h>
</coordinates>
@ -316,32 +316,32 @@ style=wordwrap</panel_attributes>
<element>
<id>UMLState</id>
<coordinates>
<x>1110</x>
<y>1490</y>
<w>160</w>
<x>1030</x>
<y>890</y>
<w>140</w>
<h>20</h>
</coordinates>
<panel_attributes>State 3 : SYNC-1
<panel_attributes>State 4 : SYNC-1
bg=orange</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>UMLState</id>
<coordinates>
<x>1110</x>
<y>1640</y>
<w>150</w>
<x>1030</x>
<y>990</y>
<w>140</w>
<h>20</h>
</coordinates>
<panel_attributes>State 4 : NEW-2
<panel_attributes>State 5 : NEW-2
bg=orange</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>UMLState</id>
<coordinates>
<x>1110</x>
<y>980</y>
<x>1030</x>
<y>490</y>
<w>140</w>
<h>20</h>
</coordinates>
@ -352,31 +352,31 @@ bg=orange</panel_attributes>
<element>
<id>UMLState</id>
<coordinates>
<x>1120</x>
<y>1790</y>
<x>1030</x>
<y>1100</y>
<w>140</w>
<h>20</h>
</coordinates>
<panel_attributes>State 5 : OLD-1
<panel_attributes>State 6 : OLD-1
bg=orange</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>1130</x>
<y>1650</y>
<w>40</w>
<h>90</h>
<x>1090</x>
<y>1000</y>
<w>30</w>
<h>50</h>
</coordinates>
<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>
<id>UMLSpecialState</id>
<coordinates>
<x>1140</x>
<y>1870</y>
<x>1080</x>
<y>1140</y>
<w>40</w>
<h>40</h>
</coordinates>
@ -386,41 +386,41 @@ bg=orange</panel_attributes>
<element>
<id>Relation</id>
<coordinates>
<x>1150</x>
<y>1800</y>
<x>1090</x>
<y>1110</y>
<w>30</w>
<h>90</h>
<h>50</h>
</coordinates>
<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>
<id>Relation</id>
<coordinates>
<x>920</x>
<y>880</y>
<w>240</w>
<h>1030</h>
<x>970</x>
<y>440</y>
<w>130</w>
<h>740</h>
</coordinates>
<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>
<id>Relation</id>
<coordinates>
<x>1130</x>
<y>900</y>
<w>40</w>
<h>100</h>
<x>1090</x>
<y>460</y>
<w>30</w>
<h>50</h>
</coordinates>
<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>
<id>UMLClass</id>
<coordinates>
<x>1340</x>
<y>1210</y>
<x>1220</x>
<y>610</y>
<w>280</w>
<h>80</h>
</coordinates>
@ -433,20 +433,20 @@ group=1</panel_attributes>
<element>
<id>Relation</id>
<coordinates>
<x>1200</x>
<y>1060</y>
<w>160</w>
<h>40</h>
<x>1150</x>
<y>540</y>
<w>90</w>
<h>30</h>
</coordinates>
<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>
<id>UMLState</id>
<coordinates>
<x>1120</x>
<y>1310</y>
<w>160</w>
<x>1030</x>
<y>690</y>
<w>140</w>
<h>20</h>
</coordinates>
<panel_attributes>State 2 : LIST-2
@ -456,45 +456,92 @@ bg=orange</panel_attributes>
<element>
<id>Relation</id>
<coordinates>
<x>1140</x>
<y>1270</y>
<x>1090</x>
<y>660</y>
<w>30</w>
<h>60</h>
<h>50</h>
</coordinates>
<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>
<id>Relation</id>
<coordinates>
<x>1140</x>
<y>1760</y>
<w>40</w>
<x>1090</x>
<y>1070</y>
<w>30</w>
<h>50</h>
</coordinates>
<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>
<id>Relation</id>
<coordinates>
<x>1110</x>
<y>1600</y>
<w>50</w>
<h>60</h>
<x>1090</x>
<y>960</y>
<w>30</w>
<h>50</h>
</coordinates>
<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>
<id>Relation</id>
<coordinates>
<x>1130</x>
<y>1410</y>
<w>60</w>
<h>100</h>
<x>1090</x>
<y>860</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>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>
<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>
</diagram>

Loading…
Cancel
Save