]> gerrit.simantics Code Review - simantics/r.git/blob - org.simantics.r.scl/src/org/simantics/r/scl/variable/RDataboardConversion.java
Share project "org.simantics.r.feature" into "https://www.simantics.org/svn/simantics"
[simantics/r.git] / org.simantics.r.scl / src / org / simantics / r / scl / variable / RDataboardConversion.java
1 package org.simantics.r.scl.variable;\r
2 \r
3 import org.rosuda.REngine.REXP;\r
4 import org.rosuda.REngine.REXPDouble;\r
5 import org.rosuda.REngine.REXPFactor;\r
6 import org.rosuda.REngine.REXPGenericVector;\r
7 import org.rosuda.REngine.REXPInteger;\r
8 import org.rosuda.REngine.REXPList;\r
9 import org.rosuda.REngine.REXPLogical;\r
10 import org.rosuda.REngine.REXPMismatchException;\r
11 import org.rosuda.REngine.REXPNull;\r
12 import org.rosuda.REngine.REXPRaw;\r
13 import org.rosuda.REngine.REXPReference;\r
14 import org.rosuda.REngine.REXPS4;\r
15 import org.rosuda.REngine.REXPString;\r
16 import org.rosuda.REngine.REXPSymbol;\r
17 import org.rosuda.REngine.RList;\r
18 import org.simantics.databoard.Bindings;\r
19 import org.simantics.databoard.Datatypes;\r
20 import org.simantics.databoard.binding.ArrayBinding;\r
21 import org.simantics.databoard.binding.Binding;\r
22 import org.simantics.databoard.binding.BooleanBinding;\r
23 import org.simantics.databoard.binding.ByteBinding;\r
24 import org.simantics.databoard.binding.DoubleBinding;\r
25 import org.simantics.databoard.binding.IntegerBinding;\r
26 import org.simantics.databoard.binding.NumberBinding;\r
27 import org.simantics.databoard.binding.StringBinding;\r
28 import org.simantics.databoard.binding.VariantBinding;\r
29 import org.simantics.databoard.binding.error.BindingException;\r
30 import org.simantics.databoard.binding.impl.BooleanArrayBinding;\r
31 import org.simantics.databoard.binding.impl.ByteArrayBinding;\r
32 import org.simantics.databoard.binding.impl.DoubleArrayBinding;\r
33 import org.simantics.databoard.binding.impl.IntArrayBinding;\r
34 import org.simantics.databoard.binding.impl.StringArrayBinding;\r
35 import org.simantics.databoard.type.Datatype;\r
36 \r
37 public class RDataboardConversion {\r
38     public static Datatype getDatatype(REXP rexp) throws BindingException {\r
39         if (rexp == null) return Datatypes.VOID;\r
40         \r
41         if(rexp instanceof REXPDouble)\r
42             return Datatypes.DOUBLE_ARRAY;\r
43         else if(rexp instanceof REXPInteger)\r
44             return Datatypes.INTEGER_ARRAY;\r
45         else if(rexp instanceof REXPString)\r
46             return Datatypes.STRING_ARRAY;\r
47         else if(rexp instanceof REXPLogical)\r
48                 return Datatypes.BOOLEAN_ARRAY;\r
49         else if(rexp instanceof REXPSymbol)\r
50                 return Datatypes.STRING;\r
51         else if(rexp instanceof REXPFactor)\r
52                 return Datatypes.STRING_ARRAY;\r
53         else if(rexp instanceof REXPRaw)\r
54                 return Datatypes.BYTE_ARRAY;\r
55         else if(rexp instanceof REXPReference)\r
56                 return getDatatype(((REXPReference)rexp).resolve());\r
57         else if(rexp instanceof REXPList || rexp instanceof REXPNull || rexp instanceof REXPGenericVector)\r
58                 return Datatypes.VARIANT_ARRAY;\r
59         else if(rexp instanceof REXPS4)\r
60                 return Datatypes.VARIANT;\r
61                 else\r
62             throw new BindingException("Cannot handle REXP of type " + rexp != null ? (rexp.getClass().getSimpleName() + ".") : "null");\r
63     }\r
64 \r
65     public static Object fromREXP(REXP value, Binding binding) throws BindingException {\r
66         if (value == null)\r
67                 return binding.createDefault();\r
68         \r
69         try {\r
70             if(binding instanceof DoubleBinding)\r
71                 return ((DoubleBinding)binding).create(value.asDouble());\r
72             else if(binding instanceof IntegerBinding)\r
73                 return ((IntegerBinding)binding).create(value.asInteger());\r
74             else if(binding instanceof ByteBinding)\r
75                 return ((ByteBinding)binding).create(value.asInteger());\r
76             else if(binding instanceof StringBinding)\r
77                 return ((StringBinding)binding).create(value.asString());\r
78             else if(binding instanceof NumberBinding)\r
79                 return ((NumberBinding)binding).create(value.asDouble());\r
80             else if(binding instanceof BooleanBinding)\r
81                 return ((BooleanBinding)binding).create(value.asInteger() == 1);\r
82             else if(binding instanceof VariantBinding) {\r
83                 Datatype dt = getDatatype(value);\r
84                 if (dt != null) {\r
85                         if (dt == Datatypes.VARIANT)\r
86                                 return ((VariantBinding) binding).create(Bindings.OBJECT, value);\r
87                         else {\r
88                                 Binding bd = Bindings.getBinding(dt);\r
89                                 if (bd != null) {\r
90                                         return ((VariantBinding)binding).create(bd, fromREXP(value, bd));\r
91                                 }\r
92                         }\r
93                 }\r
94             }\r
95             else if(binding instanceof ArrayBinding) {\r
96                 if(binding instanceof DoubleArrayBinding)\r
97                     return value.asDoubles();\r
98                 else if(binding instanceof ByteArrayBinding)\r
99                     return value.asBytes();\r
100                 else if(binding instanceof IntArrayBinding)\r
101                     return value.asIntegers();\r
102                 else if(binding instanceof StringArrayBinding)\r
103                     return value.asStrings();\r
104                 else if(binding instanceof BooleanArrayBinding) {\r
105                         int[] values = value.asIntegers();\r
106                         boolean[] result = new boolean[values.length];\r
107                         for (int i = 0; i < values.length; i++)\r
108                                 result[i] = values[i] == 1;\r
109                         return result;\r
110                 }\r
111                 \r
112                 ArrayBinding arrayBinding = (ArrayBinding)binding;\r
113                 if(arrayBinding.componentBinding instanceof DoubleBinding) {\r
114                     DoubleBinding componentBinding = (DoubleBinding)arrayBinding.componentBinding;\r
115                     double[] vs = value.asDoubles();\r
116                     Object[] components = new Object[vs.length];\r
117                     for(int i=0;i<vs.length;++i)\r
118                         components[i] = componentBinding.create(vs[i]);\r
119                     return arrayBinding.create(components);\r
120                 }\r
121                 else if(arrayBinding.componentBinding instanceof IntegerBinding) {\r
122                     IntegerBinding componentBinding = (IntegerBinding)arrayBinding.componentBinding;\r
123                     int[] vs = value.asIntegers();\r
124                     Object[] components = new Object[vs.length];\r
125                     for(int i=0;i<vs.length;++i)\r
126                         components[i] = componentBinding.create(vs[i]);\r
127                     return arrayBinding.create(components);\r
128                 }\r
129                 else if(arrayBinding.componentBinding instanceof StringBinding) {\r
130                     StringBinding componentBinding = (StringBinding)arrayBinding.componentBinding;\r
131                     String[] vs = value.asStrings();\r
132                     Object[] components = new Object[vs.length];\r
133                     for(int i=0;i<vs.length;++i)\r
134                         components[i] = componentBinding.create(vs[i]);\r
135                     return arrayBinding.create(components);\r
136                 }\r
137                 else if(arrayBinding.componentBinding instanceof NumberBinding) {\r
138                     NumberBinding componentBinding = (NumberBinding)arrayBinding.componentBinding;\r
139                     double[] vs = value.asDoubles();\r
140                     Object[] components = new Object[vs.length];\r
141                     for(int i=0;i<vs.length;++i)\r
142                         components[i] = componentBinding.create(vs[i]);\r
143                     return arrayBinding.create(components);\r
144                 }\r
145                 else if(arrayBinding.componentBinding instanceof VariantBinding) {\r
146                         if (value instanceof REXPNull || value.length() == 0)\r
147                                 return arrayBinding.create();\r
148                         \r
149                         VariantBinding componentBinding = (VariantBinding)arrayBinding.componentBinding;\r
150                         Object[] components = new Object[value.length()];\r
151                         if (value.isInteger()) {\r
152                                 int[] vs = value.asIntegers();\r
153                                 for (int i=0; i<vs.length; i++)\r
154                                         components[i] = componentBinding.create(Bindings.INTEGER, vs[i]);\r
155                         }\r
156                         else if (value.isNumeric()) {\r
157                                 double[] vs = value.asDoubles();\r
158                                 for (int i=0; i<vs.length; i++)\r
159                                         components[i] = componentBinding.create(Bindings.DOUBLE, vs[i]);\r
160                         }\r
161                         else if (value.isString()) {\r
162                                 String[] vs = value.asStrings();\r
163                                 for (int i=0; i<vs.length; i++)\r
164                                         components[i] = componentBinding.create(Bindings.STRING, vs[i]);\r
165                         }\r
166                         else if (value.isList()) {\r
167                                 RList vs = value.asList();\r
168                                 for (int i=0; i<vs.size(); i++)\r
169                                         components[i] = fromREXP(vs.at(i), componentBinding);\r
170                         }\r
171                         return arrayBinding.create(components);\r
172                 }\r
173                 //TODO: Other bindings\r
174             }\r
175             \r
176             throw new BindingException("Couldn't handle binding " + binding + ".");\r
177         } catch(REXPMismatchException e) {\r
178             throw new BindingException(e);\r
179         }\r
180     }\r
181 \r
182     public static REXP toREXP(Object value, Binding binding) throws BindingException {\r
183         if(binding instanceof DoubleBinding)\r
184             return new REXPDouble(((DoubleBinding)binding).getValue_(value));\r
185         else if(binding instanceof IntegerBinding)\r
186             return new REXPInteger(((IntegerBinding)binding).getValue_(value));\r
187         else if(binding instanceof StringBinding)\r
188             return new REXPString(((StringBinding)binding).getValue(value));\r
189         else if(binding instanceof NumberBinding)\r
190             return new REXPDouble(((NumberBinding)binding).getValue(value).doubleValue());\r
191         else if(binding instanceof ArrayBinding) {\r
192             if(binding instanceof DoubleArrayBinding)\r
193                 return new REXPDouble((double[])value);\r
194             else if(binding instanceof IntArrayBinding)\r
195                 return new REXPInteger((int[])value);\r
196             else if(binding instanceof StringArrayBinding)\r
197                 return new REXPString((String[])value);\r
198             ArrayBinding arrayBinding = (ArrayBinding)binding;\r
199             if(arrayBinding.componentBinding instanceof DoubleBinding) {\r
200                 DoubleBinding componentBinding = (DoubleBinding)arrayBinding.componentBinding;\r
201                 double[] vs = new double[arrayBinding.size(value)];\r
202                 for(int i=0;i<vs.length;++i)\r
203                     vs[i] = componentBinding.getValue_(arrayBinding.get(value, i));\r
204                 return new REXPDouble(vs);\r
205             }\r
206             if(arrayBinding.componentBinding instanceof IntegerBinding) {\r
207                 IntegerBinding componentBinding = (IntegerBinding)arrayBinding.componentBinding;\r
208                 int[] vs = new int[arrayBinding.size(value)];\r
209                 for(int i=0;i<vs.length;++i)\r
210                     vs[i] = componentBinding.getValue_(arrayBinding.get(value, i));\r
211                 return new REXPInteger(vs);\r
212             }\r
213             if(arrayBinding.componentBinding instanceof StringBinding) {\r
214                 StringBinding componentBinding = (StringBinding)arrayBinding.componentBinding;\r
215                 String[] vs = new String[arrayBinding.size(value)];\r
216                 for(int i=0;i<vs.length;++i)\r
217                     vs[i] = componentBinding.getValue(arrayBinding.get(value, i));\r
218                 return new REXPString(vs);\r
219             }\r
220             if(arrayBinding.componentBinding instanceof NumberBinding) {\r
221                 NumberBinding componentBinding = (NumberBinding)arrayBinding.componentBinding;\r
222                 double[] vs = new double[arrayBinding.size(value)];\r
223                 for(int i=0;i<vs.length;++i)\r
224                     vs[i] = componentBinding.getValue(arrayBinding.get(value, i)).doubleValue();\r
225                 return new REXPDouble(vs);\r
226             }\r
227         }\r
228         \r
229         throw new BindingException("Couldn't handle binding " + binding + ".");\r
230     }\r
231 }\r