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