1 package org.simantics.interop.mapping;
\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
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
34 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
\r
37 public class Mapper {
\r
39 private static final Logger LOGGER = LoggerFactory.getLogger(Mapper.class);
\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
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
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
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
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
82 public void addRule(IdentificationRule idRule, MappingRule mappingRule) {
\r
83 addRule(0,idRule,mappingRule);
\r
86 public void addRule(IdentificationRule idRule, MappingRule... mappingRules) {
\r
87 for (MappingRule mappingRule : mappingRules)
\r
88 addRule(0,idRule,mappingRule);
\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
97 List<Pair<IdentificationRule,ModificationRule>> priList = modificationRules.get(pass);
\r
98 priList.add(new Pair<IdentificationRule, ModificationRule>(idRule, (ModificationRule)mappingRule));
\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
106 public void addRule(int pass, IdentificationRule idRule, MappingRule... mappingRules) {
\r
107 for (MappingRule mappingRule : mappingRules)
\r
108 addRule(pass,idRule,mappingRule);
\r
111 public void addRule(IdentificationRule idRule, ModificationRule... modRules) {
\r
112 addRule(0, idRule, modRules);
\r
115 public void addRule(int pass, IdentificationRule idRule, ModificationRule... modRules) {
\r
116 if (idRule == null) throw new NullPointerException();
\r
118 while (pass >= modificationRules.size()) {
\r
119 modificationRules.add(new ArrayList<Pair<IdentificationRule,ModificationRule>>());
\r
121 List<Pair<IdentificationRule,ModificationRule>> priList = modificationRules.get(pass);
\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
130 public void addRule(ModificationRule modRule) {
\r
131 addRule(0, modRule);
\r
134 public void addRule(InitializedRule initRule) {
\r
135 initializedRules.add(initRule);
\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
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
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
157 * Runs the mapping procedure. Disposes nodes after mapping is done.
\r
162 * @throws Exception
\r
164 public void map(WriteGraph g, Resource model, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
165 startMapping(null);
\r
167 if (monitor == null)
\r
168 monitor = new NullProgressMonitor();
\r
170 for (InitializedRule rule : initializedRules)
\r
171 rule.initialize(g, model);
\r
173 applyModifications(g, nodes, monitor);
\r
175 applyGenerations(g,nodes,monitor);
\r
177 applyConnections(g,nodes,monitor);
\r
180 MappingTools.disposeNodes(nodes);
\r
187 * Runs the mapping procedure. Disposes nodes after mapping is done.
\r
192 * @throws Exception
\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
199 * Runs the mapping procedure. Disposes nodes after mapping is done.
\r
205 * @throws Exception
\r
207 public void map(Session session, Resource model, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
210 long time = System.currentTimeMillis();
\r
211 if (monitor == null)
\r
212 monitor = new NullProgressMonitor();
\r
214 initializeRules(session, vg, model);
\r
215 if (USE_SPLIT_TRANSACTIONS) {
\r
216 applyModifications(session, nodes, monitor);
\r
218 applyGenerations(session, vg, nodes, monitor);
\r
220 applyConnections(session, vg, nodes, monitor);
\r
223 applyModifications2(session, nodes, monitor);
\r
225 applyGenerations2(session, vg, nodes, monitor);
\r
227 applyConnections2(session, vg, nodes, monitor);
\r
230 long time2 = System.currentTimeMillis();
\r
231 System.out.println("Mapping took " + ((time2-time)/1000) + " seconds");
\r
233 MappingTools.disposeNodes(nodes);
\r
234 if (COLLECT_BETWEEN_WRITES) {
\r
236 SessionGarbageCollection.gc(null, session, true, null);
\r
244 //private boolean autosaveEndabled = false;
\r
245 private VirtualGraph vg;
\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
254 protected void endMapping() {
\r
255 SessionGarbageCollectorJob.getInstance().setEnabled(true).scheduleAfterQuietTime();
\r
256 // AutosaveCommands.getInstance().setEnabled(autosaveEndabled);
\r
260 private void applyModifications(ReadGraph g, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
262 // Apply global modification rules first
\r
264 int passCount = Math.max(globalModificationRules.size(),modificationRules.size());
\r
266 for (int pass = 0; pass < passCount; pass++) {
\r
267 if (globalModificationRules.size() > pass) {
\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
276 for (GraphNode<Identifiable> m : ruleModified) {
\r
277 if (m.isDisposed()) {
\r
280 else if (!nodes.contains(m)) {
\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
288 if (COLLECT_WITHIN_TRANSACTIONS)
\r
291 } if (modificationRules.size() > pass) {
\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
305 for (GraphNode<Identifiable> m : ruleModified) {
\r
306 if (m.isDisposed()) {
\r
309 else if (!nodes.contains(m)) {
\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
326 protected void applyGenerations(WriteGraph graph, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
328 int size = nodes.size();
\r
330 monitor.subTask("Assigning generation rules ("+ count + "/" + size + ")");
\r
331 // populate generation rules
\r
332 for (GraphNode<Identifiable> n : nodes) {
\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
339 monitor.subTask("Assigning generation rules ("+ (++count) + "/" + size + ")");
\r
340 if(monitor.isCanceled()) {
\r
341 throw new CancelException("Cancel requested.");
\r
343 if (COLLECT_WITHIN_TRANSACTIONS)
\r
348 monitor.subTask("Generating objects ("+ count + "/" + size + ")");
\r
350 // apply generation rules.
\r
351 //WriteWrapper g = new WriteWrapper(graph);
\r
353 //Collection<GenerationRule> usedRules = new ArrayList<GenerationRule>();
\r
354 for (int stage = 0; stage <= maxGenPass; stage++) {
\r
356 for (GraphNode<Identifiable> n : nodes) {
\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
366 monitor.subTask("Generating objects, stage " + stage + " : ("+ (++count) + "/" + size + ")");
\r
367 if(monitor.isCanceled()) {
\r
368 throw new CancelException("Cancel requested.");
\r
370 if (COLLECT_WITHIN_TRANSACTIONS)
\r
376 protected void applyConnections(WriteGraph g, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
377 int size = nodes.size();
\r
380 monitor.subTask("Generating connections ("+ count + "/" + size + ")");
\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
388 if (COLLECT_WITHIN_TRANSACTIONS)
\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
399 return res.toString();
\r
404 protected void initializeRules(Session session, VirtualGraph vg, final Resource model ) throws DatabaseException{
\r
405 session.syncRequest(new WriteRequest(vg) {
\r
407 public void perform(WriteGraph g) throws DatabaseException {
\r
408 for (InitializedRule rule : initializedRules)
\r
409 rule.initialize(g, model);
\r
416 protected void collect(ReadGraph g) throws DatabaseException {
\r
419 SessionGarbageCollection.gc(g, 0, -1);
\r
424 protected void collect2(ReadGraph g) throws DatabaseException {
\r
428 if (collect == OBJECTS_BEFORE_COLLECT) {
\r
429 SessionGarbageCollection.gc(g, 0, -1);
\r
436 protected void applyModifications(Session session, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {
\r
440 int passCount = Math.max(globalModificationRules.size(),modificationRules.size());
\r
442 for (int pass = 0; pass <passCount; pass++) {
\r
443 // Apply global modification rules first
\r
444 if (globalModificationRules.size() > pass) {
\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
453 public void run(ReadGraph g) throws DatabaseException {
\r
455 Collection<GraphNode<Identifiable>> ruleModified = r.modify(g, nodes);
\r
457 if (ruleModified == null)
\r
459 for (GraphNode<Identifiable> m : ruleModified) {
\r
460 if (m.isDisposed()) {
\r
463 else if (!nodes.contains(m)) {
\r
467 if (COLLECT_WITHIN_TRANSACTIONS)
\r
469 } catch (Exception e) {
\r
470 throw new DatabaseException(e);
\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
482 if (modificationRules.size() > pass) {
\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
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
496 public void run(ReadGraph g) throws DatabaseException {
\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
506 if (COLLECT_WITHIN_TRANSACTIONS)
\r
509 } catch (Exception e) {
\r
510 throw new DatabaseException(e);
\r
516 for (GraphNode<Identifiable> m : ruleModified) {
\r
517 if (m.isDisposed()) {
\r
520 else if (!nodes.contains(m)) {
\r
524 ruleModified.clear();
\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
537 private void applyModifications2(Session session, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {
\r
538 session.syncRequest(new ReadRequest() {
\r
541 public void run(ReadGraph g) throws DatabaseException {
\r
543 applyModifications(g, nodes, monitor);
\r
544 } catch (Exception e) {
\r
545 throw new DatabaseException(e);
\r
552 protected void applyGenerations(Session session, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
554 int size = nodes.size();
\r
556 monitor.subTask("Assigning generation rules ("+ count + "/" + size + ")");
\r
557 // populate generation rules
\r
560 final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();
\r
561 while (iter.hasNext()) {
\r
562 int c = session.syncRequest(new Read<Integer>() {
\r
565 public Integer perform(ReadGraph graph)
\r
566 throws DatabaseException {
\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
576 rules.add(r.second.first,r.second.second);
\r
577 n.setHint(MappingHints.KEY_GENERATION_RULES, rules);
\r
582 if (COLLECT_WITHIN_TRANSACTIONS)
\r
589 monitor.subTask("Assigning generation rules ("+ (count+=c) + "/" + size + ")");
\r
590 if(monitor.isCanceled()) {
\r
591 throw new CancelException("Cancel requested.");
\r
598 monitor.subTask("Generating objects ("+ (count) + "/" + size + ")");
\r
600 // apply generation rules.
\r
603 for (int stage = 0; stage <= maxGenPass; stage++) {
\r
604 final int fStage = stage;
\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
611 public Integer perform(WriteGraph graph) throws DatabaseException {
\r
614 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {
\r
615 GraphNode<Identifiable> n = iter.next();
\r
617 MapList<Integer,GenerationRule> priRules = n.getHint(MappingHints.KEY_GENERATION_RULES);
\r
618 if (priRules == null) {
\r
622 final List<GenerationRule> rules = priRules.getValues(fStage);
\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
635 if (COLLECT_WITHIN_TRANSACTIONS)
\r
639 } catch (Exception e) {
\r
640 throw new DatabaseException(e);
\r
644 monitor.subTask("Generating objects, stage " + stage + " : ("+ (count+=c) + "/" + size + ")");
\r
645 if(monitor.isCanceled()) {
\r
646 throw new CancelException("Cancel requested.");
\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
658 public void perform(WriteGraph graph) throws DatabaseException {
\r
660 applyGenerations(graph, nodes, monitor);
\r
661 } catch (Exception e) {
\r
662 throw new DatabaseException(e);
\r
669 private void collect(Session session) {
\r
670 if (COLLECT_BETWEEN_WRITES)
\r
671 SessionGarbageCollection.gc(null, session, true, null);
\r
675 private void sleep() {
\r
676 if (SLEEP_BETWEEN_WRITES) {
\r
678 Thread.sleep(SLEEP_TIME);
\r
679 } catch (InterruptedException e) {
\r
685 protected void applyConnections(Session session, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
686 int size = nodes.size();
\r
689 monitor.subTask("Generating connections ("+ count + "/" + size + ")");
\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
696 public Integer perform(WriteGraph g) throws DatabaseException {
\r
699 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {
\r
700 GraphNode<Identifiable> node = iter.next();
\r
701 applyConnections(g, node);
\r
704 if (COLLECT_WITHIN_TRANSACTIONS)
\r
708 } catch (Exception e) {
\r
709 throw new DatabaseException(e);
\r
714 monitor.subTask("Generating connections ("+ (count+=c) + "/" + size + ")");
\r
715 if(monitor.isCanceled()) {
\r
716 throw new CancelException("Cancel requested.");
\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
726 public void perform(WriteGraph graph) throws DatabaseException {
\r
728 applyConnections(graph, nodes, monitor);
\r
729 } catch (Exception e) {
\r
730 throw new DatabaseException(e);
\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
741 ruleModified.addAll(modRule.second.modify(g, perRule));
\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
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