]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java
Fixed function name clash in Simantics/DB#createList
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / utils / ListUtils.java
1 package org.simantics.db.common.utils;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Set;
6
7 import org.simantics.db.ReadGraph;
8 import org.simantics.db.Resource;
9 import org.simantics.db.WriteGraph;
10 import org.simantics.db.WriteOnlyGraph;
11 import org.simantics.db.exception.DatabaseException;
12 import org.simantics.layer0.Layer0;
13
14 public class ListUtils {
15
16     /**
17      * Inserts {@code elements} between list nodes 
18      * {@code before} and {@code after}.
19      */
20     private static void insertBetween(
21             WriteGraph g, Layer0 L0, Resource list,
22             Resource before, Resource after, 
23             Iterable<Resource> elements) throws DatabaseException {
24         Resource elementPredicate = getElementPredicate(g, list);
25         for(Resource item : elements) {
26             Resource cur = g.newResource();
27             g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
28             g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
29             g.claim(before, L0.List_Next, L0.List_Previous, cur);
30             g.claim(cur, elementPredicate, item);
31             before = cur;
32         }  
33         g.claim(before, L0.List_Next, L0.List_Previous, after);
34     }
35
36     private static void insertBetween(
37             WriteGraph g, Layer0 L0, Resource list, 
38             Resource before, Resource after, 
39             Resource[] elements) throws DatabaseException {
40         Resource elementPredicate = getElementPredicate(g, list);
41         for(Resource item : elements) {
42             Resource cur = g.newResource();
43             g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
44             g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
45             g.claim(before, L0.List_Next, L0.List_Previous, cur);
46             g.claim(cur, elementPredicate, item);
47             before = cur;
48         }  
49         g.claim(before, L0.List_Next, L0.List_Previous, after);
50     }
51     
52     /**
53      * Creates a list containing the given {@code elements}.
54      */
55     public static Resource create(WriteGraph g, Iterable<Resource> elements) throws DatabaseException {
56         Layer0 L0 = Layer0.getInstance(g);
57         
58         Resource list = g.newResource();
59         g.claim(list, L0.InstanceOf, L0.List);
60         
61         insertBetween(g, L0, list, list, list, elements);
62         return list;
63     }
64
65     /**
66      * Creates a list of the given list type containing the given {@code elements}.
67      */
68     public static Resource create(WriteGraph g, Resource type, Iterable<Resource> elements) throws DatabaseException {
69         Layer0 L0 = Layer0.getInstance(g);
70         
71         Resource list = g.newResource();
72         g.claim(list, L0.InstanceOf, null, type);
73         
74         insertBetween(g, L0, list, list, list, elements);
75         return list;
76     }
77
78     public static Resource create(WriteGraph g, Resource type, Resource ... elements) throws DatabaseException {
79         Layer0 L0 = Layer0.getInstance(g);
80         
81         Resource list = g.newResource();
82         g.claim(list, L0.InstanceOf, null, type);
83         
84         insertBetween(g, L0, list, list, list, elements);
85         return list;
86     }
87     
88     /**
89      * Inserts given {@code elements} into the front of the list.
90      */
91     public static void insertFront(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
92         if (!elements.iterator().hasNext())
93             return;
94         Layer0 L0 = Layer0.getInstance(g);
95         
96         Resource first = g.getSingleObject(list, L0.List_Next);        
97         g.deny(list, L0.List_Next, L0.List_Previous, first);        
98         insertBetween(g, L0, list, list, first, elements);
99     }
100     
101     public static void createExisting(WriteOnlyGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
102         createExisting(g, list, false, elements);
103     }
104
105     public static void createExisting(WriteOnlyGraph g, Resource list, boolean withInverses, Iterable<Resource> elements) throws DatabaseException {
106     
107         Layer0 L0 = g.getService(Layer0.class);
108         Resource before = list;
109         Resource elementPredicate = withInverses ? L0.List_ElementWithInverse : L0.List_Element;
110         for(Resource item : elements) {
111             Resource cur = g.newResource();
112             g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
113             g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
114             g.claim(before, L0.List_Next, L0.List_Previous, cur);
115             g.claim(cur, elementPredicate, null, item);
116             before = cur;
117         }  
118         g.claim(before, L0.List_Next, L0.List_Previous, list);
119         
120     }
121     
122     /**
123      * Inserts given {@code elements} into the back of the list.
124      */
125     public static void insertBack(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
126         if (!elements.iterator().hasNext())
127             return;
128         Layer0 L0 = Layer0.getInstance(g);
129         
130         Resource last = g.getSingleObject(list, L0.List_Previous);        
131         g.deny(last, L0.List_Next, L0.List_Previous, list);        
132         insertBetween(g, L0, list, last, list, elements);
133     }
134     
135     /**
136      * Replaces a given element in the a given list
137      * @param g WriteGraph
138      * @param list List resource
139      * @param element Element to be replaced
140      * @param replacement Resource that replaces element
141      * @return true if successful replacement, false otherwise
142      * @throws DatabaseException
143      */
144     public static boolean replace(WriteGraph g, Resource list, Resource element, Resource replacement) throws DatabaseException {
145         if(list == null || element == null || replacement == null)
146             return false;
147         
148         Layer0 L0 = Layer0.getInstance(g);
149
150         Resource node = getNode(g, list, element);
151         if(node != null) {
152             Resource elementPredicate = getElementPredicate(g, list);
153             g.deny(node, L0.List_Element);
154             g.claim(node, elementPredicate, replacement);
155             return true;
156         } else {
157             return false;
158         }
159     }
160     
161     private static void toList(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
162         
163         Layer0 L0 = Layer0.getInstance(g);
164         
165         Resource cur = g.getSingleObject(list, L0.List_Next);
166         while(!cur.equals(list)) {
167             Resource el = g.getPossibleObject(cur, L0.List_Element);
168             if(el != null)
169                 result.add(el);
170             cur = g.getSingleObject(cur, L0.List_Next);
171         }
172         
173     }
174     
175     /**
176      * Converts a list in the graph to a Java List.
177      */
178     public static List<Resource> toList(ReadGraph g, Resource list) throws DatabaseException {
179         ArrayList<Resource> result = new ArrayList<Resource>();
180         toList(g, result, list);
181         return result;
182     }
183
184     public static List<Resource> toPossibleList(ReadGraph g, Resource list) throws DatabaseException {
185         try {
186                 return toList(g, list);
187         } catch (DatabaseException e) {
188                 return null;
189         }
190     }
191
192     /**
193      * Removes an element from a list. Returns true if actually removed something.
194      */
195     public static boolean removeElement(WriteGraph g, Resource list, Resource element) throws DatabaseException {
196         Layer0 L0 = Layer0.getInstance(g);
197         Resource prev = list;
198         Resource cur = g.getSingleObject(list, L0.List_Next);
199         while(!cur.equals(list)) {
200             Resource el = g.getPossibleObject(cur, L0.List_Element);
201             Resource next = g.getSingleObject(cur, L0.List_Next);
202             if(element.equals(el)) {
203                 g.deny(cur);
204                 g.claim(prev, L0.List_Next, next);
205                 return true;
206             }
207             prev = cur;
208             cur = next;
209         }
210         return false;
211     }
212     
213     /**
214      * Removes an elements from a list. Returns true if actually removed something.
215      */
216     public static boolean removeElements(WriteGraph g, Resource list, Set<Resource> elements) throws DatabaseException {
217         Layer0 L0 = Layer0.getInstance(g);
218         Resource prev = list;
219         Resource cur = g.getSingleObject(list, L0.List_Next);
220         boolean removed = false;
221         while(!cur.equals(list)) {
222             Resource el = g.getPossibleObject(cur, L0.List_Element);
223             Resource next = g.getSingleObject(cur, L0.List_Next);
224             if(elements.contains(el)) {
225                 g.deny(cur);
226                 g.claim(prev, L0.List_Next, next);
227                 removed = true;
228             }
229             else
230                 prev = cur;
231             cur = next;
232         }
233         return removed;
234     }
235     
236     private static void getListNodes(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
237         
238         Layer0 L0 = Layer0.getInstance(g);
239         
240         Resource cur = g.getSingleObject(list, L0.List_Next);
241         while(!cur.equals(list)) {
242             result.add(cur);
243             cur = g.getSingleObject(cur, L0.List_Next);
244         }
245         
246     }
247     
248     public static List<Resource> getListNodes(ReadGraph g, Resource list) throws DatabaseException {
249         ArrayList<Resource> result = new ArrayList<Resource>();
250         getListNodes(g, result, list);
251         return result;
252     }
253     
254     public static Resource getNode(ReadGraph g, Resource list, Resource element) throws DatabaseException {
255         Layer0 L0 = Layer0.getInstance(g);
256         
257         Resource cur = g.getSingleObject(list, L0.List_Next);
258         while(!cur.equals(list)) {
259             Resource el = g.getPossibleObject(cur, L0.List_Element);
260             if(element.equals(el))
261                 return cur;
262             cur = g.getSingleObject(cur, L0.List_Next);
263         }
264         return null;
265     }     
266     
267     public static boolean swapWithPrevious(WriteGraph g, Resource list, Resource element) throws DatabaseException {
268         Resource node = getNode(g, list, element);
269         if(node == null)
270             return false;
271         Layer0 L0 = Layer0.getInstance(g);
272         Resource prev = g.getSingleObject(node, L0.List_Previous);
273         if(list.equals(prev))
274             return false;
275         swap(g, list, node, prev);
276         return true;
277     }
278     
279     public static boolean swapWithNext(WriteGraph g, Resource list, Resource element) throws DatabaseException {
280         Resource node = getNode(g, list, element);
281         if(node == null)
282             return false;
283         Layer0 L0 = Layer0.getInstance(g);
284         Resource next = g.getSingleObject(node, L0.List_Next);
285         if(list.equals(next))
286             return false;
287         swap(g, list, node, next);
288         return true;
289     }
290
291     private static void swap(WriteGraph g, Resource list, Resource a, Resource b) throws DatabaseException {
292         Layer0 L0 = Layer0.getInstance(g);
293         Resource ea = g.getPossibleObject(a, L0.List_Element);
294         Resource eb = g.getPossibleObject(b, L0.List_Element);
295         
296         g.deny(a, L0.List_Element);
297         g.deny(b, L0.List_Element);
298         
299         Resource elementPredicate = getElementPredicate(g, list);
300         
301         if(eb != null)
302             g.claim(a, elementPredicate, eb);
303         if(ea != null)
304             g.claim(b, elementPredicate, ea);
305     }
306
307     public static Resource getElementPredicate(ReadGraph g, Resource list) throws DatabaseException {
308         Layer0 L0 = Layer0.getInstance(g);
309         Resource predicate = g.getPossibleObject(list, L0.List_ElementPredicate);
310         if(predicate != null) return predicate;
311         return g.isInstanceOf(list, L0.ListWithInverses) ?
312                         L0.List_ElementWithInverse : L0.List_Element; 
313     }
314
315     public static Resource getListElementList(ReadGraph g, Resource element) throws DatabaseException {
316         Layer0 L0 = Layer0.getInstance(g);
317         return g.getSingleObject(element, L0.IsOwnedBy);
318     }
319     
320     
321 }