import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import java.util.TreeMap;
import org.simantics.Simantics;
private Resource ontology;
private Map<Resource, String> names = new HashMap<>();
- private Map<Resource,Resource> parents = new HashMap<>();
+ private Map<Resource,Resource> parents = new TreeMap<>();
private Map<Resource, File> libraryFolders = new HashMap<>();
private Map<Resource, byte[]> contentDumps = new HashMap<>();
private void readNameAndParent(ReadGraph graph, Resource container, Resource r) throws DatabaseException {
+ String name = NameUtils.getSafeName(graph, r);
parents.put(r, container);
- names.put(r, NameUtils.getSafeName(graph, r));
+ names.put(r, FileUtils.escapeFileName(name));
}
- private Collection<Resource> containers() {
- return parents.values();
+ /*
+ * This shall return containers sorted by full path.
+ * This makes processing order stable and ensures that
+ * directories are processed before their contents.
+ */
+ private Collection<Resource> sortedContainers(File rootFolder) {
+ Set<Resource> parentSet = new HashSet<Resource>(parents.values());
+ TreeMap<String,Resource> result = new TreeMap<>();
+ for(Resource r : parentSet) {
+ File f = getFolder(rootFolder, r);
+ result.put(f.getAbsolutePath(), r);
+ }
+ return result.values();
+ }
+
+ private Collection<Resource> sortedResources(File rootFolder) {
+ TreeMap<String,Resource> result = new TreeMap<>();
+ for(Resource r : parents.keySet()) {
+ byte[] dump = contentDumps.get(r);
+ if(dump == null)
+ dump = "".getBytes(StandardCharsets.UTF_8);
+ if(isParent(r)) {
+ if(dump.length > 0) {
+ File f = new File(getFolder(rootFolder, r), "__contents__");
+ result.put(f.getAbsolutePath(), r);
+ }
+ } else {
+ File f = getFile(rootFolder, r);
+ result.put(f.getAbsolutePath(), r);
+ }
+ }
+ return result.values();
}
private void readHierarchy(ReadGraph graph, Resource container) throws DatabaseException {
public void write(File unsafeFolder) throws IOException {
File folder = escapeFile(unsafeFolder);
FileUtils.delete(folder.toPath());
- folder.mkdirs();
+ folder.getParentFile().mkdirs();
writeDirectories(folder);
writeResources(folder);
}
+ Resource getParent(Resource r) {
+ return parents.get(r);
+ }
+
private File getFolder(File root, Resource library) {
if(ontology.equals(library))
return root;
- Resource parent = parents.get(library);
+ Resource parent = getParent(library);
if(parent == null)
throw new IllegalStateException("null parent for " + library);
File parentFolder = getFolder(root, parent);
- return new File(parentFolder, FileUtils.escapeFileName(names.get(library)));
+ return new File(parentFolder, names.get(library));
}
private File getFile(File rootFolder, Resource r) {
- Resource parent = parents.get(r);
+ Resource parent = getParent(r);
File folder = getFolder(rootFolder, parent);
- return new File(folder, FileUtils.escapeFileName(names.get(r)));
+ return new File(folder, names.get(r));
}
+ private File makeUnique(File original, Resource r) {
+ int counter = 2;
+ File file = new File(original.getParent(), original.getName());
+ File test = file;
+ while(test.exists()) {
+ // Here we have a name clash with small and big letters! (windows)
+ test = new File(file.getParent(), file.getName() + "____" + (counter++));
+ }
+ // Enforce this renaming in future operations also
+ names.put(r, test.getName());
+ return test;
+ }
+
private void writeDirectories(File rootFolder) {
- for(Resource library : containers()) {
- File folder = getFolder(rootFolder, library);
+ // Here stuff shall be returned in alphabetical order
+ for(Resource library : sortedContainers(rootFolder)) {
+ File folder = makeUnique(getFolder(rootFolder, library), library);
folder.mkdirs();
libraryFolders.put(library, folder);
}
}
private void writeResources(File rootFolder) throws IOException {
- for(Resource r : parents.keySet()) {
+ // Here stuff shall be returned in alphabetical order
+ for(Resource r : sortedResources(rootFolder)) {
writeResource(rootFolder, r);
}
}
}
private void write(File rootFolder, Resource resource, byte[] bytes) throws IOException {
- FileUtils.writeFile(getFile(rootFolder, resource), bytes);
+ FileUtils.writeFile(makeUnique(getFile(rootFolder, resource), resource), bytes);
}
}
\ No newline at end of file