package org.simantics.district.network.techtype.variable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+
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.WriteGraph;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.PossibleIndexRoot;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.AbstractChildVariable;
import org.simantics.db.layer0.variable.ValueAccessor;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.district.network.techtype.TechTypeUtils;
+import org.simantics.district.network.techtype.requests.PossibleTechTypeTable;
+import org.simantics.district.network.techtype.requests.TechTypeTableData;
import org.simantics.scl.reflection.annotations.SCLValue;
import org.simantics.structural.stubs.StructuralResource2;
TechTypeUtils.updateComponent(graph, component.getRepresents(graph));
}
+
+ @SCLValue(type = "ReadGraph -> Resource -> a -> b")
+ public static Object techTypeKeys(ReadGraph graph, Resource resource, Object context) throws DatabaseException {
+ if (!(context instanceof Variable))
+ return Collections.<String>emptyList();
+
+ Variable var = (Variable)context;
+ // Typically 'var' is <component>#<property>#HasDisplayValue#HasEnumerationValues
+ // We want the component part
+ while (!(var instanceof AbstractChildVariable))
+ var = var.getParent(graph);
+
+ Resource type = var.getType(graph, StructuralResource2.getInstance(graph).Component);
+ Resource model = var.getIndexRoot(graph);
+ if (model == null)
+ return Collections.<String>emptyList();
+ Resource table = graph.syncRequest(new PossibleTechTypeTable(model , type), TransientCacheListener.instance());
+ if (table == null)
+ return Collections.<String>emptyList();
+
+ Map<String, Map<String, String>> data = graph.syncRequest(new TechTypeTableData(table), TransientCacheListener.instance());
+ ArrayList<String> result = new ArrayList<String>(data.keySet());
+
+ // Sort so that all numbers are in growing order
+ result.sort(Functions::compareNatural);
+
+ return result;
+ }
+
+ // From https://stackoverflow.com/questions/104599/sort-on-a-string-that-may-contain-a-number
+ private static final int compareNatural(String s1, String s2) {
+ // Skip all identical characters
+ int len1 = s1.length();
+ int len2 = s2.length();
+ int i;
+ char c1, c2;
+ for (i = 0, c1 = 0, c2 = 0; (i < len1) && (i < len2) && (c1 = s1.charAt(i)) == (c2 = s2.charAt(i)); i++)
+ ;
+
+ // Check end of string
+ if (c1 == c2)
+ return (len1 - len2);
+
+ // Check digit in first string
+ if (Character.isDigit(c1)) {
+ // Check digit only in first string
+ if (!Character.isDigit(c2))
+ return (1);
+
+ // Scan all integer digits
+ int x1, x2;
+ for (x1 = i + 1; (x1 < len1) && Character.isDigit(s1.charAt(x1)); x1++)
+ ;
+ for (x2 = i + 1; (x2 < len2) && Character.isDigit(s2.charAt(x2)); x2++)
+ ;
+
+ // Longer integer wins, first digit otherwise
+ return (x2 == x1 ? c1 - c2 : x1 - x2);
+ }
+
+ // Check digit only in second string
+ if (Character.isDigit(c2))
+ return (-1);
+
+ // No digits
+ return (c1 - c2);
+ }
}