package org.simantics.db.layer0.request; import gnu.trove.map.hash.THashMap; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; import org.simantics.databoard.Bindings; import org.simantics.databoard.accessor.reference.ChildReference; import org.simantics.databoard.accessor.reference.IndexReference; import org.simantics.databoard.accessor.reference.NameReference; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.type.Datatype; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.layer0.variable.ValueAccessor; import org.simantics.db.layer0.variable.VariableBuilder; import org.simantics.layer0.Layer0; import org.simantics.operation.Layer0X; import org.simantics.utils.datastructures.Pair; final public class PropertyInfoRequest extends ResourceRead { public PropertyInfoRequest(Resource resource) { super(resource); } @Override public PropertyInfo perform(ReadGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); Layer0X L0X = Layer0X.getInstance(graph); boolean isHasProperty = graph.isSubrelationOf(resource, L0.HasProperty); String name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING); if(name != null) name = name.intern(); boolean isFunctional = graph.isInstanceOf(resource, L0.FunctionalRelation); Set classifications = graph.sync(new ClassificationsRequest(graph.getPrincipalTypes(resource))); VariableBuilder variableBuilder = graph.getPossibleAdapter(resource, VariableBuilder.class); Datatype requiredDataType = graph.getPossibleRelatedValue(resource, L0X.RequiresDataType, Bindings.DATATYPE); String definedUnit = graph.getPossibleRelatedValue(resource, L0X.HasUnit, Bindings.STRING); Resource literalRange = graph.getPossibleObject(resource, L0.HasRange); String requiredValueType = graph.getPossibleRelatedValue(resource, L0.RequiresValueType, Bindings.STRING); //System.out.println(name + " -> " + requiredValueType); ValueAccessor accessor = graph.getPossibleRelatedValue2(resource, Layer0.getInstance(graph).valueAccessor, resource); boolean hasEnumerationRange = graph.syncRequest(new HasEnumerationRange(resource)); Collection ranges = graph.getObjects(resource, L0.HasRange); if (!ranges.isEmpty()) { for (Resource range : ranges) { if (requiredValueType == null) { // Check if the single range defines value type Collection valueTypes = graph.getAssertedObjects(range, L0.HasValueType); if (valueTypes.size() > 0) { for (Resource valueType : valueTypes) { String vt = graph.getPossibleValue(valueType, Bindings.STRING); if (vt != null && !vt.isEmpty()) { requiredValueType = vt; continue; } } } } Collection subliterals = graph.getObjects(range, L0.HasSubliteralPredicate); if(!subliterals.isEmpty()) { Map> map = new THashMap>(); for(Resource p : subliterals) { String pN = graph.getPossibleRelatedValue(p, L0.HasName, Bindings.STRING); if(pN == null) continue; if(pN.startsWith("n-")) { ChildReference r = new NameReference(pN.substring(2)); map.put(pN, Pair.make(p, r)); } else if (pN.startsWith("i-")) { ChildReference r = new IndexReference(Integer.parseInt(pN.substring(2))); map.put(pN, Pair.make(p, r)); } } return PropertyInfo.make(graph, resource, name, isFunctional, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, map, accessor, hasEnumerationRange); } } } return PropertyInfo.make(graph, resource, name, isFunctional, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, Collections.>emptyMap(), accessor, hasEnumerationRange); } @Override public boolean equals(Object object) { if (this == object) return true; else if (object == null) return false; else if (!(object instanceof PropertyInfoRequest)) return false; PropertyInfoRequest r = (PropertyInfoRequest)object; return r.resource.equals(resource); } @Override public int hashCode() { return resource.hashCode() + classHash; } private static int classHash = 31*PropertyInfo.class.hashCode(); }