]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementsRule.java
43a8ff49325fc46436954243092c5a22e391998b
[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
17 import org.simantics.db.ReadGraph;
18 import org.simantics.db.WriteGraph;
19 import org.simantics.objmap.backward.IBackwardMapping;
20 import org.simantics.objmap.bidirectional.IBidirectionalMappingRule;
21 import org.simantics.objmap.exceptions.MappingException;
22 import org.simantics.objmap.forward.IForwardMapping;
23 import org.simantics.objmap.graph.rules.domain.IDomainAccessor;
24 import org.simantics.objmap.graph.rules.range.IRangeAccessor;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28
29 /**
30  * A rule that synchronizes collection of elements between
31  * domain and range accessors. Elements are mapped from
32  * between domain and range during the synchronization.
33  * @author Hannu Niemistö
34  */
35 public class MappedElementsRule<Domain, Range> implements IBidirectionalMappingRule<Domain, Range> {
36
37     static final Logger LOGGER = LoggerFactory.getLogger(MappedElementsRule.class);
38
39     IDomainAccessor<Domain,Collection<Domain>> domainAccessor;
40     IRangeAccessor<Range,Collection<Range>> rangeAccessor;
41
42     public MappedElementsRule(IDomainAccessor<Domain,Collection<Domain>> domainAccessor,
43             IRangeAccessor<Range,Collection<Range>> rangeAccessor) {
44         this.domainAccessor = domainAccessor;
45         this.rangeAccessor = rangeAccessor;
46     }
47
48     @Override
49     public boolean updateDomain(WriteGraph g, IBackwardMapping<Domain, Range> map,
50             Domain domainElement, Range rangeElement)
51     throws MappingException {
52         LOGGER.info("    MappedElementsRule.updateDomain");
53         // Snapshot the accessed range value for concurrency safety.
54         // NOTE: still assumes that the accessed collection is concurrent or
55         // synchronized for toArray to be atomic.
56         Collection<Range> value = rangeAccessor.get(rangeElement);
57         Object[] rangeSnapshot = value.toArray();
58         ArrayList<Domain> mappedValue = new ArrayList<Domain>(rangeSnapshot.length);
59         for (Object obj : rangeSnapshot)
60             mappedValue.add(map.inverseMap(g, (Range)obj));//map.inverseGet((Range)obj));
61         return domainAccessor.set(g, domainElement, mappedValue);
62     }
63
64     @Override
65     public boolean updateRange(ReadGraph g, IForwardMapping<Domain, Range> map,
66             Domain domainElement, Range rangeElement)
67     throws MappingException {
68         LOGGER.info("    MappedElementsRule.updateRange");
69         Collection<Domain> value = domainAccessor.get(g, domainElement);
70         ArrayList<Range> mappedValue = new ArrayList<Range>(value.size());
71         for(Domain r : value)
72             mappedValue.add(map.map(g, r));//map.get(r));
73         return rangeAccessor.set(rangeElement, mappedValue);
74     }
75     
76     public void createDomain(WriteGraph g, IBackwardMapping<Domain,Range> map, Domain domainElement, Range rangeElement) throws MappingException {
77         updateDomain(g, map, domainElement, rangeElement);
78     };
79     
80     public void createRange(ReadGraph g, IForwardMapping<Domain,Range> map, Domain domainElement, Range rangeElement) throws MappingException {
81         updateRange(g, map, domainElement, rangeElement);
82     };
83 }