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