]> gerrit.simantics Code Review - simantics/r.git/blob - bundles/org.simantics.r.scl/src/org/rosuda/REngine/REXPGenericVector.java
(refs #6833) Test RExp inheritance in SCL
[simantics/r.git] / bundles / org.simantics.r.scl / src / org / rosuda / REngine / REXPGenericVector.java
1 package org.rosuda.REngine;
2 import java.util.Vector;
3 import java.util.HashMap;
4
5 /** REXPGenericVector represents a generic vector in R. Its elements can be typically of any {@link REXP} type. */
6 public class REXPGenericVector extends REXPVector {
7         /** payload */
8         public RList payload;
9         
10         /** creates a new generic vector from a list. If the list is named, the <code>"names"</code> attribute is created automatically from it.
11          *  @param list list to create the vector from */
12         public REXPGenericVector(RList list) {
13                 super();
14                 payload=(list==null)?new RList():list;
15                 // automatically generate 'names' attribute
16                 if (payload.isNamed())
17                         attr = new REXPList(
18                                 new RList(new REXP[] { new REXPString(payload.keys()) },
19                                                   new String[] { "names" }));
20         }
21         
22         /** creates a new generic vector from a list. Note that the names in the list are ignored as they are expected to be defined by the attributes parameter.
23          *  @param list list to create the vector from (names are ignored - use {@link #REXPGenericVector(RList)} or the <code>"names"</code> attribute for named lists
24          *  @param attr attributes */
25         public REXPGenericVector(RList list, REXPList attr) {
26                 super(attr);
27                 payload=(list==null)?new RList():list;
28         }
29
30         /* generic vectors are converted either to a <code>Map</code> (if it is a named vector and there are no duplicate names) or a <code>Vector</code>. The contained elements are converted using <code>asNativeJavaObject</code> recursively. */
31         public Object asNativeJavaObject() throws REXPMismatchException {
32                 // we need to convert the inside as well
33                 int n = payload.size();
34
35                 // named list -> map but only if
36                 //  a) all names are present
37                 //  b) there are no duplicates in the names
38                 if (payload.isNamed()) {
39                         String[] names = payload.keys();
40                         if (names.length == n) {
41                                 HashMap map = new HashMap();
42                                 boolean valid = true;
43                                 for (int i = 0; i < n; i++) {
44                                         if (map.containsKey(names[i])) {
45                                                 valid = false;
46                                                 break;
47                                         }
48                                         Object value = payload.elementAt(i);
49                                         if (value != null)
50                                                 value = ((REXP) value).asNativeJavaObject();
51                                         map.put(value, names[i]);
52                                 }
53                                 if (valid)
54                                         return map;
55                         }
56                 }
57
58                 // otherwise drop names and use just a vector
59                 Vector v = new Vector();
60                 for (int i = 0; i < n; i++) {
61                         Object value = payload.elementAt(i);
62                         if (value != null)
63                                 value = ((REXP) value).asNativeJavaObject();
64                         v.addElement(value);
65                 }
66
67                 return v;
68         }
69         
70         public int length() { return payload.size(); }
71
72         public boolean isList() { return true; }
73
74         public boolean isRecursive() { return true; }
75
76         public RList asList() { return payload; }
77         
78         public String toString() {
79                 return super.toString()+(asList().isNamed()?"named":"");
80         }
81
82         public String toDebugString() {
83                 StringBuffer sb = new StringBuffer(super.toDebugString()+"{");
84                 int i = 0;
85                 while (i < payload.size() && i < maxDebugItems) {
86                         if (i>0) sb.append(",\n");
87                         sb.append(payload.at(i).toDebugString());
88                         i++;
89                 }
90                 if (i < payload.size()) sb.append(",..");
91                 return sb.toString()+"}";
92         }
93 }