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);
59 Resource list = g.newResource();
60 g.claim(list, L0.InstanceOf, L0.List);
62 insertBetween(g, L0, list, list, list, 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 createExisting(g, list, elementPredicate, elementPredicateInverse, elements);
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));
102 * Inserts given {@code elements} into the front of the list.
104 public static void insertFront(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
105 if (!elements.iterator().hasNext())
107 Layer0 L0 = Layer0.getInstance(g);
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);
114 public static void createExisting(WriteOnlyGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
115 createExisting(g, list, false, elements);
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);
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);
136 g.claim(before, L0.List_Next, L0.List_Previous, list);
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));
144 * Inserts given {@code elements} into the back of the list.
146 public static void insertBack(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
147 if (!elements.iterator().hasNext())
149 Layer0 L0 = Layer0.getInstance(g);
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);
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
165 public static boolean replace(WriteGraph g, Resource list, Resource element, Resource replacement) throws DatabaseException {
166 if(list == null || element == null || replacement == null)
169 Layer0 L0 = Layer0.getInstance(g);
171 Resource node = getNode(g, list, element);
173 Resource elementPredicate = getElementPredicate(g, list);
174 g.deny(node, L0.List_Element);
175 g.claim(node, elementPredicate, replacement);
182 private static void toList(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
184 Layer0 L0 = Layer0.getInstance(g);
186 Resource cur = g.getSingleObject(list, L0.List_Next);
187 while(!cur.equals(list)) {
188 Resource el = g.getPossibleObject(cur, L0.List_Element);
191 cur = g.getSingleObject(cur, L0.List_Next);
197 * Converts a list in the graph to a Java List.
199 public static List<Resource> toList(ReadGraph g, Resource list) throws DatabaseException {
200 ArrayList<Resource> result = new ArrayList<Resource>();
201 toList(g, result, list);
205 public static List<Resource> toPossibleList(ReadGraph g, Resource list) throws DatabaseException {
207 return toList(g, list);
208 } catch (DatabaseException e) {
214 * Removes an element from a list. Returns true if actually removed something.
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)) {
225 g.claim(prev, L0.List_Next, next);
235 * Removes an elements from a list. Returns true if actually removed something.
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)) {
247 g.claim(prev, L0.List_Next, next);
257 private static void getListNodes(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
259 Layer0 L0 = Layer0.getInstance(g);
261 Resource cur = g.getSingleObject(list, L0.List_Next);
262 while(!cur.equals(list)) {
264 cur = g.getSingleObject(cur, L0.List_Next);
269 public static List<Resource> getListNodes(ReadGraph g, Resource list) throws DatabaseException {
270 ArrayList<Resource> result = new ArrayList<Resource>();
271 getListNodes(g, result, list);
275 public static Resource getNode(ReadGraph g, Resource list, Resource element) throws DatabaseException {
276 Layer0 L0 = Layer0.getInstance(g);
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))
283 cur = g.getSingleObject(cur, L0.List_Next);
288 public static boolean swapWithPrevious(WriteGraph g, Resource list, Resource element) throws DatabaseException {
289 Resource node = getNode(g, list, element);
292 Layer0 L0 = Layer0.getInstance(g);
293 Resource prev = g.getSingleObject(node, L0.List_Previous);
294 if(list.equals(prev))
296 swap(g, list, node, prev);
300 public static boolean swapWithNext(WriteGraph g, Resource list, Resource element) throws DatabaseException {
301 Resource node = getNode(g, list, element);
304 Layer0 L0 = Layer0.getInstance(g);
305 Resource next = g.getSingleObject(node, L0.List_Next);
306 if(list.equals(next))
308 swap(g, list, node, next);
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);
317 g.deny(a, L0.List_Element);
318 g.deny(b, L0.List_Element);
320 Resource elementPredicate = getElementPredicate(g, list);
323 g.claim(a, elementPredicate, eb);
325 g.claim(b, elementPredicate, ea);
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;
336 public static Resource getListElementList(ReadGraph g, Resource element) throws DatabaseException {
337 Layer0 L0 = Layer0.getInstance(g);
338 return g.getSingleObject(element, L0.IsOwnedBy);