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