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