X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2Fvariable%2FVariableUtils.java;fp=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2Fvariable%2FVariableUtils.java;h=8f203375b5f4268b18ba79fd19e2c3691c9885f2;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableUtils.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableUtils.java new file mode 100644 index 000000000..8f203375b --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableUtils.java @@ -0,0 +1,113 @@ +package org.simantics.db.layer0.variable; + +import java.util.Map; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.adapter.AdaptException; +import org.simantics.databoard.adapter.Adapter; +import org.simantics.databoard.adapter.AdapterConstructionException; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.type.Datatype; +import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.EnumerationMap; +import org.simantics.db.common.request.IsEnumeratedValue; +import org.simantics.db.common.utils.CommonDBUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.RuntimeDatabaseException; +import org.simantics.db.layer0.util.Layer0Utils; +import org.simantics.layer0.Layer0; +import org.simantics.scl.runtime.function.Function4; +import org.simantics.scl.runtime.function.FunctionImpl4; + +public class VariableUtils { + + final private static Binding datatype_binding = Bindings.getBindingUnchecked(Datatype.class); + + public static Function4 defaultInputModifier = new FunctionImpl4() { + + public String apply(WriteGraph graph, Variable variable, Object value, Object _binding) { + try { + return safeApply(graph, variable, value, _binding); + } catch (DatabaseException e) { + throw new RuntimeDatabaseException(e); + } + } + + public String safeApply(WriteGraph graph, Variable variable, Object value, Object _binding) throws DatabaseException { + + Binding binding = (Binding)_binding; + + Variable parent = variable.getParent(graph); + Resource property = variable.getPossiblePredicateResource(graph); + Resource container = parent.getPossibleRepresents(graph); + if(container == null) return null; + if(property == null) return null; + + CommonDBUtils.selectClusterSet(graph, container); + + Statement object = graph.getPossibleStatement(container, property); + if(object == null) return null; + + Resource objectResource = object.getObject(); + if(graph.sync(new IsEnumeratedValue(objectResource))) { + + Layer0 L0 = Layer0.getInstance(graph); + Resource type = graph.getSingleObject(objectResource, L0.PartOf); + + Map enumMap = graph.syncRequest(new EnumerationMap(type)); + Resource newLiteral = enumMap.get(value); + graph.deny(container, property, objectResource); + graph.claim(container, property, newLiteral); + + return null; + + } + + Layer0 L0 = Layer0.getInstance(graph); + Statement dt = graph.getPossibleStatement(objectResource, L0.HasDataType); + if (dt == null) { + throw new DatabaseException("Can't write variable " + variable.getURI(graph) + " since its literal resource " + objectResource + " does not contain a datatype statement"); + } + + boolean needsCustomDatatype = !dt.isAsserted(objectResource); + Datatype correctDatatype = graph.getValue(dt.getObject(), datatype_binding); + Binding correctBinding = Bindings.getBinding(correctDatatype); + + try { + Adapter adapter = Bindings.getTypeAdapter(binding, correctBinding); + Object correctValue = adapter.adapt(value); + if (correctValue == value) { + // Adapter is passthrough, i.e. the specified binding can be + // considered correct for the value. + correctBinding = binding; + } + value = correctValue; + } catch (AdapterConstructionException e) { + throw new DatabaseException("Can't adapt values from source datatype '" + binding.type().toSingleLineString() + "' to target '" + correctDatatype.toSingleLineString() + "'"); + } catch (AdaptException e) { + throw new DatabaseException("Can't adapt value " + value + " from source datatype '" + binding.type().toSingleLineString() + "' to target '" + correctDatatype.toSingleLineString() + "'"); + } + + if (object.isAsserted(container)) { + String sclType = needsCustomDatatype ? Layer0Utils.getSCLType(correctDatatype) : null; + + Resource type = graph.getPossibleType(objectResource, L0.Literal); + objectResource = graph.newResource(); + graph.claim(objectResource, L0.InstanceOf, null, type); + graph.claim(container, property, objectResource); + if(needsCustomDatatype) { + graph.addLiteral(objectResource, L0.HasDataType, L0.HasDataType_Inverse, L0.DataType, correctDatatype, datatype_binding); + graph.addLiteral(objectResource, L0.HasValueType, L0.HasValueType_Inverse, L0.String, sclType, Bindings.STRING); + } + } + + graph.claimValue(objectResource, value, correctBinding); + return null; + + } + + }; + +}