run-compiler:
cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler camerapolicy.pol camerarequires.pol lightbulbpolicy.pol lightbulbrequires.pol -cplus Cplus -java Java
+# Runtime system compilation
+PHONY += runtime
+runtime:
+ $(JAVAC) -classpath . iotruntime/master/*.java -d $(BIN_DIR)
+
# RMI compilation and run
PHONY += rmi
rmi:
$(JAVAC) -cp . -d $(BIN_DIR) iotrmi/*.java
$(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/*.java
+ $(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/sample/*.java
PHONY += run-rmiserver
run-rmiserver:
"void" // 0 byte
};
-
+
/**
* Primitive data types in C++ to map the primitives list
*/
map.put(arrKey[i], arrVal[i]);
}
}
+
+ // Inserting array members into a Map object
+ // that maps arrKey to arrVal objects
+ public static void arraysToMap(Map<Object,Object> map, Object[] arrKey, Object[] arrVal) {
+
+ for(int i = 0; i < arrKey.length; i++) {
+
+ map.put(arrKey[i], arrVal[i]);
+ }
+ }
}
import java.util.Map;
import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
/** Class IoTRMICall is a class that serves method calls on stub.
* <p>
*/
public class IoTRMICall {
+
/**
* Class Properties
*/
/**
* remoteCall() calls a method remotely by passing in parameters and getting a return Object
*/
- public Object remoteCall(String methodSign, String retType, Class<?>[] paramCls, Object[] paramObj) throws IOException {
+ public Object remoteCall(String methodSign, Class<?> retType, Class<?> retGenTypeKey,
+ Class<?> retGenTypeVal, Class<?>[] paramCls, Object[] paramObj) {
// Send method info
byte[] methodBytes = methodToBytes(methodSign, paramCls, paramObj);
- rmiClient.sendBytes(methodBytes);
+ try {
+ rmiClient.sendBytes(methodBytes);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ throw new Error("IoTRMICall: Error when sending bytes - rmiClient.sendBytes()");
+ }
// Receive return value and return it to caller
- byte[] retObjBytes = null;
- retObjBytes = rmiClient.receiveBytes(retObjBytes);
- Object retObj = IoTRMIUtil.getParamObject(retType, retObjBytes);
+ Object retObj = null;
+ if (retType != void.class) {
+ byte[] retObjBytes = null;
+ try {
+ retObjBytes = rmiClient.receiveBytes(retObjBytes);
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ throw new Error("IoTRMICall: Error when receiving bytes - rmiClient.receiveBytes()");
+ }
+ retObj = IoTRMIUtil.getParamObject(retType, retGenTypeKey, retGenTypeVal, retObjBytes);
+ }
return retObj;
}
public static void main(String[] args) throws Exception {
- int port = 5010;
- String address = "localhost";
- int rev = 0;
- IoTRMICall rmiCall = new IoTRMICall(port, address, rev);
- String sign = "intsetACAndGetA(string,int)";
- String retType = "int";
- System.out.println("Calling function: " + sign);
- Object retObj = rmiCall.remoteCall(sign, retType, new Class<?>[] { String.class, int.class },
- new Object[] { "Test param", 1234567 });
- System.out.println("Returned object: " + retObj);
-
- System.out.println();
+ String[] test = { "123", "456", "789" };
+ byte[] b = IoTRMIUtil.getObjectBytes(test);
+
+ Boolean[] test2 = new Boolean[] { true, false, false };
+ byte[] b2 = IoTRMIUtil.getObjectBytes(test2);
+
+ System.out.println(Arrays.toString(b));
+ System.out.println(Arrays.toString(b2));
+
+ String[] c = (String[]) IoTRMIUtil.getParamObjectArray(String[].class, b);
+ System.out.println(Arrays.toString(c));
+
+ Boolean[] c2 = (Boolean[]) IoTRMIUtil.getParamObjectArray(Boolean[].class, b2);
+ System.out.println(Arrays.toString(c2));
+
+ // Set
+ /*Set<String> set = new HashSet<String>();
+ set.add("1234");
+ set.add("5678");
+
+ byte[] objBytes = IoTRMIUtil.getObjectBytes(set);
+ System.out.println(Arrays.toString(objBytes));
+ Object obj = IoTRMIUtil.getParamObject(Set.class, null, String.class, objBytes);
+
+ @SuppressWarnings("unchecked")
+ Set<String> setStr = (Set<String>) obj;
+ System.out.println("Set: " + setStr.toString());*/
+
+ // List
+ /*List<Long> list = new ArrayList<Long>();
+ list.add(12345678l);
+ list.add(23455432l);
+ list.add(34566543l);
+
+ byte[] objBytes = IoTRMIUtil.getObjectBytes(list);
+ System.out.println(Arrays.toString(objBytes));
+ Object obj = IoTRMIUtil.getParamObject(List.class, null, Long.class, objBytes);
+
+ @SuppressWarnings("unchecked")
+ List<Long> listStr = (List<Long>) obj;
+ System.out.println("List: " + listStr.toString());*/
+
+ // Map
+ Map<Long,Integer> map = new HashMap<Long,Integer>();
+ map.put(12345678l, 1234);
+ map.put(23455432l, 5678);
+ map.put(34566543l, 4321);
+
+ byte[] objBytes = IoTRMIUtil.getObjectBytes(map);
+ System.out.println(Arrays.toString(objBytes));
+ Object obj = IoTRMIUtil.getParamObject(Map.class, Long.class, Integer.class, objBytes);
+
+ map = (Map<Long,Integer>) obj;
+ System.out.println("Received map: " + map.toString());
+
+ //@SuppressWarnings("unchecked")
+ //List<Long> listStr = (List<Long>) obj;
+ //System.out.println("List: " + listStr.toString());
+
}
}
/**
* Class Properties
*/
- private Map<String,Method> mapSign2Method; // Map from signature to method
private Map<Integer,String> mapHash2Sign; // Map from hashcode(method ID) to signature
private IoTRMIUtil rmiUtil;
private IoTSocketServer rmiServer;
- private Object obj;
- private Class<?> cls;
- private Method[] methods;
+ private byte[] methodBytes;
/**
* Constructors
*/
- public IoTRMIObject(String _clsName, int _port) throws
- ClassNotFoundException, InstantiationException,
- IllegalAccessException, IOException {
+ public IoTRMIObject(int _port, String[] _methodSign) throws
+ ClassNotFoundException, InstantiationException,
+ IllegalAccessException, IOException {
rmiUtil = new IoTRMIUtil();
- cls = Class.forName(_clsName);
- obj = cls.newInstance();
- methods = cls.getDeclaredMethods();
- mapSign2Method = new HashMap<String,Method>();
mapHash2Sign = new HashMap<Integer,String>();
- getMethodSignatures(); // Initialize the signature map
- getMethodIds(); // Initialize the method ID map
+ methodBytes = null;
+ getMethodIds(_methodSign); // Initialize the method ID map
rmiServer = new IoTSocketServer(_port);
rmiServer.connect();
}
/**
- * getName() gets class name
+ * sendReturnObj() sends back return Object to client
*/
- public String getName() {
+ public void sendReturnObj(Object retObj) throws IOException {
- return cls.getName();
+ // Send back return value
+ byte[] retObjBytes = IoTRMIUtil.getObjectBytes(retObj);
+ rmiServer.sendBytes(retObjBytes);
}
/**
- * getSignatures() gets method signatures
- */
- public Set<String> getSignatures() {
-
- return mapSign2Method.keySet();
- }
-
-
- /**
- * getMethodParamTypes() gets method parameter types
+ * getMethodBytes() waits for method transmission in bytes
*/
- public Class<?>[] getMethodParamTypes(String signature) {
+ public void getMethodBytes() throws IOException {
- Method method = mapSign2Method.get(signature);
- return method.getParameterTypes();
+ // Receive method info
+ methodBytes = rmiServer.receiveBytes(methodBytes);
}
/**
- * getMethodRetType() gets method return type
- */
- public Class<?> getMethodRetType(String signature) {
-
- Method method = mapSign2Method.get(signature);
- return method.getReturnType();
- }
-
-
- /**
- * invokeMethod() invokes a method based on signature and params
+ * getSignature() gets method signature from bytes
*/
- public Object invokeMethod(String signature, Object[] params) {
-
- Method method = mapSign2Method.get(signature);
- Object retVal = null;
- try {
- retVal = method.invoke(obj, params);
- } catch (IllegalAccessException |
- InvocationTargetException ex) {
- ex.printStackTrace();
- throw new Error("IoTRMICall: Error invoking method: " + signature);
- }
+ public String getSignature() {
- return retVal;
+ // Get method ID
+ byte[] methodIdBytes = new byte[IoTRMIUtil.METHOD_ID_LEN];
+ System.arraycopy(methodBytes, 0, methodIdBytes, 0, IoTRMIUtil.METHOD_ID_LEN);
+ // Get Method object to handle method
+ int methodId = IoTRMIUtil.byteArrayToInt(methodIdBytes);
+ // Get method signature from the Map
+ return mapHash2Sign.get(methodId);
}
/**
- * recvAndInvoke() waits for method transmission and invoke the method
- */
- private void recvAndInvoke() throws IOException {
-
- // Receive method info and invoke
- byte[] method = null;
- method = rmiServer.receiveBytes(method);
- Object retObj = invokeMethod(method);
- // Send back return value
- byte[] retObjBytes = IoTRMIUtil.getObjectBytes(retObj);
- rmiServer.sendBytes(retObjBytes);
- }
-
-
- /**
- * invokeMethod() invokes a method based on byte array received
+ * getMethodParams() gets method params based on byte array received
* <p>
* Basically this is the format of a method in bytes:
* 1) 32-bit value of method ID (hash code)
* | 32-bit method ID | 32-bit length | n-bit actual data | ...
*
*/
- public Object invokeMethod(byte[] methodBytes) {
+ public Object[] getMethodParams(Class<?>[] arrCls, Class<?>[] arrGenKeyCls, Class<?>[] arrGenValCls) {
// Byte scanning position
- int pos = 0;
- // Get method ID
- byte[] methodIdBytes = new byte[IoTRMIUtil.METHOD_ID_LEN];
- System.arraycopy(methodBytes, pos, methodIdBytes, 0, IoTRMIUtil.METHOD_ID_LEN);
- pos = pos + IoTRMIUtil.METHOD_ID_LEN;
- // Get Method object to handle method
- int methodId = IoTRMIUtil.byteArrayToInt(methodIdBytes);
- String signature = mapHash2Sign.get(methodId);
- Method method = mapSign2Method.get(signature);
- // Get class name and then param length
- Class<?>[] arrCls = method.getParameterTypes();
+ int pos = IoTRMIUtil.METHOD_ID_LEN;
Object[] paramObj = new Object[arrCls.length];
for (int i=0; i < arrCls.length; i++) {
byte[] paramBytes = new byte[paramSize];
System.arraycopy(methodBytes, pos, paramBytes, 0, paramSize);
pos = pos + paramSize;
- paramObj[i] = IoTRMIUtil.getParamObject(paramType, paramBytes);
+ paramObj[i] = IoTRMIUtil.getParamObject(arrCls[i], arrGenKeyCls[i],
+ arrGenValCls[i], paramBytes);
}
- Object retObj = null;
- try {
- retObj = method.invoke(obj, paramObj);
- } catch (IllegalAccessException |
- InvocationTargetException ex) {
- ex.printStackTrace();
- throw new Error("IoTRMICall: Error invoking method: " + signature);
- }
-
- return retObj;
- }
-
- /**================
- * Helper methods
- **================
- */
- /**
- * getMethodSignatures() gets methods signatures and store them in the Map
- */
- private void getMethodSignatures() {
-
- for (Method m : methods) {
- String sign = rmiUtil.getSignature(m);
- //System.out.println("Signature: " + sign);
- mapSign2Method.put(sign, m);
- }
+ return paramObj;
}
-
+
/**
* getMethodIds() gets methods identifiers (hash code) and store them in the Map
*/
- private void getMethodIds() {
+ private void getMethodIds(String[] methodSign) {
- Set<String> setSignatures = getSignatures();
- for (String sign : setSignatures) {
+ for (String sign : methodSign) {
byte[] hashCode = IoTRMIUtil.getHashCodeBytes(sign);
int methodId = IoTRMIUtil.byteArrayToInt(hashCode);
mapHash2Sign.put(methodId, sign);
}
}
-
-
- public static void main(String[] args) throws Exception {
-
- int port = 5010;
- IoTRMIObject rmiObj = new IoTRMIObject("TestClass", port);
- rmiObj.recvAndInvoke();
- }
}
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
-import java.lang.reflect.Method;
+import java.util.Set;
import iotrmi.IoTRMITypes;
public final static int METHOD_ID_LEN = 4; // 4 bytes = 32 bits
public final static int PARAM_LEN = 4; // 4 bytes = 32 bits (4-byte field that stores the length of the param)
+ public final static int SHT_LEN = 2;
+ public final static int INT_LEN = 4;
+ public final static int LNG_LEN = 8;
+ public final static int FLT_LEN = 4;
+ public final static int DBL_LEN = 8;
+ public final static int CHR_LEN = 2;
+ public final static int BYT_LEN = 1;
+ public final static int BOL_LEN = 1;
+
/**
* Constructors
*/
}
- /**
- * getSignature() gets method signature, i.e. type, identifier, parameters
- */
- public String getSignature(Method m) {
-
- String retType = translateType(m.getReturnType().getSimpleName());
- String signature = retType +
- m.getName() + "(";
- Class<?>[] clsParam = m.getParameterTypes();
- for (int i = 0; i < clsParam.length; i++) {
- String paramType = translateType(clsParam[i].getSimpleName());
- signature = signature + paramType;
- if (i < clsParam.length - 1) {
- signature = signature + ",";
- }
- }
- signature = signature + ")";
- return signature;
- }
-
-
/**
* getHashCodeBytes() gets hash value (in bytes) from method name
*/
return -1; // Size is unknown
}
+
+ /**
+ * getTypeSize() gets the size of a type
+ *
+ */
+ public static int getTypeSize(Class<?> type) {
+
+ int size = 0;
+ if (type == byte.class) {
+ size = BYT_LEN;
+ } else if (type == Byte.class) {
+ size = BYT_LEN;
+ } else if (type == short.class) {
+ size = SHT_LEN;
+ } else if (type == Short.class) {
+ size = SHT_LEN;
+ } else if ( type == int.class) {
+ size = INT_LEN;
+ } else if ( type == Integer.class) {
+ size = INT_LEN;
+ } else if ( type == long.class) {
+ size = LNG_LEN;
+ } else if ( type == Long.class) {
+ size = LNG_LEN;
+ } else if ( type == float.class) {
+ size = FLT_LEN;
+ } else if ( type == Float.class) {
+ size = FLT_LEN;
+ } else if ( type == double.class) {
+ size = DBL_LEN;
+ } else if ( type == Double.class) {
+ size = DBL_LEN;
+ } else if ( type == boolean.class) {
+ size = BOL_LEN;
+ } else if ( type == Boolean.class) {
+ size = BOL_LEN;
+ } else if ( type == char.class) {
+ size = CHR_LEN;
+ } else if ( type == Character[].class) {
+ size = CHR_LEN;
+ } else if (type == String[].class) {
+ size = -1;
+ } else
+ throw new Error("IoTRMIUtil: Unrecognizable type: " + type.getName());
+
+ return size;
+ }
+
/**
* getParamObject() converts byte array of certain object type into Object
*/
- public static Object getParamObject(String type, byte[] paramBytes) {
+ public static Object getParamObject(Class<?> type, Class<?> genTypeKey, Class<?> genTypeVal, byte[] paramBytes) {
Object retObj = null;
- if (type.equals("byte") ||
- type.equals("Byte")) {
+ if (type == byte.class ||
+ type == Byte.class) {
retObj = (Object) paramBytes[0];
- } else if ( type.equals("short") ||
- type.equals("Short")) {
+ } else if ( type == short.class ||
+ type == Short.class) {
retObj = (Object) byteArrayToShort(paramBytes);
- } else if ( type.equals("int") ||
- type.equals("Integer")) {
+ } else if ( type == int.class ||
+ type == Integer.class) {
retObj = (Object) byteArrayToInt(paramBytes);
- } else if ( type.equals("long") ||
- type.equals("Long")) {
+ } else if ( type == long.class ||
+ type == Long.class) {
retObj = (Object) byteArrayToLong(paramBytes);
- } else if ( type.equals("float") ||
- type.equals("Float")) {
+ } else if ( type == float.class ||
+ type == Float.class) {
retObj = (Object) byteArrayToFloat(paramBytes);
- } else if ( type.equals("double") ||
- type.equals("Double")) {
+ } else if ( type == double.class ||
+ type == Double.class) {
retObj = (Object) byteArrayToDouble(paramBytes);
- } else if ( type.equals("boolean") ||
- type.equals("Boolean")) {
+ } else if ( type == boolean.class ||
+ type == Boolean.class) {
retObj = (Object) byteArrayToBoolean(paramBytes);
- } else if ( type.equals("char") ||
- type.equals("Character")) {
+ } else if ( type == char.class ||
+ type == Character.class) {
retObj = (Object) byteArrayToChar(paramBytes);
- } else if (type.equals("String")) {
- retObj = (Object) toString(paramBytes);
+ } else if (type == String.class) {
+ retObj = (Object) byteArrayToString(paramBytes);
+ // Array
+ } else if (type.isArray()) {
+ retObj = getParamObjectArray(type, paramBytes);
+ // Set
+ // e.g. Set<String> - type = Set.class, genTypeVal = String.class
+ } else if (type == Set.class) {
+ retObj = getParamSetObject(genTypeVal, paramBytes);
+ // List
+ } else if (type == List.class) {
+ retObj = getParamListObject(genTypeVal, paramBytes);
+ // Map
+ // e.g. Map<String,Integer> - type = Map.class, genTypeKey = String.class, genTypeVal = Integer.class
+ } else if (type == Map.class) {
+ retObj = getParamMapObject(genTypeKey, genTypeVal, paramBytes);
} else
- throw new Error("IoTRMIUtil: Unrecognizable type: " + type);
+ throw new Error("IoTRMIUtil: Unrecognizable type: " + type.getName());
+
+ return retObj;
+ }
+
+
+ /**
+ * getParamObjectArray() converts byte array of certain object type into array of Objects
+ */
+ public static Object getParamObjectArray(Class<?> type, byte[] paramBytes) {
+
+ Object retObj = null;
+ if ((type == byte[].class) ||
+ (type == byte.class)) {
+ retObj = (Object) paramBytes;
+ } else if ( (type == Byte[].class) ||
+ (type == Byte.class)) {
+ retObj = (Object) byteArrayToByteArray(paramBytes);
+ } else if ( (type == short[].class) ||
+ (type == short.class)) {
+ retObj = (Object) byteArrayToShtArray(paramBytes);
+ } else if ( (type == Short[].class) ||
+ (type == Short.class)) {
+ retObj = (Object) byteArrayToShortArray(paramBytes);
+ } else if ( (type == int[].class) ||
+ (type == int.class)) {
+ retObj = (Object) byteArrayToIntArray(paramBytes);
+ } else if ( (type == Integer[].class) ||
+ (type == Integer.class)) {
+ retObj = (Object) byteArrayToIntegerArray(paramBytes);
+ } else if ( (type == long[].class) ||
+ (type == long.class)) {
+ retObj = (Object) byteArrayToLngArray(paramBytes);
+ } else if ( (type == Long[].class) ||
+ (type == Long.class)) {
+ retObj = (Object) byteArrayToLongArray(paramBytes);
+ } else if ( (type == float[].class) ||
+ (type == float.class)) {
+ retObj = (Object) byteArrayToFltArray(paramBytes);
+ } else if ( (type == Float[].class) ||
+ (type == Float.class)) {
+ retObj = (Object) byteArrayToFloatArray(paramBytes);
+ } else if ( (type == double[].class) ||
+ (type == double.class)) {
+ retObj = (Object) byteArrayToDblArray(paramBytes);
+ } else if ( (type == Double[].class) ||
+ (type == Double.class)) {
+ retObj = (Object) byteArrayToDoubleArray(paramBytes);
+ } else if ( (type == boolean[].class) ||
+ (type == boolean.class)) {
+ retObj = (Object) byteArrayToBolArray(paramBytes);
+ } else if ( (type == Boolean[].class) ||
+ (type == Boolean.class)) {
+ retObj = (Object) byteArrayToBooleanArray(paramBytes);
+ } else if ( (type == char[].class) ||
+ (type == char.class)) {
+ retObj = (Object) byteArrayToChrArray(paramBytes);
+ } else if ( (type == Character[].class) ||
+ (type == Character.class)) {
+ retObj = (Object) byteArrayToCharacterArray(paramBytes);
+ } else if ( (type == String[].class) ||
+ (type == String.class)) {
+ retObj = (Object) byteArrayToStringArray(paramBytes);
+ } else
+ throw new Error("IoTRMIUtil: Unrecognizable type: " + type.getName());
return retObj;
}
} else if (obj instanceof Boolean) {
retObjBytes = booleanToByteArray((boolean) obj);
} else if (obj instanceof String) {
- retObjBytes = ((String) obj).getBytes();
+ retObjBytes = stringToByteArray((String) obj);
+ // Arrays
+ } else if (obj.getClass().isArray()) {
+ retObjBytes = getArrayObjectBytes(obj);
+ // Set and its implementations
+ } else if (obj instanceof Set<?>) {
+ retObjBytes = setToByteArray((Set<?>) obj);
+ // List and its implementations
+ } else if (obj instanceof List<?>) {
+ retObjBytes = listToByteArray((List<?>) obj);
+ // Map and its implementations
+ } else if (obj instanceof Map<?,?>) {
+ retObjBytes = mapToByteArray((Map<?,?>) obj);
} else
- throw new Error("IoTRMIUtil: Unrecognizable object: " + obj);
+ throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
return retObjBytes;
}
-
+
+
+ /**
+ * getArrayObjectBytes() converts array of objects into bytes array
+ */
+ public static byte[] getArrayObjectBytes(Object obj) {
+
+ byte[] retObjBytes = null;
+ if (obj instanceof byte[]) {
+ retObjBytes = (byte[]) obj;
+ } else if (obj instanceof Byte[]) {
+ retObjBytes = arrByteToByteArray((Byte[]) obj);
+ } else if (obj instanceof short[]) {
+ retObjBytes = arrShortToByteArray((short[]) obj);
+ } else if (obj instanceof Short[]) {
+ retObjBytes = arrShortToByteArray((Short[]) obj);
+ } else if (obj instanceof int[]) {
+ retObjBytes = arrIntToByteArray((int[]) obj);
+ } else if (obj instanceof Integer[]) {
+ retObjBytes = arrIntToByteArray((Integer[]) obj);
+ } else if (obj instanceof long[]) {
+ retObjBytes = arrLongToByteArray((long[]) obj);
+ } else if (obj instanceof Long[]) {
+ retObjBytes = arrLongToByteArray((Long[]) obj);
+ } else if (obj instanceof float[]) {
+ retObjBytes = arrFloatToByteArray((float[]) obj);
+ } else if (obj instanceof Float[]) {
+ retObjBytes = arrFloatToByteArray((Float[]) obj);
+ } else if (obj instanceof double[]) {
+ retObjBytes = arrDoubleToByteArray((double[]) obj);
+ } else if (obj instanceof Double[]) {
+ retObjBytes = arrDoubleToByteArray((Double[]) obj);
+ } else if (obj instanceof char[]) {
+ retObjBytes = arrCharToByteArray((char[]) obj);
+ } else if (obj instanceof Character[]) {
+ retObjBytes = arrCharToByteArray((Character[]) obj);
+ } else if (obj instanceof boolean[]) {
+ retObjBytes = arrBooleanToByteArray((boolean[]) obj);
+ } else if (obj instanceof Boolean[]) {
+ retObjBytes = arrBooleanToByteArray((Boolean[]) obj);
+ } else if (obj instanceof String[]) {
+ retObjBytes = arrStringToByteArray((String[]) obj);
+ } else
+ throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
+
+ return retObjBytes;
+ }
+
+
+ // Collection data structures
+ public static byte[] setToByteArray(Set<?> set) {
+
+ // Find out the class of the type
+ Iterator<?> it = set.iterator();
+ Object[] arrObj = null;
+ Object obj = it.next();
+
+ if (obj instanceof Byte) {
+ arrObj = set.toArray(new Byte[set.size()]);
+ } else if (obj instanceof Short) {
+ arrObj = set.toArray(new Short[set.size()]);
+ } else if (obj instanceof Integer) {
+ arrObj = set.toArray(new Integer[set.size()]);
+ } else if (obj instanceof Long) {
+ arrObj = set.toArray(new Long[set.size()]);
+ } else if (obj instanceof Float) {
+ arrObj = set.toArray(new Float[set.size()]);
+ } else if (obj instanceof Double) {
+ arrObj = set.toArray(new Double[set.size()]);
+ } else if (obj instanceof Character) {
+ arrObj = set.toArray(new Character[set.size()]);
+ } else if (obj instanceof Boolean) {
+ arrObj = set.toArray(new Boolean[set.size()]);
+ } else if (obj instanceof String) {
+ arrObj = set.toArray(new String[set.size()]);
+ } else
+ throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
+
+ byte[] arrObjBytes = getArrayObjectBytes(arrObj);
+ return arrObjBytes;
+ }
+
+
+ public static byte[] listToByteArray(List<?> list) {
+
+ // Find out the class of the type
+ Iterator<?> it = list.iterator();
+ Object[] arrObj = null;
+ Object obj = it.next();
+
+ if (obj instanceof Byte) {
+ arrObj = list.toArray(new Byte[list.size()]);
+ } else if (obj instanceof Short) {
+ arrObj = list.toArray(new Short[list.size()]);
+ } else if (obj instanceof Integer) {
+ arrObj = list.toArray(new Integer[list.size()]);
+ } else if (obj instanceof Long) {
+ arrObj = list.toArray(new Long[list.size()]);
+ } else if (obj instanceof Float) {
+ arrObj = list.toArray(new Float[list.size()]);
+ } else if (obj instanceof Double) {
+ arrObj = list.toArray(new Double[list.size()]);
+ } else if (obj instanceof Character) {
+ arrObj = list.toArray(new Character[list.size()]);
+ } else if (obj instanceof Boolean) {
+ arrObj = list.toArray(new Boolean[list.size()]);
+ } else if (obj instanceof String) {
+ arrObj = list.toArray(new String[list.size()]);
+ } else
+ throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
+
+ byte[] arrObjBytes = getArrayObjectBytes(arrObj);
+ return arrObjBytes;
+ }
+
+
+ // Convert keySet of a Map
+ public static byte[] mapKeyToByteArray(Map<?,?> map) {
+
+ // Map<K,V>
+ // Find out the class of the type for K
+ Iterator<?> it = map.keySet().iterator();
+ Object[] arrObj = null;
+ Object obj = it.next();
+
+ if (obj instanceof Byte) {
+ arrObj = map.keySet().toArray(new Byte[map.size()]);
+ } else if (obj instanceof Short) {
+ arrObj = map.keySet().toArray(new Short[map.size()]);
+ } else if (obj instanceof Integer) {
+ arrObj = map.keySet().toArray(new Integer[map.size()]);
+ } else if (obj instanceof Long) {
+ arrObj = map.keySet().toArray(new Long[map.size()]);
+ } else if (obj instanceof Float) {
+ arrObj = map.keySet().toArray(new Float[map.size()]);
+ } else if (obj instanceof Double) {
+ arrObj = map.keySet().toArray(new Double[map.size()]);
+ } else if (obj instanceof Character) {
+ arrObj = map.keySet().toArray(new Character[map.size()]);
+ } else if (obj instanceof Boolean) {
+ arrObj = map.keySet().toArray(new Boolean[map.size()]);
+ } else if (obj instanceof String) {
+ arrObj = map.keySet().toArray(new String[map.size()]);
+ } else
+ throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
+ byte[] arrObjBytes = getArrayObjectBytes(arrObj);
+
+ return arrObjBytes;
+ }
+
+
+ // Convert entrySet of a Map
+ public static byte[] mapEntryToByteArray(Map<?,?> map) {
+
+ // Map<K,V>
+ // Find out the class of the type for V
+ Iterator<?> it = map.values().iterator();
+ Object[] arrObj = null;
+ Object obj = it.next();
+
+ if (obj instanceof Byte) {
+ arrObj = map.values().toArray(new Byte[map.size()]);
+ } else if (obj instanceof Short) {
+ arrObj = map.values().toArray(new Short[map.size()]);
+ } else if (obj instanceof Integer) {
+ arrObj = map.values().toArray(new Integer[map.size()]);
+ } else if (obj instanceof Long) {
+ arrObj = map.values().toArray(new Long[map.size()]);
+ } else if (obj instanceof Float) {
+ arrObj = map.values().toArray(new Float[map.size()]);
+ } else if (obj instanceof Double) {
+ arrObj = map.values().toArray(new Double[map.size()]);
+ } else if (obj instanceof Character) {
+ arrObj = map.values().toArray(new Character[map.size()]);
+ } else if (obj instanceof Boolean) {
+ arrObj = map.values().toArray(new Boolean[map.size()]);
+ } else if (obj instanceof String) {
+ arrObj = map.values().toArray(new String[map.size()]);
+ } else
+ throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
+
+ byte[] arrObjBytes = getArrayObjectBytes(arrObj);
+ return arrObjBytes;
+ }
+
+
+ // Merge keySet and entrySet of a Map into one long byte array
+ public static byte[] mapToByteArray(Map<?,?> map) {
+
+ // Put map size in the packet
+ byte[] numEntries = intToByteArray(map.size());
+ byte[] keySetBytes = mapKeyToByteArray(map);
+ byte[] entrySetBytes = mapEntryToByteArray(map);
+ byte[] mapBytes = new byte[INT_LEN + keySetBytes.length + entrySetBytes.length];
+ // Copy the bytes
+ System.arraycopy(numEntries, 0, mapBytes, 0, INT_LEN);
+ System.arraycopy(keySetBytes, 0, mapBytes, INT_LEN, keySetBytes.length);
+ System.arraycopy(entrySetBytes, 0, mapBytes, (INT_LEN + keySetBytes.length), entrySetBytes.length);
+
+ return mapBytes;
+ }
+
+
+ // Get a Set object from bytes
+ public static Object getParamSetObject(Class<?> genericType, byte[] paramBytes) {
+
+ Set<Object> retSet = new HashSet<Object>();
+ Object retObj = null;
+ if (genericType == Byte.class) {
+ Byte[] retArr = byteArrayToByteArray(paramBytes);
+ Collections.addAll(retSet, retArr);
+ } else if (genericType == Short.class) {
+ Short[] retArr = byteArrayToShortArray(paramBytes);
+ Collections.addAll(retSet, retArr);
+ } else if (genericType == Integer.class) {
+ Integer[] retArr = byteArrayToIntegerArray(paramBytes);
+ Collections.addAll(retSet, retArr);
+ } else if (genericType == Long.class) {
+ Long[] retArr = byteArrayToLongArray(paramBytes);
+ Collections.addAll(retSet, retArr);
+ } else if (genericType == Float.class) {
+ Float[] retArr = byteArrayToFloatArray(paramBytes);
+ Collections.addAll(retSet, retArr);
+ } else if (genericType == Double.class) {
+ Double[] retArr = byteArrayToDoubleArray(paramBytes);
+ Collections.addAll(retSet, retArr);
+ } else if (genericType == Boolean.class) {
+ Boolean[] retArr = byteArrayToBooleanArray(paramBytes);
+ Collections.addAll(retSet, retArr);
+ } else if (genericType == Character.class) {
+ Character[] retArr = byteArrayToCharacterArray(paramBytes);
+ Collections.addAll(retSet, retArr);
+ } else if (genericType == String.class) {
+ String[] retArr = byteArrayToStringArray(paramBytes);
+ Collections.addAll(retSet, retArr);
+ } else
+ throw new Error("IoTRMIUtil: Unrecognizable object: " + genericType.getSimpleName());
+
+ return retSet;
+ }
+
+
+ // Get a List object from bytes
+ public static Object getParamListObject(Class<?> genericType, byte[] paramBytes) {
+
+ List<Object> retList = new ArrayList<Object>();
+ Object retObj = null;
+ if (genericType == Byte.class) {
+ Byte[] retArr = byteArrayToByteArray(paramBytes);
+ Collections.addAll(retList, retArr);
+ } else if (genericType == Short.class) {
+ Short[] retArr = byteArrayToShortArray(paramBytes);
+ Collections.addAll(retList, retArr);
+ } else if (genericType == Integer.class) {
+ Integer[] retArr = byteArrayToIntegerArray(paramBytes);
+ Collections.addAll(retList, retArr);
+ } else if (genericType == Long.class) {
+ Long[] retArr = byteArrayToLongArray(paramBytes);
+ Collections.addAll(retList, retArr);
+ } else if (genericType == Float.class) {
+ Float[] retArr = byteArrayToFloatArray(paramBytes);
+ Collections.addAll(retList, retArr);
+ } else if (genericType == Double.class) {
+ Double[] retArr = byteArrayToDoubleArray(paramBytes);
+ Collections.addAll(retList, retArr);
+ } else if (genericType == Boolean.class) {
+ Boolean[] retArr = byteArrayToBooleanArray(paramBytes);
+ Collections.addAll(retList, retArr);
+ } else if (genericType == Character.class) {
+ Character[] retArr = byteArrayToCharacterArray(paramBytes);
+ Collections.addAll(retList, retArr);
+ } else if (genericType == String.class) {
+ String[] retArr = byteArrayToStringArray(paramBytes);
+ Collections.addAll(retList, retArr);
+ } else
+ throw new Error("IoTRMIUtil: Unrecognizable object: " + genericType.getSimpleName());
+
+ return retList;
+ }
+
+
+ // Get a Key array for Map object from bytes
+ public static Object getParamMapObject(Class<?> genTypeKey, Class<?> genTypeVal, byte[] paramBytes) {
+
+ // The complete set of bytes always consists of all keys followed by all values - <K,V> pairs
+ // Calculate number of elements
+ byte[] numElBytes = new byte[INT_LEN];
+ System.arraycopy(paramBytes, 0, numElBytes, 0, INT_LEN);
+ int numEl = byteArrayToInt(numElBytes);
+ int keyLen = numEl * getTypeSize(genTypeKey);
+ int valLen = numEl * getTypeSize(genTypeVal);
+ byte[] prmKeyBytes = new byte[keyLen];
+ byte[] prmValBytes = new byte[valLen];
+ // Copy bytes
+ System.arraycopy(paramBytes, INT_LEN, prmKeyBytes, 0, keyLen);
+ System.arraycopy(paramBytes, (INT_LEN + keyLen), prmValBytes, 0, valLen);
+ // Get array of keys
+ Object[] retObjKey = (Object[]) getParamObjectArray(genTypeKey, prmKeyBytes);
+ Object[] retObjVal = (Object[]) getParamObjectArray(genTypeVal, prmValBytes);
+ // Put everything back to a Map
+ Map<Object,Object> retMap = new HashMap<Object,Object>();
+ IoTRMITypes.arraysToMap(retMap, retObjKey, retObjVal);
+
+ return retMap;
+ }
+
/**
* Converters to byte array
*/
- // Single variables
+ // Single variables
public static byte[] shortToByteArray(short s) {
- ByteBuffer bb = ByteBuffer.allocate(2);
+ ByteBuffer bb = ByteBuffer.allocate(SHT_LEN);
bb.putShort(s);
return bb.array();
public static byte[] intToByteArray(int i) {
- ByteBuffer bb = ByteBuffer.allocate(4);
+ ByteBuffer bb = ByteBuffer.allocate(INT_LEN);
bb.putInt(i);
return bb.array();
public static byte[] longToByteArray(long l) {
- ByteBuffer bb = ByteBuffer.allocate(8);
+ ByteBuffer bb = ByteBuffer.allocate(LNG_LEN);
bb.putLong(l);
return bb.array();
public static byte[] floatToByteArray(float f) {
- ByteBuffer bb = ByteBuffer.allocate(4);
+ ByteBuffer bb = ByteBuffer.allocate(FLT_LEN);
bb.putFloat(f);
return bb.array();
public static byte[] doubleToByteArray(double d) {
- ByteBuffer bb = ByteBuffer.allocate(8);
+ ByteBuffer bb = ByteBuffer.allocate(DBL_LEN);
bb.putDouble(d);
return bb.array();
public static byte[] charToByteArray(char c) {
- ByteBuffer bb = ByteBuffer.allocate(2);
+ ByteBuffer bb = ByteBuffer.allocate(CHR_LEN);
bb.putChar(c);
return bb.array();
public static byte[] booleanToByteArray(boolean b) {
- ByteBuffer bb = ByteBuffer.allocate(1);
+ ByteBuffer bb = ByteBuffer.allocate(BOL_LEN);
if (b)
bb.put((byte)1);
else
}
+ public static byte[] stringToByteArray(String str) {
+
+ return str.getBytes();
+ }
+
+
// Arrays
+ public static byte[] arrByteToByteArray(Byte[] arrByte) {
+
+ byte[] arrByt = new byte[arrByte.length];
+ for(int i = 0; i < arrByte.length; i++) {
+ arrByt[i] = arrByte[i];
+ }
+
+ return arrByt;
+ }
+
+
public static byte[] arrShortToByteArray(short[] arrShort) {
- ByteBuffer bb = ByteBuffer.allocate(2 * arrShort.length);
+ ByteBuffer bb = ByteBuffer.allocate(SHT_LEN * arrShort.length);
for(short s : arrShort) {
bb.putShort(s);
}
}
+ public static byte[] arrShortToByteArray(Short[] arrShort) {
+
+ ByteBuffer bb = ByteBuffer.allocate(SHT_LEN * arrShort.length);
+ for(Short s : arrShort) {
+ bb.putShort(s);
+ }
+
+ return bb.array();
+ }
+
+
public static byte[] arrIntToByteArray(int[] arrInt) {
- ByteBuffer bb = ByteBuffer.allocate(4 * arrInt.length);
+ ByteBuffer bb = ByteBuffer.allocate(INT_LEN * arrInt.length);
for(int i : arrInt) {
bb.putInt(i);
}
}
+ public static byte[] arrIntToByteArray(Integer[] arrInt) {
+
+ ByteBuffer bb = ByteBuffer.allocate(INT_LEN * arrInt.length);
+ for(Integer i : arrInt) {
+ bb.putInt(i);
+ }
+
+ return bb.array();
+ }
+
+
public static byte[] arrLongToByteArray(long[] arrLong) {
- ByteBuffer bb = ByteBuffer.allocate(8 * arrLong.length);
+ ByteBuffer bb = ByteBuffer.allocate(LNG_LEN * arrLong.length);
for(long l : arrLong) {
bb.putLong(l);
}
}
+ public static byte[] arrLongToByteArray(Long[] arrLong) {
+
+ ByteBuffer bb = ByteBuffer.allocate(LNG_LEN * arrLong.length);
+ for(Long l : arrLong) {
+ bb.putLong(l);
+ }
+
+ return bb.array();
+ }
+
+
public static byte[] arrFloatToByteArray(float[] arrFloat) {
- ByteBuffer bb = ByteBuffer.allocate(4 * arrFloat.length);
+ ByteBuffer bb = ByteBuffer.allocate(FLT_LEN * arrFloat.length);
for(float f : arrFloat) {
bb.putFloat(f);
}
}
+ public static byte[] arrFloatToByteArray(Float[] arrFloat) {
+
+ ByteBuffer bb = ByteBuffer.allocate(FLT_LEN * arrFloat.length);
+ for(Float f : arrFloat) {
+ bb.putFloat(f);
+ }
+
+ return bb.array();
+ }
+
+
public static byte[] arrDoubleToByteArray(double[] arrDouble) {
- ByteBuffer bb = ByteBuffer.allocate(8 * arrDouble.length);
+ ByteBuffer bb = ByteBuffer.allocate(DBL_LEN * arrDouble.length);
for(double d : arrDouble) {
bb.putDouble(d);
}
}
+ public static byte[] arrDoubleToByteArray(Double[] arrDouble) {
+
+ ByteBuffer bb = ByteBuffer.allocate(DBL_LEN * arrDouble.length);
+ for(Double d : arrDouble) {
+ bb.putDouble(d);
+ }
+
+ return bb.array();
+ }
+
+
public static byte[] arrCharToByteArray(char[] arrChar) {
- ByteBuffer bb = ByteBuffer.allocate(2 * arrChar.length);
+ ByteBuffer bb = ByteBuffer.allocate(CHR_LEN * arrChar.length);
for(char c : arrChar) {
bb.putChar(c);
}
}
+ public static byte[] arrCharToByteArray(Character[] arrChar) {
+
+ ByteBuffer bb = ByteBuffer.allocate(CHR_LEN * arrChar.length);
+ for(Character c : arrChar) {
+ bb.putChar(c);
+ }
+
+ return bb.array();
+ }
+
+
public static byte[] arrBooleanToByteArray(boolean[] arrBool) {
- ByteBuffer bb = ByteBuffer.allocate(1 * arrBool.length);
+ ByteBuffer bb = ByteBuffer.allocate(BOL_LEN * arrBool.length);
for(boolean b : arrBool) {
if (b)
bb.put((byte)1);
}
+ public static byte[] arrBooleanToByteArray(Boolean[] arrBool) {
+
+ ByteBuffer bb = ByteBuffer.allocate(BOL_LEN * arrBool.length);
+ for(Boolean b : arrBool) {
+ if (b)
+ bb.put((byte)1);
+ else
+ bb.put((byte)0);
+ }
+
+ return bb.array();
+ }
+
+
+ public static byte[] arrStringToByteArray(String[] arrString) {
+
+ // Format of bytes: | array length | length #1 | string #1 | length #2 | string #2 | ...
+ // Prepare array of bytes
+ int arrLen = INT_LEN; // First allocation for array length
+ for (int i = 0; i < arrString.length; i++) {
+ arrLen = arrLen + INT_LEN + arrString[i].length();
+ }
+ byte[] arrStrBytes = new byte[arrLen];
+ // Copy bytes
+ int pos = 0;
+ byte[] strArrLenBytes = intToByteArray(arrString.length);
+ System.arraycopy(strArrLenBytes, 0, arrStrBytes, pos, INT_LEN);
+ pos = pos + INT_LEN;
+ for (String str : arrString) {
+
+ // Copy string length
+ int strLen = str.length();
+ byte[] strLenBytes = intToByteArray(strLen);
+ System.arraycopy(strLenBytes, 0, arrStrBytes, pos, INT_LEN);
+ pos = pos + INT_LEN;
+ // Copy string
+ byte[] strBytes = stringToByteArray(str);
+ System.arraycopy(strBytes, 0, arrStrBytes, pos, strLen);
+ pos = pos + strLen;
+ }
+
+ return arrStrBytes;
+ }
+
+
/**
* Converters from byte array
*/
- // Single variables
+ // Single variables
public static short byteArrayToShort(byte[] bytes) {
return ByteBuffer.wrap(bytes).getShort();
}
- public static String toString(byte[] bytes) {
+ public static String byteArrayToString(byte[] bytes) {
return new String(bytes);
}
+ // Arrays
+ public static Byte[] byteArrayToByteArray(byte[] arrByt) {
+
+ Byte[] arrByte = new Byte[arrByt.length];
+ for(int i = 0; i < arrByt.length; i++) {
+ arrByte[i] = arrByt[i];
+ }
+
+ return arrByte;
+ }
+
+
+ public static short[] byteArrayToShtArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[SHT_LEN];
+ // Prepare array
+ int arrLen = bytes.length / SHT_LEN;
+ short[] arr = new short[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * SHT_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, SHT_LEN);
+ arr[i] = byteArrayToShort(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static Short[] byteArrayToShortArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[SHT_LEN];
+ // Prepare array
+ int arrLen = bytes.length / SHT_LEN;
+ Short[] arr = new Short[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * SHT_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, SHT_LEN);
+ arr[i] = byteArrayToShort(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static int[] byteArrayToIntArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[INT_LEN];
+ // Prepare array
+ int arrLen = bytes.length / INT_LEN;
+ int[] arr = new int[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * INT_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, INT_LEN);
+ arr[i] = byteArrayToInt(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static Integer[] byteArrayToIntegerArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[INT_LEN];
+ // Prepare array
+ int arrLen = bytes.length / INT_LEN;
+ Integer[] arr = new Integer[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * INT_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, INT_LEN);
+ arr[i] = byteArrayToInt(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static long[] byteArrayToLngArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[LNG_LEN];
+ // Prepare array
+ int arrLen = bytes.length / LNG_LEN;
+ long[] arr = new long[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * LNG_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, LNG_LEN);
+ arr[i] = byteArrayToLong(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static Long[] byteArrayToLongArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[LNG_LEN];
+ // Prepare array
+ int arrLen = bytes.length / LNG_LEN;
+ Long[] arr = new Long[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * LNG_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, LNG_LEN);
+ arr[i] = byteArrayToLong(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static float[] byteArrayToFltArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[FLT_LEN];
+ // Prepare array
+ int arrLen = bytes.length / FLT_LEN;
+ float[] arr = new float[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * FLT_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, FLT_LEN);
+ arr[i] = byteArrayToFloat(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static Float[] byteArrayToFloatArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[FLT_LEN];
+ // Prepare array
+ int arrLen = bytes.length / FLT_LEN;
+ Float[] arr = new Float[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * FLT_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, FLT_LEN);
+ arr[i] = byteArrayToFloat(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static double[] byteArrayToDblArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[DBL_LEN];
+ // Prepare array
+ int arrLen = bytes.length / DBL_LEN;
+ double[] arr = new double[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * DBL_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, DBL_LEN);
+ arr[i] = byteArrayToDouble(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static Double[] byteArrayToDoubleArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[DBL_LEN];
+ // Prepare array
+ int arrLen = bytes.length / DBL_LEN;
+ Double[] arr = new Double[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * DBL_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, DBL_LEN);
+ arr[i] = byteArrayToDouble(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static char[] byteArrayToChrArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[CHR_LEN];
+ // Prepare array
+ int arrLen = bytes.length / CHR_LEN;
+ char[] arr = new char[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * CHR_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, CHR_LEN);
+ arr[i] = byteArrayToChar(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static Character[] byteArrayToCharacterArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[CHR_LEN];
+ // Prepare array
+ int arrLen = bytes.length / CHR_LEN;
+ Character[] arr = new Character[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * CHR_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, CHR_LEN);
+ arr[i] = byteArrayToChar(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static boolean[] byteArrayToBolArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[BOL_LEN];
+ // Prepare array
+ int arrLen = bytes.length / BOL_LEN;
+ boolean[] arr = new boolean[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * BOL_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, BOL_LEN);
+ arr[i] = byteArrayToBoolean(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static Boolean[] byteArrayToBooleanArray(byte[] bytes) {
+
+ // Single element bytes
+ byte[] elmt = new byte[BOL_LEN];
+ // Prepare array
+ int arrLen = bytes.length / BOL_LEN;
+ Boolean[] arr = new Boolean[arrLen];
+ for(int i = 0; i < arrLen; i++) {
+ int offset = i * BOL_LEN;
+ System.arraycopy(bytes, offset, elmt, 0, BOL_LEN);
+ arr[i] = byteArrayToBoolean(elmt);
+ }
+
+ return arr;
+ }
+
+
+ public static String[] byteArrayToStringArray(byte[] bytes) {
+
+ // Format of bytes: | array length | length #1 | string #1 | length #2 | string #2 | ...
+ // Get string array length
+ int pos = 0;
+ byte[] strArrLenBytes = new byte[INT_LEN];
+ System.arraycopy(bytes, pos, strArrLenBytes, 0, INT_LEN);
+ int strArrLen = byteArrayToInt(strArrLenBytes);
+ pos = pos + INT_LEN;
+ // Prepare string array
+ String[] strArray = new String[strArrLen];
+ // Extract array of strings
+ for(int i = 0; i < strArrLen; i++) {
+
+ // Extract string length
+ byte[] strLenBytes = new byte[INT_LEN];
+ System.arraycopy(bytes, pos, strLenBytes, 0, INT_LEN);
+ int strLen = byteArrayToInt(strLenBytes);
+ pos = pos + INT_LEN;
+ // Extract string
+ byte[] strBytes = new byte[strLen];
+ System.arraycopy(bytes, pos, strBytes, 0, strLen);
+ pos = pos + strLen;
+ strArray[i] = byteArrayToString(strBytes);
+ }
+
+ return strArray;
+ }
+
+
/**
* toByteArray() gets Object and return its byte array
* <p>
int i;
int totalbytes = 0;
int numbytes;
+ // Wait until input is available
+ while(input.available() == 0);
// Read the maxlen first
int maxlen = (int)input.read();
if (maxlen>BUFFSIZE)
--- /dev/null
+package iotrmi.Java.sample;
+
+public class CallBack implements CallBackInterface {
+
+ /**
+ * Class Properties
+ */
+ private int intA;
+
+ /**
+ * Constructors
+ */
+ public CallBack(int _i) {
+
+ intA = _i;
+ }
+
+
+ public int printInt() {
+
+ System.out.println("Integer: " + intA);
+ return intA;
+ }
+
+
+ public void setInt(int _i) {
+
+ intA = _i;
+ }
+}
--- /dev/null
+package iotrmi.Java.sample;
+
+public interface CallBackInterface {
+
+ public int printInt();
+ public void setInt(int _i);
+
+}
--- /dev/null
+package iotrmi.Java.sample;
+
+import java.io.IOException;
+import java.util.Set;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMIObject;
+
+public class CallBack_Skeleton {
+
+ private String[] methodSignatures = {
+
+ "intprintInt()",
+ "voidsetInt(int)"
+ };
+
+ private CallBackInterface cb;
+ private IoTRMIObject rmiObj;
+
+
+ /**
+ * Constructors
+ */
+ public CallBack_Skeleton(CallBackInterface _cb, int _port) throws
+ ClassNotFoundException, InstantiationException,
+ IllegalAccessException, IOException {
+
+ cb = _cb;
+ System.out.println("Creating CallBack_Skeleton and waiting!");
+ rmiObj = new IoTRMIObject(_port, methodSignatures);
+ }
+
+
+ public void waitRequestInvokeMethod() throws IOException {
+
+ // Loop continuously waiting for incoming bytes
+ while (true) {
+
+ rmiObj.getMethodBytes();
+ String methodSign = rmiObj.getSignature();
+ Object[] paramObj = null;
+ Object retObj = null;
+ System.out.println("Method sign: " + methodSign);
+
+ if (methodSign.equals("intprintInt()")) {
+ //paramObj = rmiObj.getMethodParams(new Class<?>[] { },
+ // new Class<?>[] { null }, new Class<?>[] { null });
+ retObj = cb.printInt();
+ } else if (methodSign.equals("voidsetInt(int)")) {
+ paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class },
+ new Class<?>[] { null }, new Class<?>[] { null });
+ cb.setInt((int) paramObj[0]);
+ } else
+ throw new Error("Signature un-recognized!");
+ System.out.println("Return object: " + retObj);
+
+ if (retObj != null) {
+ rmiObj.sendReturnObj(retObj);
+ }
+ System.out.println("Servicing remote call for method: " + methodSign);
+ }
+ }
+
+
+ public static void main(String[] args) throws Exception {
+
+ int port = 5010;
+ CallBack cb = new CallBack(23);
+ CallBack_Skeleton cbSkel = new CallBack_Skeleton(cb, port);
+ cbSkel.waitRequestInvokeMethod();
+ }
+}
--- /dev/null
+package iotrmi.Java.sample;
+
+import java.io.IOException;
+import iotrmi.Java.IoTRMICall;
+
+public class CallBack_Stub implements CallBackInterface {
+
+ /**
+ * Class Properties
+ */
+ private IoTRMICall rmiCall;
+
+ /**
+ * Constructors
+ */
+ public CallBack_Stub(int _port, String _address, int _rev) throws IOException {
+
+ rmiCall = new IoTRMICall(_port, _address, _rev);
+ }
+
+
+ public int printInt() {
+
+ String sign = "intprintInt()";
+ Class<?> retType = int.class;
+ Class<?>[] paramCls = new Class<?>[] { };
+ Object[] paramObj = new Object[] { };
+ Object retObj = rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ return (int)retObj;
+ }
+
+
+ public void setInt(int _i) {
+
+ String sign = "voidsetInt(int)";
+ Class<?> retType = void.class;
+ Class<?>[] paramCls = new Class<?>[] { int.class };
+ Object[] paramObj = new Object[] { _i };
+ rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ }
+
+
+ public static void main(String[] args) throws Exception {
+
+ int port = 5010;
+ String address = "localhost";
+ int rev = 0;
+
+ CallBack_Stub cbstub = new CallBack_Stub(port, address, rev);
+ cbstub.setInt(23);
+ cbstub.printInt();
+ }
+}
--- /dev/null
+package iotrmi.Java.sample;
+
+import java.util.Set;
+
+public class TestClass {
+
+ /**
+ * Class Properties
+ */
+ private int intA;
+ private float floatB;
+ private String stringC;
+ private CallBackInterface cb;
+
+ /**
+ * Constructors
+ */
+ public TestClass() {
+
+ intA = 1;
+ floatB = 2;
+ stringC = "345";
+ cb = null;
+ }
+
+
+ public TestClass(int _int, float _float, String _string) {
+
+ intA = _int;
+ floatB = _float;
+ stringC = _string;
+ }
+
+
+ public void setA(int _int) {
+
+ intA = _int;
+ }
+
+
+ public void setB(float _float) {
+
+ floatB = _float;
+ }
+
+
+ public void setC(String _string) {
+
+ stringC = _string;
+ }
+
+
+ // Getters
+ public String sumArray(String[] newA) {
+
+ String sum = "";
+ for (String i : newA)
+ sum = sum + i;
+ return sum;
+ }
+
+
+ public int setAndGetA(int newA) {
+
+ intA = newA;
+ return intA;
+ }
+
+
+ public int setACAndGetA(String newC, int newA) {
+
+ stringC = newC;
+ intA = newA;
+ return intA;
+ }
+
+
+ public void registerCallback(CallBackInterface _cb) {
+
+ cb = _cb;
+ }
+
+
+ public int callBack() {
+
+ System.out.println("This callBack function is called inside TestClass!");
+ return cb.printInt();
+ }
+
+
+ public static void main(String[] args) {
+
+ TestClass tc = new TestClass();
+ CallBack cb = new CallBack(3);
+
+ tc.registerCallback(cb);
+ System.out.println("Return value: " + tc.callBack());
+ }
+}
--- /dev/null
+package iotrmi.Java.sample;
+
+import java.io.IOException;
+import java.util.Set;
+import iotrmi.Java.IoTRMIObject;
+
+import java.util.Arrays;
+
+public class TestClass_Skeleton {
+
+ private String[] methodSignatures = {
+
+ "voidsetA(int)",
+ "voidsetB(float)",
+ "voidsetC(string)",
+ "sumArray(string[])",
+ "intsetAndGetA(int)",
+ "intsetACAndGetA(string,int)",
+ "intcallBack()",
+ "voidregisterCallBack(CallBackInterface)"
+ };
+
+ private TestClass tc;
+ private IoTRMIObject rmiObj;
+ private CallBackInterface cbstub;
+
+
+ /**
+ * Constructors
+ */
+ //public TestClass_Skeleton(Object[] paramObj, int _port) throws
+ public TestClass_Skeleton(TestClass _tc, int _port) throws
+ ClassNotFoundException, InstantiationException,
+ IllegalAccessException, IOException {
+
+ //tc = new TestClass((int)paramObj[0], (float)paramObj[1], (String)paramObj[2]);
+ tc = _tc;
+ rmiObj = new IoTRMIObject(_port, methodSignatures);
+ }
+
+
+ public void waitRequestInvokeMethod() throws IOException {
+
+ // Loop continuously waiting for incoming bytes
+ while (true) {
+
+ rmiObj.getMethodBytes();
+ String methodSign = rmiObj.getSignature();
+ Object[] paramObj = null;
+ Object retObj = null;
+ System.out.println("Method sign: " + methodSign);
+
+ if (methodSign.equals("voidsetA(int)")) {
+ paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class },
+ new Class<?>[] { null }, new Class<?>[] { null });
+ tc.setA((int) paramObj[0]);
+ } else if (methodSign.equals("voidsetB(float)")) {
+ paramObj = rmiObj.getMethodParams(new Class<?>[] { float.class },
+ new Class<?>[] { null }, new Class<?>[] { null });
+ tc.setB((float) paramObj[0]);
+ } else if (methodSign.equals("voidsetC(string)")) {
+ paramObj = rmiObj.getMethodParams(new Class<?>[] { String.class },
+ new Class<?>[] { null }, new Class<?>[] { null });
+ tc.setC((String) paramObj[0]);
+ } else if (methodSign.equals("sumArray(string[])")) {
+ paramObj = rmiObj.getMethodParams(new Class<?>[] { String[].class },
+ new Class<?>[] { null }, new Class<?>[] { null });
+ retObj = tc.sumArray((String[]) paramObj[0]);
+ } else if (methodSign.equals("intsetAndGetA(int)")) {
+ paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class },
+ new Class<?>[] { null }, new Class<?>[] { null });
+ retObj = tc.setAndGetA((int) paramObj[0]);
+ } else if (methodSign.equals("intsetACAndGetA(string,int)")) {
+ paramObj = rmiObj.getMethodParams(new Class<?>[] { String.class, int.class },
+ new Class<?>[] { null, null }, new Class<?>[] { null, null });
+ retObj = tc.setACAndGetA((String) paramObj[0], (int) paramObj[1]);
+ } else if (methodSign.equals("voidregisterCallBack(CallBackInterface)")) {
+ paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class, String.class, int.class },
+ new Class<?>[] { null, null, null }, new Class<?>[] { null, null, null });
+ CallBackInterface cbstub = new CallBack_Stub((int) paramObj[0], (String) paramObj[1], (int) paramObj[2]);
+ tc.registerCallback((CallBackInterface) cbstub);
+ } else if (methodSign.equals("intcallBack()")) {
+ retObj = tc.callBack();
+ } else
+ throw new Error("Signature un-recognized!");
+
+ if (retObj != null) {
+ rmiObj.sendReturnObj(retObj);
+ }
+ System.out.println("Servicing remote call for method: " + methodSign);
+ }
+ }
+
+
+ public static void main(String[] args) throws Exception {
+
+ int port = 5010;
+ TestClass tc = new TestClass(3, 5f, "7911");
+ //TestClass_Skeleton tcSkel = new TestClass_Skeleton(new Object[] { 3, 5f, "7911"}, port);
+ TestClass_Skeleton tcSkel = new TestClass_Skeleton(tc, port);
+ tcSkel.waitRequestInvokeMethod();
+ }
+}
--- /dev/null
+package iotrmi.Java.sample;
+
+import java.io.IOException;
+import iotrmi.Java.IoTRMICall;
+import iotruntime.master.CommunicationHandler;
+
+import java.util.Arrays;
+
+public class TestClass_Stub {
+
+ /**
+ * Class Properties
+ */
+ private IoTRMICall rmiCall;
+ private String address;
+ private int[] ports;
+
+ /**
+ * Class Constants
+ */
+ private final static int NUM_CB_OBJ = 1;
+
+ /**
+ * Constructors
+ */
+ public TestClass_Stub(int _port, String _address, int _rev, int[] _ports) throws IOException {
+
+ address = _address;
+ ports = _ports;
+ rmiCall = new IoTRMICall(_port, _address, _rev);
+ }
+
+
+ /**
+ * Instantiation of callback objects
+ */
+ public static int numCallbackObjects() {
+
+ return NUM_CB_OBJ; // Generated by the IoTCompiler
+ }
+
+
+ private void registerCallback(CallBackInterface _cb) {
+
+ //int port = 5011; // Send this info to the other end to start the stub
+ //String address = "localhost";
+
+ Thread thread = new Thread() {
+ public void run() {
+ try{
+ CallBack_Skeleton cbskel = new CallBack_Skeleton(_cb, ports[0]);
+ cbskel.waitRequestInvokeMethod();
+ } catch (Exception ex){
+ ex.printStackTrace();
+ throw new Error("Error instantiating class CallBack_Skeleton!");
+ }
+ }
+ };
+ thread.start();
+
+ String sign = "voidregisterCallBack(CallBackInterface)";
+ Class<?> retType = void.class;
+ // port, address, and rev
+ Class<?>[] paramCls = new Class<?>[] { int.class, String.class, int.class };
+ Object[] paramObj = new Object[] { ports[0], address, 0 };
+ rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ }
+
+
+ public void setA(int _int) {
+
+ String sign = "voidsetA(int)";
+ Class<?> retType = void.class;
+ Class<?>[] paramCls = new Class<?>[] { int.class };
+ Object[] paramObj = new Object[] { _int };
+ rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ }
+
+
+ public void setB(float _float) {
+
+ String sign = "voidsetB(float)";
+ Class<?> retType = void.class;
+ Class<?>[] paramCls = new Class<?>[] { float.class };
+ Object[] paramObj = new Object[] { _float };
+ rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ }
+
+
+ public void setC(String _string) {
+
+ String sign = "voidsetC(string)";
+ Class<?> retType = void.class;
+ Class<?>[] paramCls = new Class<?>[] { String.class };
+ Object[] paramObj = new Object[] { _string };
+ rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ }
+
+
+ // Getters
+ public String sumArray(String[] newA) {
+
+ String sign = "sumArray(string[])";
+ Class<?> retType = String.class;
+ Class<?>[] paramCls = new Class<?>[] { String[].class };
+ Object[] paramObj = new Object[] { newA };
+ Object retObj = rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ return (String)retObj;
+ }
+
+
+ public int setAndGetA(int newA) {
+ String sign = "intsetAndGetA(int)";
+ Class<?> retType = int.class;
+ Class<?>[] paramCls = new Class<?>[] { int.class };
+ Object[] paramObj = new Object[] { newA };
+ Object retObj = rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ return (int)retObj;
+ }
+
+
+ public int setACAndGetA(String newC, int newA) {
+
+ String sign = "intsetACAndGetA(string,int)";
+ Class<?> retType = int.class;
+ Class<?>[] paramCls = new Class<?>[] { String.class, int.class };
+ Object[] paramObj = new Object[] { newC, newA };
+ Object retObj = rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ return (int)retObj;
+ }
+
+
+ public int callBack() {
+
+ String sign = "intcallBack()";
+ Class<?> retType = int.class;
+ Class<?>[] paramCls = new Class<?>[] { };
+ Object[] paramObj = new Object[] { };
+ Object retObj = rmiCall.remoteCall(sign, retType, null, null, paramCls, paramObj);
+ return (int)retObj;
+
+ }
+
+
+ public static void main(String[] args) throws Exception {
+
+ CommunicationHandler comHan = new CommunicationHandler(true);
+ int numOfPorts = TestClass_Stub.numCallbackObjects();
+ int[] ports = comHan.getCallbackPorts(numOfPorts);
+
+ System.out.println("Allocated ports: " + Arrays.toString(ports));
+
+ int port = 5010;
+ String address = "localhost";
+ int rev = 0;
+
+ TestClass_Stub tcstub = new TestClass_Stub(port, address, rev, ports);
+ System.out.println("Return value: " + tcstub.setAndGetA(123));
+ System.out.println("Return value: " + tcstub.setACAndGetA("string", 123));
+ System.out.println("Return value: " + tcstub.sumArray(new String[] { "123", "456", "987" }));
+
+ CallBack cb = new CallBack(23);
+ tcstub.registerCallback(cb);
+ System.out.println("Return value from callback: " + tcstub.callBack());
+ //System.out.println("Return value: " + tcstub.setAndGetA(1234));
+ }
+}
--- /dev/null
+package iotruntime.master;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+
+/** Class CommunicationHandler is a class that maintains
+ * a data structure that preserves a collection of host name,
+ * port numbers, and objects that are running
+ * +-----------------+----+--------+------------------+--------------+----------------+
+ * | HOST-ADDRESS | ...|IN-PORT | RMIREGISTRY-PORT | RMISTUB-PORT | ACTIVE OBJECTS |
+ * +-----------------+----+--------+------------------+--------------+----------------+
+ * | XXX.XXX.XXX.XXX | | XXXXX | XXXXX | XXXXX | XXXXXXXXXXXXXX |
+ * | | | XXXXX | XXXXX | XXXXX | XXXXXXXXXXXXXX |
+ * | | | XXXXX | XXXXX | XXXXX | XXXXXXXXXXXXXX |
+ * | | ...| ... | ... | ... | ... |
+ * +-----------------+----+--------+------------------+--------------+----------------+
+ * In this case we use ACTIVE OBJECTS names as the key
+ * So ACTIVE OBJECTS maps to numbers and these numbers map to each other
+ * entry in hashmaps (HostAddress can be repetitive)
+ * e.g. ACTIVE OBJECTS ProximitySensorPS0 - 0
+ * ProximitySensorPS1 - 1
+ * TempSensorTS1 - 2
+ * ...
+ * IN-PORT / RMIREGISTRY-PORT / RMISTUB-PORT / HOST-ADDRESS: 0 - XXXXX
+ * 1 - XXXXX
+ * 2 - XXXXX
+ * +-------------+
+ * | DEVICE-PORT |
+ * +-------------+
+ * | XXXXX |
+ * | XXXXX |
+ * | XXXXX |
+ * | ... |
+ * +-------------+
+ * We add a Set structure to handle all the other ports that are used by devices
+ * when communicating with their respective drivers
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2016-01-07
+ */
+public final class CommunicationHandler {
+
+ /**
+ * CommunicationHandler class properties
+ * <p>
+ * Random, host name, port number, active objects
+ * HostAdd is the key to the table so we use it
+ * as a key to elements
+ * HostList gives a mapping from hostname to list of objects
+ */
+ private Random random;
+ private List<String> listActiveControllerObj;
+ private List<String> listFieldObjectID;
+ private List<ObjectCreationInfo> listObjCrtInfo;
+ private List<Object[]> listArrFieldValues;
+ private List<Class[]> listArrFieldClasses;
+ private Map<String, Integer> hmActiveObj;
+ private Map<Integer, String> hmHostAdd;
+ private Map<String, ArrayList<String> > hmHostList;
+ private Map<Integer, Integer> hmComPort;
+ private Map<Integer, Integer> hmRMIRegPort;
+ private Map<Integer, Integer> hmRMIStubPort;
+ private Set<Integer> hsDevicePort;
+ private Set<Integer> hsCallbackPort;
+ private int iNumOfObjects;
+ private int iNumOfHosts;
+ private boolean bVerbose;
+
+ /**
+ * CommunicationHandler class constants
+ */
+ private final int INT_MAX_PORT = 65535;
+ private final int INT_MIN_PORT = 10000;
+
+ /**
+ * Empty constructor
+ */
+ public CommunicationHandler(boolean _bVerbose) {
+
+ random = new Random();
+ listActiveControllerObj = new ArrayList<String>();
+ listFieldObjectID = new ArrayList<String>();
+ listObjCrtInfo = new ArrayList<ObjectCreationInfo>();
+ listArrFieldValues = new ArrayList<Object[]>();
+ listArrFieldClasses = new ArrayList<Class[]>();
+ hmActiveObj = new HashMap<String, Integer>();
+ hmHostAdd = new HashMap<Integer, String>();
+ hmHostList = new HashMap<String, ArrayList<String>>();
+ hmComPort = new HashMap<Integer, Integer>();
+ hmRMIRegPort = new HashMap<Integer, Integer>();
+ hmRMIStubPort = new HashMap<Integer, Integer>();
+ hsDevicePort = new HashSet<Integer>();
+ hsCallbackPort = new HashSet<Integer>();
+ iNumOfObjects = 0;
+ iNumOfHosts = 0;
+ bVerbose = _bVerbose;
+ RuntimeOutput.print("CommunicationHandler: Creating a new CommunicationHandler object!", bVerbose);
+ }
+
+ /**
+ * Method addPortConnection()
+ * <p>
+ * Add a new connection then generate new in-port and out-port numbers
+ *
+ * @param sHAddress String host address
+ * @param sAObject String active object name
+ * @return void
+ */
+ public void addPortConnection(String sHAddress, String sAObject) {
+
+ // Increment counter first before we add objects as we start from 0
+ // Objects are named uniquely so we record this and match with the host
+ // Hostname occurrence can be repetitive as there can be more than
+ // one host on one compute node
+
+ // Add a new object in the list of objects
+ hmActiveObj.put(sAObject, iNumOfObjects);
+
+ // Check host existence in our data structure
+ // Add a new host and a new object
+ if(hmHostList.containsKey(sHAddress) == false) {
+ iNumOfHosts++;
+ hmHostList.put(sHAddress, new ArrayList<String>());
+ }
+ hmHostList.get(sHAddress).add(sAObject);
+
+ // Map object to host
+ hmHostAdd.put(iNumOfObjects, sHAddress);
+
+ int iComPort = 0;
+ do {
+ iComPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
+ // Check port existence in HashMap
+ } while (portIsAvailable(iComPort) == false);
+ hmComPort.put(iNumOfObjects, iComPort);
+
+ int iRMIRegPort = 0;
+ do {
+ iRMIRegPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
+ // Check port existence in HashMap
+ } while (portIsAvailable(iRMIRegPort) == false);
+ hmRMIRegPort.put(iNumOfObjects, iRMIRegPort);
+
+ int iRMIStubPort = 0;
+ do {
+ iRMIStubPort = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
+ // Check port existence in HashMap
+ } while (portIsAvailable(iRMIStubPort) == false);
+ hmRMIStubPort.put(iNumOfObjects, iRMIStubPort);
+
+ iNumOfObjects++;
+ }
+
+ /**
+ * A private method to add a new active controller object
+ *
+ * @params strFieldObjectID String field object ID
+ * @params strObjName String object name
+ * @params strObjClassName String object class name
+ * @params strObjClassInterfaceName String object class interface name
+ * @params strIoTSlaveObjectHostAdd String IoTSlave host address
+ * @params arrFieldValues Array of field values
+ * @params arrFieldClasses Array of field classes
+ * @return void
+ */
+ public void addActiveControllerObject(String strFieldObjectID, String strObjName, String strObjClassName,
+ String strObjClassInterfaceName, String strIoTSlaveObjectHostAdd, Object[] arrFieldValues,
+ Class[] arrFieldClasses) {
+
+ listActiveControllerObj.add(strObjName);
+ listFieldObjectID.add(strFieldObjectID);
+ listArrFieldValues.add(arrFieldValues);
+ listArrFieldClasses.add(arrFieldClasses);
+ ObjectCreationInfo objCrtInfo = new ObjectCreationInfo(strIoTSlaveObjectHostAdd, strObjName,
+ strObjClassName, strObjClassInterfaceName);
+ listObjCrtInfo.add(objCrtInfo);
+ }
+
+
+ /**
+ * Method getCallbackPort()
+ * <p>
+ * Get a new port for new connections for callback objects in the program.
+ * This newly generated port number will be recorded.
+ *
+ * @return int[] A set of callback ports
+ */
+ public int[] getCallbackPorts(int numOfPorts) {
+
+ int[] ports = new int[numOfPorts];
+
+ for(int i = 0; i < numOfPorts; i++) {
+ do {
+ ports[i] = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
+ // Check port existence in HashMap
+ } while (portIsAvailable(ports[i]) == false);
+ hsCallbackPort.add(ports[i]);
+ }
+
+ return ports;
+ }
+
+
+ /**
+ * Method addDevicePort()
+ * <p>
+ * Add a port that is used by a device when communicating with its driver
+ * This port will be taken into account when checking for port availability
+ *
+ * @param iDevPort Device port number
+ * @return void
+ */
+ public void addDevicePort(int iDevPort) {
+
+ hsDevicePort.add(iDevPort);
+
+ }
+
+ /**
+ * Method portIsAvailable()
+ * <p>
+ * Checks the availability of the newly generated port.
+ * If port number has been used in any of the lists then
+ * it is not available
+ *
+ * @param iPortNumber Device port number
+ * @return boolean
+ */
+ public boolean portIsAvailable(int iPortNumber) {
+
+ if (hmComPort.containsValue(iPortNumber) == true) {
+ return false;
+ } else if (hmRMIRegPort.containsValue(iPortNumber) == true) {
+ return false;
+ } else if (hmRMIStubPort.containsValue(iPortNumber) == true) {
+ return false;
+ } else if (hsDevicePort.contains(iPortNumber) == true) {
+ return false;
+ } else if (hsCallbackPort.contains(iPortNumber) == true) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Method getNumOfObjects()
+ *
+ * @return int
+ */
+ public int getNumOfObjects() {
+
+ return iNumOfObjects;
+
+ }
+
+ /**
+ * Method getNumOfHosts()
+ *
+ * @return int
+ */
+ public int getNumOfHosts() {
+
+ return iNumOfHosts;
+
+ }
+
+ /**
+ * Method objectExists()
+ *
+ * @param sObjName String object name
+ * @return boolean
+ */
+ public boolean objectExists(String sObjName) {
+
+ return hmActiveObj.containsKey(sObjName);
+
+ }
+
+ /**
+ * Method hostExists()
+ *
+ * @param sHostName String host name
+ * @return boolean
+ */
+ public boolean hostExists(String sHostName) {
+
+ return hmHostList.containsKey(sHostName);
+
+ }
+
+ /**
+ * Method getHostAddress()
+ * <p>
+ * User finds HostAddress using Object name
+ *
+ * @param sAObject String active object name
+ * @return String
+ */
+ public String getHostAddress(String sAObject) {
+
+ return hmHostAdd.get(hmActiveObj.get(sAObject));
+
+ }
+
+ /**
+ * Method getHosts()
+ * <p>
+ * User gets the set of hostnames
+ *
+ * @return String
+ */
+ public Set<String> getHosts() {
+
+ return hmHostList.keySet();
+
+ }
+
+ /**
+ * Method getComPort()
+ * <p>
+ * User finds In-Port number using Object name
+ *
+ * @param sAObject String active object name
+ * @return Integer
+ */
+ public Integer getComPort(String sAObject) {
+
+ return hmComPort.get(hmActiveObj.get(sAObject));
+ }
+
+ /**
+ * Method getRMIRegPort()
+ * <p>
+ * User finds Out-Port number using Object name
+ *
+ * @param sAObject String active object name
+ * @return Integer
+ */
+ public Integer getRMIRegPort(String sAObject) {
+
+ return hmRMIRegPort.get(hmActiveObj.get(sAObject));
+
+ }
+
+ /**
+ * Method getRMIStubPort()
+ * <p>
+ * User finds Out-Port number using Object name
+ *
+ * @param sAObject String active object name
+ * @return Integer
+ */
+ public Integer getRMIStubPort(String sAObject) {
+
+ return hmRMIStubPort.get(hmActiveObj.get(sAObject));
+
+ }
+
+ /**
+ * Method getFieldObjectID()
+ * <p>
+ * User finds field object ID using Object name
+ *
+ * @param sAObject String active object name
+ * @return String
+ */
+ public String getFieldObjectID(String sAObject) {
+
+ return listFieldObjectID.get(listActiveControllerObj.indexOf(sAObject));
+
+ }
+
+ /**
+ * Method getObjectCreationInfo()
+ * <p>
+ * User finds ObjectCreationInfo using Object name
+ *
+ * @param sAObject String active object name
+ * @return ObjectCreationInfo
+ */
+ public ObjectCreationInfo getObjectCreationInfo(String sAObject) {
+
+ return listObjCrtInfo.get(listActiveControllerObj.indexOf(sAObject));
+
+ }
+
+ /**
+ * Method getArrayFieldClasses()
+ * <p>
+ * User finds array of field classes using Object name
+ *
+ * @param sAObject String active object name
+ * @return Class[]
+ */
+ public Class[] getArrayFieldClasses(String sAObject) {
+
+ return listArrFieldClasses.get(listActiveControllerObj.indexOf(sAObject));
+
+ }
+
+ /**
+ * Method getArrayFieldValues()
+ * <p>
+ * User finds array of field values using Object name
+ *
+ * @param sAObject String active object name
+ * @return Object[]
+ */
+ public Object[] getArrayFieldValues(String sAObject) {
+
+ return listArrFieldValues.get(listActiveControllerObj.indexOf(sAObject));
+
+ }
+
+ /**
+ * Method getActiveControllerObjectList()
+ *
+ * @return List<String>
+ */
+ public List<String> getActiveControllerObjectList() {
+
+ return listActiveControllerObj;
+
+ }
+
+ /**
+ * Method printLists()
+ *
+ * @return void
+ */
+ public void printLists() {
+
+ // Iterate on HostAddress
+ for(String s : hmHostList.keySet()) {
+
+ for(String str : hmHostList.get(s)) {
+
+ int iIndex = hmActiveObj.get(str);
+ RuntimeOutput.print("Active Object: " + str, bVerbose);
+ RuntimeOutput.print("Communication Port: " + hmComPort.get(iIndex), bVerbose);
+ RuntimeOutput.print("RMI Registry Port: " + hmRMIRegPort.get(iIndex), bVerbose);
+ RuntimeOutput.print("RMI Stub Port: " + hmRMIStubPort.get(iIndex), bVerbose);
+ }
+ }
+
+ for(int iPort : hsDevicePort) {
+
+ RuntimeOutput.print("Device Port: " + iPort, bVerbose);
+
+ }
+ }
+}
--- /dev/null
+package iotruntime.master;
+
+/** A class that construct object creation info
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2015-05-13
+ */
+
+public class ObjectCreationInfo {
+
+ /**
+ * ObjectCreationInfo properties
+ */
+ protected String strIoTSlaveObjectHostAdd;
+ protected String strObjName;
+ protected String strObjClassName;
+ protected String strObjClassInterfaceName;
+
+ /**
+ * Constructor
+ */
+ public ObjectCreationInfo(String _strIoTSlaveObjectHostAdd, String _strObjName,
+ String _strObjClassName, String _strObjClassInterfaceName) {
+
+ strIoTSlaveObjectHostAdd = _strIoTSlaveObjectHostAdd;
+ strObjName = _strObjName;
+ strObjClassName = _strObjClassName;
+ strObjClassInterfaceName = _strObjClassInterfaceName;
+ }
+
+ /**
+ * Method getIoTSlaveObjectHostAdd()
+ */
+ public String getIoTSlaveObjectHostAdd() {
+ return strIoTSlaveObjectHostAdd;
+ }
+
+ /**
+ * Method getObjectName()
+ */
+ public String getObjectName() {
+ return strObjName;
+ }
+
+ /**
+ * Method getObjectClassName()
+ */
+ public String getObjectClassName() {
+ return strObjClassName;
+ }
+
+ /**
+ * Method getObjectClassInterfaceName()
+ */
+ public String getObjectClassInterfaceName() {
+ return strObjClassInterfaceName;
+ }
+}
--- /dev/null
+package iotruntime.master;
+
+/** Class RuntimeOutput is a class that controls the verboseness
+ * of the runtime system
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2016-05-11
+ */
+public final class RuntimeOutput {
+
+ /**
+ * print() method to print messages
+ *
+ * @param strMessage Message to print out
+ * @return void
+ */
+ public static void print(String strMessage, boolean bVerbose) {
+
+ if (bVerbose == true) {
+ System.out.println(strMessage);
+ }
+ }
+}