1 package org.simantics.modeling.utils;
4 import java.io.IOException;
5 import java.nio.charset.StandardCharsets;
6 import java.util.Collection;
7 import java.util.HashMap;
9 import java.util.TreeMap;
11 import org.simantics.Simantics;
12 import org.simantics.db.ReadGraph;
13 import org.simantics.db.Resource;
14 import org.simantics.db.common.utils.CommonDBUtils;
15 import org.simantics.db.common.utils.NameUtils;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.layer0.variable.Variable;
18 import org.simantics.db.layer0.variable.Variables;
19 import org.simantics.layer0.Layer0;
20 import org.simantics.modeling.ModelingResources;
21 import org.simantics.scl.runtime.function.Function;
22 import org.simantics.utils.FileUtils;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
26 import gnu.trove.list.array.TByteArrayList;
28 public class DumpOntologyStructure {
30 private static final Logger LOGGER = LoggerFactory.getLogger(DumpOntologyStructure.class);
32 private Resource ontology;
34 private Map<Resource, String> names = new HashMap<>();
35 private Map<Resource,Resource> parents = new HashMap<>();
36 private Map<Resource, File> libraryFolders = new HashMap<>();
37 private Map<Resource, byte[]> contentDumps = new HashMap<>();
39 private void readNameAndParent(ReadGraph graph, Resource container, Resource r) throws DatabaseException {
40 parents.put(r, container);
41 names.put(r, NameUtils.getSafeName(graph, r));
44 private Collection<Resource> containers() {
45 return parents.values();
48 private void readHierarchy(ReadGraph graph, Resource container) throws DatabaseException {
49 Layer0 L0 = Layer0.getInstance(graph);
50 for(Resource r : CommonDBUtils.objectsWithType(graph, container, L0.ConsistsOf, L0.Entity)) {
52 readNameAndParent(graph, container, r);
53 readHierarchy(graph, r);
54 } catch (DatabaseException e) {
55 LOGGER.error("Error while reading content dump hierarchy for " + r, e);
60 private void readGeneric(ReadGraph graph) throws DatabaseException {
61 ModelingResources MOD = ModelingResources.getInstance(graph);
62 for(Resource r : parents.keySet()) {
63 if(contentDumps.containsKey(r))
65 TByteArrayList result = new TByteArrayList();
67 TreeMap<String,Resource> sortedTypes = new TreeMap<>();
68 for(Resource type : graph.getTypes(r)) {
69 String uri = graph.getPossibleURI(type);
71 sortedTypes.put(uri, type);
73 for(Resource type : sortedTypes.values()) {
75 Variable typeVariable = Variables.getVariable(graph, type);
76 @SuppressWarnings("rawtypes")
77 Function f = typeVariable.getPossiblePropertyValue(graph, MOD.contentDumpFunction);
79 @SuppressWarnings("unchecked")
80 byte[] dump = (byte[])Simantics.applySCLRead(graph, f, r);
85 } catch (DatabaseException e) {
86 LOGGER.error("Error while computing content dump for " + r, e);
90 contentDumps.put(r, result.toArray());
91 } catch (DatabaseException e) {
92 LOGGER.error("Error while computing content dump for " + r, e);
97 public void read(ReadGraph graph, Resource ontology) throws DatabaseException {
98 this.ontology = ontology;
99 readHierarchy(graph, ontology);
103 private File escapeFile(File file) {
108 return new File(escapeFile(file.getParentFile()), FileUtils.escapeFileName(file.getName()));
112 public void write(File unsafeFolder) throws IOException {
113 File folder = escapeFile(unsafeFolder);
115 FileUtils.deleteAll(folder);
117 writeDirectories(folder);
118 writeResources(folder);
121 private File getFolder(File root, Resource library) {
122 if(ontology.equals(library))
124 Resource parent = parents.get(library);
126 throw new IllegalStateException("null parent for " + library);
127 File parentFolder = getFolder(root, parent);
128 return new File(parentFolder, FileUtils.escapeFileName(names.get(library)));
131 private File getFile(File rootFolder, Resource r) {
132 Resource parent = parents.get(r);
133 File folder = getFolder(rootFolder, parent);
134 return new File(folder, FileUtils.escapeFileName(names.get(r)));
137 private void writeDirectories(File rootFolder) {
138 for(Resource library : containers()) {
139 File folder = getFolder(rootFolder, library);
141 libraryFolders.put(library, folder);
145 private void writeResources(File rootFolder) throws IOException {
146 for(Resource r : parents.keySet()) {
147 writeResource(rootFolder, r);
151 private boolean isParent(Resource r) {
152 return parents.values().contains(r);
155 private void writeResource(File rootFolder, Resource resource) throws IOException {
156 byte[] dump = contentDumps.get(resource);
158 dump = "".getBytes(StandardCharsets.UTF_8);
159 if(isParent(resource)) {
161 FileUtils.writeFile(new File(getFolder(rootFolder, resource), "__contents__"), dump);
163 write(rootFolder, resource, dump);
167 private void write(File rootFolder, Resource resource, byte[] bytes) throws IOException {
168 FileUtils.writeFile(getFile(rootFolder, resource), bytes);