--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modeling.typicals.rules;\r
+\r
+import java.util.Collections;\r
+import java.util.Set;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.databoard.util.ObjectUtils;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.diagram.synchronization.graph.CopyAdvisorUtil;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class Properties {\r
+\r
+ /**\r
+ * Synchronizes a simple primitive-valued property from the specified\r
+ * resource to another.\r
+ * \r
+ * @param graph write access\r
+ * @param from property source\r
+ * @param to property target\r
+ * @param property the property to synchronize\r
+ * @return <code>true</code> if changes were made\r
+ * @throws DatabaseException\r
+ */\r
+ public static boolean synchronizePrimitivePropertyValue(WriteGraph graph, Resource from, Resource to, Resource property) throws DatabaseException {\r
+ Statement templateStm = graph.getPossibleStatement(from, property);\r
+ Statement instanceStm = graph.getPossibleStatement(to, property);\r
+ if (templateStm == null && instanceStm == null)\r
+ return false;\r
+\r
+ if (templateStm == null) {\r
+ graph.deny(instanceStm);\r
+ RemoverUtil.remove(graph, instanceStm.getObject());\r
+ return true;\r
+ } else if (instanceStm == null) {\r
+ Resource copiedLabel = CopyAdvisorUtil.copy2(graph, templateStm.getObject(), null);\r
+ graph.claim(to, property, copiedLabel);\r
+ return true;\r
+ }\r
+\r
+ boolean templateAsserted = templateStm.isAsserted(from);\r
+ boolean instanceAsserted = instanceStm.isAsserted(to);\r
+ if (templateAsserted && instanceAsserted)\r
+ return false;\r
+\r
+ if (templateAsserted) {\r
+ // Remove instance label to let assertions work.\r
+ graph.denyValue(to, property);\r
+ } else if (instanceAsserted) {\r
+ // Instance is missing defined label property\r
+ Resource copiedLabel = CopyAdvisorUtil.copy2(graph, templateStm.getObject(), null);\r
+ graph.claim(to, property, copiedLabel);\r
+ } else {\r
+ // Make sure that both literals are of the same type.\r
+ Set<Resource> templateTypes = graph.getTypes(templateStm.getObject());\r
+ Set<Resource> instanceTypes = graph.getTypes(instanceStm.getObject());\r
+ if (Collections.disjoint(templateTypes, instanceTypes)) {\r
+ graph.denyValue(to, property);\r
+ Resource copiedValue = CopyAdvisorUtil.copy2(graph, templateStm.getObject(), null);\r
+ graph.claim(to, property, copiedValue);\r
+ } else {\r
+ Datatype dt = graph.getDataType(templateStm.getObject());\r
+ Binding binding = Bindings.getBinding(dt);\r
+ Object templateValue = graph.getPossibleValue(templateStm.getObject(), binding);\r
+ Object instanceValue = graph.getPossibleValue(instanceStm.getObject(), binding);\r
+ if (ObjectUtils.objectEquals(templateValue, instanceValue))\r
+ return false;\r
+ if (templateValue == null) {\r
+ graph.denyValue(instanceStm.getObject());\r
+ } else {\r
+ graph.claimValue(instanceStm.getObject(), templateValue, binding);\r
+ }\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+\r
+ public static boolean synchronizeDeepPropertyValue(WriteGraph graph, Resource from, Resource to, Resource property) throws DatabaseException {\r
+ \r
+ Statement templateStm = graph.getPossibleStatement(from, property);\r
+ Statement instanceStm = graph.getPossibleStatement(to, property);\r
+ if (templateStm == null || instanceStm == null)\r
+ return false;\r
+\r
+ boolean templateAsserted = templateStm.isAsserted(from);\r
+ boolean instanceAsserted = instanceStm.isAsserted(to);\r
+ if (templateAsserted && instanceAsserted)\r
+ return false;\r
+ \r
+ if (templateAsserted) {\r
+ graph.deny(instanceStm);\r
+ RemoverUtil.remove(graph, instanceStm.getObject());\r
+ return true;\r
+ }\r
+ \r
+ if (instanceAsserted) {\r
+ Resource copied = CopyAdvisorUtil.copy2(graph, templateStm.getObject(), null);\r
+ graph.claim(to, property, copied);\r
+ return true;\r
+ }\r
+\r
+ return Layer0Utils.merge(graph, templateStm.getObject(), instanceStm.getObject());\r
+ \r
+ }\r
+ \r
+ /**\r
+ * @param graph\r
+ * @param from\r
+ * @param to\r
+ * @param property\r
+ * @return\r
+ * @throws DatabaseException\r
+ */\r
+ public static boolean synchronizeEnumerationPropertyValue(WriteGraph graph, Resource from, Resource to, Resource property) throws DatabaseException {\r
+ Statement templateStm = graph.getPossibleStatement(from, property);\r
+ Statement instanceStm = graph.getPossibleStatement(to, property);\r
+ if (templateStm == null && instanceStm == null)\r
+ return false;\r
+\r
+ if (templateStm == null) {\r
+ graph.deny(instanceStm);\r
+ return true;\r
+ } else if (instanceStm == null) {\r
+ graph.claim(to, property, templateStm.getObject());\r
+ return true;\r
+ }\r
+\r
+ boolean templateAsserted = templateStm.isAsserted(from);\r
+ boolean instanceAsserted = instanceStm.isAsserted(to);\r
+ if (templateAsserted && instanceAsserted)\r
+ return false;\r
+\r
+ if (templateAsserted) {\r
+ // Remove instance label to let assertions work.\r
+ graph.denyValue(to, property);\r
+ } else if (instanceAsserted) {\r
+ // Instance is missing defined property\r
+ graph.claim(to, property, templateStm.getObject());\r
+ } else {\r
+ // Make sure that both literals are of the same type.\r
+ if (templateStm.getObject().equals(instanceStm.getObject()))\r
+ return false;\r
+ graph.deny(instanceStm);\r
+ graph.claim(to, property, templateStm.getObject());\r
+ }\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * @param graph\r
+ * @param from\r
+ * @param to\r
+ * @param property\r
+ * @return\r
+ * @throws DatabaseException\r
+ */\r
+ public static boolean synchronizeTag(WriteGraph graph, Resource from, Resource to, Resource tag) throws DatabaseException {\r
+ boolean fromHas = graph.hasStatement(from, tag);\r
+ boolean toHas = graph.hasStatement(to, tag);\r
+ if (fromHas == toHas)\r
+ return false;\r
+ if (fromHas)\r
+ graph.claim(to, tag, to);\r
+ else\r
+ graph.deny(to, tag);\r
+ return true;\r
+ }\r
+\r
+}\r