X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2Fvariable%2FVariables.java;h=341a496a4ff2778a3e9972cb2c0c998dbe9f6114;hp=e323f4f8c28bc4cb755bb38e609b7d0c6461ea44;hb=e3a908eaf0d1625c6b8c2e58b710e37da05602e8;hpb=ad8333027322fda6b9a8a524c7a7e15a54c52f38 diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/Variables.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/Variables.java index e323f4f8c..341a496a4 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/Variables.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/Variables.java @@ -1,807 +1,844 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 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.db.layer0.variable; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.mutable.Variant; -import org.simantics.databoard.type.Datatype; -import org.simantics.databoard.type.NumberType; -import org.simantics.databoard.util.URIStringUtils; -import org.simantics.db.ReadGraph; -import org.simantics.db.RequestProcessor; -import org.simantics.db.Resource; -import org.simantics.db.common.request.PossibleIndexRoot; -import org.simantics.db.common.request.TernaryRead; -import org.simantics.db.common.utils.Logger; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.exception.MissingVariableException; -import org.simantics.db.layer0.request.Model; -import org.simantics.db.layer0.request.PossibleActiveVariableFromVariable; -import org.simantics.db.layer0.request.PossibleVariableIndexRoot; -import org.simantics.db.layer0.request.PossibleVariableModel; -import org.simantics.db.layer0.request.PropertyInfo; -import org.simantics.db.layer0.request.PropertyInfoRequest; -import org.simantics.db.layer0.request.ResourceURIToVariable; -import org.simantics.db.layer0.request.VariableIndexRoot; -import org.simantics.db.layer0.request.VariableURI; -import org.simantics.layer0.Layer0; -import org.simantics.operation.Layer0X; -import org.simantics.project.ontology.ProjectResource; -import org.simantics.scl.runtime.function.Function1; -import org.simantics.scl.runtime.function.Function2; -import org.simantics.scl.runtime.function.Function3; -import org.simantics.simulation.ontology.SimulationResource; -import org.simantics.simulator.variable.exceptions.NodeManagerException; -import org.simantics.utils.datastructures.Pair; - -import gnu.trove.map.hash.TObjectIntHashMap; - -final public class Variables { - - public static final Variant PENDING_NODE_VALUE = new Variant(); - - public static final NodeStructure PENDING_NODE_STRUCTURE = new NodeStructure(Collections.emptyMap(), Collections.emptyMap()) { - public boolean equals(Object object) { - return this == object; - } - }; - - public static enum Role { - - CHILD("/"), PROPERTY("#"); - - transient final String identifier; - - private Role(String identifier) { - this.identifier = identifier; - } - - final public String getIdentifier() { - return identifier; - } - - public static Role getRole( String identifier ) { - for (Role role : Role.values()) if (role.identifier.equals( identifier )) return role; - return null; - } - - } - - // use getPredicate - //final public static String PREDICATE = "PREDICATE"; - - @Deprecated - // use getName - final public static String NAME = "HasName"; - final public static String CLASSIFICATIONS = "classifications"; - final public static String EXPRESSION = "HasExpression"; - final public static String INPUT_VALIDATOR = "HasInputValidator"; - final public static String INPUT_MODIFIER = "HasInputModifier"; - final public static String FORMATTER = "HasFormatter"; - - final public static String STANDARD_RESOURCE = "hasStandardResource"; - //@Deprecated - // use getPresents - //final public static String REPRESENTS = "Represents"; - final public static String TYPE = "Type"; - final public static String URI = "URI"; - /** - * @deprecated use {@link Variable#getRVI(ReadGraph)} and {@link RVI} instead. - */ -// @Deprecated -// final public static String SERIALISED = "Serialised"; -// @Deprecated - // use getParent - //final public static String PARENT = "Parent"; - //final public static String ROLE = "Role"; - //final public static String DATATYPE = "DATATYPE"; - //final public static String UNIT = "UNIT"; - - final public static String VALID = "valid"; - final public static String REQUIRED = "required"; - final public static String DEFAULT = "default"; - final public static String READONLY = "readOnly"; - final public static String VALIDATOR = "validator"; - - final public static String LABEL = "HasLabel"; - - final public static String ENUMERATION_VALUES = "HasEnumerationValues"; - final public static String CUSTOM_MODIFIER = "HasCustomModifier"; - - final public static String DISPLAY_COLUMN = "HasDisplayColumn"; - - final public static String DISPLAY_PROPERTY = "HasDisplayProperty"; - final public static String DISPLAY_VALUE = "HasDisplayValue"; - final public static String DISPLAY_UNIT = "HasDisplayUnit"; - - final public static String CONVERTED_VALUE = "convertedValue"; - - /** - * This property should exist for array valued property variables. - */ - final public static String ARRAY_SIZE = "ARRAY_SIZE"; - - - @Deprecated - // use etc. variable.adapt(graph, Interface.class).getResource() - final public static String RESOURCE = "Resource"; - @Deprecated - final public static String CONTAINER_RESOURCE = "ContainerResource"; - @Deprecated - final public static String PROPERTY_RESOURCE = "PROPERTY_RESOURCE"; - - @Deprecated - public final static String[] builtins = { - TYPE, RESOURCE, URI - //, SERIALISED - }; - - public static Variable getPossibleVariable(ReadGraph graph, Resource resource) throws DatabaseException { - String uri = graph.getPossibleURI(resource); - return uri != null ? getPossibleVariable(graph, uri) : null; - } - - public static Variable getPossibleVariable(ReadGraph graph, String uri) throws DatabaseException { - try { - return getVariable(graph, uri); - } catch (DatabaseException e) { - return null; - } - } - - public static Variable getVariable(ReadGraph graph, Resource resource) throws DatabaseException { - return getVariable(graph, graph.getURI(resource)); - } - - public static Variable getVariable(ReadGraph graph, String uri) throws DatabaseException { - try { - return graph.sync(new ResourceURIToVariable(uri)); - } catch (MissingVariableException e) { - return VariableRepository.get(graph, uri); - } - } - - private static int commonPrefixLength(String a, String b) { - int maxC = Math.min(a.length(), b.length()); - for(int c=0;c 0 && !isSplitPos(baseURI, prefixLength);--prefixLength); - } - if(prefixLength == baseURI.length()) - return otherURI.substring(prefixLength); - else - return prefixByParentPath( - pathLength(baseURI.substring(prefixLength)), - otherURI.substring(prefixLength)); - } - - public static String getRVI2(ReadGraph graph, Variable base, Variable other) throws DatabaseException { - TObjectIntHashMap baseLength = new TObjectIntHashMap(); - for(int depth=0;base != null;base = base.getParent(graph),++depth) - baseLength.put(base, depth); - Variable cur; - for(cur=other;!baseLength.containsKey(cur);cur=cur.getParent(graph)); - - // To string - String curURI = cur.getURI(graph); - String otherURI = other.getURI(graph); - - return prefixByParentPath(baseLength.get(cur), otherURI.substring(curURI.length())); - } - - public static String getProjectRVI(ReadGraph graph, Variable variable) throws DatabaseException { - Resource project = getProject(graph, variable); - String projectURI = graph.getURI(project); - return variable.getURI(graph).substring(projectURI.length()); - } - - private static int getSegmentEnd(String suffix) { - int pos; - for(pos=1;pos getPath(ReadGraph graph, Variable base, Variable var) throws DatabaseException { - if(!isChild(graph, base, var)) return null; - LinkedList result = new LinkedList(); - var = var.getParent(graph); - while(!var.equals(base)) { - result.addFirst(var); - var = var.getParent(graph); - } - return result; - } - - public static Variable getChild(ReadGraph graph, Variable base, Variable var) throws DatabaseException { - List path = getPath(graph, base, var); - if(path == null || path.size() == 0) return null; - return path.get(0); - } - - public static boolean isChild(ReadGraph graph, Variable base, Variable var) throws DatabaseException { - if(base.equals(var)) return false; - return var.getURI(graph).startsWith(base.getURI(graph)); - } - - public static Variable switchRealization(ReadGraph graph, Variable variable, Resource realization) throws DatabaseException { - Resource current = getRealization(graph, variable); - if(current == null) throw new DatabaseException("No current realization found for variable"); - return switchRealization(graph, variable, current, realization); - } - - public static Variable switchPossibleContext(ReadGraph graph, Variable variable, Resource realization) throws DatabaseException { - Variable current = getPossibleContext(graph, variable); - if (current == null) - return null; - Resource currentContext = current.getPossibleRepresents(graph); - if (currentContext == null) - return null; - return switchPossibleRealization(graph, variable, currentContext, realization); - } - - public static Variable switchRealization(ReadGraph graph, Variable variable, Variable realization) throws DatabaseException { - Resource current = getRealization(graph, variable); - return switchRealization(graph, variable, current, realization); - } - - public static Variable switchRealization(ReadGraph graph, Variable variable, Resource currentRealization, Resource targetRealization) throws DatabaseException { - String currentURI = graph.getURI(currentRealization); - String targetURI = graph.getURI(targetRealization); - String variableURI = variable.getURI(graph); - String targetVariableURI = targetURI + variableURI.substring(currentURI.length()); - return getVariable(graph, targetVariableURI); - } - - public static Variable switchRealization(ReadGraph graph, Variable variable, Resource currentRealization, Variable targetRealization) throws DatabaseException { - String currentURI = graph.getURI(currentRealization); - String targetURI = targetRealization.getURI(graph); - String variableURI = variable.getURI(graph); - String targetVariableURI = targetURI + variableURI.substring(currentURI.length()); - return getVariable(graph, targetVariableURI); - } - - public static Variable switchPossibleRealization(ReadGraph graph, Variable variable, Resource currentRealization, Resource targetRealization) throws DatabaseException { - String currentURI = graph.getURI(currentRealization); - String targetURI = graph.getURI(targetRealization); - String variableURI = variable.getURI(graph); - String targetVariableURI = targetURI + variableURI.substring(currentURI.length()); - return getPossibleVariable(graph, targetVariableURI); - } - - public static Variable toConfigurationVariable(ReadGraph graph, Variable variable) throws DatabaseException { - Variable config = getConfigurationContext(graph, variable); - return switchRealization(graph, variable, config); - } - - public static Variable toPossibleConfigurationVariable(ReadGraph graph, Variable variable) throws DatabaseException { - - Resource represents = variable.getPossibleRepresents(graph); - if(represents == null) return null; - Resource config = getPossibleConfigurationContextResource(graph, represents); - if(config == null) return null; - return switchPossibleContext(graph, variable, config); - - } - - public static String toRVI(ReadGraph graph, List compositePath) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - StringBuilder rvi = new StringBuilder(); - for (Resource composite : compositePath) { - String name = graph.getPossibleRelatedValue(composite, L0.HasName); - if (name == null) - return null; - - rvi.append('/'); - String escapedName = URIStringUtils.escape(name); - rvi.append(escapedName); - } - return rvi.toString(); - } - - public static String appendRVI(ReadGraph graph, String modelURI, String rvi, Resource configuration) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - String partName = graph.getPossibleRelatedValue(configuration, L0.HasName); - if(partName == null) throw new MissingVariableException("Can not append a child corresponding to " + configuration + " to rvi '" + rvi + "' since there is no name."); - String escaped = URIStringUtils.escape(partName); - return rvi + "/" + escaped; - - } - - public static boolean isValid(ReadGraph graph, Variable variable) { - if(variable == null) return false; - try { - variable.getURI(graph); - } catch (DatabaseException e) { - return false; - } - return true; - } - - public static Variable possibleChildWithType(ReadGraph graph, Variable variable, Resource targetType) throws DatabaseException { - Variable found = null; - for(Variable child : variable.getChildren(graph)) { - Resource type = child.getPossiblePropertyValue(graph, Variables.TYPE); - if(type != null && graph.isInheritedFrom(type, targetType)) { - if(found != null) return null; - found = child; - } - } - return found; - } - - public static Collection childrenWithType(ReadGraph graph, Variable variable, Resource targetType) throws DatabaseException { - ArrayList result = new ArrayList(); - for(Variable child : variable.getChildren(graph)) { - Resource type = child.getPossiblePropertyValue(graph, Variables.TYPE); - if(graph.isInheritedFrom(type, targetType)) result.add(child); - } - return result; - } - - public static T adapt(ReadGraph graph, Variable variable, String property, Class clazz) throws DatabaseException { - Resource resource = variable.getPropertyValue(graph, property); - return graph.adapt(resource, clazz); - } - - public static T getPossiblePropertyValue(RequestProcessor processor, Variable variable, Resource property, Binding binding) { - try { - return processor.sync(new TernaryRead(variable, property, binding) { - - @Override - public T perform(ReadGraph graph) throws DatabaseException { - return parameter.getPossiblePropertyValue(graph, parameter2, parameter3); - } - - }); - } catch (DatabaseException e) { - return null; - } - } - - public static Variable possibleActiveVariable(ReadGraph graph, Variable variable) throws DatabaseException { - Variable activeVariable = graph.sync(new PossibleActiveVariableFromVariable(variable)); - return activeVariable; - } - - public static Variant requestNodeValue(ReadGraph graph, VariableNode node) throws DatabaseException { - return requestNodeValue(graph, node, null); - } - - public static Variant requestNodeValue(ReadGraph graph, VariableNode node, final Binding binding) throws DatabaseException { - Variant value = graph.syncRequest(new NodeValueRequest(node, binding)); - if(PENDING_NODE_VALUE == value && graph.getSynchronous()) { - // In this case a PENDING value was previously cached but now the value needs to be obtained for real. - - ValueGetter getter = new ValueGetter(node, binding); - try { - node.support.manager.getRealm().syncExec(getter); - } catch (InterruptedException e) { - Logger.defaultLogError(e); - } - - if (getter.exception != null) - throw new DatabaseException(getter.exception); - - return getter.result; - } - return value; - } - - public static class NodeStructure { - // Immutable but wrapped with Collections.unmodifiableMap as an optimization - public final Map children; - // Immutable but not wrapped with Collections.unmodifiableMap as an optimization - public final Map properties; - private final int hash; - - public NodeStructure(Map children, Map properties) { - this.children = children; - this.properties = properties; - this.hash = calcHash(); - } - - private int calcHash() { - return 31*children.hashCode() + 41*properties.hashCode(); - } - - @Override - public int hashCode() { - return hash; - } - - @Override - public boolean equals(Object object) { - if (this == object) - return true; - else if (object == null || object == Variables.PENDING_NODE_STRUCTURE) - return false; - else if (!(object instanceof NodeStructure)) - return false; - NodeStructure r = (NodeStructure)object; - return r.children.equals(children) && r.properties.equals(properties); - } - } - - public static NodeStructure requestNodeStructure(ReadGraph graph, VariableNode node) throws DatabaseException { - NodeStructure value = graph.syncRequest(new NodeStructureRequest(node)); - if (value == null) throw new DatabaseException("External data access error"); - if(PENDING_NODE_STRUCTURE == value && graph.getSynchronous()) { - // In this case a PENDING value was previously cached but now the value needs to be obtained for real. - - StructureGetter getter = new StructureGetter(node); - try { - node.support.manager.getRealm().syncExec(getter); - } catch (InterruptedException e) { - Logger.defaultLogError(e); - throw new DatabaseException("External data access error", e); - } - - if (getter.exception != null) - throw new DatabaseException("External data access error", getter.exception); - if (getter.result == null) - throw new DatabaseException("External data access error"); - - return getter.result; - - } - return value; - - } - - public static String getPossibleUnit(ReadGraph graph, Variable variable) throws DatabaseException { - - try { - - Resource predicate = variable.getPossiblePredicateResource(graph); - if(predicate != null) { - PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate)); - if(info.definedUnit != null) return info.definedUnit; - } - - Variant variant = variable.getVariantValue(graph); - Binding binding = variant.getBinding(); - if(binding == null) return null; - Datatype dt = binding.type(); - if(!(dt instanceof NumberType)) return null; - NumberType nt = (NumberType)dt; - return nt.getUnit(); - - } catch (DatabaseException e) { - return null; - } - - } - - /** - * @param graph - * @param rvi - * @param context1 primary context to use for resolving the specified RVI, must not be null - * @param context2 secondary context to use for resolving the specified RVI, may be null - * @return pair of variables where first is the resolved variable and second - * is the context it was resolved with - * @throws DatabaseException - * @since 1.18.1 - */ - public static Pair resolvePossible(ReadGraph graph, RVI rvi, Variable context1, Variable context2) throws DatabaseException { - Variable v = rvi.resolvePossible(graph, context1); - if (v != null) - return new Pair<>(v, context1); - if (context2 != null) { - v = rvi.resolvePossible(graph, context2); - if (v != null) - return new Pair<>(v, context2); - } - return null; - } - - - @SuppressWarnings("rawtypes") - private static class ValueGetter implements VariableNodeReadRunnable { - - final VariableNode n; - final Binding binding; - Variant result; - Exception exception; - - public ValueGetter(VariableNode n, Binding binding) { - this.n = n; - this.binding = binding; - } - - @SuppressWarnings("unchecked") - @Override - public void run() { - try { - if (binding != null) - result = new Variant(binding, n.support.manager.getValue(n.node, binding)); - else - result = n.support.manager.getValue(n.node); - } catch (Exception e) { - Logger.defaultLogError(e); - exception = e; - } - } - - } - - @SuppressWarnings("rawtypes") - private static class StructureGetter implements VariableNodeReadRunnable { - - final VariableNode n; - NodeStructure result; - Exception exception; - - public StructureGetter(VariableNode n) { - this.n = n; - } - - @Override - public void run() { - try { - result = NodeStructureRequest.get(n); - } catch (NodeManagerException e) { - Logger.defaultLogError(e); - exception = e; - } - } - - }; - - public static Variable tryGetProperty(ReadGraph graph, Resource entity, Resource property) throws DatabaseException { - Variable v = Variables.getPossibleVariable(graph, entity); - return v != null ? v.getPossibleProperty(graph, property) : null; - } - - public static ValueAccessor createValueAccessor(Function1 getValue1, Function2 getValue2, - Function2 setValue2, Function3 setValue3, - Function1 getDatatype) { - return new SCLValueAccessor(getValue1, getValue2, setValue2, setValue3, getDatatype); - } - - -} +/******************************************************************************* + * Copyright (c) 2007, 2010 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.db.layer0.variable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Databoard; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.databoard.type.Datatype; +import org.simantics.databoard.type.NumberType; +import org.simantics.databoard.util.URIStringUtils; +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.request.TernaryRead; +import org.simantics.db.common.utils.CommonDBUtils; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.InvalidVariableException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.exception.MissingVariableValueException; +import org.simantics.db.layer0.request.Model; +import org.simantics.db.layer0.request.PossibleActiveVariableFromVariable; +import org.simantics.db.layer0.request.PossibleVariableIndexRoot; +import org.simantics.db.layer0.request.PossibleVariableModel; +import org.simantics.db.layer0.request.PropertyInfo; +import org.simantics.db.layer0.request.PropertyInfoRequest; +import org.simantics.db.layer0.request.ResourceURIToVariable; +import org.simantics.db.layer0.request.VariableIndexRoot; +import org.simantics.db.layer0.request.VariableURI; +import org.simantics.layer0.Layer0; +import org.simantics.operation.Layer0X; +import org.simantics.project.ontology.ProjectResource; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.scl.runtime.function.Function2; +import org.simantics.scl.runtime.function.Function3; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.simulator.variable.exceptions.NodeManagerException; +import org.simantics.utils.datastructures.Pair; + +import gnu.trove.map.hash.TObjectIntHashMap; + +final public class Variables { + + public static final Variant PENDING_NODE_VALUE = new Variant(); + + public static final NodeStructure PENDING_NODE_STRUCTURE = new NodeStructure(Collections.emptyMap(), Collections.emptyMap()) { + public boolean equals(Object object) { + return this == object; + } + }; + + public static enum Role { + + CHILD("/"), PROPERTY("#"); + + transient final String identifier; + + private Role(String identifier) { + this.identifier = identifier; + } + + final public String getIdentifier() { + return identifier; + } + + public static Role getRole( String identifier ) { + for (Role role : Role.values()) if (role.identifier.equals( identifier )) return role; + return null; + } + + } + + // use getPredicate + //final public static String PREDICATE = "PREDICATE"; + + @Deprecated + // use getName + final public static String NAME = "HasName"; + final public static String CLASSIFICATIONS = "classifications"; + final public static String EXPRESSION = "HasExpression"; + final public static String INPUT_VALIDATOR = "HasInputValidator"; + final public static String INPUT_MODIFIER = "HasInputModifier"; + final public static String FORMATTER = "HasFormatter"; + + final public static String STANDARD_RESOURCE = "hasStandardResource"; + //@Deprecated + // use getPresents + //final public static String REPRESENTS = "Represents"; + final public static String TYPE = "Type"; + final public static String URI = "URI"; + /** + * @deprecated use {@link Variable#getRVI(ReadGraph)} and {@link RVI} instead. + */ +// @Deprecated +// final public static String SERIALISED = "Serialised"; +// @Deprecated + // use getParent + //final public static String PARENT = "Parent"; + //final public static String ROLE = "Role"; + //final public static String DATATYPE = "DATATYPE"; + //final public static String UNIT = "UNIT"; + + final public static String VALID = "valid"; + final public static String REQUIRED = "required"; + final public static String DEFAULT = "default"; + final public static String READONLY = "readOnly"; + final public static String VALIDATOR = "validator"; + + final public static String LABEL = "HasLabel"; + + final public static String ENUMERATION_VALUES = "HasEnumerationValues"; + final public static String CUSTOM_MODIFIER = "HasCustomModifier"; + + final public static String DISPLAY_COLUMN = "HasDisplayColumn"; + + final public static String DISPLAY_PROPERTY = "HasDisplayProperty"; + final public static String DISPLAY_VALUE = "HasDisplayValue"; + final public static String DISPLAY_UNIT = "HasDisplayUnit"; + + final public static String CONVERTED_VALUE = "convertedValue"; + + /** + * This property should exist for array valued property variables. + */ + final public static String ARRAY_SIZE = "ARRAY_SIZE"; + + + @Deprecated + // use etc. variable.adapt(graph, Interface.class).getResource() + final public static String RESOURCE = "Resource"; + @Deprecated + final public static String CONTAINER_RESOURCE = "ContainerResource"; + @Deprecated + final public static String PROPERTY_RESOURCE = "PROPERTY_RESOURCE"; + + @Deprecated + public final static String[] builtins = { + TYPE, RESOURCE, URI + //, SERIALISED + }; + + public static Variable getPossibleVariable(ReadGraph graph, Resource resource) throws DatabaseException { + String uri = graph.getPossibleURI(resource); + if (uri != null) + return getPossibleVariable(graph, uri); + Resource parent = CommonDBUtils.getPossibleOwner(graph, resource); + if (parent == null) + return null; + Variable possibleVariable = getPossibleVariable(graph, parent); + if (possibleVariable == null) + return null; + String possibleName = graph.getPossibleRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING); + if (possibleName == null) + possibleName = VariableUtils.unnamedResourceName(resource); + Variable possibleChild = possibleVariable.getPossibleChild(graph, possibleName); + if (possibleChild != null) + return possibleChild; + for (Variable v : possibleVariable.getChildren(graph)) { + Resource vr = v.getPossibleRepresents(graph); + if (vr != null && vr.equals(resource)) { + return v; + } + } + return null; + } + + public static Variable getPossibleVariable(ReadGraph graph, String uri) throws DatabaseException { + try { + return getVariable(graph, uri); + } catch (DatabaseException e) { + return null; + } + } + + public static Variable getVariable(ReadGraph graph, Resource resource) throws DatabaseException { + return getVariable(graph, graph.getURI(resource)); + } + + public static Variable getVariable(ReadGraph graph, String uri) throws DatabaseException { + try { + return graph.sync(new ResourceURIToVariable(uri)); + } catch (MissingVariableException e) { + return VariableRepository.get(graph, uri); + } + } + + private static int commonPrefixLength(String a, String b) { + int maxC = Math.min(a.length(), b.length()); + for(int c=0;c 0 && !isSplitPos(baseURI, prefixLength);--prefixLength); + } + if(prefixLength == baseURI.length()) + return otherURI.substring(prefixLength); + else + return prefixByParentPath( + pathLength(baseURI.substring(prefixLength)), + otherURI.substring(prefixLength)); + } + + public static String getRVI2(ReadGraph graph, Variable base, Variable other) throws DatabaseException { + TObjectIntHashMap baseLength = new TObjectIntHashMap(); + for(int depth=0;base != null;base = base.getParent(graph),++depth) + baseLength.put(base, depth); + Variable cur; + for(cur=other;!baseLength.containsKey(cur);cur=cur.getParent(graph)); + + // To string + String curURI = cur.getURI(graph); + String otherURI = other.getURI(graph); + + return prefixByParentPath(baseLength.get(cur), otherURI.substring(curURI.length())); + } + + public static String getProjectRVI(ReadGraph graph, Variable variable) throws DatabaseException { + Resource project = getProject(graph, variable); + String projectURI = graph.getURI(project); + return variable.getURI(graph).substring(projectURI.length()); + } + + private static int getSegmentEnd(String suffix) { + int pos; + for(pos=1;pos getPath(ReadGraph graph, Variable base, Variable var) throws DatabaseException { + if(!isChild(graph, base, var)) return null; + LinkedList result = new LinkedList(); + var = var.getParent(graph); + while(!var.equals(base)) { + result.addFirst(var); + var = var.getParent(graph); + } + return result; + } + + public static Variable getChild(ReadGraph graph, Variable base, Variable var) throws DatabaseException { + List path = getPath(graph, base, var); + if(path == null || path.size() == 0) return null; + return path.get(0); + } + + public static boolean isChild(ReadGraph graph, Variable base, Variable var) throws DatabaseException { + if(base.equals(var)) return false; + return var.getURI(graph).startsWith(base.getURI(graph)); + } + + public static Variable switchRealization(ReadGraph graph, Variable variable, Resource realization) throws DatabaseException { + Resource current = getRealization(graph, variable); + if (current == null) + throw new InvalidVariableException("No current realization found for variable"); + return switchRealization(graph, variable, current, realization); + } + + public static Variable switchPossibleContext(ReadGraph graph, Variable variable, Resource realization) throws DatabaseException { + Variable current = getPossibleContext(graph, variable); + if (current == null) + return null; + Resource currentContext = current.getPossibleRepresents(graph); + if (currentContext == null) + return null; + return switchPossibleRealization(graph, variable, currentContext, realization); + } + + public static Variable switchRealization(ReadGraph graph, Variable variable, Variable realization) throws DatabaseException { + Resource current = getRealization(graph, variable); + return switchRealization(graph, variable, current, realization); + } + + public static Variable switchRealization(ReadGraph graph, Variable variable, Resource currentRealization, Resource targetRealization) throws DatabaseException { + String currentURI = graph.getURI(currentRealization); + String targetURI = graph.getURI(targetRealization); + String variableURI = variable.getURI(graph); + String targetVariableURI = targetURI + variableURI.substring(currentURI.length()); + return getVariable(graph, targetVariableURI); + } + + public static Variable switchRealization(ReadGraph graph, Variable variable, Resource currentRealization, Variable targetRealization) throws DatabaseException { + String currentURI = graph.getURI(currentRealization); + String targetURI = targetRealization.getURI(graph); + String variableURI = variable.getURI(graph); + String targetVariableURI = targetURI + variableURI.substring(currentURI.length()); + return getVariable(graph, targetVariableURI); + } + + public static Variable switchPossibleRealization(ReadGraph graph, Variable variable, Resource currentRealization, Resource targetRealization) throws DatabaseException { + String currentURI = graph.getURI(currentRealization); + String targetURI = graph.getURI(targetRealization); + String variableURI = variable.getURI(graph); + String targetVariableURI = targetURI + variableURI.substring(currentURI.length()); + return getPossibleVariable(graph, targetVariableURI); + } + + public static Variable toConfigurationVariable(ReadGraph graph, Variable variable) throws DatabaseException { + Variable config = getConfigurationContext(graph, variable); + return switchRealization(graph, variable, config); + } + + public static Variable toPossibleConfigurationVariable(ReadGraph graph, Variable variable) throws DatabaseException { + + Resource represents = variable.getPossibleRepresents(graph); + if(represents == null) return null; + Resource config = getPossibleConfigurationContextResource(graph, represents); + if(config == null) return null; + return switchPossibleContext(graph, variable, config); + + } + + public static String toRVI(ReadGraph graph, List compositePath) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + StringBuilder rvi = new StringBuilder(); + for (Resource composite : compositePath) { + String name = graph.getPossibleRelatedValue(composite, L0.HasName); + if (name == null) + return null; + + rvi.append('/'); + String escapedName = URIStringUtils.escape(name); + rvi.append(escapedName); + } + return rvi.toString(); + } + + public static String appendRVI(ReadGraph graph, String modelURI, String rvi, Resource configuration) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + String partName = graph.getPossibleRelatedValue(configuration, L0.HasName); + if (partName == null) + throw new MissingVariableException("Can not append a child corresponding to " + configuration + " to rvi '" + + rvi + "' since there is no name.", configuration); + String escaped = URIStringUtils.escape(partName); + return rvi + "/" + escaped; + } + + public static boolean isValid(ReadGraph graph, Variable variable) { + if(variable == null) return false; + try { + variable.getURI(graph); + } catch (DatabaseException e) { + return false; + } + return true; + } + + public static Variable possibleChildWithType(ReadGraph graph, Variable variable, Resource targetType) throws DatabaseException { + Variable found = null; + for(Variable child : variable.getChildren(graph)) { + Resource type = child.getPossiblePropertyValue(graph, Variables.TYPE); + if(type != null && graph.isInheritedFrom(type, targetType)) { + if(found != null) return null; + found = child; + } + } + return found; + } + + public static Collection childrenWithType(ReadGraph graph, Variable variable, Resource targetType) throws DatabaseException { + ArrayList result = new ArrayList(); + for(Variable child : variable.getChildren(graph)) { + Resource type = child.getPossiblePropertyValue(graph, Variables.TYPE); + if(graph.isInheritedFrom(type, targetType)) result.add(child); + } + return result; + } + + public static T adapt(ReadGraph graph, Variable variable, String property, Class clazz) throws DatabaseException { + Resource resource = variable.getPropertyValue(graph, property); + return graph.adapt(resource, clazz); + } + + public static T getPossiblePropertyValue(RequestProcessor processor, Variable variable, Resource property, Binding binding) { + try { + return processor.sync(new TernaryRead(variable, property, binding) { + + @Override + public T perform(ReadGraph graph) throws DatabaseException { + return parameter.getPossiblePropertyValue(graph, parameter2, parameter3); + } + + }); + } catch (DatabaseException e) { + return null; + } + } + + public static Variable possibleActiveVariable(ReadGraph graph, Variable variable) throws DatabaseException { + Variable activeVariable = graph.sync(new PossibleActiveVariableFromVariable(variable)); + return activeVariable; + } + + public static Variant requestNodeValue(ReadGraph graph, VariableNode node) throws DatabaseException { + return requestNodeValue(graph, node, null); + } + + public static Variant requestNodeValue(ReadGraph graph, VariableNode node, final Binding binding) throws DatabaseException { + Variant value = graph.syncRequest(new NodeValueRequest(node, binding)); + if(PENDING_NODE_VALUE == value && graph.getSynchronous()) { + // In this case a PENDING value was previously cached but now the value needs to be obtained for real. + + ValueGetter getter = new ValueGetter(node, binding); + try { + node.support.manager.getRealm().syncExec(getter); + } catch (InterruptedException e) { + Logger.defaultLogError(e); + } + + if (getter.exception != null) + throw new MissingVariableValueException("No value for node " + node, getter.exception); + + return getter.result; + } + return value; + } + + public static class NodeStructure { + // Immutable but wrapped with Collections.unmodifiableMap as an optimization + public final Map children; + // Immutable but not wrapped with Collections.unmodifiableMap as an optimization + public final Map properties; + private final int hash; + + public NodeStructure(Map children, Map properties) { + this.children = children; + this.properties = properties; + this.hash = calcHash(); + } + + private int calcHash() { + return 31*children.hashCode() + 41*properties.hashCode(); + } + + @Override + public int hashCode() { + return hash; + } + + @Override + public boolean equals(Object object) { + if (this == object) + return true; + else if (object == null || object == Variables.PENDING_NODE_STRUCTURE) + return false; + else if (!(object instanceof NodeStructure)) + return false; + NodeStructure r = (NodeStructure)object; + return r.children.equals(children) && r.properties.equals(properties); + } + } + + public static NodeStructure requestNodeStructure(ReadGraph graph, VariableNode node) throws DatabaseException { + NodeStructure value = graph.syncRequest(new NodeStructureRequest(node)); + if (value == null) + throw new InvalidVariableException("External data access error " + String.valueOf(node)); + if(PENDING_NODE_STRUCTURE == value && graph.getSynchronous()) { + // In this case a PENDING value was previously cached but now the value needs to be obtained for real. + + StructureGetter getter = new StructureGetter(node); + try { + node.support.manager.getRealm().syncExec(getter); + } catch (InterruptedException e) { + Logger.defaultLogError(e); + throw new InvalidVariableException("External data access error " + String.valueOf(node), e); + } + + if (getter.exception != null) + throw new InvalidVariableException("External data access error " + String.valueOf(node), getter.exception); + if (getter.result == null) + throw new InvalidVariableException("External data access error " + String.valueOf(node)); + + return getter.result; + + } + return value; + + } + + public static String getPossibleUnit(ReadGraph graph, Variable variable) throws DatabaseException { + + try { + + Resource predicate = variable.getPossiblePredicateResource(graph); + if(predicate != null) { + PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate)); + if(info.definedUnit != null) return info.definedUnit; + } + + Variant variant = variable.getVariantValue(graph); + Binding binding = variant.getBinding(); + if(binding == null) return null; + Datatype dt = binding.type(); + if(!(dt instanceof NumberType)) return null; + NumberType nt = (NumberType)dt; + return nt.getUnit(); + + } catch (DatabaseException e) { + return null; + } + + } + + /** + * @param graph + * @param rvi + * @param context1 primary context to use for resolving the specified RVI, must not be null + * @param context2 secondary context to use for resolving the specified RVI, may be null + * @return pair of variables where first is the resolved variable and second + * is the context it was resolved with + * @throws DatabaseException + * @since 1.18.1 + */ + public static Pair resolvePossible(ReadGraph graph, RVI rvi, Variable context1, Variable context2) throws DatabaseException { + Variable v = rvi.resolvePossible(graph, context1); + if (v != null) + return new Pair<>(v, context1); + if (context2 != null) { + v = rvi.resolvePossible(graph, context2); + if (v != null) + return new Pair<>(v, context2); + } + return null; + } + + + @SuppressWarnings("rawtypes") + private static class ValueGetter implements VariableNodeReadRunnable { + + final VariableNode n; + final Binding binding; + Variant result; + Exception exception; + + public ValueGetter(VariableNode n, Binding binding) { + this.n = n; + this.binding = binding; + } + + @SuppressWarnings("unchecked") + @Override + public void run() { + try { + if (binding != null) + result = new Variant(binding, n.support.manager.getValue(n.node, binding)); + else + result = n.support.manager.getValue(n.node); + } catch (Exception e) { + Logger.defaultLogError(e); + exception = e; + } + } + + } + + @SuppressWarnings("rawtypes") + private static class StructureGetter implements VariableNodeReadRunnable { + + final VariableNode n; + NodeStructure result; + Exception exception; + + public StructureGetter(VariableNode n) { + this.n = n; + } + + @Override + public void run() { + try { + result = NodeStructureRequest.get(n); + } catch (NodeManagerException e) { + Logger.defaultLogError(e); + exception = e; + } + } + + }; + + public static Variable tryGetProperty(ReadGraph graph, Resource entity, Resource property) throws DatabaseException { + Variable v = Variables.getPossibleVariable(graph, entity); + return v != null ? v.getPossibleProperty(graph, property) : null; + } + + public static ValueAccessor createValueAccessor(Function1 getValue1, Function2 getValue2, + Function2 setValue2, Function3 setValue3, + Function1 getDatatype) { + return new SCLValueAccessor(getValue1, getValue2, setValue2, setValue3, getDatatype); + } + + public static void setRVIProperty(WriteGraph graph, Variable variable, RVI rvi) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Binding rviBinding = graph.getService(Databoard.class).getBindingUnchecked( RVI.class ); + Resource predicate = variable.getPredicateResource(graph); + Resource subject = variable.getParent(graph).getRepresents(graph); + graph.deny(subject, predicate); + graph.claimLiteral(subject, predicate, L0.RVI, rvi, rviBinding); + } + +}