]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/range/CollectionAccessor.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.objmap2 / src / org / simantics / objmap / graph / rules / range / CollectionAccessor.java
1 /*******************************************************************************
2  * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
3  * 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.range;
13
14 import java.lang.reflect.InvocationTargetException;
15 import java.lang.reflect.Method;
16 import java.util.ArrayList;
17 import java.util.Collection;
18
19 import org.simantics.objmap.exceptions.MappingException;
20
21
22 /**
23  * Accessor for mapped collections. 
24  * Uses three methods:
25  * - Getter: returns the collection.
26  * - Adder: adds one item into the collection.
27  * - Remover: removes one item from the collection. 
28  * 
29  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
30  *
31  * @param <T>
32  */
33 public class CollectionAccessor<Range,T>  implements IRangeAccessor<Range,Collection<T>> {
34         
35         private Method getter;
36         private Method adder;
37         private Method remover;
38         
39         public CollectionAccessor(Method getter, Method adder, Method remover) {
40                 this.getter = getter;
41                 this.adder = adder;
42                 this.remover = remover;
43         }
44         
45         @SuppressWarnings("unchecked")
46         public java.util.Collection<T> get(Object element) throws MappingException {
47                 try {
48                         return (Collection<T>) getter.invoke(element);
49                 } catch (IllegalArgumentException e) {
50                         throw new MappingException(e);
51                 } catch (IllegalAccessException e) {
52                         throw new MappingException(e);
53                 } catch (InvocationTargetException e) {
54                         throw new MappingException(e.getCause());
55                 }
56         };
57
58         @Override
59         public boolean set(Range element, Collection<T> value)
60                         throws MappingException {
61                 java.util.Collection<T> current = get(element);
62                 Collection<T> adding = new ArrayList<T>();
63                 Collection<T> removing = new ArrayList<T>();
64                 for (T e : current) {
65                         if (!value.contains(e))
66                                 removing.add(e);
67                 }
68                 for (T e : value) {
69                         if (!current.contains(e))
70                                 adding.add(e);
71                 }
72                 
73                 try {
74                         for (T e : removing) {
75                                 remover.invoke(element, e);
76                         }
77                         
78                         for (T e : adding) {
79                                 adder.invoke(element, e);
80                         }
81                 } catch (IllegalArgumentException e) {
82                         throw new MappingException(e);
83                 } catch (IllegalAccessException e) {
84                         throw new MappingException(e);
85                 } catch (InvocationTargetException e) {
86                         throw new MappingException(e.getCause());
87                 }
88                 return removing.size() > 0 || adding.size() > 0;
89                 
90         }
91 }