]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph/src/org/simantics/graph/refactoring/GraphRefactoringUtils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / refactoring / GraphRefactoringUtils.java
1 package org.simantics.graph.refactoring;\r
2 \r
3 import java.util.ArrayList;\r
4 \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
21 \r
22 import gnu.trove.list.array.TIntArrayList;\r
23 import gnu.trove.set.hash.TIntHashSet;\r
24 \r
25 public class GraphRefactoringUtils {\r
26 \r
27     /**\r
28      * Moves an external resource. Returns true if did something.\r
29      * @param parentsAffected \r
30      */\r
31     public static boolean moveExternal(TransferableGraph1 tg, IdentityStore ids, Path from, PathChild to, TIntHashSet parentsAffected) throws GraphRefactoringException {\r
32         // Find from id\r
33         int fromId = ids.pathToId(from);\r
34         if(fromId < 0)\r
35             return false;\r
36         if(ids.isNewResource(fromId))\r
37             throw new GraphRefactoringException("Cannot move internal resource " + from + ".");\r
38 \r
39         // Remove old identity\r
40         int parentId = ids.removeIdentity(fromId);\r
41         if(parentId >= 0)\r
42             parentsAffected.add(parentId);\r
43 \r
44         // Find parent id\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
53             }\r
54             return true;\r
55         }\r
56         \r
57         // Set new identity\r
58         ids.setIdentity(fromId, toParentId, to.name);\r
59         return true;\r
60     }\r
61     \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
68         }\r
69     }\r
70 \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
78                     return true;\r
79                 }\r
80             }\r
81         }\r
82         return false;\r
83     }\r
84 \r
85     public static void fixOntologyExport(TransferableGraph1 tg) {\r
86         \r
87         fixIncorrectRoot(tg.identities);\r
88         fixOntologyRoot(tg, true);\r
89         \r
90     }\r
91     \r
92     public static void fixOntologyRoot(TransferableGraph1 tg, boolean tryToFix) {\r
93 \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
112                                 return;\r
113                         } else {\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
123                                 return;\r
124                         }\r
125                         \r
126                 }\r
127             }\r
128         }\r
129         \r
130     }\r
131 \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
139                     return;\r
140                 }\r
141             }\r
142         }\r
143     }\r
144 \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
158         }\r
159         for(int r : tg.statements)\r
160             removed.remove(r);\r
161         for(OldValue1 value : tg.values)\r
162             removed.remove(value.resource);\r
163         \r
164         // Compactify\r
165         if(!removed.isEmpty()) {\r
166             // create map\r
167             int resourceCount = tg.resourceCount;\r
168             int[] map = new int[resourceCount];\r
169             for(int i=0;i<resourceCount;++i)\r
170                 map[i] = i;\r
171             for(int r : removed.toArray()) {\r
172                 map[--resourceCount] = map[r];\r
173             }\r
174             \r
175             // map\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
179                     continue;\r
180                 else\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
187                 }\r
188                 else if(def instanceof Internal) {\r
189                     External d = (External)def;\r
190                     d.parent = map[d.parent];\r
191                 }\r
192                 else if(def instanceof Optional) {\r
193                     External d = (External)def;\r
194                     d.parent = map[d.parent];\r
195                 }\r
196             }\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
201                 if(r >= 0)\r
202                     statements[i] = map[r];\r
203             }\r
204             for(OldValue1 value : tg.values)\r
205                 value.resource = map[value.resource];\r
206             tg.resourceCount = resourceCount;\r
207         }\r
208     }\r
209 \r
210 }\r