]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementsRule.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.objmap2 / src / org / simantics / objmap / graph / rules / MappedElementsRule.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2013 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.objmap.graph.rules;
13
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Objects;
17
18 import org.simantics.db.ReadGraph;
19 import org.simantics.db.WriteGraph;
20 import org.simantics.objmap.backward.IBackwardMapping;
21 import org.simantics.objmap.bidirectional.IBidirectionalMappingRule;
22 import org.simantics.objmap.exceptions.MappingException;
23 import org.simantics.objmap.forward.IForwardMapping;
24 import org.simantics.objmap.graph.rules.domain.IDomainAccessor;
25 import org.simantics.objmap.graph.rules.range.IRangeAccessor;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29
30 /**
31  * A rule that synchronizes collection of elements between
32  * domain and range accessors. Elements are mapped from
33  * between domain and range during the synchronization.
34  * @author Hannu Niemistö
35  */
36 public class MappedElementsRule<Domain, Range> implements IBidirectionalMappingRule<Domain, Range> {
37
38     static final Logger LOGGER = LoggerFactory.getLogger(MappedElementsRule.class);
39
40     IDomainAccessor<Domain,Collection<Domain>> domainAccessor;
41     IRangeAccessor<Range,Collection<Range>> rangeAccessor;
42
43     public MappedElementsRule(IDomainAccessor<Domain,Collection<Domain>> domainAccessor,
44             IRangeAccessor<Range,Collection<Range>> rangeAccessor) {
45         this.domainAccessor = domainAccessor;
46         this.rangeAccessor = rangeAccessor;
47     }
48
49     @Override
50     public boolean updateDomain(WriteGraph g, IBackwardMapping<Domain, Range> map,
51             Domain domainElement, Range rangeElement)
52     throws MappingException {
53         LOGGER.trace("    MappedElementsRule.updateDomain");
54         // Snapshot the accessed range value for concurrency safety.
55         // NOTE: still assumes that the accessed collection is concurrent or
56         // synchronized for toArray to be atomic.
57         Collection<Range> value = rangeAccessor.get(rangeElement);
58         Object[] rangeSnapshot = value.toArray();
59         ArrayList<Domain> mappedValue = new ArrayList<Domain>(rangeSnapshot.length);
60         for (Object obj : rangeSnapshot)
61             mappedValue.add(map.inverseMap(g, (Range)obj));//map.inverseGet((Range)obj));
62         return domainAccessor.set(g, domainElement, mappedValue);
63     }
64
65     @Override
66     public boolean updateRange(ReadGraph g, IForwardMapping<Domain, Range> map,
67             Domain domainElement, Range rangeElement)
68     throws MappingException {
69         LOGGER.trace("    MappedElementsRule.updateRange");
70         ArrayList<Range> mappedValue = getMappedValue(g, map, domainElement);
71         return rangeAccessor.set(rangeElement, mappedValue);
72     }
73     
74     @Override
75     public boolean checkChanges(ReadGraph g, IForwardMapping<Domain, Range> map, Domain domainElement, Range rangeElement) throws MappingException {
76         LOGGER.trace("    MappedElementsRule.updateRange");
77         ArrayList<Range> mappedValue = getMappedValue(g, map, domainElement);
78         return !Objects.equals(mappedValue, rangeAccessor.get(rangeElement));
79     }
80
81         private ArrayList<Range> getMappedValue(ReadGraph g, IForwardMapping<Domain, Range> map, Domain domainElement)
82                         throws MappingException {
83                 Collection<Domain> value = domainAccessor.get(g, domainElement);
84         ArrayList<Range> mappedValue = new ArrayList<Range>(value.size());
85         for(Domain r : value)
86             mappedValue.add(map.map(g, r));//map.get(r));
87                 return mappedValue;
88         }
89     
90     public void createDomain(WriteGraph g, IBackwardMapping<Domain,Range> map, Domain domainElement, Range rangeElement) throws MappingException {
91         updateDomain(g, map, domainElement, rangeElement);
92     };
93     
94     public void createRange(ReadGraph g, IForwardMapping<Domain,Range> map, Domain domainElement, Range rangeElement) throws MappingException {
95         updateRange(g, map, domainElement, rangeElement);
96     };
97 }