1 package org.simantics.db.common.utils;
3 import java.util.ArrayList;
4 import java.util.Arrays;
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;
15 public class ListUtils {
18 * Inserts {@code elements} between list nodes
19 * {@code before} and {@code after}.
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);
34 g.claim(before, L0.List_Next, L0.List_Previous, after);
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);
50 g.claim(before, L0.List_Next, L0.List_Previous, after);
54 * Creates a list containing the given {@code elements}.
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_Element, null, elements);
61 public static Resource createWithInverses(WriteGraph g, Iterable<Resource> elements) throws DatabaseException {
62 Layer0 L0 = Layer0.getInstance(g);
63 return ListUtils.create(g,L0.ListWithInverses, L0.List_ElementWithInverse, L0.List_ElementWithInverse_Inverse, elements);
67 * Creates a list of the given list type containing the given {@code elements}.
69 public static Resource create(WriteGraph g, Resource type, Iterable<Resource> elements) throws DatabaseException {
70 Layer0 L0 = Layer0.getInstance(g);
72 Resource list = g.newResource();
73 g.claim(list, L0.InstanceOf, null, type);
75 insertBetween(g, L0, list, list, list, elements);
79 public static Resource create(WriteGraph g, Resource type, Resource ... elements) throws DatabaseException {
80 Layer0 L0 = Layer0.getInstance(g);
82 Resource list = g.newResource();
83 g.claim(list, L0.InstanceOf, null, type);
85 insertBetween(g, L0, list, list, list, elements);
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 if (!elementPredicate.equals(L0.List_Element))
94 g.claim(list, L0.List_ElementPredicate, L0.List_ElementPredicate_Inverse, elementPredicate);
95 createExisting(g, list, elementPredicate, elementPredicateInverse, elements);
99 public static Resource create(WriteOnlyGraph g, Resource type, Resource elementPredicate, Resource elementPredicateInverse, Resource... elements) throws DatabaseException {
100 return create(g, type, elementPredicate, elementPredicateInverse, Arrays.asList(elements));
104 * Inserts given {@code elements} into the front of the list.
106 public static void insertFront(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
107 if (!elements.iterator().hasNext())
109 Layer0 L0 = Layer0.getInstance(g);
111 Resource first = g.getSingleObject(list, L0.List_Next);
112 g.deny(list, L0.List_Next, L0.List_Previous, first);
113 insertBetween(g, L0, list, list, first, elements);
116 public static void createExisting(WriteOnlyGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
117 createExisting(g, list, false, elements);
120 public static void createExisting(WriteOnlyGraph g, Resource list, boolean withInverses, Iterable<Resource> elements) throws DatabaseException {
121 Layer0 L0 = g.getService(Layer0.class);
122 Resource elementPredicate = withInverses ? L0.List_ElementWithInverse : L0.List_Element;
123 Resource elementPredicateInverse = withInverses ? L0.List_ElementWithInverse_Inverse : null;
124 createExisting(g, list, elementPredicate, elementPredicateInverse, elements);
127 public static void createExisting(WriteOnlyGraph g, Resource list, Resource elementPredicate, Resource elementPredicateInverse, Iterable<Resource> elements) throws DatabaseException {
128 Layer0 L0 = g.getService(Layer0.class);
129 Resource before = list;
130 for(Resource item : elements) {
131 Resource cur = g.newResource();
132 g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
133 g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
134 g.claim(before, L0.List_Next, L0.List_Previous, cur);
135 g.claim(cur, elementPredicate, elementPredicateInverse, item);
138 g.claim(before, L0.List_Next, L0.List_Previous, list);
141 public static void createExisting(WriteOnlyGraph g, Resource list, Resource elementPredicate, Resource elementPredicateInverse, Resource... elements) throws DatabaseException {
142 createExisting(g, list, elementPredicate, elementPredicateInverse, Arrays.asList(elements));
146 * Inserts given {@code elements} into the back of the list.
148 public static void insertBack(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
149 if (!elements.iterator().hasNext())
151 Layer0 L0 = Layer0.getInstance(g);
153 Resource last = g.getSingleObject(list, L0.List_Previous);
154 g.deny(last, L0.List_Next, L0.List_Previous, list);
155 insertBetween(g, L0, list, last, list, elements);
159 * Replaces a given element in the a given list
160 * @param g WriteGraph
161 * @param list List resource
162 * @param element Element to be replaced
163 * @param replacement Resource that replaces element
164 * @return true if successful replacement, false otherwise
165 * @throws DatabaseException
167 public static boolean replace(WriteGraph g, Resource list, Resource element, Resource replacement) throws DatabaseException {
168 if(list == null || element == null || replacement == null)
171 Layer0 L0 = Layer0.getInstance(g);
173 Resource node = getNode(g, list, element);
175 Resource elementPredicate = getElementPredicate(g, list);
176 g.deny(node, L0.List_Element);
177 g.claim(node, elementPredicate, replacement);
184 private static void toList(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
186 Layer0 L0 = Layer0.getInstance(g);
188 Resource cur = g.getSingleObject(list, L0.List_Next);
189 while(!cur.equals(list)) {
190 Resource el = g.getPossibleObject(cur, L0.List_Element);
193 cur = g.getSingleObject(cur, L0.List_Next);
199 * Converts a list in the graph to a Java List.
201 public static List<Resource> toList(ReadGraph g, Resource list) throws DatabaseException {
202 ArrayList<Resource> result = new ArrayList<Resource>();
203 toList(g, result, list);
207 public static List<Resource> toPossibleList(ReadGraph g, Resource list) throws DatabaseException {
209 return toList(g, list);
210 } catch (DatabaseException e) {
216 * Removes an element from a list. Returns true if actually removed something.
218 public static boolean removeElement(WriteGraph g, Resource list, Resource element) throws DatabaseException {
219 Layer0 L0 = Layer0.getInstance(g);
220 Resource prev = list;
221 Resource cur = g.getSingleObject(list, L0.List_Next);
222 while(!cur.equals(list)) {
223 Resource el = g.getPossibleObject(cur, L0.List_Element);
224 Resource next = g.getSingleObject(cur, L0.List_Next);
225 if(element.equals(el)) {
227 g.claim(prev, L0.List_Next, next);
237 * Removes an elements from a list. Returns true if actually removed something.
239 public static boolean removeElements(WriteGraph g, Resource list, Set<Resource> elements) throws DatabaseException {
240 Layer0 L0 = Layer0.getInstance(g);
241 Resource prev = list;
242 Resource cur = g.getSingleObject(list, L0.List_Next);
243 boolean removed = false;
244 while(!cur.equals(list)) {
245 Resource el = g.getPossibleObject(cur, L0.List_Element);
246 Resource next = g.getSingleObject(cur, L0.List_Next);
247 if(elements.contains(el)) {
249 g.claim(prev, L0.List_Next, next);
259 private static void getListNodes(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
261 Layer0 L0 = Layer0.getInstance(g);
263 Resource cur = g.getSingleObject(list, L0.List_Next);
264 while(!cur.equals(list)) {
266 cur = g.getSingleObject(cur, L0.List_Next);
271 public static List<Resource> getListNodes(ReadGraph g, Resource list) throws DatabaseException {
272 ArrayList<Resource> result = new ArrayList<Resource>();
273 getListNodes(g, result, list);
277 public static Resource getNode(ReadGraph g, Resource list, Resource element) throws DatabaseException {
278 Layer0 L0 = Layer0.getInstance(g);
280 Resource cur = g.getSingleObject(list, L0.List_Next);
281 while(!cur.equals(list)) {
282 Resource el = g.getPossibleObject(cur, L0.List_Element);
283 if(element.equals(el))
285 cur = g.getSingleObject(cur, L0.List_Next);
290 public static boolean swapWithPrevious(WriteGraph g, Resource list, Resource element) throws DatabaseException {
291 Resource node = getNode(g, list, element);
294 Layer0 L0 = Layer0.getInstance(g);
295 Resource prev = g.getSingleObject(node, L0.List_Previous);
296 if(list.equals(prev))
298 swap(g, list, node, prev);
302 public static boolean swapWithNext(WriteGraph g, Resource list, Resource element) throws DatabaseException {
303 Resource node = getNode(g, list, element);
306 Layer0 L0 = Layer0.getInstance(g);
307 Resource next = g.getSingleObject(node, L0.List_Next);
308 if(list.equals(next))
310 swap(g, list, node, next);
314 private static void swap(WriteGraph g, Resource list, Resource a, Resource b) throws DatabaseException {
315 Layer0 L0 = Layer0.getInstance(g);
316 Resource ea = g.getPossibleObject(a, L0.List_Element);
317 Resource eb = g.getPossibleObject(b, L0.List_Element);
319 g.deny(a, L0.List_Element);
320 g.deny(b, L0.List_Element);
322 Resource elementPredicate = getElementPredicate(g, list);
325 g.claim(a, elementPredicate, eb);
327 g.claim(b, elementPredicate, ea);
330 public static Resource getElementPredicate(ReadGraph g, Resource list) throws DatabaseException {
331 Layer0 L0 = Layer0.getInstance(g);
332 Resource predicate = g.getPossibleObject(list, L0.List_ElementPredicate);
333 if(predicate != null) return predicate;
334 return g.isInstanceOf(list, L0.ListWithInverses) ?
335 L0.List_ElementWithInverse : L0.List_Element;
338 public static Resource getListElementList(ReadGraph g, Resource element) throws DatabaseException {
339 Layer0 L0 = Layer0.getInstance(g);
340 return g.getSingleObject(element, L0.IsOwnedBy);