X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.common%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fcommon%2Futils%2FListUtils.java;h=656dfeb27550b8acfe8e1f1c8801cbebefe6e879;hp=6474bf79cccb4133ada70f5703886113d710d08e;hb=b28a9d30e47693246404bac50c7e031c1146c273;hpb=969bd23cab98a79ca9101af33334000879fb60c5 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 index 6474bf79c..656dfeb27 100644 --- 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 @@ -1,298 +1,343 @@ -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); - } - - -} +package org.simantics.db.common.utils; + +import java.util.ArrayList; +import java.util.Arrays; +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 { + Resource elementPredicate = getElementPredicate(g, 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, elementPredicate, 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 { + Resource elementPredicate = getElementPredicate(g, 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, elementPredicate, item); + before = cur; + } + g.claim(before, L0.List_Next, L0.List_Previous, after); + } + + /** + * Creates a list containing the given {@code elements}. + */ + public static Resource create(WriteGraph g, Iterable elements) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + return ListUtils.create(g,L0.List, L0.List_Element, null, elements); + } + + public static Resource createWithInverses(WriteGraph g, Iterable elements) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + return ListUtils.create(g,L0.ListWithInverses, L0.List_ElementWithInverse, L0.List_ElementWithInverse_Inverse, elements); + } + + /** + * Creates a list of the given list type containing the given {@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; + } + + public static Resource create(WriteOnlyGraph g, Resource type, Resource elementPredicate, Resource elementPredicateInverse, Iterable elements) throws DatabaseException { + Layer0 L0 = g.getService(Layer0.class); + Resource list = g.newResource(); + g.claim(list, L0.InstanceOf, null, type); + if (!elementPredicate.equals(L0.List_Element)) + g.claim(list, L0.List_ElementPredicate, L0.List_ElementPredicate_Inverse, elementPredicate); + createExisting(g, list, elementPredicate, elementPredicateInverse, elements); + return list; + } + + public static Resource create(WriteOnlyGraph g, Resource type, Resource elementPredicate, Resource elementPredicateInverse, Resource... elements) throws DatabaseException { + return create(g, type, elementPredicate, elementPredicateInverse, Arrays.asList(elements)); + } + + /** + * 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 { + createExisting(g, list, false, elements); + } + + public static void createExisting(WriteOnlyGraph g, Resource list, boolean withInverses, Iterable elements) throws DatabaseException { + Layer0 L0 = g.getService(Layer0.class); + Resource elementPredicate = withInverses ? L0.List_ElementWithInverse : L0.List_Element; + Resource elementPredicateInverse = withInverses ? L0.List_ElementWithInverse_Inverse : null; + createExisting(g, list, elementPredicate, elementPredicateInverse, elements); + } + + public static void createExisting(WriteOnlyGraph g, Resource list, Resource elementPredicate, Resource elementPredicateInverse, 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, elementPredicate, elementPredicateInverse, item); + before = cur; + } + g.claim(before, L0.List_Next, L0.List_Previous, list); + } + + public static void createExisting(WriteOnlyGraph g, Resource list, Resource elementPredicate, Resource elementPredicateInverse, Resource... elements) throws DatabaseException { + createExisting(g, list, elementPredicate, elementPredicateInverse, Arrays.asList(elements)); + } + + /** + * 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) { + Resource elementPredicate = getElementPredicate(g, list); + g.deny(node, L0.List_Element); + g.claim(node, elementPredicate, 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, list, 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, list, node, next); + return true; + } + + private static void swap(WriteGraph g, Resource list, 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); + + Resource elementPredicate = getElementPredicate(g, list); + + if(eb != null) + g.claim(a, elementPredicate, eb); + if(ea != null) + g.claim(b, elementPredicate, ea); + } + + public static Resource getElementPredicate(ReadGraph g, Resource list) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource predicate = g.getPossibleObject(list, L0.List_ElementPredicate); + if(predicate != null) return predicate; + return g.isInstanceOf(list, L0.ListWithInverses) ? + L0.List_ElementWithInverse : L0.List_Element; + } + + public static Resource getListElementList(ReadGraph g, Resource element) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + return g.getSingleObject(element, L0.IsOwnedBy); + } + +}