String formatter property using SCL function instead of adapter
[simantics/platform.git] / bundles / org.simantics.selectionview / src / org / simantics / selectionview / DisplayValueVariableAdapter.java
1 package org.simantics.selectionview;
2
3 import java.io.IOException;
4
5 import org.simantics.common.format.Formatter;
6 import org.simantics.databoard.Bindings;
7 import org.simantics.databoard.Datatypes;
8 import org.simantics.databoard.adapter.AdaptException;
9 import org.simantics.databoard.binding.Binding;
10 import org.simantics.databoard.binding.NumberBinding;
11 import org.simantics.databoard.binding.StringBinding;
12 import org.simantics.databoard.binding.error.BindingConstructionException;
13 import org.simantics.databoard.binding.error.BindingException;
14 import org.simantics.databoard.binding.mutable.MutableStringBinding;
15 import org.simantics.databoard.parser.DataValuePrinter;
16 import org.simantics.databoard.parser.repository.DataTypeSyntaxError;
17 import org.simantics.databoard.parser.repository.DataValueRepository;
18 import org.simantics.databoard.primitives.MutableString;
19 import org.simantics.databoard.type.Datatype;
20 import org.simantics.databoard.util.ObjectUtils;
21 import org.simantics.db.ReadGraph;
22 import org.simantics.db.Resource;
23 import org.simantics.db.WriteGraph;
24 import org.simantics.db.common.CommentMetadata;
25 import org.simantics.db.common.adaption.SimpleContextualAdapter;
26 import org.simantics.db.exception.DatabaseException;
27 import org.simantics.db.layer0.util.Layer0Utils;
28 import org.simantics.db.layer0.variable.ModelledVariablePropertyDescriptor;
29 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
30 import org.simantics.db.layer0.variable.Variable;
31 import org.simantics.db.layer0.variable.Variables;
32 import org.simantics.layer0.Layer0;
33 import org.simantics.modeling.ModelingResources;
34 import org.simantics.scl.runtime.function.Function1;
35
36 public class DisplayValueVariableAdapter extends SimpleContextualAdapter<Variable, ModelledVariablePropertyDescriptor> {
37         
38         final String key;
39         
40         public DisplayValueVariableAdapter() {
41                 key = SelectionViewResources.URIs.HasDisplayValue;
42         }
43
44         public DisplayValueVariableAdapter(String key) {
45                 this.key = key;
46         }
47
48         class Impl extends StandardGraphPropertyVariable {
49
50                 private Datatype datatype;
51
52                 public Impl(ReadGraph graph, Variable parent, Resource parentResource, Datatype datatype) throws DatabaseException {
53                         super(graph, parent, null, parentResource, graph.getResource(key));
54                         this.datatype = datatype;
55                 }
56                 
57                 @SuppressWarnings("unchecked")
58                 @Override
59                 public <T> T getValue(ReadGraph graph) throws DatabaseException {
60                         return (T)standardGetDisplayValue1(graph, this);
61                 }
62                 
63                 @SuppressWarnings("unchecked")
64                 @Override
65                 public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {
66                         return (T)standardGetDisplayValue2(graph, this, binding);
67                 }
68                 
69                 @Override
70                 public Datatype getDatatype(ReadGraph graph) throws DatabaseException {
71                         return datatype;
72                 }
73                         
74                 @Override
75                 public void setValue(WriteGraph graph, Object value) throws DatabaseException {
76                         standardSetDisplayValue2(graph, this, value);
77                 }
78                 
79
80                 @Override
81                 public void setValue(WriteGraph graph, Object _value, Binding _binding) throws DatabaseException {
82                         standardSetDisplayValue3(graph, this, _value, _binding);
83                 }
84                 
85         }
86         
87         public static boolean isPrimitive(Datatype dt) {
88                 if(Datatypes.STRING.equals(dt)) return true;
89                 else return false;
90         }
91
92         private static String possibleExpression(ReadGraph graph, Variable variable) throws DatabaseException {
93                 
94                 Layer0 L0 = Layer0.getInstance(graph);
95                 ModelingResources MOD = ModelingResources.getInstance(graph);
96                 Resource object = variable.getPossibleRepresents(graph);
97                 if(object != null && graph.isInstanceOf(object, MOD.SCLValue)) {
98                         String expression = graph.getPossibleRelatedValue(object, L0.SCLValue_expression);
99                         if (expression != null)
100                                 return "=" + expression;
101                 }
102                 return null;
103                 
104         }
105
106         @Override
107         public Variable adapt(ReadGraph graph, Resource source, ModelledVariablePropertyDescriptor context) throws DatabaseException {
108                 
109 //      String value = getDisplayValue(graph, context.getVariable());
110         return new Impl(graph, context.getVariable(), context.getSubject(), Datatypes.STRING);
111                 
112         }
113
114     public static Object standardGetDisplayValue1(ReadGraph graph, Variable property_) throws DatabaseException {
115
116         Variable property = property_.getParent(graph); 
117         
118         String expression = possibleExpression(graph, property);
119         if(expression != null) return expression;
120         
121         Object value = null;
122
123         Resource formatter = property.getPossiblePropertyValue(graph, Variables.FORMATTER);
124         if(formatter != null) {
125                 Formatter fmt = graph.adaptContextual(formatter, property, Variable.class, Formatter.class);
126                 value = fmt.format(property.getValue(graph));
127         }
128         if(value == null) {
129                 SelectionViewResources SEL = SelectionViewResources.getInstance(graph);
130                 Function1<Object,String> formatterFunction = property.getPossiblePropertyValue(graph, SEL.formatter);
131                 if(formatterFunction != null) {
132                         value = formatterFunction.apply(property.getValue(graph)); 
133                 }
134         }
135         if(value == null) {
136
137                 Datatype dt = property.getPossibleDatatype(graph);
138                 if(dt != null) {
139                         if(!isPrimitive(dt)) {
140                                 Binding binding = Bindings.getBinding(dt);
141                                 try {
142                                         value = DataValuePrinter.writeValueSingleLine(binding, property.getValue(graph));
143                                 } catch (IOException e) {
144                                         e.printStackTrace();
145                                 } catch (BindingException e) {
146                                         e.printStackTrace();
147                                 }
148                         }
149                 }
150
151         }
152
153         return value != null ? value.toString() : "null";
154         
155     }
156
157     public static Object standardGetDisplayValue2(ReadGraph graph, Variable property, Binding binding) throws DatabaseException {
158         
159                 try {
160                         return Bindings.adapt(standardGetDisplayValue1(graph, property), Bindings.STRING, binding);
161                 } catch (AdaptException e) {
162                         throw new DatabaseException(e);
163                 }
164         
165     }
166
167     public static void standardSetDisplayValue2(WriteGraph graph, Variable property_, Object _value) throws DatabaseException {
168                         
169                 try {
170                         Binding binding = Bindings.getBinding(_value.getClass());
171                         standardSetDisplayValue3(graph, property_, _value, binding);
172                 } catch (BindingConstructionException e) {
173                         throw new DatabaseException(e);
174                 }
175
176     }
177
178     public static void standardSetDisplayValue3(WriteGraph graph, Variable property_, Object _value, Binding binding_) throws DatabaseException {
179
180         try {
181                 
182                 Variable parent = property_.getParent(graph);
183                 
184                         if(!(_value instanceof String)) throw new DatabaseException("setValue for HasDisplayValue only accepts String (got " + _value.getClass().getSimpleName() + ")");
185
186                         String text = (String)_value;
187                         if(text.startsWith("=")) {
188                             Layer0Utils.setExpression(graph, parent, text, ModelingResources.getInstance(graph).SCLValue);
189                                 return;
190                         }
191
192                 String parsedLabel = (String)_value;
193             Object value = parsedLabel;
194                 
195             Datatype type = parent.getPossibleDatatype(graph);
196             if (type != null) {
197
198                     Binding binding = Bindings.getBinding(type);
199
200                     if (binding instanceof StringBinding) {
201                         
202                         if (binding instanceof MutableStringBinding)
203                             value = new MutableString(parsedLabel);
204                         else
205                             value = parsedLabel;
206                         
207                     } else {
208                         
209                         if (binding instanceof NumberBinding) {
210                             parsedLabel = parsedLabel.replace(",", ".");
211                         }
212
213                         value = binding.parseValue(parsedLabel, new DataValueRepository());
214                     }
215
216                     //System.out.println("VariableWrite " + ObjectUtils.toString(value));
217                     parent.setValue(graph, value, binding);
218                     
219             } else {
220
221                 parent.setValue(graph, value);
222                 
223             }
224
225
226             // Add a comment to metadata.
227             CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
228             graph.addMetadata(cm.add("Set value " + ObjectUtils.toString(value)));
229             
230         } catch (DataTypeSyntaxError e) {
231             throw new DatabaseException(e);
232         } catch (BindingException e) {
233             throw new DatabaseException(e);
234         }
235         
236     }
237
238     public static Datatype standardGetDisplayValueDatatype(ReadGraph graph, Variable property_) throws DatabaseException {
239         return Datatypes.STRING;
240     }
241         
242 }