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_ElementWithInverse, L0.List_ElementWithInverse_Inverse, elements);
62 * Creates a list of the given list type containing the given {@code elements}.
64 public static Resource create(WriteGraph g, Resource type, Iterable<Resource> elements) throws DatabaseException {
65 Layer0 L0 = Layer0.getInstance(g);
67 Resource list = g.newResource();
68 g.claim(list, L0.InstanceOf, null, type);
70 insertBetween(g, L0, list, list, list, elements);
74 public static Resource create(WriteGraph g, Resource type, Resource ... elements) throws DatabaseException {
75 Layer0 L0 = Layer0.getInstance(g);
77 Resource list = g.newResource();
78 g.claim(list, L0.InstanceOf, null, type);
80 insertBetween(g, L0, list, list, list, elements);
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);
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));
97 * Inserts given {@code elements} into the front of the list.
99 public static void insertFront(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
100 if (!elements.iterator().hasNext())
102 Layer0 L0 = Layer0.getInstance(g);
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);
109 public static void createExisting(WriteOnlyGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
110 createExisting(g, list, false, elements);
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);
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);
131 g.claim(before, L0.List_Next, L0.List_Previous, list);
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));
139 * Inserts given {@code elements} into the back of the list.
141 public static void insertBack(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
142 if (!elements.iterator().hasNext())
144 Layer0 L0 = Layer0.getInstance(g);
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);
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
160 public static boolean replace(WriteGraph g, Resource list, Resource element, Resource replacement) throws DatabaseException {
161 if(list == null || element == null || replacement == null)
164 Layer0 L0 = Layer0.getInstance(g);
166 Resource node = getNode(g, list, element);
168 Resource elementPredicate = getElementPredicate(g, list);
169 g.deny(node, L0.List_Element);
170 g.claim(node, elementPredicate, replacement);
177 private static void toList(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
179 Layer0 L0 = Layer0.getInstance(g);
181 Resource cur = g.getSingleObject(list, L0.List_Next);
182 while(!cur.equals(list)) {
183 Resource el = g.getPossibleObject(cur, L0.List_Element);
186 cur = g.getSingleObject(cur, L0.List_Next);
192 * Converts a list in the graph to a Java List.
194 public static List<Resource> toList(ReadGraph g, Resource list) throws DatabaseException {
195 ArrayList<Resource> result = new ArrayList<Resource>();
196 toList(g, result, list);
200 public static List<Resource> toPossibleList(ReadGraph g, Resource list) throws DatabaseException {
202 return toList(g, list);
203 } catch (DatabaseException e) {
209 * Removes an element from a list. Returns true if actually removed something.
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)) {
220 g.claim(prev, L0.List_Next, next);
230 * Removes an elements from a list. Returns true if actually removed something.
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)) {
242 g.claim(prev, L0.List_Next, next);
252 private static void getListNodes(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
254 Layer0 L0 = Layer0.getInstance(g);
256 Resource cur = g.getSingleObject(list, L0.List_Next);
257 while(!cur.equals(list)) {
259 cur = g.getSingleObject(cur, L0.List_Next);
264 public static List<Resource> getListNodes(ReadGraph g, Resource list) throws DatabaseException {
265 ArrayList<Resource> result = new ArrayList<Resource>();
266 getListNodes(g, result, list);
270 public static Resource getNode(ReadGraph g, Resource list, Resource element) throws DatabaseException {
271 Layer0 L0 = Layer0.getInstance(g);
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))
278 cur = g.getSingleObject(cur, L0.List_Next);
283 public static boolean swapWithPrevious(WriteGraph g, Resource list, Resource element) throws DatabaseException {
284 Resource node = getNode(g, list, element);
287 Layer0 L0 = Layer0.getInstance(g);
288 Resource prev = g.getSingleObject(node, L0.List_Previous);
289 if(list.equals(prev))
291 swap(g, list, node, prev);
295 public static boolean swapWithNext(WriteGraph g, Resource list, Resource element) throws DatabaseException {
296 Resource node = getNode(g, list, element);
299 Layer0 L0 = Layer0.getInstance(g);
300 Resource next = g.getSingleObject(node, L0.List_Next);
301 if(list.equals(next))
303 swap(g, list, node, next);
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);
312 g.deny(a, L0.List_Element);
313 g.deny(b, L0.List_Element);
315 Resource elementPredicate = getElementPredicate(g, list);
318 g.claim(a, elementPredicate, eb);
320 g.claim(b, elementPredicate, ea);
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;
331 public static Resource getListElementList(ReadGraph g, Resource element) throws DatabaseException {
332 Layer0 L0 = Layer0.getInstance(g);
333 return g.getSingleObject(element, L0.IsOwnedBy);