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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.r.scl.variable;
\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
48 public class RDataboardConversion {
\r
49 public static Datatype getDatatype(REXP rexp) throws BindingException {
\r
50 if (rexp == null) return Datatypes.VOID;
\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
73 throw new BindingException("Cannot handle REXP of type " + rexp != null ? (rexp.getClass().getSimpleName() + ".") : "null");
\r
76 public static Object fromREXP(REXP value, Binding binding) throws BindingException {
\r
78 return binding.createDefault();
\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
96 if (dt == Datatypes.VARIANT)
\r
97 return ((VariantBinding) binding).create(Bindings.OBJECT, value);
\r
99 Binding bd = Bindings.getBinding(dt);
\r
101 return ((VariantBinding)binding).create(bd, fromREXP(value, bd));
\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
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
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
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
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
156 else if(arrayBinding.componentBinding instanceof VariantBinding) {
\r
157 if (value instanceof REXPNull || value.length() == 0)
\r
158 return arrayBinding.create();
\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
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
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
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
182 return arrayBinding.create(components);
\r
184 //TODO: Other bindings
\r
187 throw new BindingException("Couldn't handle binding " + binding + ".");
\r
188 } catch(REXPMismatchException e) {
\r
189 throw new BindingException(e);
\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
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
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
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
240 throw new BindingException("Couldn't handle binding " + binding + ".");
\r