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