1 package org.simantics.graph.refactoring;
3 import java.util.ArrayList;
5 import org.simantics.graph.query.Path;
6 import org.simantics.graph.query.PathChild;
7 import org.simantics.graph.query.TransferableGraphConversion;
8 import org.simantics.graph.query.UriUtils;
9 import org.simantics.graph.refactoring.MappingSpecification.MappingRule;
10 import org.simantics.graph.representation.External;
11 import org.simantics.graph.representation.Identity;
12 import org.simantics.graph.representation.IdentityDefinition;
13 import org.simantics.graph.representation.Internal;
14 import org.simantics.graph.representation.Optional;
15 import org.simantics.graph.representation.Root;
16 import org.simantics.graph.representation.TransferableGraph1;
17 import org.simantics.graph.representation.TransferableGraphUtils;
18 import org.simantics.graph.representation.old.OldTransferableGraph1;
19 import org.simantics.graph.representation.old.OldValue1;
20 import org.simantics.graph.store.IdentityStore;
22 import gnu.trove.list.array.TIntArrayList;
23 import gnu.trove.set.hash.TIntHashSet;
25 public class GraphRefactoringUtils {
28 * Moves an external resource. Returns true if did something.
29 * @param parentsAffected
31 public static boolean moveExternal(TransferableGraph1 tg, IdentityStore ids, Path from, PathChild to, TIntHashSet parentsAffected) throws GraphRefactoringException {
33 int fromId = ids.pathToId(from);
36 if(ids.isNewResource(fromId))
37 throw new GraphRefactoringException("Cannot move internal resource " + from + ".");
39 // Remove old identity
40 int parentId = ids.removeIdentity(fromId);
42 parentsAffected.add(parentId);
45 int toParentId = ids.createPathToId(to.parent);
46 if(ids.hasChild(toParentId, to.name)) {
47 System.err.println("refactor statements from " + from + " to " + to);
48 //throw new GraphRefactoringException("External reference to " + to + " already exists.");
49 int toId = ids.pathToId(to);
50 int[] statements = tg.statements;
51 for(int i=0;i<tg.statements.length;++i) {
52 if(statements[i] == fromId) statements[i] = toId;
58 ids.setIdentity(fromId, toParentId, to.name);
62 public static void refactor(TransferableGraph1 tg, IdentityStore ids, MappingSpecification spec, TIntHashSet parentsAffected) throws GraphRefactoringException {
63 for(MappingRule rule : spec.getRules()) {
64 if(!(rule.to instanceof PathChild))
65 throw new GraphRefactoringException("Invalid target URI " + rule.to);
66 if(!moveExternal(tg, ids, rule.from, (PathChild)rule.to, parentsAffected))
67 System.err.println("Didn't find " + rule.from);
71 public static boolean fixIncorrectRoot(Identity[] ids) {
72 for(int i=0;i<ids.length;++i) {
74 if(id.definition instanceof External) {
75 External ext = (External)id.definition;
76 if(ext.parent == -1 && (ext.name.equals("http:/") || ext.name.equals(""))) {
77 id.definition = new Root("", "");
85 public static void fixOntologyExport(TransferableGraph1 tg) {
87 fixIncorrectRoot(tg.identities);
88 fixOntologyRoot(tg, true);
92 public static void fixOntologyRoot(TransferableGraph1 tg, boolean tryToFix) {
94 Identity[] ids = tg.identities;
95 for(int i=0;i<ids.length;++i) {
97 if(id.definition instanceof Root) {
98 Root ext = (Root)id.definition;
99 if(ext.name.startsWith("http://")) {
100 String rootName = ext.name.substring(ext.name.lastIndexOf("/")+1);
101 String path = ext.name.substring(0, ext.name.lastIndexOf("/"));
102 Identity pathId = TransferableGraphUtils.findExternal(tg, path);
103 System.err.println("GraphRefactoringUtils.rootName=" + rootName);
104 System.err.println("GraphRefactoringUtils.path2=" + path);
106 if(!tryToFix) return;
107 IdentityStore idStore = TransferableGraphConversion.extractIdentities(tg);
108 idStore.createPathToId(UriUtils.uriToPath(path));
109 tg.resourceCount = idStore.getResourceCount();
110 tg.identities = idStore.toArray();
111 fixOntologyRoot(tg, false);
114 id.definition = new Internal(pathId.resource, rootName);
115 TIntArrayList stms = new TIntArrayList(tg.statements);
116 Identity consistsOf = TransferableGraphUtils.findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
117 Identity partOf = TransferableGraphUtils.findExternal(tg, "http://www.simantics.org/Layer0-1.1/PartOf");
118 stms.add(id.resource);
119 stms.add(partOf.resource);
120 stms.add(consistsOf.resource);
121 stms.add(pathId.resource);
122 tg.statements = stms.toArray();
132 public static void unfixIncorrectRoot(Identity[] ids) {
133 for(int i=0;i<ids.length;++i) {
134 Identity id = ids[i];
135 if(id.definition instanceof Root) {
136 Root root = (Root)id.definition;
137 if(root.name.equals("") && root.type.equals("")) {
138 id.definition = new External(-1, "http:/");
145 public static void compactify(OldTransferableGraph1 tg,
146 TIntHashSet removed) {
147 // Filter removed set
148 for(Identity id : tg.identities) {
149 IdentityDefinition def = id.definition;
150 if(def instanceof Root)
151 removed.remove(id.resource);
152 else if(def instanceof External)
153 removed.remove(((External)def).parent);
154 else if(def instanceof Internal)
155 removed.remove(((Internal)def).parent);
156 else if(def instanceof Optional)
157 removed.remove(((Optional)def).parent);
159 for(int r : tg.statements)
161 for(OldValue1 value : tg.values)
162 removed.remove(value.resource);
165 if(!removed.isEmpty()) {
167 int resourceCount = tg.resourceCount;
168 int[] map = new int[resourceCount];
169 for(int i=0;i<resourceCount;++i)
171 for(int r : removed.toArray()) {
172 map[--resourceCount] = map[r];
176 ArrayList<Identity> newIdentities = new ArrayList<Identity>(tg.identities.length);
177 for(Identity id : tg.identities) {
178 if(removed.contains(id.resource))
181 newIdentities.add(id);
182 id.resource = map[id.resource];
183 IdentityDefinition def = id.definition;
184 if(def instanceof External) {
185 External d = (External)def;
186 d.parent = map[d.parent];
188 else if(def instanceof Internal) {
189 External d = (External)def;
190 d.parent = map[d.parent];
192 else if(def instanceof Optional) {
193 External d = (External)def;
194 d.parent = map[d.parent];
197 tg.identities = newIdentities.toArray(new Identity[newIdentities.size()]);
198 int[] statements = tg.statements;
199 for(int i=0;i<statements.length;++i) {
200 int r = statements[i];
202 statements[i] = map[r];
204 for(OldValue1 value : tg.values)
205 value.resource = map[value.resource];
206 tg.resourceCount = resourceCount;