1 /*******************************************************************************
2 * Copyright (c) 2007, 2013, 2019 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 * Semantum oy - linked list utilities
12 *******************************************************************************/
13 package org.simantics.objmap.graph.rules.domain;
15 import java.util.Arrays;
16 import java.util.Collection;
17 import java.util.List;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21 import org.simantics.db.Resource;
22 import org.simantics.db.WriteGraph;
23 import org.simantics.db.common.utils.ListUtils;
24 import org.simantics.db.exception.DatabaseException;
25 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
26 import org.simantics.db.exception.NoSingleResultException;
27 import org.simantics.db.exception.ServiceException;
28 import org.simantics.layer0.Layer0;
31 * Static utility methods for rule implementations.
32 * @author Hannu Niemistö
34 public class MappingUtils {
36 static final Logger LOGGER = LoggerFactory.getLogger(MappingUtils.class);
39 * Adds and removes statements to/from the database so that <code>objects</code>
40 * will be exactly the objects connected to <code>subject</code> by <code>predicate</code>.
41 * Returns true if the method made modifications to the database.
43 public static boolean synchronizeStatements(WriteGraph g, Resource subject, Resource predicate, Resource[] objects,
44 boolean deleteExtraObjects)
45 throws DatabaseException {
46 Collection<Resource> currentObjects0 = g.getObjects(subject, predicate);
47 Resource[] currentObjects = currentObjects0.toArray(new Resource[currentObjects0.size()]);
50 Arrays.sort(currentObjects);
52 boolean modified = false;
54 if(currentObjects.length > 0 && objects.length > 0)
56 int cmp = currentObjects[i].compareTo(objects[j]);
58 LOGGER.trace(" remove statement");
59 if(deleteExtraObjects)
60 g.deny(currentObjects[i]);
62 g.denyStatement(subject, predicate, currentObjects[i]);
65 if(i >= currentObjects.length)
69 LOGGER.trace(" add statement");
70 g.claim(subject, predicate, objects[j]);
73 if(j >= objects.length)
78 if(i >= currentObjects.length)
80 if(j >= objects.length)
84 while(i < currentObjects.length) {
85 if(deleteExtraObjects)
86 g.deny(currentObjects[i]);
88 g.denyStatement(subject, predicate, currentObjects[i]);
92 while(j < objects.length) {
93 g.claim(subject, predicate, objects[j]);
100 public static boolean synchronizeList(WriteGraph g, Resource element, Resource relation, Resource listType, List<Resource> value, boolean deleteExtraObjects) throws DatabaseException {
101 final Layer0 L0 = Layer0.getInstance(g);
104 boolean modified = false;
106 // Get the list - create a new one, if necessary
107 Resource currentList = g.getPossibleObject(element, relation);
108 if (currentList == null) {
109 currentList = ListUtils.create(g, listType);
110 g.claim(element, relation, currentList);
114 // Synchronize elements
115 List<Resource> currentNodes = ListUtils.getListNodes(g, currentList);
117 while (i < currentNodes.size()) {
118 Resource node = currentNodes.get(i);
119 Resource v = g.getSingleObject(node, L0.List_Element);
120 if (j < value.size() && v.equals(value.get(j))) {
124 else if (value.indexOf(v) > j) {
125 // Insert new element in the middle
126 insertElementBefore(g, L0, node, value.get(j));
131 // Remove deleted element
132 if (deleteExtraObjects) g.deny(v);
133 removeNode(g, L0, node);
139 // Add new elements at end
140 while (j < value.size()) {
141 // Add tailing elements
142 insertElementBefore(g, L0, currentList, value.get(j));
150 private static Resource insertElementBefore(WriteGraph g, final Layer0 L0, Resource node, final Resource val)
151 throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
152 Resource prev = g.getSingleObject(node, L0.List_Previous);
153 g.deny(prev, L0.List_Next, L0.List_Previous, node);
155 Resource newNode = g.newResource();
156 g.claim(newNode, L0.InstanceOf, L0.List_Entry);
157 g.claim(prev, L0.List_Next, L0.List_Previous, newNode);
158 g.claim(newNode, L0.List_Next, L0.List_Previous, node);
159 g.claim(newNode, L0.List_Element, val);
163 private static void removeNode(WriteGraph g, final Layer0 L0, Resource node)
164 throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
165 Resource prev = g.getSingleObject(node, L0.List_Previous);
166 Resource next = g.getSingleObject(node, L0.List_Next);
167 g.claim(prev, L0.List_Next, L0.List_Previous, next);