]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop.mapping/src/org/simantics/interop/mapping/Mapper.java
Replace log4j with slf4j
[simantics/interop.git] / org.simantics.interop.mapping / src / org / simantics / interop / mapping / Mapper.java
1 package org.simantics.interop.mapping;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Collection;\r
5 import java.util.Iterator;\r
6 import java.util.List;\r
7 \r
8 import org.eclipse.core.runtime.IProgressMonitor;\r
9 import org.eclipse.core.runtime.NullProgressMonitor;\r
10 import org.simantics.db.ReadGraph;\r
11 import org.simantics.db.Resource;\r
12 import org.simantics.db.Session;\r
13 import org.simantics.db.VirtualGraph;\r
14 import org.simantics.db.WriteGraph;\r
15 import org.simantics.db.common.request.ReadRequest;\r
16 import org.simantics.db.common.request.WriteRequest;\r
17 import org.simantics.db.common.request.WriteResultRequest;\r
18 import org.simantics.db.common.utils.NameUtils;\r
19 import org.simantics.db.exception.DatabaseException;\r
20 import org.simantics.db.layer0.util.SessionGarbageCollection;\r
21 import org.simantics.db.request.Read;\r
22 import org.simantics.interop.mapping.data.GraphNode;\r
23 import org.simantics.interop.mapping.data.Identifiable;\r
24 import org.simantics.interop.mapping.data.Link;\r
25 import org.simantics.interop.mapping.data.ResourceIdentifiable;\r
26 import org.simantics.ui.jobs.SessionGarbageCollectorJob;\r
27 import org.simantics.utils.datastructures.MapList;\r
28 import org.simantics.utils.datastructures.Pair;\r
29 import org.slf4j.Logger;\r
30 import org.slf4j.LoggerFactory;\r
31 \r
32 /**\r
33  * \r
34  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
35  *\r
36  */\r
37 public class Mapper {\r
38 \r
39         private static final Logger LOGGER = LoggerFactory.getLogger(Mapper.class);\r
40 \r
41         public static final boolean USE_SPLIT_TRANSACTIONS = false; // Split transactions\r
42         public static int OBJECTS_PER_TRANSACTION = 5000;           // number of objects handled per transaction (split mode) \r
43         private static boolean SLEEP_BETWEEN_WRITES = false;        // sleep between transactions (split mode)     \r
44         private static int SLEEP_TIME = 10;                         // time to sleep (ms)\r
45         private static boolean COLLECT_BETWEEN_WRITES = false;      // Run SessionGC between split transactions\r
46         private static boolean COLLECT_WITHIN_TRANSACTIONS = true;  // Run Collect within transactions (both modes)\r
47         public static int OBJECTS_BEFORE_COLLECT = 5000;            // number of objects that are handled before collect (non-split mode)\r
48         \r
49         private List<InitializedRule> initializedRules = new ArrayList<InitializedRule>();\r
50         private List<Pair<IdentificationRule, Pair<Integer,GenerationRule>>> generationRules;\r
51         private List<List<ModificationRule>> globalModificationRules;\r
52         private List<List<Pair<IdentificationRule, ModificationRule>>> modificationRules;\r
53         private List<Pair<ConnectionIdentificationRule, ConnectionGenerationRule>> connectionRules;\r
54 \r
55         int maxGenPass = 0;\r
56         \r
57         public Mapper() {\r
58                 long maxMemory = Runtime.getRuntime().maxMemory();\r
59                 maxMemory /= (1024*1024);                            // Convert to MB;\r
60                 int use = 290;                                       // Estimated memory usage of the system\r
61                 int freeMem = (int)maxMemory-use;                                        // Free memory for mappings    \r
62                 OBJECTS_BEFORE_COLLECT = (freeMem * freeMem) / 1000; //600M heap -> 84, 3000M heap -> 5645\r
63                 if (OBJECTS_BEFORE_COLLECT < 2)\r
64                         OBJECTS_BEFORE_COLLECT = 2;\r
65                 OBJECTS_PER_TRANSACTION = OBJECTS_BEFORE_COLLECT;\r
66                 \r
67                 \r
68                 generationRules = new ArrayList<Pair<IdentificationRule,Pair<Integer,GenerationRule>>>();\r
69                 modificationRules = new ArrayList<List<Pair<IdentificationRule,ModificationRule>>>();\r
70                 globalModificationRules = new ArrayList<List<ModificationRule>>();\r
71                 connectionRules = new ArrayList<Pair<ConnectionIdentificationRule, ConnectionGenerationRule>>();\r
72         }\r
73         \r
74         public void addRule(int pass, IdentificationRule idRule, GenerationRule genRule) {\r
75                 if (idRule == null || genRule == null) throw new NullPointerException();\r
76                 generationRules.add(new Pair<IdentificationRule, Pair<Integer,GenerationRule>>(idRule, new Pair<Integer,GenerationRule>(pass,genRule)));\r
77                 maxGenPass = Math.max(maxGenPass, pass);\r
78                 if (genRule instanceof InitializedRule)\r
79                         initializedRules.add((InitializedRule)genRule);\r
80         }\r
81         \r
82         public void addRule(IdentificationRule idRule, MappingRule mappingRule) {\r
83                 addRule(0,idRule,mappingRule);\r
84         }\r
85         \r
86         public void addRule(IdentificationRule idRule, MappingRule... mappingRules) {\r
87                 for (MappingRule mappingRule : mappingRules)\r
88                         addRule(0,idRule,mappingRule);\r
89         }\r
90         \r
91         public void addRule(int pass, IdentificationRule idRule, MappingRule mappingRule) {\r
92                 if (idRule == null || mappingRule == null) throw new NullPointerException();\r
93                 if (mappingRule instanceof ModificationRule) {\r
94                         while (pass >= modificationRules.size()) {\r
95                                 modificationRules.add(new ArrayList<Pair<IdentificationRule,ModificationRule>>());\r
96                         }\r
97                         List<Pair<IdentificationRule,ModificationRule>> priList = modificationRules.get(pass);\r
98                         priList.add(new Pair<IdentificationRule, ModificationRule>(idRule, (ModificationRule)mappingRule));\r
99                 }\r
100                 if (mappingRule instanceof GenerationRule)\r
101                         generationRules.add(new Pair<IdentificationRule, Pair<Integer,GenerationRule>>(idRule, new Pair<Integer,GenerationRule>(pass,(GenerationRule)mappingRule)));\r
102                 if (mappingRule instanceof InitializedRule)\r
103                         initializedRules.add((InitializedRule)mappingRule);\r
104         }\r
105         \r
106         public void addRule(int pass, IdentificationRule idRule, MappingRule... mappingRules) {\r
107                 for (MappingRule mappingRule : mappingRules)\r
108                         addRule(pass,idRule,mappingRule);\r
109         }\r
110         \r
111         public void addRule(IdentificationRule idRule, ModificationRule... modRules) {\r
112                 addRule(0, idRule, modRules);\r
113         }\r
114 \r
115         public void addRule(int pass, IdentificationRule idRule, ModificationRule... modRules) {\r
116                 if (idRule == null) throw new NullPointerException();\r
117                 \r
118                 while (pass >= modificationRules.size()) {\r
119                         modificationRules.add(new ArrayList<Pair<IdentificationRule,ModificationRule>>());\r
120                 }\r
121                 List<Pair<IdentificationRule,ModificationRule>> priList = modificationRules.get(pass);\r
122                 \r
123                 for (ModificationRule modRule : modRules){\r
124                         if (modRule == null) throw new NullPointerException();  \r
125                         priList.add(new Pair<IdentificationRule, ModificationRule>(idRule, modRule));\r
126                         if (modRule instanceof InitializedRule)\r
127                                 initializedRules.add((InitializedRule)modRule);\r
128                 }\r
129         }\r
130         public void addRule(ModificationRule modRule) {\r
131                 addRule(0, modRule);\r
132         }\r
133         \r
134         public void addRule(InitializedRule initRule) {\r
135                 initializedRules.add(initRule);\r
136         }\r
137         \r
138         public void addRule(int pass, ModificationRule modRule) {\r
139                 if (modRule == null) throw new NullPointerException();\r
140                 while (pass >= globalModificationRules.size()) {\r
141                         globalModificationRules.add(new ArrayList<ModificationRule>());\r
142                 }\r
143                 List<ModificationRule> priList = globalModificationRules.get(pass);\r
144                 priList.add(modRule);\r
145                 if (modRule instanceof InitializedRule)\r
146                         initializedRules.add((InitializedRule)modRule);\r
147         }\r
148         \r
149         public void addRule(ConnectionIdentificationRule idRule, ConnectionGenerationRule genRule) {\r
150                 if (idRule == null || genRule == null) throw new NullPointerException();\r
151                 connectionRules.add(new Pair<ConnectionIdentificationRule, ConnectionGenerationRule>(idRule, genRule));\r
152                 if (genRule instanceof InitializedRule)\r
153                         initializedRules.add((InitializedRule)genRule);\r
154         }\r
155         \r
156         /**\r
157          * Runs the mapping procedure. Disposes nodes after mapping is done.\r
158          * @param g\r
159          * @param model\r
160          * @param nodes\r
161          * @param monitor\r
162          * @throws Exception\r
163          */\r
164         public void map(WriteGraph g, Resource model, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
165                 startMapping(null);\r
166                 try {\r
167                         if (monitor == null)\r
168                                 monitor = new NullProgressMonitor();\r
169                         \r
170                         for (InitializedRule rule : initializedRules)\r
171                                 rule.initialize(g, model);\r
172                         \r
173                         applyModifications(g, nodes, monitor);\r
174                         monitor.worked(1);\r
175                         applyGenerations(g,nodes,monitor);\r
176                         monitor.worked(1);\r
177                         applyConnections(g,nodes,monitor);\r
178                         monitor.worked(1);\r
179                 } finally {\r
180                         MappingTools.disposeNodes(nodes);\r
181                         endMapping();\r
182                 }\r
183                 \r
184         }\r
185         \r
186         /**\r
187          * Runs the mapping procedure. Disposes nodes after mapping is done.\r
188          * @param session\r
189          * @param model\r
190          * @param nodes\r
191          * @param monitor\r
192          * @throws Exception\r
193          */\r
194         public void map(Session session, Resource model, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
195                 map(session, model, null, nodes, monitor);\r
196         }\r
197         \r
198         /**\r
199          * Runs the mapping procedure. Disposes nodes after mapping is done.\r
200          * @param session\r
201          * @param model\r
202          * @param vg\r
203          * @param nodes\r
204          * @param monitor\r
205          * @throws Exception\r
206          */\r
207         public void map(Session session, Resource model, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
208                 startMapping(vg);\r
209                 try {\r
210                         long time = System.currentTimeMillis();\r
211                         if (monitor == null)\r
212                                 monitor = new NullProgressMonitor();\r
213                         \r
214                         initializeRules(session, vg, model);\r
215                         if (USE_SPLIT_TRANSACTIONS) {\r
216                                 applyModifications(session, nodes, monitor);\r
217                                 monitor.worked(1);\r
218                                 applyGenerations(session, vg, nodes, monitor);\r
219                                 monitor.worked(1);\r
220                                 applyConnections(session, vg, nodes, monitor);\r
221                                 monitor.worked(1);\r
222                         } else {\r
223                                 applyModifications2(session, nodes, monitor);\r
224                                 monitor.worked(1);\r
225                                 applyGenerations2(session, vg, nodes, monitor);\r
226                                 monitor.worked(1);\r
227                                 applyConnections2(session, vg, nodes, monitor);\r
228                                 monitor.worked(1);\r
229                         }\r
230                         long time2 = System.currentTimeMillis();\r
231                         System.out.println("Mapping took " + ((time2-time)/1000) + " seconds");\r
232                 } finally {\r
233                         MappingTools.disposeNodes(nodes);\r
234                         if (COLLECT_BETWEEN_WRITES) {\r
235 \r
236                                 SessionGarbageCollection.gc(null, session, true, null);\r
237                         }\r
238                         endMapping();\r
239                 }\r
240                 \r
241         }\r
242         \r
243         \r
244         //private boolean autosaveEndabled = false;\r
245         private VirtualGraph vg;\r
246         \r
247         protected void startMapping(VirtualGraph vg) {\r
248                  SessionGarbageCollectorJob.getInstance().setEnabled(false);\r
249                  //autosaveEndabled = AutosaveCommands.getInstance().isEnabled();\r
250                  //AutosaveCommands.getInstance().setEnabled(false);\r
251                  this.vg = vg;\r
252         }\r
253         \r
254         protected void endMapping() {\r
255                  SessionGarbageCollectorJob.getInstance().setEnabled(true).scheduleAfterQuietTime();\r
256                 // AutosaveCommands.getInstance().setEnabled(autosaveEndabled);\r
257                  vg = null;\r
258         }\r
259         \r
260         private void applyModifications(ReadGraph g, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
261                 \r
262                 // Apply global modification rules first\r
263                 \r
264                 int passCount = Math.max(globalModificationRules.size(),modificationRules.size());\r
265 \r
266                 for (int pass = 0; pass < passCount; pass++) {\r
267                         if (globalModificationRules.size() > pass) {\r
268                                 int count = 0;\r
269                                 List<ModificationRule> modRules = globalModificationRules.get(pass);\r
270                                 int size = modRules.size();\r
271                                 monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
272                                 for (ModificationRule r : modRules) {\r
273                                         Collection<GraphNode<Identifiable>> ruleModified = r.modify(g, nodes);\r
274                                         if (ruleModified == null)\r
275                                                 continue;\r
276                                         for (GraphNode<Identifiable> m : ruleModified) {\r
277                                                 if (m.isDisposed()) {\r
278                                                         nodes.remove(m);\r
279                                                 }\r
280                                                 else if (!nodes.contains(m)) {\r
281                                                         nodes.add(m);\r
282                                                 }\r
283                                         }\r
284                                         monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
285                                         if(monitor.isCanceled()) {\r
286                                                 throw new CancelException("Cancel requested.");\r
287                                         }\r
288                                         if (COLLECT_WITHIN_TRANSACTIONS)\r
289                                                 collect(g);\r
290                                 }\r
291                         } if (modificationRules.size() > pass) {\r
292                                 int count = 0;\r
293                                 List<Pair<IdentificationRule, ModificationRule>> modRules = modificationRules.get(pass);\r
294                                 int size = modRules.size();\r
295                                 monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
296                                 // Apply per object modification rules \r
297                                 for (Pair<IdentificationRule, ModificationRule> modRule : modRules) {\r
298                                         Collection<GraphNode<Identifiable>> ruleModified = new ArrayList<GraphNode<Identifiable>>();\r
299                                         for (GraphNode<Identifiable> n : nodes) {\r
300                                                 applyModifications(g, n, modRule, ruleModified);\r
301                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
302                                                         collect2(g);\r
303                                         }\r
304                                         \r
305                                         for (GraphNode<Identifiable> m : ruleModified) {\r
306                                                 if (m.isDisposed()) {\r
307                                                         nodes.remove(m);\r
308                                                 }\r
309                                                 else if (!nodes.contains(m)) {\r
310                                                         nodes.add(m);\r
311                                                 }\r
312                                         }\r
313                                         monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
314                                         if(monitor.isCanceled()) {\r
315                                                 throw new CancelException("Cancel requested.");\r
316                                         }\r
317                                         \r
318                                 }\r
319                         }\r
320                 }\r
321                 \r
322         }\r
323         \r
324         \r
325         \r
326         protected void applyGenerations(WriteGraph graph, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
327                 \r
328                 int size = nodes.size();\r
329                 int count = 0;\r
330                 monitor.subTask("Assigning generation rules ("+ count + "/" + size + ")");\r
331                 // populate generation rules\r
332                 for (GraphNode<Identifiable> n : nodes) {\r
333                         \r
334                         for (Pair<IdentificationRule,Pair<Integer,GenerationRule>> r : generationRules) {\r
335                                 if (r.first.matches(graph, n)) {\r
336                                         MappingTools.assignGenerationRule(n, r.second.first,r.second.second);\r
337                                 }\r
338                         }\r
339                         monitor.subTask("Assigning generation rules ("+ (++count) + "/" + size + ")");\r
340                         if(monitor.isCanceled()) {\r
341                                 throw new CancelException("Cancel requested.");\r
342                         }\r
343                         if (COLLECT_WITHIN_TRANSACTIONS)\r
344                                 collect2(graph);\r
345                 }\r
346                 \r
347                 count = 0;\r
348                 monitor.subTask("Generating objects ("+ count + "/" + size + ")");\r
349                 \r
350                 // apply generation rules.\r
351                 //WriteWrapper g  = new WriteWrapper(graph);\r
352                 \r
353                 //Collection<GenerationRule> usedRules = new ArrayList<GenerationRule>();\r
354                 for (int stage = 0; stage <= maxGenPass; stage++) {\r
355                         count = 0;\r
356                         for (GraphNode<Identifiable> n : nodes) {\r
357 \r
358                                 MapList<Integer,GenerationRule> priRules = n.getHint(MappingHints.KEY_GENERATION_RULES);\r
359                                 if (priRules != null) {\r
360                                         List<GenerationRule> rules = priRules.getValues(stage);\r
361                                         for (GenerationRule r : rules) {\r
362                                                 r.generate(graph, n);\r
363                                         }\r
364                                 }\r
365 \r
366                                 monitor.subTask("Generating objects, stage " + stage + " :  ("+ (++count) + "/" + size + ")");\r
367                                 if(monitor.isCanceled()) {\r
368                                         throw new CancelException("Cancel requested.");\r
369                                 }\r
370                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
371                                         collect2(graph);\r
372                         }\r
373                 }\r
374         }\r
375         \r
376         protected void applyConnections(WriteGraph g, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
377                 int size = nodes.size();\r
378                 int count = 0;\r
379                 \r
380                 monitor.subTask("Generating connections ("+ count + "/" + size + ")");\r
381                 \r
382                 for (GraphNode<Identifiable> node : nodes) {\r
383                         applyConnections(g, node);\r
384                         monitor.subTask("Generating connections ("+ (++count) + "/" + size + ")");\r
385                         if(monitor.isCanceled()) {\r
386                                 throw new CancelException("Cancel requested.");\r
387                         }\r
388                         if (COLLECT_WITHIN_TRANSACTIONS)\r
389                                 collect2(g);\r
390                 }\r
391         }\r
392         \r
393         \r
394         \r
395         protected String getName(ReadGraph g, Identifiable res) throws DatabaseException {\r
396                 if (res instanceof ResourceIdentifiable)\r
397                         return NameUtils.getSafeName(g, ((ResourceIdentifiable)res).getResource());\r
398                 else\r
399                         return res.toString();\r
400         }\r
401         \r
402 \r
403         \r
404         protected void initializeRules(Session session, VirtualGraph vg, final Resource model ) throws DatabaseException{\r
405                 session.syncRequest(new WriteRequest(vg) {\r
406                         @Override\r
407                         public void perform(WriteGraph g) throws DatabaseException {\r
408                                 for (InitializedRule rule : initializedRules)\r
409                                         rule.initialize(g, model);\r
410                                 \r
411                         }\r
412                 });\r
413                 \r
414         }\r
415                 \r
416         protected void collect(ReadGraph g) throws DatabaseException {\r
417                 if (vg != null)\r
418                         return;\r
419                 SessionGarbageCollection.gc(g, 0, -1);\r
420         }\r
421         \r
422         int collect = 0;\r
423         \r
424         protected void collect2(ReadGraph g) throws DatabaseException {\r
425                 if (vg != null)\r
426                         return;\r
427                 \r
428                 if (collect == OBJECTS_BEFORE_COLLECT) {\r
429                         SessionGarbageCollection.gc(g, 0, -1);\r
430                         collect = 0;\r
431                 } else {\r
432                         collect++;\r
433                 }\r
434         }\r
435         \r
436         protected void applyModifications(Session session, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {\r
437                 \r
438                 \r
439                 \r
440                 int passCount = Math.max(globalModificationRules.size(),modificationRules.size());\r
441                 \r
442                 for (int pass = 0; pass <passCount; pass++) {\r
443                         // Apply global modification rules first\r
444                         if (globalModificationRules.size() > pass) {\r
445                                 int count = 0;\r
446                                 List<ModificationRule> modRules = globalModificationRules.get(pass);\r
447                                 int size = modRules.size();\r
448                                 monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
449                                 for (final ModificationRule r : modRules) {\r
450                                         session.syncRequest(new ReadRequest() {\r
451                                                 \r
452                                                 @Override\r
453                                                 public void run(ReadGraph g) throws DatabaseException {\r
454                                                         try {\r
455                                                                 Collection<GraphNode<Identifiable>> ruleModified = r.modify(g, nodes);\r
456                                                                 \r
457                                                                 if (ruleModified == null)\r
458                                                                         return;\r
459                                                                 for (GraphNode<Identifiable> m : ruleModified) {\r
460                                                                         if (m.isDisposed()) {\r
461                                                                                 nodes.remove(m);\r
462                                                                         }\r
463                                                                         else if (!nodes.contains(m)) {\r
464                                                                                 nodes.add(m);\r
465                                                                         }\r
466                                                                 }\r
467                                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
468                                                                         collect(g);\r
469                                                         } catch (Exception e) {\r
470                                                                 throw new DatabaseException(e);\r
471                                                         }\r
472                                                         \r
473                                                 }\r
474                                         });\r
475                                         //SessionGarbageCollection.gc(null, session, true, null);\r
476                                         monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
477                                         if(monitor.isCanceled()) {\r
478                                                 throw new CancelException("Cancel requested.");\r
479                                         }\r
480                                 }\r
481                         }\r
482                         if (modificationRules.size() > pass) {\r
483                                 int count = 0;\r
484                                 List<Pair<IdentificationRule, ModificationRule>> modRules = modificationRules.get(pass);\r
485                                 int size = modRules.size();\r
486                                 monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
487                                 \r
488                                 // Apply per object modification rules \r
489                                 for (final Pair<IdentificationRule, ModificationRule> modRule : modRules) {\r
490                                         final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();\r
491                                         final Collection<GraphNode<Identifiable>> ruleModified = new ArrayList<GraphNode<Identifiable>>();\r
492                                         while (iter.hasNext()) {\r
493                                                 session.syncRequest(new ReadRequest() {\r
494                                                         \r
495                                                         @Override\r
496                                                         public void run(ReadGraph g) throws DatabaseException {\r
497                                                                 try {\r
498                                                                         \r
499                                                                         int j = 0; \r
500                                                                         //for (GraphNode<Identifiable> n : nodes) {\r
501                                                                         while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {\r
502                                                                                 GraphNode<Identifiable> n = iter.next();\r
503                                                                                 applyModifications(g, n, modRule, ruleModified);\r
504                                                                                 j++;\r
505                                                                         }\r
506                                                                         if (COLLECT_WITHIN_TRANSACTIONS)\r
507                                                                                 collect(g);\r
508                                                                         \r
509                                                                 } catch (Exception e) {\r
510                                                                         throw new DatabaseException(e);\r
511                                                                 }\r
512                                                                 \r
513                                                         }\r
514                                                 });\r
515                                         }\r
516                                         for (GraphNode<Identifiable> m : ruleModified) {\r
517                                                 if (m.isDisposed()) {\r
518                                                         nodes.remove(m);\r
519                                                 }\r
520                                                 else if (!nodes.contains(m)) {\r
521                                                         nodes.add(m);\r
522                                                 }\r
523                                         }\r
524                                         ruleModified.clear();\r
525                                         \r
526                                         //SessionGarbageCollection.gc(null, session, true, null);\r
527                                         monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
528                                         if(monitor.isCanceled()) {\r
529                                                 throw new CancelException("Cancel requested.");\r
530                                         }\r
531                                 }\r
532                         }       \r
533                 }\r
534                 \r
535         }\r
536         \r
537         private void applyModifications2(Session session, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {\r
538                 session.syncRequest(new ReadRequest() {\r
539                         \r
540                         @Override\r
541                         public void run(ReadGraph g) throws DatabaseException {\r
542                                 try {\r
543                                         applyModifications(g, nodes, monitor);\r
544                                 } catch (Exception e) {\r
545                                         throw new DatabaseException(e);\r
546                                 }\r
547                                 \r
548                         }\r
549                 });\r
550         }\r
551         \r
552         protected void applyGenerations(Session session, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
553                 \r
554                 int size = nodes.size();\r
555                 int count = 0;\r
556                 monitor.subTask("Assigning generation rules ("+ count + "/" + size + ")");\r
557                 // populate generation rules\r
558 \r
559                 {\r
560                         final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();\r
561                         while (iter.hasNext()) {\r
562                                 int c = session.syncRequest(new Read<Integer>() {\r
563                                         \r
564                                         @Override\r
565                                         public Integer perform(ReadGraph graph)\r
566                                                         throws DatabaseException {\r
567                                                 int j = 0;\r
568                                                 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {\r
569                                                         GraphNode<Identifiable> n = iter.next();\r
570                                                         for (Pair<IdentificationRule,Pair<Integer,GenerationRule>> r : generationRules) {\r
571                                                                 if (r.first.matches(graph, n)) {\r
572                                                                         MapList<Integer,GenerationRule> rules = n.getHint(MappingHints.KEY_GENERATION_RULES);\r
573                                                                         if (rules == null) {\r
574                                                                                 rules = new MapList<Integer,GenerationRule>();  \r
575                                                                         }\r
576                                                                         rules.add(r.second.first,r.second.second);\r
577                                                                         n.setHint(MappingHints.KEY_GENERATION_RULES, rules);\r
578                                                                 }\r
579                                                         }\r
580                                                         j++;\r
581                                                 }\r
582                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
583                                                         collect(graph);\r
584                                                 return j;\r
585                                                 \r
586                                         }\r
587                                 });\r
588                                 collect(session);\r
589                                 monitor.subTask("Assigning generation rules ("+ (count+=c) + "/" + size + ")");\r
590                                 if(monitor.isCanceled()) {\r
591                                         throw new CancelException("Cancel requested.");\r
592                                 }\r
593                                 sleep();\r
594                         }\r
595                 }\r
596                 \r
597                 count = 0;\r
598                 monitor.subTask("Generating objects ("+ (count) + "/" + size + ")");\r
599                 \r
600                 // apply generation rules.\r
601                 \r
602                 {\r
603                         for (int stage = 0; stage <= maxGenPass; stage++) {\r
604                                 final int fStage = stage;\r
605                                 count = 0;\r
606                                 final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();\r
607                                 while (iter.hasNext()) {\r
608                                         int c = session.syncRequest(new WriteResultRequest<Integer>(vg) {\r
609                                                 \r
610                                                 @Override\r
611                                                 public Integer perform(WriteGraph graph) throws DatabaseException {\r
612                                                         int j = 0;\r
613                                                         try {\r
614                                                                 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {\r
615                                                                         GraphNode<Identifiable> n = iter.next();\r
616                                                                         \r
617                                                                         MapList<Integer,GenerationRule> priRules = n.getHint(MappingHints.KEY_GENERATION_RULES);\r
618                                                                         if (priRules == null) {\r
619                                                                                 j++;\r
620                                                                                 continue;\r
621                                                                         }\r
622                                                                         final List<GenerationRule> rules = priRules.getValues(fStage);\r
623                                                                         \r
624                                                                         if (fStage == 0 && rules.size() == 0)\r
625                                                                                 System.out.println();\r
626                                                                         for (GenerationRule r : rules) {\r
627                                                                                 r.generate(graph, n);\r
628 \r
629                                                                         }\r
630 \r
631                                                                                 \r
632                                                                         j++;\r
633                                                                         \r
634                                                                 }\r
635                                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
636                                                                         collect(graph);\r
637                                                                 return j;\r
638                                                         \r
639                                                 } catch (Exception e) {\r
640                                                         throw new DatabaseException(e);\r
641                                                 }\r
642                                         }});\r
643                                         collect(session);\r
644                                         monitor.subTask("Generating objects, stage " + stage + " :  ("+ (count+=c) + "/" + size + ")");\r
645                                         if(monitor.isCanceled()) {\r
646                                                 throw new CancelException("Cancel requested.");\r
647                                         }\r
648                                         sleep();\r
649                                 }\r
650                         }\r
651                 }\r
652         }\r
653         \r
654         private void applyGenerations2(Session session, VirtualGraph vg, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {\r
655                 session.syncRequest(new WriteRequest(vg) {\r
656                         \r
657                         @Override\r
658                         public void perform(WriteGraph graph) throws DatabaseException {\r
659                                 try {\r
660                                         applyGenerations(graph, nodes, monitor);\r
661                                 } catch (Exception e) {\r
662                                         throw new DatabaseException(e);\r
663                                 }\r
664                                 \r
665                         }\r
666                 });\r
667         }\r
668         \r
669         private void collect(Session session) {\r
670                 if (COLLECT_BETWEEN_WRITES)\r
671                         SessionGarbageCollection.gc(null, session, true, null);\r
672         }\r
673         \r
674         \r
675         private void sleep() {\r
676                 if (SLEEP_BETWEEN_WRITES) {\r
677                         try {\r
678                                 Thread.sleep(SLEEP_TIME);\r
679                         } catch (InterruptedException e) {\r
680                                 \r
681                         }\r
682                 }\r
683         }\r
684         \r
685         protected void applyConnections(Session session, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
686                 int size = nodes.size();\r
687                 int count = 0;\r
688                 \r
689                 monitor.subTask("Generating connections ("+ count + "/" + size + ")");\r
690                 \r
691                 final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();\r
692                 while (iter.hasNext()) {\r
693                         int c = session.syncRequest(new WriteResultRequest<Integer>(vg) {\r
694                                 \r
695                                 @Override\r
696                                 public Integer perform(WriteGraph g) throws DatabaseException {\r
697                                         int j = 0;\r
698                                         try {\r
699                                                 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {\r
700                                                         GraphNode<Identifiable> node = iter.next();\r
701                                                         applyConnections(g, node);\r
702                                                         j++;\r
703                                                 }\r
704                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
705                                                         collect(g);\r
706                                                 return j;\r
707                                                 \r
708                                         } catch (Exception e) {\r
709                                                 throw new DatabaseException(e);\r
710                                         }       \r
711                                 }       \r
712                         });\r
713                         collect(session);\r
714                         monitor.subTask("Generating connections ("+ (count+=c) + "/" + size + ")");\r
715                         if(monitor.isCanceled()) {\r
716                                 throw new CancelException("Cancel requested.");\r
717                         }\r
718                         sleep();\r
719                 }\r
720         }\r
721         \r
722         private void applyConnections2(Session session, VirtualGraph vg, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {\r
723                 session.syncRequest(new WriteRequest(vg) {\r
724                         \r
725                         @Override\r
726                         public void perform(WriteGraph graph) throws DatabaseException {\r
727                                 try {\r
728                                         applyConnections(graph, nodes, monitor);\r
729                                 } catch (Exception e) {\r
730                                         throw new DatabaseException(e);\r
731                                 }\r
732                                 \r
733                         }\r
734                 });\r
735         }\r
736 \r
737         protected void applyModifications(ReadGraph g, GraphNode<Identifiable> n, Pair<IdentificationRule, ModificationRule> modRule, Collection<GraphNode<Identifiable>> ruleModified) throws Exception {\r
738                 if (!n.isDisposed() && modRule.first.matches(g, n)) { // we have to check \r
739                         Collection<GraphNode<Identifiable>> perRule = new ArrayList<GraphNode<Identifiable>>();\r
740                         perRule.add(n);\r
741                         ruleModified.addAll(modRule.second.modify(g, perRule));\r
742                 }\r
743         }\r
744         \r
745         protected void applyConnections(WriteGraph g, GraphNode<Identifiable> node) throws Exception {\r
746                 for (Link<Identifiable> link : node.getLinks()) {\r
747                         if (link.isMain()) {\r
748                                 \r
749                                 for (Pair<ConnectionIdentificationRule, ConnectionGenerationRule> r : connectionRules) {\r
750                                         if (r.first.mathces(g, node, link.to(), link)) {\r
751                                                 LOGGER.info("Connecting " +  getName(g, node.getData()) + " to " + getName(g, link.to().getData()) + " " + link.getName() + "/"+link.getInverseName());\r
752                                                 r.second.generate(g, node, link.to(), link);\r
753                                                 break;\r
754                                         }\r
755                                 }\r
756                         }\r
757                 }\r
758         }\r
759 }\r