1 package org.simantics.district.network.techtype.variable;
3 import java.util.ArrayList;
4 import java.util.Collections;
7 import org.simantics.databoard.binding.Binding;
8 import org.simantics.databoard.type.Datatype;
9 import org.simantics.db.ReadGraph;
10 import org.simantics.db.Resource;
11 import org.simantics.db.WriteGraph;
12 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
13 import org.simantics.db.common.request.PossibleIndexRoot;
14 import org.simantics.db.exception.DatabaseException;
15 import org.simantics.db.layer0.variable.AbstractChildVariable;
16 import org.simantics.db.layer0.variable.ValueAccessor;
17 import org.simantics.db.layer0.variable.Variable;
18 import org.simantics.district.network.techtype.TechTypeUtils;
19 import org.simantics.district.network.techtype.requests.PossibleTechTypeTable;
20 import org.simantics.district.network.techtype.requests.TechTypeTableData;
21 import org.simantics.scl.reflection.annotations.SCLValue;
22 import org.simantics.structural.stubs.StructuralResource2;
24 public class Functions {
25 @SCLValue(type = "ValueAccessor")
26 public static final ValueAccessor techTypeCodeValueAccessor = new ValueAccessor() {
29 public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
30 return org.simantics.db.layer0.function.All.standardValueAccessor.getValue(graph, context);
34 public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {
35 return org.simantics.db.layer0.function.All.standardValueAccessor.getValue(graph, context, binding);
39 public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {
40 org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, value);
42 updateComponentProperties(graph, context, value);
46 public void setValue(WriteGraph graph, Variable context, Object value, Binding binding)
47 throws DatabaseException {
48 org.simantics.db.layer0.function.All.standardValueAccessor.setValue(graph, context, value, binding);
50 updateComponentProperties(graph, context, value);
54 public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {
55 return org.simantics.db.layer0.function.All.standardValueAccessor.getDatatype(graph, context);
60 protected static void updateComponentProperties(WriteGraph graph, Variable context, Object value) throws DatabaseException {
61 Variable component = context.getParent(graph);
62 Resource type = component.getPossibleType(graph, StructuralResource2.getInstance(graph).Component);
66 TechTypeUtils.updateComponent(graph, component.getRepresents(graph));
69 @SCLValue(type = "ReadGraph -> Resource -> a -> b")
70 public static Object techTypeKeys(ReadGraph graph, Resource resource, Object context) throws DatabaseException {
71 if (!(context instanceof Variable))
72 return Collections.<String>emptyList();
74 Variable var = (Variable)context;
75 // Typically 'var' is <component>#<property>#HasDisplayValue#HasEnumerationValues
76 // We want the component part
77 while (!(var instanceof AbstractChildVariable))
78 var = var.getParent(graph);
80 Resource type = var.getType(graph, StructuralResource2.getInstance(graph).Component);
81 Resource model = var.getIndexRoot(graph);
83 return Collections.<String>emptyList();
84 Resource table = graph.syncRequest(new PossibleTechTypeTable(model , type), TransientCacheListener.instance());
86 return Collections.<String>emptyList();
88 Map<String, Map<String, String>> data = graph.syncRequest(new TechTypeTableData(table), TransientCacheListener.instance());
89 ArrayList<String> result = new ArrayList<String>(data.keySet());
91 // Sort so that all numbers are in growing order
92 result.sort(Functions::compareNatural);
97 // From https://stackoverflow.com/questions/104599/sort-on-a-string-that-may-contain-a-number
98 private static final int compareNatural(String s1, String s2) {
99 // Skip all identical characters
100 int len1 = s1.length();
101 int len2 = s2.length();
104 for (i = 0, c1 = 0, c2 = 0; (i < len1) && (i < len2) && (c1 = s1.charAt(i)) == (c2 = s2.charAt(i)); i++)
107 // Check end of string
109 return (len1 - len2);
111 // Check digit in first string
112 if (Character.isDigit(c1)) {
113 // Check digit only in first string
114 if (!Character.isDigit(c2))
117 // Scan all integer digits
119 for (x1 = i + 1; (x1 < len1) && Character.isDigit(s1.charAt(x1)); x1++)
121 for (x2 = i + 1; (x2 < len2) && Character.isDigit(s2.charAt(x2)); x2++)
124 // Longer integer wins, first digit otherwise
125 return (x2 == x1 ? c1 - c2 : x1 - x2);
128 // Check digit only in second string
129 if (Character.isDigit(c2))