1 package org.simantics.db.common.utils;
3 import java.util.ArrayList;
7 import org.simantics.db.ReadGraph;
8 import org.simantics.db.Resource;
9 import org.simantics.db.WriteGraph;
10 import org.simantics.db.WriteOnlyGraph;
11 import org.simantics.db.exception.DatabaseException;
12 import org.simantics.layer0.Layer0;
14 public class ListUtils {
17 * Inserts {@code elements} between list nodes
18 * {@code before} and {@code after}.
20 private static void insertBetween(
21 WriteGraph g, Layer0 L0, Resource list,
22 Resource before, Resource after,
23 Iterable<Resource> elements) throws DatabaseException {
24 Resource elementPredicate = getElementPredicate(g, list);
25 for(Resource item : elements) {
26 Resource cur = g.newResource();
27 g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
28 g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
29 g.claim(before, L0.List_Next, L0.List_Previous, cur);
30 g.claim(cur, elementPredicate, item);
33 g.claim(before, L0.List_Next, L0.List_Previous, after);
36 private static void insertBetween(
37 WriteGraph g, Layer0 L0, Resource list,
38 Resource before, Resource after,
39 Resource[] elements) throws DatabaseException {
40 Resource elementPredicate = getElementPredicate(g, list);
41 for(Resource item : elements) {
42 Resource cur = g.newResource();
43 g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
44 g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
45 g.claim(before, L0.List_Next, L0.List_Previous, cur);
46 g.claim(cur, elementPredicate, item);
49 g.claim(before, L0.List_Next, L0.List_Previous, after);
53 * Creates a list containing the given {@code elements}.
55 public static Resource create(WriteGraph g, Iterable<Resource> elements) throws DatabaseException {
56 Layer0 L0 = Layer0.getInstance(g);
58 Resource list = g.newResource();
59 g.claim(list, L0.InstanceOf, L0.List);
61 insertBetween(g, L0, list, list, list, elements);
66 * Creates a list of the given list type containing the given {@code elements}.
68 public static Resource create(WriteGraph g, Resource type, Iterable<Resource> elements) throws DatabaseException {
69 Layer0 L0 = Layer0.getInstance(g);
71 Resource list = g.newResource();
72 g.claim(list, L0.InstanceOf, null, type);
74 insertBetween(g, L0, list, list, list, elements);
78 public static Resource create(WriteGraph g, Resource type, Resource ... elements) throws DatabaseException {
79 Layer0 L0 = Layer0.getInstance(g);
81 Resource list = g.newResource();
82 g.claim(list, L0.InstanceOf, null, type);
84 insertBetween(g, L0, list, list, list, elements);
89 * Inserts given {@code elements} into the front of the list.
91 public static void insertFront(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
92 if (!elements.iterator().hasNext())
94 Layer0 L0 = Layer0.getInstance(g);
96 Resource first = g.getSingleObject(list, L0.List_Next);
97 g.deny(list, L0.List_Next, L0.List_Previous, first);
98 insertBetween(g, L0, list, list, first, elements);
101 public static void createExisting(WriteOnlyGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
102 createExisting(g, list, false, elements);
105 public static void createExisting(WriteOnlyGraph g, Resource list, boolean withInverses, Iterable<Resource> elements) throws DatabaseException {
107 Layer0 L0 = g.getService(Layer0.class);
108 Resource before = list;
109 Resource elementPredicate = withInverses ? L0.List_ElementWithInverse : L0.List_Element;
110 for(Resource item : elements) {
111 Resource cur = g.newResource();
112 g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
113 g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
114 g.claim(before, L0.List_Next, L0.List_Previous, cur);
115 g.claim(cur, elementPredicate, null, item);
118 g.claim(before, L0.List_Next, L0.List_Previous, list);
123 * Inserts given {@code elements} into the back of the list.
125 public static void insertBack(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
126 if (!elements.iterator().hasNext())
128 Layer0 L0 = Layer0.getInstance(g);
130 Resource last = g.getSingleObject(list, L0.List_Previous);
131 g.deny(last, L0.List_Next, L0.List_Previous, list);
132 insertBetween(g, L0, list, last, list, elements);
136 * Replaces a given element in the a given list
137 * @param g WriteGraph
138 * @param list List resource
139 * @param element Element to be replaced
140 * @param replacement Resource that replaces element
141 * @return true if successful replacement, false otherwise
142 * @throws DatabaseException
144 public static boolean replace(WriteGraph g, Resource list, Resource element, Resource replacement) throws DatabaseException {
145 if(list == null || element == null || replacement == null)
148 Layer0 L0 = Layer0.getInstance(g);
150 Resource node = getNode(g, list, element);
152 Resource elementPredicate = getElementPredicate(g, list);
153 g.deny(node, L0.List_Element);
154 g.claim(node, elementPredicate, replacement);
161 private static void toList(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
163 Layer0 L0 = Layer0.getInstance(g);
165 Resource cur = g.getSingleObject(list, L0.List_Next);
166 while(!cur.equals(list)) {
167 Resource el = g.getPossibleObject(cur, L0.List_Element);
170 cur = g.getSingleObject(cur, L0.List_Next);
176 * Converts a list in the graph to a Java List.
178 public static List<Resource> toList(ReadGraph g, Resource list) throws DatabaseException {
179 ArrayList<Resource> result = new ArrayList<Resource>();
180 toList(g, result, list);
184 public static List<Resource> toPossibleList(ReadGraph g, Resource list) throws DatabaseException {
186 return toList(g, list);
187 } catch (DatabaseException e) {
193 * Removes an element from a list. Returns true if actually removed something.
195 public static boolean removeElement(WriteGraph g, Resource list, Resource element) throws DatabaseException {
196 Layer0 L0 = Layer0.getInstance(g);
197 Resource prev = list;
198 Resource cur = g.getSingleObject(list, L0.List_Next);
199 while(!cur.equals(list)) {
200 Resource el = g.getPossibleObject(cur, L0.List_Element);
201 Resource next = g.getSingleObject(cur, L0.List_Next);
202 if(element.equals(el)) {
204 g.claim(prev, L0.List_Next, next);
214 * Removes an elements from a list. Returns true if actually removed something.
216 public static boolean removeElements(WriteGraph g, Resource list, Set<Resource> elements) throws DatabaseException {
217 Layer0 L0 = Layer0.getInstance(g);
218 Resource prev = list;
219 Resource cur = g.getSingleObject(list, L0.List_Next);
220 boolean removed = false;
221 while(!cur.equals(list)) {
222 Resource el = g.getPossibleObject(cur, L0.List_Element);
223 Resource next = g.getSingleObject(cur, L0.List_Next);
224 if(elements.contains(el)) {
226 g.claim(prev, L0.List_Next, next);
236 private static void getListNodes(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
238 Layer0 L0 = Layer0.getInstance(g);
240 Resource cur = g.getSingleObject(list, L0.List_Next);
241 while(!cur.equals(list)) {
243 cur = g.getSingleObject(cur, L0.List_Next);
248 public static List<Resource> getListNodes(ReadGraph g, Resource list) throws DatabaseException {
249 ArrayList<Resource> result = new ArrayList<Resource>();
250 getListNodes(g, result, list);
254 public static Resource getNode(ReadGraph g, Resource list, Resource element) throws DatabaseException {
255 Layer0 L0 = Layer0.getInstance(g);
257 Resource cur = g.getSingleObject(list, L0.List_Next);
258 while(!cur.equals(list)) {
259 Resource el = g.getPossibleObject(cur, L0.List_Element);
260 if(element.equals(el))
262 cur = g.getSingleObject(cur, L0.List_Next);
267 public static boolean swapWithPrevious(WriteGraph g, Resource list, Resource element) throws DatabaseException {
268 Resource node = getNode(g, list, element);
271 Layer0 L0 = Layer0.getInstance(g);
272 Resource prev = g.getSingleObject(node, L0.List_Previous);
273 if(list.equals(prev))
275 swap(g, list, node, prev);
279 public static boolean swapWithNext(WriteGraph g, Resource list, Resource element) throws DatabaseException {
280 Resource node = getNode(g, list, element);
283 Layer0 L0 = Layer0.getInstance(g);
284 Resource next = g.getSingleObject(node, L0.List_Next);
285 if(list.equals(next))
287 swap(g, list, node, next);
291 private static void swap(WriteGraph g, Resource list, Resource a, Resource b) throws DatabaseException {
292 Layer0 L0 = Layer0.getInstance(g);
293 Resource ea = g.getPossibleObject(a, L0.List_Element);
294 Resource eb = g.getPossibleObject(b, L0.List_Element);
296 g.deny(a, L0.List_Element);
297 g.deny(b, L0.List_Element);
299 Resource elementPredicate = getElementPredicate(g, list);
302 g.claim(a, elementPredicate, eb);
304 g.claim(b, elementPredicate, ea);
307 public static Resource getElementPredicate(ReadGraph g, Resource list) throws DatabaseException {
308 Layer0 L0 = Layer0.getInstance(g);
309 Resource predicate = g.getPossibleObject(list, L0.List_ElementPredicate);
310 if(predicate != null) return predicate;
311 return g.isInstanceOf(list, L0.ListWithInverses) ?
312 L0.List_ElementWithInverse : L0.List_Element;
315 public static Resource getListElementList(ReadGraph g, Resource element) throws DatabaseException {
316 Layer0 L0 = Layer0.getInstance(g);
317 return g.getSingleObject(element, L0.IsOwnedBy);