1 package org.simantics.graph.refactoring;
3 import java.util.Arrays;
5 import org.simantics.databoard.util.URIStringUtils;
6 import org.simantics.graph.query.Path;
7 import org.simantics.graph.query.PathChild;
8 import org.simantics.graph.query.TransferableGraphConversion;
9 import org.simantics.graph.query.UriUtils;
10 import org.simantics.graph.refactoring.MappingSpecification.MappingRule;
11 import org.simantics.graph.representation.External;
12 import org.simantics.graph.representation.Identity;
13 import org.simantics.graph.representation.Internal;
14 import org.simantics.graph.representation.Root;
15 import org.simantics.graph.representation.TransferableGraph1;
16 import org.simantics.graph.representation.TransferableGraphUtils;
17 import org.simantics.graph.store.GraphStore;
18 import org.simantics.graph.store.IdentityStore;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
22 import gnu.trove.set.hash.TIntHashSet;
24 public class GraphRefactoringUtils {
25 private static final Logger LOGGER = LoggerFactory.getLogger(GraphRefactoringUtils.class);
27 * Moves an external resource. Returns true if did something.
28 * @param parentsAffected
30 public static boolean moveExternal(TransferableGraph1 tg, IdentityStore ids, Path from, PathChild to, TIntHashSet parentsAffected) throws GraphRefactoringException {
32 int fromId = ids.pathToId(from);
35 if(ids.isNewResource(fromId))
36 throw new GraphRefactoringException("Cannot move internal resource " + from + ".");
38 // Remove old identity
39 int parentId = ids.removeIdentity(fromId);
41 parentsAffected.add(parentId);
44 int toParentId = ids.createPathToId(to.parent);
45 if(ids.hasChild(toParentId, to.name)) {
46 LOGGER.info("refactor statements from " + from + " to " + to);
47 //throw new GraphRefactoringException("External reference to " + to + " already exists.");
48 int toId = ids.pathToId(to);
49 int[] statements = tg.statements;
50 for(int i=0;i<tg.statements.length;++i) {
51 if(statements[i] == fromId) statements[i] = toId;
57 ids.setIdentity(fromId, toParentId, to.name);
61 public static void refactor(TransferableGraph1 tg, IdentityStore ids, MappingSpecification spec, TIntHashSet parentsAffected) throws GraphRefactoringException {
62 for(MappingRule rule : spec.getRules()) {
63 if(!(rule.to instanceof PathChild))
64 throw new GraphRefactoringException("Invalid target URI " + rule.to);
65 if(!moveExternal(tg, ids, rule.from, (PathChild)rule.to, parentsAffected))
66 LOGGER.warn("Didn't find " + rule.from);
70 public static boolean fixIncorrectRoot(Identity[] ids) {
71 for(int i=0;i<ids.length;++i) {
73 if(id.definition instanceof External) {
74 External ext = (External)id.definition;
75 if(ext.parent == -1 && (ext.name.equals("http:/") || ext.name.equals(""))) {
76 id.definition = new Root("", "");
84 public static void fixOntologyExport(TransferableGraph1 tg) {
86 fixIncorrectRoot(tg.identities);
87 fixOntologyRoot(tg, true);
91 private static Identity recursePath(TransferableGraph1 tg, String path) {
93 Identity extId = TransferableGraphUtils.findExternal(tg, path);
94 if(extId != null) return extId;
95 if("http://".equals(path)) return TransferableGraphUtils.findRootWithName(tg, "");
96 String[] parts = URIStringUtils.splitURI(path);
97 Identity parentId = recursePath(tg, parts[0]);
98 tg.identities = Arrays.copyOf(tg.identities, tg.identities.length+1);
99 Identity childIdentity = new Identity(tg.resourceCount++, new External(parentId.resource, parts[1]));
100 tg.identities[tg.identities.length-1] = childIdentity;
101 return childIdentity;
105 public static void fixOntologyRoot(TransferableGraph1 tg, boolean tryToFix) {
107 Identity[] ids = tg.identities;
108 for(int i=0;i<ids.length;++i) {
109 Identity id = ids[i];
110 if(id.definition instanceof Root) {
111 Root ext = (Root)id.definition;
112 if(ext.name.startsWith("http://")) {
114 String[] parts = URIStringUtils.splitURI(ext.name);
115 Identity path = recursePath(tg, parts[0]);
116 id.definition = new Internal(path.resource, parts[1]);
118 GraphStore store = TransferableGraphConversion.convert(tg);
119 int rootId = store.identities.createPathToId(UriUtils.uriToPath(ext.name));
120 propagateNewMarks(store.identities, rootId);
122 TransferableGraph1 tgNew = TransferableGraphConversion.convert(store);
124 tg.resourceCount = tgNew.resourceCount;
125 tg.identities = tgNew.identities;
126 tg.values = tgNew.values;
127 tg.statements = tgNew.statements;
131 } else if (ext.type.startsWith("http://")) {
132 String first = "http://Projects/Development Project";
133 Identity path = recursePath(tg, first);
134 id.definition = new Internal(path.resource, ext.name);
136 GraphStore store = TransferableGraphConversion.convert(tg);
137 int rootId = store.identities.createPathToId(UriUtils.uriToPath(first + "/" + ext.name));
138 propagateNewMarks(store.identities, rootId);
140 TransferableGraph1 tgNew = TransferableGraphConversion.convert(store);
142 tg.resourceCount = tgNew.resourceCount;
143 tg.identities = tgNew.identities;
144 tg.values = tgNew.values;
145 tg.statements = tgNew.statements;
153 private static void propagateNewMarks(IdentityStore identities, int resource) {
154 if(identities.markNew(resource)) {
155 for(int child : identities.getChildren(resource))
156 propagateNewMarks(identities, child);
160 public static void unfixIncorrectRoot(Identity[] ids) {
161 for(int i=0;i<ids.length;++i) {
162 Identity id = ids[i];
163 if(id.definition instanceof Root) {
164 Root root = (Root)id.definition;
165 if(root.name.equals("") && root.type.equals("")) {
166 id.definition = new External(-1, "http:/");