X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.common%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fcommon%2Futils%2FListUtils.java;fp=bundles%2Forg.simantics.db.common%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fcommon%2Futils%2FListUtils.java;h=6474bf79cccb4133ada70f5703886113d710d08e;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java new file mode 100644 index 000000000..6474bf79c --- /dev/null +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java @@ -0,0 +1,298 @@ +package org.simantics.db.common.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.WriteOnlyGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; + +public class ListUtils { + + /** + * Inserts {@code elements} between list nodes + * {@code before} and {@code after}. + */ + private static void insertBetween( + WriteGraph g, Layer0 L0, Resource list, + Resource before, Resource after, + Iterable elements) throws DatabaseException { + for(Resource item : elements) { + Resource cur = g.newResource(); + g.claim(cur, L0.InstanceOf, null, L0.List_Entry); + g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list); + g.claim(before, L0.List_Next, L0.List_Previous, cur); + g.claim(cur, L0.List_Element, item); + before = cur; + } + g.claim(before, L0.List_Next, L0.List_Previous, after); + } + + private static void insertBetween( + WriteGraph g, Layer0 L0, Resource list, + Resource before, Resource after, + Resource[] elements) throws DatabaseException { + for(Resource item : elements) { + Resource cur = g.newResource(); + g.claim(cur, L0.InstanceOf, null, L0.List_Entry); + g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list); + g.claim(before, L0.List_Next, L0.List_Previous, cur); + g.claim(cur, L0.List_Element, item); + before = cur; + } + g.claim(before, L0.List_Next, L0.List_Previous, after); + } + + /** + * Creates a list containing the givens {@code elements}. + */ + public static Resource create(WriteGraph g, Iterable elements) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + + Resource list = g.newResource(); + g.claim(list, L0.InstanceOf, L0.List); + + insertBetween(g, L0, list, list, list, elements); + return list; + } + + /** + * Creates a list containing the givens {@code elements}. + */ + public static Resource create(WriteGraph g, Resource type, Iterable elements) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + + Resource list = g.newResource(); + g.claim(list, L0.InstanceOf, null, type); + + insertBetween(g, L0, list, list, list, elements); + return list; + } + + public static Resource create(WriteGraph g, Resource type, Resource ... elements) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + + Resource list = g.newResource(); + g.claim(list, L0.InstanceOf, null, type); + + insertBetween(g, L0, list, list, list, elements); + return list; + } + + /** + * Inserts given {@code elements} into the front of the list. + */ + public static void insertFront(WriteGraph g, Resource list, Iterable elements) throws DatabaseException { + if (!elements.iterator().hasNext()) + return; + Layer0 L0 = Layer0.getInstance(g); + + Resource first = g.getSingleObject(list, L0.List_Next); + g.deny(list, L0.List_Next, L0.List_Previous, first); + insertBetween(g, L0, list, list, first, elements); + } + + public static void createExisting(WriteOnlyGraph g, Resource list, Iterable elements) throws DatabaseException { + + Layer0 L0 = g.getService(Layer0.class); + Resource before = list; + for(Resource item : elements) { + Resource cur = g.newResource(); + g.claim(cur, L0.InstanceOf, null, L0.List_Entry); + g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list); + g.claim(before, L0.List_Next, L0.List_Previous, cur); + g.claim(cur, L0.List_Element, null, item); + before = cur; + } + g.claim(before, L0.List_Next, L0.List_Previous, list); + + } + + /** + * Inserts given {@code elements} into the back of the list. + */ + public static void insertBack(WriteGraph g, Resource list, Iterable elements) throws DatabaseException { + if (!elements.iterator().hasNext()) + return; + Layer0 L0 = Layer0.getInstance(g); + + Resource last = g.getSingleObject(list, L0.List_Previous); + g.deny(last, L0.List_Next, L0.List_Previous, list); + insertBetween(g, L0, list, last, list, elements); + } + + /** + * Replaces a given element in the a given list + * @param g WriteGraph + * @param list List resource + * @param element Element to be replaced + * @param replacement Resource that replaces element + * @return true if successful replacement, false otherwise + * @throws DatabaseException + */ + public static boolean replace(WriteGraph g, Resource list, Resource element, Resource replacement) throws DatabaseException { + if(list == null || element == null || replacement == null) + return false; + + Layer0 L0 = Layer0.getInstance(g); + + Resource node = getNode(g, list, element); + if(node != null) { + g.deny(node, L0.List_Element); + g.claim(node, L0.List_Element, replacement); + return true; + } else { + return false; + } + } + + private static void toList(ReadGraph g, List result, Resource list) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(g); + + Resource cur = g.getSingleObject(list, L0.List_Next); + while(!cur.equals(list)) { + Resource el = g.getPossibleObject(cur, L0.List_Element); + if(el != null) + result.add(el); + cur = g.getSingleObject(cur, L0.List_Next); + } + + } + + /** + * Converts a list in the graph to a Java List. + */ + public static List toList(ReadGraph g, Resource list) throws DatabaseException { + ArrayList result = new ArrayList(); + toList(g, result, list); + return result; + } + + public static List toPossibleList(ReadGraph g, Resource list) throws DatabaseException { + try { + return toList(g, list); + } catch (DatabaseException e) { + return null; + } + } + + /** + * Removes an element from a list. Returns true if actually removed something. + */ + public static boolean removeElement(WriteGraph g, Resource list, Resource element) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource prev = list; + Resource cur = g.getSingleObject(list, L0.List_Next); + while(!cur.equals(list)) { + Resource el = g.getPossibleObject(cur, L0.List_Element); + Resource next = g.getSingleObject(cur, L0.List_Next); + if(element.equals(el)) { + g.deny(cur); + g.claim(prev, L0.List_Next, next); + return true; + } + prev = cur; + cur = next; + } + return false; + } + + /** + * Removes an elements from a list. Returns true if actually removed something. + */ + public static boolean removeElements(WriteGraph g, Resource list, Set elements) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource prev = list; + Resource cur = g.getSingleObject(list, L0.List_Next); + boolean removed = false; + while(!cur.equals(list)) { + Resource el = g.getPossibleObject(cur, L0.List_Element); + Resource next = g.getSingleObject(cur, L0.List_Next); + if(elements.contains(el)) { + g.deny(cur); + g.claim(prev, L0.List_Next, next); + removed = true; + } + else + prev = cur; + cur = next; + } + return removed; + } + + private static void getListNodes(ReadGraph g, List result, Resource list) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(g); + + Resource cur = g.getSingleObject(list, L0.List_Next); + while(!cur.equals(list)) { + result.add(cur); + cur = g.getSingleObject(cur, L0.List_Next); + } + + } + + public static List getListNodes(ReadGraph g, Resource list) throws DatabaseException { + ArrayList result = new ArrayList(); + getListNodes(g, result, list); + return result; + } + + public static Resource getNode(ReadGraph g, Resource list, Resource element) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + + Resource cur = g.getSingleObject(list, L0.List_Next); + while(!cur.equals(list)) { + Resource el = g.getPossibleObject(cur, L0.List_Element); + if(element.equals(el)) + return cur; + cur = g.getSingleObject(cur, L0.List_Next); + } + return null; + } + + public static boolean swapWithPrevious(WriteGraph g, Resource list, Resource element) throws DatabaseException { + Resource node = getNode(g, list, element); + if(node == null) + return false; + Layer0 L0 = Layer0.getInstance(g); + Resource prev = g.getSingleObject(node, L0.List_Previous); + if(list.equals(prev)) + return false; + swap(g, node, prev); + return true; + } + + public static boolean swapWithNext(WriteGraph g, Resource list, Resource element) throws DatabaseException { + Resource node = getNode(g, list, element); + if(node == null) + return false; + Layer0 L0 = Layer0.getInstance(g); + Resource next = g.getSingleObject(node, L0.List_Next); + if(list.equals(next)) + return false; + swap(g, node, next); + return true; + } + + private static void swap(WriteGraph g, Resource a, Resource b) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource ea = g.getPossibleObject(a, L0.List_Element); + Resource eb = g.getPossibleObject(b, L0.List_Element); + + g.deny(a, L0.List_Element); + g.deny(b, L0.List_Element); + + if(eb != null) + g.claim(a, L0.List_Element, eb); + if(ea != null) + g.claim(b, L0.List_Element, ea); + } + + +}