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.exception.ServiceException;
\r
21 import org.simantics.db.layer0.util.SessionGarbageCollection;
\r
22 import org.simantics.db.request.Read;
\r
23 import org.simantics.interop.mapping.data.GraphNode;
\r
24 import org.simantics.interop.mapping.data.Identifiable;
\r
25 import org.simantics.interop.mapping.data.Link;
\r
26 import org.simantics.interop.mapping.data.ResourceIdentifiable;
\r
27 import org.simantics.ui.jobs.SessionGarbageCollectorJob;
\r
28 import org.simantics.utils.datastructures.MapList;
\r
29 import org.simantics.utils.datastructures.Pair;
\r
33 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
\r
36 public class Mapper {
\r
38 public static final boolean USE_SPLIT_TRANSACTIONS = false; // Split transactions
\r
39 public static int OBJECTS_PER_TRANSACTION = 5000; // number of objects handled per transaction (split mode)
\r
40 private static boolean SLEEP_BETWEEN_WRITES = false; // sleep between transactions (split mode)
\r
41 private static int SLEEP_TIME = 10; // time to sleep (ms)
\r
42 private static boolean COLLECT_BETWEEN_WRITES = false; // Run SessionGC between split transactions
\r
43 private static boolean COLLECT_WITHIN_TRANSACTIONS = true; // Run Collect within transactions (both modes)
\r
44 public static int OBJECTS_BEFORE_COLLECT = 5000; // number of objects that are handled before collect (non-split mode)
\r
46 private List<InitializedRule> initializedRules = new ArrayList<InitializedRule>();
\r
47 private List<Pair<IdentificationRule, Pair<Integer,GenerationRule>>> generationRules;
\r
48 private List<List<ModificationRule>> globalModificationRules;
\r
49 private List<List<Pair<IdentificationRule, ModificationRule>>> modificationRules;
\r
50 private List<Pair<ConnectionIdentificationRule, ConnectionGenerationRule>> connectionRules;
\r
55 long maxMemory = Runtime.getRuntime().maxMemory();
\r
56 maxMemory /= (1024*1024); // Convert to MB;
\r
57 int use = 290; // Estimated memory usage of the system
\r
58 int freeMem = (int)maxMemory-use; // Free memory for mappings
\r
59 OBJECTS_BEFORE_COLLECT = (freeMem * freeMem) / 1000; //600M heap -> 84, 3000M heap -> 5645
\r
60 if (OBJECTS_BEFORE_COLLECT < 2)
\r
61 OBJECTS_BEFORE_COLLECT = 2;
\r
62 OBJECTS_PER_TRANSACTION = OBJECTS_BEFORE_COLLECT;
\r
65 generationRules = new ArrayList<Pair<IdentificationRule,Pair<Integer,GenerationRule>>>();
\r
66 modificationRules = new ArrayList<List<Pair<IdentificationRule,ModificationRule>>>();
\r
67 globalModificationRules = new ArrayList<List<ModificationRule>>();
\r
68 connectionRules = new ArrayList<Pair<ConnectionIdentificationRule, ConnectionGenerationRule>>();
\r
71 public void addRule(int pass, IdentificationRule idRule, GenerationRule genRule) {
\r
72 if (idRule == null || genRule == null) throw new NullPointerException();
\r
73 generationRules.add(new Pair<IdentificationRule, Pair<Integer,GenerationRule>>(idRule, new Pair<Integer,GenerationRule>(pass,genRule)));
\r
74 maxGenPass = Math.max(maxGenPass, pass);
\r
75 if (genRule instanceof InitializedRule)
\r
76 initializedRules.add((InitializedRule)genRule);
\r
79 public void addRule(IdentificationRule idRule, MappingRule mappingRule) {
\r
80 addRule(0,idRule,mappingRule);
\r
83 public void addRule(int pass, IdentificationRule idRule, MappingRule mappingRule) {
\r
84 if (idRule == null || mappingRule == null) throw new NullPointerException();
\r
85 if (mappingRule instanceof ModificationRule) {
\r
86 while (pass >= modificationRules.size()) {
\r
87 modificationRules.add(new ArrayList<Pair<IdentificationRule,ModificationRule>>());
\r
89 List<Pair<IdentificationRule,ModificationRule>> priList = modificationRules.get(pass);
\r
90 priList.add(new Pair<IdentificationRule, ModificationRule>(idRule, (ModificationRule)mappingRule));
\r
92 if (mappingRule instanceof GenerationRule)
\r
93 generationRules.add(new Pair<IdentificationRule, Pair<Integer,GenerationRule>>(idRule, new Pair<Integer,GenerationRule>(pass,(GenerationRule)mappingRule)));
\r
94 if (mappingRule instanceof InitializedRule)
\r
95 initializedRules.add((InitializedRule)mappingRule);
\r
98 public void addRule(IdentificationRule idRule, ModificationRule... modRules) {
\r
99 addRule(0, idRule, modRules);
\r
102 public void addRule(int pass, IdentificationRule idRule, ModificationRule... modRules) {
\r
103 if (idRule == null) throw new NullPointerException();
\r
105 while (pass >= modificationRules.size()) {
\r
106 modificationRules.add(new ArrayList<Pair<IdentificationRule,ModificationRule>>());
\r
108 List<Pair<IdentificationRule,ModificationRule>> priList = modificationRules.get(pass);
\r
110 for (ModificationRule modRule : modRules){
\r
111 if (modRule == null) throw new NullPointerException();
\r
112 priList.add(new Pair<IdentificationRule, ModificationRule>(idRule, modRule));
\r
113 if (modRule instanceof InitializedRule)
\r
114 initializedRules.add((InitializedRule)modRule);
\r
117 public void addRule(ModificationRule modRule) {
\r
118 addRule(0, modRule);
\r
121 public void addRule(int pass, ModificationRule modRule) {
\r
122 if (modRule == null) throw new NullPointerException();
\r
123 while (pass >= globalModificationRules.size()) {
\r
124 globalModificationRules.add(new ArrayList<ModificationRule>());
\r
126 List<ModificationRule> priList = globalModificationRules.get(pass);
\r
127 priList.add(modRule);
\r
128 if (modRule instanceof InitializedRule)
\r
129 initializedRules.add((InitializedRule)modRule);
\r
132 public void addRule(ConnectionIdentificationRule idRule, ConnectionGenerationRule genRule) {
\r
133 if (idRule == null || genRule == null) throw new NullPointerException();
\r
134 connectionRules.add(new Pair<ConnectionIdentificationRule, ConnectionGenerationRule>(idRule, genRule));
\r
135 if (genRule instanceof InitializedRule)
\r
136 initializedRules.add((InitializedRule)genRule);
\r
140 * Runs the mapping procedure. Disposes nodes after mapping is done.
\r
145 * @throws Exception
\r
147 public void map(WriteGraph g, Resource model, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
148 startMapping(null);
\r
150 if (monitor == null)
\r
151 monitor = new NullProgressMonitor();
\r
153 for (InitializedRule rule : initializedRules)
\r
154 rule.initialize(g, model);
\r
156 applyModifications(g, nodes, monitor);
\r
158 applyGenerations(g,nodes,monitor);
\r
160 applyConnections(g,nodes,monitor);
\r
163 MappingTools.disposeNodes(nodes);
\r
170 * Runs the mapping procedure. Disposes nodes after mapping is done.
\r
175 * @throws Exception
\r
177 public void map(Session session, Resource model, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
178 map(session, model, null, nodes, monitor);
\r
182 * Runs the mapping procedure. Disposes nodes after mapping is done.
\r
188 * @throws Exception
\r
190 public void map(Session session, Resource model, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
193 long time = System.currentTimeMillis();
\r
194 if (monitor == null)
\r
195 monitor = new NullProgressMonitor();
\r
197 initializeRules(session, vg, model);
\r
198 if (USE_SPLIT_TRANSACTIONS) {
\r
199 applyModifications(session, nodes, monitor);
\r
201 applyGenerations(session, vg, nodes, monitor);
\r
203 applyConnections(session, vg, nodes, monitor);
\r
206 applyModifications2(session, nodes, monitor);
\r
208 applyGenerations2(session, vg, nodes, monitor);
\r
210 applyConnections2(session, vg, nodes, monitor);
\r
213 long time2 = System.currentTimeMillis();
\r
214 System.out.println("Mapping took " + ((time2-time)/1000) + " seconds");
\r
216 MappingTools.disposeNodes(nodes);
\r
217 if (COLLECT_BETWEEN_WRITES) {
\r
219 SessionGarbageCollection.gc(null, session, true, null);
\r
227 //private boolean autosaveEndabled = false;
\r
228 private VirtualGraph vg;
\r
230 protected void startMapping(VirtualGraph vg) {
\r
231 SessionGarbageCollectorJob.getInstance().setEnabled(false);
\r
232 //autosaveEndabled = AutosaveCommands.getInstance().isEnabled();
\r
233 //AutosaveCommands.getInstance().setEnabled(false);
\r
237 protected void endMapping() {
\r
238 SessionGarbageCollectorJob.getInstance().setEnabled(true).scheduleAfterQuietTime();
\r
239 // AutosaveCommands.getInstance().setEnabled(autosaveEndabled);
\r
243 private void applyModifications(ReadGraph g, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
245 // Apply global modification rules first
\r
247 int passCount = Math.max(globalModificationRules.size(),modificationRules.size());
\r
249 for (int pass = 0; pass < passCount; pass++) {
\r
250 if (globalModificationRules.size() > pass) {
\r
252 List<ModificationRule> modRules = globalModificationRules.get(pass);
\r
253 int size = modRules.size();
\r
254 monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");
\r
255 for (ModificationRule r : modRules) {
\r
256 Collection<GraphNode<Identifiable>> ruleModified = r.modify(g, nodes);
\r
257 if (ruleModified == null)
\r
259 for (GraphNode<Identifiable> m : ruleModified) {
\r
260 if (m.isDisposed()) {
\r
263 else if (!nodes.contains(m)) {
\r
267 monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");
\r
268 if(monitor.isCanceled()) {
\r
269 throw new CancelException("Cancel requested.");
\r
271 if (COLLECT_WITHIN_TRANSACTIONS)
\r
274 } if (modificationRules.size() > pass) {
\r
276 List<Pair<IdentificationRule, ModificationRule>> modRules = modificationRules.get(pass);
\r
277 int size = modRules.size();
\r
278 monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");
\r
279 // Apply per object modification rules
\r
280 for (Pair<IdentificationRule, ModificationRule> modRule : modRules) {
\r
281 Collection<GraphNode<Identifiable>> ruleModified = new ArrayList<GraphNode<Identifiable>>();
\r
282 for (GraphNode<Identifiable> n : nodes) {
\r
283 applyModifications(g, n, modRule, ruleModified);
\r
284 if (COLLECT_WITHIN_TRANSACTIONS)
\r
288 for (GraphNode<Identifiable> m : ruleModified) {
\r
289 if (m.isDisposed()) {
\r
292 else if (!nodes.contains(m)) {
\r
296 monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");
\r
297 if(monitor.isCanceled()) {
\r
298 throw new CancelException("Cancel requested.");
\r
309 private void applyGenerations(WriteGraph graph, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
311 int size = nodes.size();
\r
313 monitor.subTask("Assigning generation rules ("+ count + "/" + size + ")");
\r
314 // populate generation rules
\r
315 for (GraphNode<Identifiable> n : nodes) {
\r
317 for (Pair<IdentificationRule,Pair<Integer,GenerationRule>> r : generationRules) {
\r
318 if (r.first.matches(graph, n)) {
\r
319 MappingTools.assignGenerationRule(n, r.second.first,r.second.second);
\r
322 monitor.subTask("Assigning generation rules ("+ (++count) + "/" + size + ")");
\r
323 if(monitor.isCanceled()) {
\r
324 throw new CancelException("Cancel requested.");
\r
326 if (COLLECT_WITHIN_TRANSACTIONS)
\r
331 monitor.subTask("Generating objects ("+ count + "/" + size + ")");
\r
333 // apply generation rules.
\r
334 //WriteWrapper g = new WriteWrapper(graph);
\r
336 //Collection<GenerationRule> usedRules = new ArrayList<GenerationRule>();
\r
337 for (int stage = 0; stage <= maxGenPass; stage++) {
\r
339 for (GraphNode<Identifiable> n : nodes) {
\r
341 MapList<Integer,GenerationRule> priRules = n.getHint(MappingHints.KEY_GENERATION_RULES);
\r
342 List<GenerationRule> rules = priRules.getValues(stage);
\r
343 for (GenerationRule r : rules) {
\r
344 r.generate(graph, n);
\r
347 monitor.subTask("Generating objects, stage " + stage + " : ("+ (++count) + "/" + size + ")");
\r
348 if(monitor.isCanceled()) {
\r
349 throw new CancelException("Cancel requested.");
\r
351 if (COLLECT_WITHIN_TRANSACTIONS)
\r
357 private void applyConnections(WriteGraph g, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
358 int size = nodes.size();
\r
361 monitor.subTask("Generating connections ("+ count + "/" + size + ")");
\r
363 for (GraphNode<Identifiable> node : nodes) {
\r
364 applyConnections(g, node);
\r
365 monitor.subTask("Generating connections ("+ (++count) + "/" + size + ")");
\r
366 if(monitor.isCanceled()) {
\r
367 throw new CancelException("Cancel requested.");
\r
369 if (COLLECT_WITHIN_TRANSACTIONS)
\r
376 protected String getName(ReadGraph g, Identifiable res) throws DatabaseException {
\r
377 if (res instanceof ResourceIdentifiable)
\r
378 return NameUtils.getSafeName(g, ((ResourceIdentifiable)res).getResource());
\r
380 return res.toString();
\r
383 public class WriteWrapper extends WriteGraphProxy {
\r
386 private Collection<Resource> createdResources = new ArrayList<Resource>();
\r
388 public WriteWrapper(WriteGraph graph) {
\r
392 public Collection<Resource> getCreatedResources() {
\r
393 return createdResources;
\r
396 public void clearCreated() {
\r
397 createdResources = new ArrayList<Resource>();
\r
401 public Resource newResource() throws ServiceException {
\r
402 Resource res = graph.newResource();
\r
403 createdResources.add(res);
\r
408 public Resource newResource(long clusterId) throws ServiceException {
\r
409 Resource res = graph.newResource(clusterId);
\r
410 createdResources.add(res);
\r
417 private void initializeRules(Session session, VirtualGraph vg, final Resource model ) throws DatabaseException{
\r
418 session.syncRequest(new WriteRequest(vg) {
\r
420 public void perform(WriteGraph g) throws DatabaseException {
\r
421 for (InitializedRule rule : initializedRules)
\r
422 rule.initialize(g, model);
\r
429 private void collect(ReadGraph g) throws DatabaseException {
\r
432 SessionGarbageCollection.gc(g, 0, -1);
\r
437 private void collect2(ReadGraph g) throws DatabaseException {
\r
441 if (collect == OBJECTS_BEFORE_COLLECT) {
\r
442 SessionGarbageCollection.gc(g, 0, -1);
\r
449 private void applyModifications(Session session, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {
\r
453 int passCount = Math.max(globalModificationRules.size(),modificationRules.size());
\r
455 for (int pass = 0; pass <passCount; pass++) {
\r
456 // Apply global modification rules first
\r
457 if (globalModificationRules.size() > pass) {
\r
459 List<ModificationRule> modRules = globalModificationRules.get(pass);
\r
460 int size = modRules.size();
\r
461 monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");
\r
462 for (final ModificationRule r : modRules) {
\r
463 session.syncRequest(new ReadRequest() {
\r
466 public void run(ReadGraph g) throws DatabaseException {
\r
468 Collection<GraphNode<Identifiable>> ruleModified = r.modify(g, nodes);
\r
470 if (ruleModified == null)
\r
472 for (GraphNode<Identifiable> m : ruleModified) {
\r
473 if (m.isDisposed()) {
\r
476 else if (!nodes.contains(m)) {
\r
480 if (COLLECT_WITHIN_TRANSACTIONS)
\r
482 } catch (Exception e) {
\r
483 throw new DatabaseException(e);
\r
488 //SessionGarbageCollection.gc(null, session, true, null);
\r
489 monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");
\r
490 if(monitor.isCanceled()) {
\r
491 throw new CancelException("Cancel requested.");
\r
495 if (modificationRules.size() > pass) {
\r
497 List<Pair<IdentificationRule, ModificationRule>> modRules = modificationRules.get(pass);
\r
498 int size = modRules.size();
\r
499 monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");
\r
501 // Apply per object modification rules
\r
502 for (final Pair<IdentificationRule, ModificationRule> modRule : modRules) {
\r
503 final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();
\r
504 final Collection<GraphNode<Identifiable>> ruleModified = new ArrayList<GraphNode<Identifiable>>();
\r
505 while (iter.hasNext()) {
\r
506 session.syncRequest(new ReadRequest() {
\r
509 public void run(ReadGraph g) throws DatabaseException {
\r
513 //for (GraphNode<Identifiable> n : nodes) {
\r
514 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {
\r
515 GraphNode<Identifiable> n = iter.next();
\r
516 applyModifications(g, n, modRule, ruleModified);
\r
519 if (COLLECT_WITHIN_TRANSACTIONS)
\r
522 } catch (Exception e) {
\r
523 throw new DatabaseException(e);
\r
529 for (GraphNode<Identifiable> m : ruleModified) {
\r
530 if (m.isDisposed()) {
\r
533 else if (!nodes.contains(m)) {
\r
537 ruleModified.clear();
\r
539 //SessionGarbageCollection.gc(null, session, true, null);
\r
540 monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");
\r
541 if(monitor.isCanceled()) {
\r
542 throw new CancelException("Cancel requested.");
\r
550 private void applyModifications2(Session session, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {
\r
551 session.syncRequest(new ReadRequest() {
\r
554 public void run(ReadGraph g) throws DatabaseException {
\r
556 applyModifications(g, nodes, monitor);
\r
557 } catch (Exception e) {
\r
558 throw new DatabaseException(e);
\r
565 private void applyGenerations(Session session, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
567 int size = nodes.size();
\r
569 monitor.subTask("Assigning generation rules ("+ count + "/" + size + ")");
\r
570 // populate generation rules
\r
573 final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();
\r
574 while (iter.hasNext()) {
\r
575 int c = session.syncRequest(new Read<Integer>() {
\r
578 public Integer perform(ReadGraph graph)
\r
579 throws DatabaseException {
\r
581 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {
\r
582 GraphNode<Identifiable> n = iter.next();
\r
583 for (Pair<IdentificationRule,Pair<Integer,GenerationRule>> r : generationRules) {
\r
584 if (r.first.matches(graph, n)) {
\r
585 MapList<Integer,GenerationRule> rules = n.getHint(MappingHints.KEY_GENERATION_RULES);
\r
586 if (rules == null) {
\r
587 rules = new MapList<Integer,GenerationRule>();
\r
589 rules.add(r.second.first,r.second.second);
\r
590 n.setHint(MappingHints.KEY_GENERATION_RULES, rules);
\r
595 if (COLLECT_WITHIN_TRANSACTIONS)
\r
602 monitor.subTask("Assigning generation rules ("+ (count+=c) + "/" + size + ")");
\r
603 if(monitor.isCanceled()) {
\r
604 throw new CancelException("Cancel requested.");
\r
611 monitor.subTask("Generating objects ("+ (count) + "/" + size + ")");
\r
613 // apply generation rules.
\r
616 for (int stage = 0; stage <= maxGenPass; stage++) {
\r
617 final int fStage = stage;
\r
619 final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();
\r
620 while (iter.hasNext()) {
\r
621 int c = session.syncRequest(new WriteResultRequest<Integer>(vg) {
\r
624 public Integer perform(WriteGraph graph) throws DatabaseException {
\r
627 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {
\r
628 GraphNode<Identifiable> n = iter.next();
\r
630 MapList<Integer,GenerationRule> priRules = n.getHint(MappingHints.KEY_GENERATION_RULES);
\r
631 if (priRules == null) {
\r
635 final List<GenerationRule> rules = priRules.getValues(fStage);
\r
637 if (fStage == 0 && rules.size() == 0)
\r
638 System.out.println();
\r
639 for (GenerationRule r : rules) {
\r
640 r.generate(graph, n);
\r
648 if (COLLECT_WITHIN_TRANSACTIONS)
\r
652 } catch (Exception e) {
\r
653 throw new DatabaseException(e);
\r
657 monitor.subTask("Generating objects, stage " + stage + " : ("+ (count+=c) + "/" + size + ")");
\r
658 if(monitor.isCanceled()) {
\r
659 throw new CancelException("Cancel requested.");
\r
667 private void applyGenerations2(Session session, VirtualGraph vg, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {
\r
668 session.syncRequest(new WriteRequest(vg) {
\r
671 public void perform(WriteGraph graph) throws DatabaseException {
\r
673 applyGenerations(graph, nodes, monitor);
\r
674 } catch (Exception e) {
\r
675 throw new DatabaseException(e);
\r
682 private void collect(Session session) {
\r
683 if (COLLECT_BETWEEN_WRITES)
\r
684 SessionGarbageCollection.gc(null, session, true, null);
\r
688 private void sleep() {
\r
689 if (SLEEP_BETWEEN_WRITES) {
\r
691 Thread.sleep(SLEEP_TIME);
\r
692 } catch (InterruptedException e) {
\r
698 private void applyConnections(Session session, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {
\r
699 int size = nodes.size();
\r
702 monitor.subTask("Generating connections ("+ count + "/" + size + ")");
\r
704 final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();
\r
705 while (iter.hasNext()) {
\r
706 int c = session.syncRequest(new WriteResultRequest<Integer>(vg) {
\r
709 public Integer perform(WriteGraph g) throws DatabaseException {
\r
712 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {
\r
713 GraphNode<Identifiable> node = iter.next();
\r
714 applyConnections(g, node);
\r
717 if (COLLECT_WITHIN_TRANSACTIONS)
\r
721 } catch (Exception e) {
\r
722 throw new DatabaseException(e);
\r
727 monitor.subTask("Generating connections ("+ (count+=c) + "/" + size + ")");
\r
728 if(monitor.isCanceled()) {
\r
729 throw new CancelException("Cancel requested.");
\r
735 private void applyConnections2(Session session, VirtualGraph vg, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {
\r
736 session.syncRequest(new WriteRequest(vg) {
\r
739 public void perform(WriteGraph graph) throws DatabaseException {
\r
741 applyConnections(graph, nodes, monitor);
\r
742 } catch (Exception e) {
\r
743 throw new DatabaseException(e);
\r
750 private void applyModifications(ReadGraph g, GraphNode<Identifiable> n, Pair<IdentificationRule, ModificationRule> modRule, Collection<GraphNode<Identifiable>> ruleModified) throws Exception {
\r
751 if (!n.isDisposed() && modRule.first.matches(g, n)) { // we have to check
\r
752 Collection<GraphNode<Identifiable>> perRule = new ArrayList<GraphNode<Identifiable>>();
\r
754 ruleModified.addAll(modRule.second.modify(g, perRule));
\r
758 private void applyConnections(WriteGraph g, GraphNode<Identifiable> node) throws Exception {
\r
759 for (Link<Identifiable> link : node.getLinks()) {
\r
760 if (link.isMain()) {
\r
762 for (Pair<ConnectionIdentificationRule, ConnectionGenerationRule> r : connectionRules) {
\r
763 if (r.first.mathces(g, node, link.to(), link)) {
\r
764 Logger.defaultLogInfo("Connecting " + getName(g, node.getData()) + " to " + getName(g, link.to().getData()) + " " + link.getName() + "/"+link.getInverseName());
\r
765 r.second.generate(g, node, link.to(), link);
\r