]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/domain/MappingUtils.java
Support for linked lists in objmap2.
[simantics/platform.git] / bundles / org.simantics.objmap2 / src / org / simantics / objmap / graph / rules / domain / MappingUtils.java
index dbda44e34f837578692e70d2906b4bf304ed86ba..6f7f9260fde774cd50b59be3b95ae4f5a834425b 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
 /*******************************************************************************
- * Copyright (c) 2007, 2013 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2013, 2019 Association for Decentralized Information Management
  * in Industry THTH ry.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * in Industry THTH ry.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -8,17 +8,24 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum oy - linked list utilities
  *******************************************************************************/
 package org.simantics.objmap.graph.rules.domain;
 
 import java.util.Arrays;
 import java.util.Collection;
  *******************************************************************************/
 package org.simantics.objmap.graph.rules.domain;
 
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.simantics.db.Resource;
 import org.simantics.db.WriteGraph;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.simantics.db.Resource;
 import org.simantics.db.WriteGraph;
+import org.simantics.db.common.utils.ListUtils;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
+import org.simantics.db.exception.NoSingleResultException;
+import org.simantics.db.exception.ServiceException;
+import org.simantics.layer0.Layer0;
 
 /**
  * Static utility methods for rule implementations.
 
 /**
  * Static utility methods for rule implementations.
@@ -90,4 +97,75 @@ public class MappingUtils {
                return modified;
        }
 
                return modified;
        }
 
+       public static boolean synchronizeList(WriteGraph g, Resource element, Resource relation, Resource listType, List<Resource> value, boolean deleteExtraObjects) throws DatabaseException {
+               final Layer0 L0 = Layer0.getInstance(g);
+               
+               // Return value
+               boolean modified = false;
+               
+               // Get the list - create a new one, if necessary
+               Resource currentList = g.getPossibleObject(element, relation);
+               if (currentList == null) {
+                       currentList = ListUtils.create(g, listType);
+                       g.claim(element, relation, currentList);
+                       modified = true;
+               }
+
+               // Synchronize elements
+               List<Resource> currentNodes = ListUtils.getListNodes(g, currentList);
+               int i = 0, j = 0;
+               while (i < currentNodes.size()) {
+                       Resource node = currentNodes.get(i);
+                       Resource v = g.getSingleObject(node, L0.List_Element);
+                       if (j < value.size() && v.equals(value.get(j))) {
+                               i++;
+                               j++;
+                       }
+                       else if (value.indexOf(v) > j) {
+                               // Insert new element in the middle
+                               insertElementBefore(g, L0, node, value.get(j));
+                               modified = true;
+                               j++;
+                       }
+                       else {
+                               // Remove deleted element
+                               if (deleteExtraObjects) g.deny(v);
+                               removeNode(g, L0, node);
+                               modified = true;
+                               i++;
+                       }
+               }
+
+               // Add new elements at end
+               while (j < value.size()) {
+                       // Add tailing elements
+                       insertElementBefore(g, L0, currentList, value.get(j));
+                       modified = true;
+                       j++;
+               }
+               
+               return modified;
+       }
+
+       private static Resource insertElementBefore(WriteGraph g, final Layer0 L0, Resource node, final Resource val)
+                       throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
+               Resource prev = g.getSingleObject(node, L0.List_Previous);
+               g.deny(prev, L0.List_Next, L0.List_Previous, node);
+               
+               Resource newNode = g.newResource();
+               g.claim(newNode, L0.InstanceOf, L0.List_Entry);
+               g.claim(prev, L0.List_Next, L0.List_Previous, newNode);
+               g.claim(newNode, L0.List_Next, L0.List_Previous, node);
+               g.claim(newNode, L0.List_Element, val);
+               return newNode;
+       }
+
+       private static void removeNode(WriteGraph g, final Layer0 L0, Resource node)
+                       throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
+               Resource prev = g.getSingleObject(node, L0.List_Previous);
+               Resource next = g.getSingleObject(node, L0.List_Next);
+               g.claim(prev, L0.List_Next, L0.List_Previous, next);
+               g.deny(node);
+       }
+
 }
 }