Adding early version of IoT RMI system; for now: 1) Connects Java to Java; 2) Transla...
[iot2.git] / iotjava / iotrmi / Java / IoTRMIUtil.java
1 package iotrmi.Java;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.IOException;
6 import java.io.ObjectInputStream;
7 import java.io.ObjectOutputStream;
8 import java.nio.ByteBuffer;
9 import java.util.Arrays;
10 import java.util.HashMap;
11 import java.util.Map;
12 import java.lang.reflect.Method;
13
14 import iotrmi.IoTRMITypes;
15
16 /** Class IoTRMI provides utility services.
17  *  <p>
18  *  It provides miscellaneous (data type/value) translations.
19  *
20  * @author      Rahmadi Trimananda <rtrimana @ uci.edu>
21  * @version     1.0
22  * @since       2016-10-04
23  */
24 public class IoTRMIUtil {
25
26         /**
27          * Class Properties
28          */
29         private Map<String,String> mapPrimitives;
30         private Map<String,Integer> mapPrimitiveSizesJava;
31         private Map<String,Integer> mapPrimitiveSizesCplus;
32         private Map<String,String> mapNonPrimitives;
33
34         /**
35          * Class Constants
36          */
37         public final static int METHOD_ID_LEN = 4;      // 4 bytes = 32 bits
38         public final static int PARAM_LEN = 4;          // 4 bytes = 32 bits (4-byte field that stores the length of the param)
39
40         /**
41          * Constructors
42          */
43         public IoTRMIUtil() {
44
45                 mapPrimitives = new HashMap<String,String>();
46                         IoTRMITypes.arraysToMap(mapPrimitives, 
47                                 IoTRMITypes.primitivesJava, IoTRMITypes.primitivesCplus);
48                 mapPrimitiveSizesJava = new HashMap<String,Integer>();
49                         IoTRMITypes.arraysToMap(mapPrimitiveSizesJava, 
50                                 IoTRMITypes.primitivesJava, IoTRMITypes.primitivesJavaSizes);
51                 mapPrimitiveSizesCplus = new HashMap<String,Integer>();
52                         IoTRMITypes.arraysToMap(mapPrimitiveSizesCplus, 
53                                 IoTRMITypes.primitivesCplus, IoTRMITypes.primitivesCplusSizes);
54                 mapNonPrimitives = new HashMap<String,String>();
55                         IoTRMITypes.arraysToMap(mapNonPrimitives, 
56                                 IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus);
57         }
58
59
60         /**
61          * getSignature() gets method signature, i.e. type, identifier, parameters
62          */
63         public String getSignature(Method m) {
64
65                 String retType = translateType(m.getReturnType().getSimpleName());
66                 String signature = retType + 
67                         m.getName() + "(";
68                 Class<?>[] clsParam = m.getParameterTypes();
69                 for (int i = 0; i < clsParam.length; i++) {
70                         String paramType = translateType(clsParam[i].getSimpleName());
71                         signature = signature + paramType;
72                         if (i < clsParam.length - 1) {
73                                 signature = signature + ",";
74                         }
75                 }
76                 signature = signature + ")";
77                 return signature;
78         }
79
80
81         /**
82          * getHashCodeBytes() gets hash value (in bytes) from method name
83          */
84         public static byte[] getHashCodeBytes(String string) {
85
86                 int hash = string.hashCode();
87                 byte[] hashBytes = ByteBuffer.allocate(4).putInt(hash).array();
88                 return hashBytes;
89         }
90
91
92         /**================
93          * Helper methods
94          **================
95          */
96         /**
97          * translateType() try to translate a type
98          * <p>
99          * It returns the original type when fails.
100          */
101         public String translateType(String type) {
102
103                 if (mapPrimitives.containsKey(type))
104                         return mapPrimitives.get(type);
105                 else if (mapNonPrimitives.containsKey(type))
106                         return mapNonPrimitives.get(type);
107                 else
108                         return type;
109         }
110
111
112         /**
113          * getTypeSize() gets the size of a type
114          *
115          */
116         public int getTypeSize(String type) {
117
118                 if (mapPrimitiveSizesJava.containsKey(type))
119                         return mapPrimitiveSizesJava.get(type);
120                 else if (mapPrimitiveSizesCplus.containsKey(type))
121                         return mapPrimitiveSizesCplus.get(type);
122                 else
123                         return -1; // Size is unknown
124         }
125         
126         
127         /**
128          * getParamObject() converts byte array of certain object type into Object
129          */
130         public static Object getParamObject(String type, byte[] paramBytes) {
131                 
132                 Object retObj = null;
133                 if (type.equals("byte") ||
134                         type.equals("Byte")) {
135                         retObj = (Object) paramBytes[0];
136                 } else if (     type.equals("short") ||
137                                         type.equals("Short")) {
138                         retObj = (Object) byteArrayToShort(paramBytes);
139                 } else if (     type.equals("int") ||
140                                         type.equals("Integer")) {
141                         retObj = (Object) byteArrayToInt(paramBytes);
142                 } else if (     type.equals("long") ||
143                                         type.equals("Long")) {
144                         retObj = (Object) byteArrayToLong(paramBytes);
145                 } else if (     type.equals("float") ||
146                                         type.equals("Float")) {
147                         retObj = (Object) byteArrayToFloat(paramBytes);
148                 } else if (     type.equals("double") ||
149                                         type.equals("Double")) {
150                         retObj = (Object) byteArrayToDouble(paramBytes);
151                 } else if (     type.equals("boolean") ||
152                                         type.equals("Boolean")) {
153                         retObj = (Object) byteArrayToBoolean(paramBytes);
154                 } else if (     type.equals("char") ||
155                                         type.equals("Character")) {
156                         retObj = (Object) byteArrayToChar(paramBytes);
157                 } else if (type.equals("String")) {
158                         retObj = (Object) toString(paramBytes);
159                 } else
160                         throw new Error("IoTRMIUtil: Unrecognizable type: " + type);
161                 
162                 return retObj;
163         }
164
165
166         /**
167          * getObjectBytes() converts an object into byte array
168          */
169         public static byte[] getObjectBytes(Object obj) {
170                 
171                 byte[] retObjBytes = null;
172                 if (obj instanceof Byte) {
173                         retObjBytes = (byte[]) obj;
174                 } else if (obj instanceof Short) {
175                         retObjBytes = shortToByteArray((short) obj);
176                 } else if (obj instanceof Integer) {
177                         retObjBytes = intToByteArray((int) obj);
178                 } else if (obj instanceof Long) {
179                         retObjBytes = longToByteArray((long) obj);
180                 } else if (obj instanceof Float) {
181                         retObjBytes = floatToByteArray((float) obj);
182                 } else if (obj instanceof Double) {
183                         retObjBytes = doubleToByteArray((double) obj);
184                 } else if (obj instanceof Character) {
185                         retObjBytes = charToByteArray((char) obj);
186                 } else if (obj instanceof Boolean) {
187                         retObjBytes = booleanToByteArray((boolean) obj);
188                 } else if (obj instanceof String) {
189                         retObjBytes = ((String) obj).getBytes();
190                 } else
191                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj);
192
193                 return retObjBytes;
194         }
195         
196
197         /**
198          * Converters to byte array
199          */
200         // Single variables
201         public static byte[] shortToByteArray(short s) {
202
203                 ByteBuffer bb = ByteBuffer.allocate(2);
204                 bb.putShort(s);
205
206                 return bb.array();
207         }
208
209
210         public static byte[] intToByteArray(int i) {
211
212                 ByteBuffer bb = ByteBuffer.allocate(4);
213                 bb.putInt(i);
214
215                 return bb.array();
216         }
217
218
219         public static byte[] longToByteArray(long l) {
220
221                 ByteBuffer bb = ByteBuffer.allocate(8);
222                 bb.putLong(l);
223
224                 return bb.array();
225         }
226
227
228         public static byte[] floatToByteArray(float f) {
229
230                 ByteBuffer bb = ByteBuffer.allocate(4);
231                 bb.putFloat(f);
232
233                 return bb.array();
234         }
235
236
237         public static byte[] doubleToByteArray(double d) {
238
239                 ByteBuffer bb = ByteBuffer.allocate(8);
240                 bb.putDouble(d);
241
242                 return bb.array();
243         }
244
245
246         public static byte[] charToByteArray(char c) {
247
248                 ByteBuffer bb = ByteBuffer.allocate(2);
249                 bb.putChar(c);
250
251                 return bb.array();
252         }
253
254
255         public static byte[] booleanToByteArray(boolean b) {
256
257                 ByteBuffer bb = ByteBuffer.allocate(1);
258                 if (b)
259                         bb.put((byte)1);
260                 else
261                         bb.put((byte)0);
262
263                 return bb.array();
264         }
265
266
267         // Arrays
268         public static byte[] arrShortToByteArray(short[] arrShort) {
269
270                 ByteBuffer bb = ByteBuffer.allocate(2 * arrShort.length);
271                 for(short s : arrShort) {
272                         bb.putShort(s);
273                 }
274
275                 return bb.array();
276         }
277
278
279         public static byte[] arrIntToByteArray(int[] arrInt) {
280
281                 ByteBuffer bb = ByteBuffer.allocate(4 * arrInt.length);
282                 for(int i : arrInt) {
283                         bb.putInt(i);
284                 }
285
286                 return bb.array();
287         }
288
289
290         public static byte[] arrLongToByteArray(long[] arrLong) {
291
292                 ByteBuffer bb = ByteBuffer.allocate(8 * arrLong.length);
293                 for(long l : arrLong) {
294                         bb.putLong(l);
295                 }
296
297                 return bb.array();
298         }
299
300
301         public static byte[] arrFloatToByteArray(float[] arrFloat) {
302
303                 ByteBuffer bb = ByteBuffer.allocate(4 * arrFloat.length);
304                 for(float f : arrFloat) {
305                         bb.putFloat(f);
306                 }
307
308                 return bb.array();
309         }
310
311
312         public static byte[] arrDoubleToByteArray(double[] arrDouble) {
313
314                 ByteBuffer bb = ByteBuffer.allocate(8 * arrDouble.length);
315                 for(double d : arrDouble) {
316                         bb.putDouble(d);
317                 }
318
319                 return bb.array();
320         }
321
322
323         public static byte[] arrCharToByteArray(char[] arrChar) {
324
325                 ByteBuffer bb = ByteBuffer.allocate(2 * arrChar.length);
326                 for(char c : arrChar) {
327                         bb.putChar(c);
328                 }
329
330                 return bb.array();
331         }
332
333
334         public static byte[] arrBooleanToByteArray(boolean[] arrBool) {
335
336                 ByteBuffer bb = ByteBuffer.allocate(1 * arrBool.length);
337                 for(boolean b : arrBool) {
338                         if (b)
339                                 bb.put((byte)1);
340                         else
341                                 bb.put((byte)0);
342                 }
343
344                 return bb.array();
345         }
346
347
348         /**
349          * Converters from byte array
350          */
351         // Single variables
352         public static short byteArrayToShort(byte[] bytes) {
353
354                 return ByteBuffer.wrap(bytes).getShort();
355         }
356
357
358         public static int byteArrayToInt(byte[] bytes) {
359
360                 return ByteBuffer.wrap(bytes).getInt();
361         }
362
363
364         public static long byteArrayToLong(byte[] bytes) {
365
366                 return ByteBuffer.wrap(bytes).getLong();
367         }
368
369
370         public static float byteArrayToFloat(byte[] bytes) {
371
372                 return ByteBuffer.wrap(bytes).getFloat();
373         }
374
375
376         public static double byteArrayToDouble(byte[] bytes) {
377
378                 return ByteBuffer.wrap(bytes).getDouble();
379         }
380
381
382         public static char byteArrayToChar(byte[] bytes) {
383
384                 return ByteBuffer.wrap(bytes).getChar();
385         }
386
387
388         public static boolean byteArrayToBoolean(byte[] bytes) {
389
390                 Byte boolValByte = ByteBuffer.wrap(bytes).get();
391                 short boolVal = boolValByte.shortValue();
392                 if (boolVal == 1)
393                         return true;
394                 else
395                         return false;
396         }
397
398
399     public static String toString(byte[] bytes) {
400         return new String(bytes);
401     }
402
403
404         /**
405          * toByteArray() gets Object and return its byte array
406          * <p>
407          * Adapted from http://www.java2s.com/
408          *              @see <a href="http://www.java2s.com/Code/Java/File-Input-
409          *              Output/Convertobjecttobytearrayandconvertbytearraytoobject.htm"</a>
410          */
411     // toByteArray and toObject are taken from: http://tinyurl.com/69h8l7x
412     public static byte[] toByteArray(Object obj) throws IOException {
413
414         byte[] bytes = null;
415         ByteArrayOutputStream bos = null;
416         ObjectOutputStream oos = null;
417         try {
418
419             bos = new ByteArrayOutputStream();
420             oos = new ObjectOutputStream(bos);
421             oos.writeObject(obj);
422             oos.flush();
423             bytes = bos.toByteArray();
424         } finally {
425
426             if (oos != null) {
427                 oos.close();
428             }
429             if (bos != null) {
430                 bos.close();
431             }
432         }
433         return bytes;
434     }
435
436
437         /**
438          * toObject() gets byte array and return its Object
439          * <p>
440          * Adapted from http://www.java2s.com/
441          *              @see <a href="http://www.java2s.com/Code/Java/File-Input-
442          *              Output/Convertobjecttobytearrayandconvertbytearraytoobject.htm"</a>
443          */
444     public static Object toObject(byte[] bytes) throws IOException, ClassNotFoundException {
445
446         Object obj = null;
447         ByteArrayInputStream bis = null;
448         ObjectInputStream ois = null;
449         try {
450
451             bis = new ByteArrayInputStream(bytes);
452             ois = new ObjectInputStream(bis);
453             obj = ois.readObject();
454         } finally {
455
456             if (bis != null) {
457                 bis.close();
458             }
459             if (ois != null) {
460                 ois.close();
461             }
462         }
463         return obj;
464     }
465 }