package org.simantics.db.layer0.variable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.simantics.databoard.Bindings; import org.simantics.databoard.Datatypes; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.error.DatatypeConstructionException; import org.simantics.databoard.type.Datatype; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.layer0.Layer0; abstract public class StandardExpressionGraphPropertyVariable extends StandardGraphPropertyVariable { final public String expressionText; transient private int hash = 0; public StandardExpressionGraphPropertyVariable(ReadGraph graph, Variable parent, Resource property, String expressionText) throws DatabaseException { super(graph, parent, null, property); assert parent != null; assert property != null; assert expressionText != null; this.expressionText = expressionText; } @Override public void validate(ReadGraph graph) throws DatabaseException { } @Override public String getName(ReadGraph graph) throws DatabaseException { return graph.getRelatedValue(property.predicate, graph.getService(Layer0.class).HasName, Bindings.STRING); } @Override public String getLabel(ReadGraph graph) throws DatabaseException { return graph.getRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent); } @Override public Variable getParent(ReadGraph graph) throws DatabaseException { return parent; } @Override public T getValue(ReadGraph graph) throws DatabaseException { assertAlive(graph); return (T)getValueAccessor(graph).getValue(graph, this); } @Override public T getValue(ReadGraph graph, Binding binding) throws DatabaseException { assertAlive(graph); return (T)getValueAccessor(graph).getValue(graph, this, binding); } @Override public Resource getRepresents(ReadGraph graph) throws DatabaseException { assertAlive(graph); return null; } @Override public Resource getPossibleRepresents(ReadGraph graph) throws DatabaseException { assertAlive(graph); return null; } @Override public void setValue(WriteGraph graph, Object value, Binding binding) throws DatabaseException { assertAlive(graph); throw new UnsupportedOperationException("Procedural expression variable cannot be set."); } @Override public void setValue(WriteGraph graph, Object value) throws DatabaseException { assertAlive(graph); throw new UnsupportedOperationException("Procedural expression variable cannot be set."); } @Override public Datatype getDatatype(ReadGraph graph) throws DatabaseException { try { return Layer0Utils.getDatatype(graph, this); } catch (DatabaseException e) { return null; } } @Override public String getUnit(ReadGraph graph) throws DatabaseException { try { return Layer0Utils.getUnit(graph, this); } catch (DatabaseException e) { return null; } } @Override public Resource getContainerResource(ReadGraph graph) throws DatabaseException { return null; } @Override public Collection getChildren(ReadGraph graph) throws DatabaseException { Map result = new HashMap(); VariableMap map = getPossibleChildVariableMap(graph); if(map != null) map.getVariables(graph, this, result); return result.values(); } @Override public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException { VariableMap map = getPossibleChildVariableMap(graph); if(map == null) return null; try { return map.getVariable(graph, this, name); } catch (DatabaseException e) { return null; } } @Override protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException { VariableMap valueMap = getPossiblePropertyVariableMap(graph); if(valueMap == null) return null; try { return valueMap.getVariable(graph, this, name); } catch (DatabaseException e) { return null; } } @Override public Map collectDomainProperties(ReadGraph graph, Map properties) throws DatabaseException { VariableMap valueMap = getPossiblePropertyVariableMap(graph); if(valueMap == null) return properties; return valueMap.getVariables(graph, this, properties); } @Override public Variable getPredicate(ReadGraph graph) throws DatabaseException { return Variables.getVariable(graph, graph.getURI(property.predicate)); } @Override public Resource getPredicateResource(ReadGraph graph) throws DatabaseException { return property.predicate; } @Override public Resource getPossiblePredicateResource(ReadGraph graph) throws DatabaseException { return property.predicate; } @Override public int hashCode() { if(hash == 0) { final int prime = 31; int result = 1; result = prime * result + parent.hashCode(); result = prime * result + property.hashCode(); result = prime * result + expressionText.hashCode(); hash =result; } return hash; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; StandardExpressionGraphPropertyVariable other = (StandardExpressionGraphPropertyVariable) obj; if (!expressionText.equals(other.expressionText)) return false; return super.equals(other); } @Override protected Variable getNameVariable(ReadGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); return new StandardGraphPropertyVariable(graph, this, L0.HasName); } private void assertAlive(ReadGraph graph) throws DatabaseException { } protected ValueAccessor getValueAccessor(ReadGraph graph) throws DatabaseException { return new ValueAccessor() { @Override public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException { throw new UnsupportedOperationException(); } @Override public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException { throw new UnsupportedOperationException(); } @Override public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException { return compute(graph, context, binding); } @Override public Object getValue(ReadGraph graph, Variable context) throws DatabaseException { return compute(graph, context); } @Override public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException { try { Object value = compute(graph, context); return Datatypes.getDatatype(value.getClass()); } catch (DatatypeConstructionException e) { throw new DatabaseException(e); } } }; } abstract protected Object compute(ReadGraph graph, Variable context) throws DatabaseException; abstract protected Object compute(ReadGraph graph, Variable context, Binding binding) throws DatabaseException; protected VariableMap getPossibleChildVariableMap(ReadGraph graph) throws DatabaseException { return graph.getPossibleRelatedValue2(property.predicate, Layer0.getInstance(graph).domainChildren, this); } protected VariableMap getPossiblePropertyVariableMap(ReadGraph graph) throws DatabaseException { return graph.getPossibleRelatedValue2(property.predicate, Layer0.getInstance(graph).domainProperties, this); } public Set getClassifications(ReadGraph graph) throws DatabaseException { ArrayList value = getPropertyValue(graph, "classifications"); return new HashSet(value); } }