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