From 599d490dfb2d36edde42dceda38b725e08e0485f Mon Sep 17 00:00:00 2001 From: rtrimana Date: Mon, 17 Oct 2016 11:35:05 -0700 Subject: [PATCH] Early version of RMI system for Java part; supports primitives, one-dimensional array, some of the Collection classes (but not recursively parsed), and callback mechanism --- iotjava/Makefile | 6 + iotjava/iotrmi/IoTRMITypes.java | 12 +- iotjava/iotrmi/Java/IoTRMICall.java | 99 +- iotjava/iotrmi/Java/IoTRMIObject.java | 152 +-- iotjava/iotrmi/Java/IoTRMIUtil.java | 968 ++++++++++++++++-- iotjava/iotrmi/Java/IoTSocket.java | 2 + iotjava/iotrmi/Java/sample/CallBack.java | 30 + .../iotrmi/Java/sample/CallBackInterface.java | 8 + .../iotrmi/Java/sample/CallBack_Skeleton.java | 71 ++ iotjava/iotrmi/Java/sample/CallBack_Stub.java | 53 + iotjava/iotrmi/Java/sample/TestClass.java | 99 ++ .../Java/sample/TestClass_Skeleton.java | 103 ++ .../iotrmi/Java/sample/TestClass_Stub.java | 167 +++ .../master/CommunicationHandler.java | 459 +++++++++ .../iotruntime/master/ObjectCreationInfo.java | 59 ++ iotjava/iotruntime/master/RuntimeOutput.java | 24 + 16 files changed, 2113 insertions(+), 199 deletions(-) create mode 100644 iotjava/iotrmi/Java/sample/CallBack.java create mode 100644 iotjava/iotrmi/Java/sample/CallBackInterface.java create mode 100644 iotjava/iotrmi/Java/sample/CallBack_Skeleton.java create mode 100644 iotjava/iotrmi/Java/sample/CallBack_Stub.java create mode 100644 iotjava/iotrmi/Java/sample/TestClass.java create mode 100644 iotjava/iotrmi/Java/sample/TestClass_Skeleton.java create mode 100644 iotjava/iotrmi/Java/sample/TestClass_Stub.java create mode 100644 iotjava/iotruntime/master/CommunicationHandler.java create mode 100644 iotjava/iotruntime/master/ObjectCreationInfo.java create mode 100644 iotjava/iotruntime/master/RuntimeOutput.java diff --git a/iotjava/Makefile b/iotjava/Makefile index c02a5fe..d9b968f 100644 --- a/iotjava/Makefile +++ b/iotjava/Makefile @@ -22,11 +22,17 @@ PHONY += run-compiler 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: diff --git a/iotjava/iotrmi/IoTRMITypes.java b/iotjava/iotrmi/IoTRMITypes.java index a0c682f..c8ebcf3 100644 --- a/iotjava/iotrmi/IoTRMITypes.java +++ b/iotjava/iotrmi/IoTRMITypes.java @@ -40,7 +40,7 @@ public class IoTRMITypes { "void" // 0 byte }; - + /** * Primitive data types in C++ to map the primitives list */ @@ -137,4 +137,14 @@ public class IoTRMITypes { map.put(arrKey[i], arrVal[i]); } } + + // Inserting array members into a Map object + // that maps arrKey to arrVal objects + public static void arraysToMap(Map map, Object[] arrKey, Object[] arrVal) { + + for(int i = 0; i < arrKey.length; i++) { + + map.put(arrKey[i], arrVal[i]); + } + } } diff --git a/iotjava/iotrmi/Java/IoTRMICall.java b/iotjava/iotrmi/Java/IoTRMICall.java index 9410662..9353f33 100644 --- a/iotjava/iotrmi/Java/IoTRMICall.java +++ b/iotjava/iotrmi/Java/IoTRMICall.java @@ -9,6 +9,9 @@ import java.util.List; 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. *

@@ -22,6 +25,7 @@ import java.lang.reflect.Method; */ public class IoTRMICall { + /** * Class Properties */ @@ -42,15 +46,29 @@ public class IoTRMICall { /** * 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; } @@ -104,17 +122,64 @@ public class IoTRMICall { 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 set = new HashSet(); + 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 setStr = (Set) obj; + System.out.println("Set: " + setStr.toString());*/ + + // List + /*List list = new ArrayList(); + 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 listStr = (List) obj; + System.out.println("List: " + listStr.toString());*/ + + // Map + Map map = new HashMap(); + 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) obj; + System.out.println("Received map: " + map.toString()); + + //@SuppressWarnings("unchecked") + //List listStr = (List) obj; + //System.out.println("List: " + listStr.toString()); + } } diff --git a/iotjava/iotrmi/Java/IoTRMIObject.java b/iotjava/iotrmi/Java/IoTRMIObject.java index 9f40b82..c8fefa4 100644 --- a/iotjava/iotrmi/Java/IoTRMIObject.java +++ b/iotjava/iotrmi/Java/IoTRMIObject.java @@ -28,109 +28,66 @@ public class IoTRMIObject { /** * Class Properties */ - private Map mapSign2Method; // Map from signature to method private Map 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(); mapHash2Sign = new HashMap(); - 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 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 *

* Basically this is the format of a method in bytes: * 1) 32-bit value of method ID (hash code) @@ -146,20 +103,10 @@ public class IoTRMIObject { * | 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++) { @@ -176,56 +123,23 @@ public class IoTRMIObject { 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 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(); - } } diff --git a/iotjava/iotrmi/Java/IoTRMIUtil.java b/iotjava/iotrmi/Java/IoTRMIUtil.java index df76959..50965ba 100644 --- a/iotjava/iotrmi/Java/IoTRMIUtil.java +++ b/iotjava/iotrmi/Java/IoTRMIUtil.java @@ -7,9 +7,14 @@ import java.io.ObjectInputStream; 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; @@ -37,6 +42,15 @@ public class IoTRMIUtil { 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 */ @@ -57,27 +71,6 @@ public class IoTRMIUtil { } - /** - * 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 */ @@ -123,41 +116,167 @@ public class IoTRMIUtil { 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 - 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 - 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; } @@ -186,21 +305,338 @@ public class IoTRMIUtil { } 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 + // 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 + // 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 retSet = new HashSet(); + 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 retList = new ArrayList(); + 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 - 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 retMap = new HashMap(); + 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(); @@ -209,7 +645,7 @@ public class IoTRMIUtil { public static byte[] intToByteArray(int i) { - ByteBuffer bb = ByteBuffer.allocate(4); + ByteBuffer bb = ByteBuffer.allocate(INT_LEN); bb.putInt(i); return bb.array(); @@ -218,7 +654,7 @@ public class IoTRMIUtil { public static byte[] longToByteArray(long l) { - ByteBuffer bb = ByteBuffer.allocate(8); + ByteBuffer bb = ByteBuffer.allocate(LNG_LEN); bb.putLong(l); return bb.array(); @@ -227,7 +663,7 @@ public class IoTRMIUtil { public static byte[] floatToByteArray(float f) { - ByteBuffer bb = ByteBuffer.allocate(4); + ByteBuffer bb = ByteBuffer.allocate(FLT_LEN); bb.putFloat(f); return bb.array(); @@ -236,7 +672,7 @@ public class IoTRMIUtil { public static byte[] doubleToByteArray(double d) { - ByteBuffer bb = ByteBuffer.allocate(8); + ByteBuffer bb = ByteBuffer.allocate(DBL_LEN); bb.putDouble(d); return bb.array(); @@ -245,7 +681,7 @@ public class IoTRMIUtil { public static byte[] charToByteArray(char c) { - ByteBuffer bb = ByteBuffer.allocate(2); + ByteBuffer bb = ByteBuffer.allocate(CHR_LEN); bb.putChar(c); return bb.array(); @@ -254,7 +690,7 @@ public class IoTRMIUtil { public static byte[] booleanToByteArray(boolean b) { - ByteBuffer bb = ByteBuffer.allocate(1); + ByteBuffer bb = ByteBuffer.allocate(BOL_LEN); if (b) bb.put((byte)1); else @@ -264,10 +700,27 @@ public class IoTRMIUtil { } + 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); } @@ -276,9 +729,20 @@ public class IoTRMIUtil { } + 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); } @@ -287,9 +751,20 @@ public class IoTRMIUtil { } + 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); } @@ -298,9 +773,20 @@ public class IoTRMIUtil { } + 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); } @@ -309,9 +795,20 @@ public class IoTRMIUtil { } + 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); } @@ -320,9 +817,20 @@ public class IoTRMIUtil { } + 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); } @@ -331,9 +839,20 @@ public class IoTRMIUtil { } + 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); @@ -345,10 +864,55 @@ public class IoTRMIUtil { } + 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(); @@ -396,11 +960,291 @@ public class IoTRMIUtil { } - 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 *

diff --git a/iotjava/iotrmi/Java/IoTSocket.java b/iotjava/iotrmi/Java/IoTSocket.java index f941e91..60aac84 100644 --- a/iotjava/iotrmi/Java/IoTSocket.java +++ b/iotjava/iotrmi/Java/IoTSocket.java @@ -68,6 +68,8 @@ public abstract class IoTSocket { 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) diff --git a/iotjava/iotrmi/Java/sample/CallBack.java b/iotjava/iotrmi/Java/sample/CallBack.java new file mode 100644 index 0000000..9c4c368 --- /dev/null +++ b/iotjava/iotrmi/Java/sample/CallBack.java @@ -0,0 +1,30 @@ +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; + } +} diff --git a/iotjava/iotrmi/Java/sample/CallBackInterface.java b/iotjava/iotrmi/Java/sample/CallBackInterface.java new file mode 100644 index 0000000..e29359f --- /dev/null +++ b/iotjava/iotrmi/Java/sample/CallBackInterface.java @@ -0,0 +1,8 @@ +package iotrmi.Java.sample; + +public interface CallBackInterface { + + public int printInt(); + public void setInt(int _i); + +} diff --git a/iotjava/iotrmi/Java/sample/CallBack_Skeleton.java b/iotjava/iotrmi/Java/sample/CallBack_Skeleton.java new file mode 100644 index 0000000..46e0df6 --- /dev/null +++ b/iotjava/iotrmi/Java/sample/CallBack_Skeleton.java @@ -0,0 +1,71 @@ +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(); + } +} diff --git a/iotjava/iotrmi/Java/sample/CallBack_Stub.java b/iotjava/iotrmi/Java/sample/CallBack_Stub.java new file mode 100644 index 0000000..3ec19d5 --- /dev/null +++ b/iotjava/iotrmi/Java/sample/CallBack_Stub.java @@ -0,0 +1,53 @@ +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(); + } +} diff --git a/iotjava/iotrmi/Java/sample/TestClass.java b/iotjava/iotrmi/Java/sample/TestClass.java new file mode 100644 index 0000000..0b9f408 --- /dev/null +++ b/iotjava/iotrmi/Java/sample/TestClass.java @@ -0,0 +1,99 @@ +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()); + } +} diff --git a/iotjava/iotrmi/Java/sample/TestClass_Skeleton.java b/iotjava/iotrmi/Java/sample/TestClass_Skeleton.java new file mode 100644 index 0000000..07dbda8 --- /dev/null +++ b/iotjava/iotrmi/Java/sample/TestClass_Skeleton.java @@ -0,0 +1,103 @@ +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(); + } +} diff --git a/iotjava/iotrmi/Java/sample/TestClass_Stub.java b/iotjava/iotrmi/Java/sample/TestClass_Stub.java new file mode 100644 index 0000000..a57f036 --- /dev/null +++ b/iotjava/iotrmi/Java/sample/TestClass_Stub.java @@ -0,0 +1,167 @@ +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)); + } +} diff --git a/iotjava/iotruntime/master/CommunicationHandler.java b/iotjava/iotruntime/master/CommunicationHandler.java new file mode 100644 index 0000000..1026b0c --- /dev/null +++ b/iotjava/iotruntime/master/CommunicationHandler.java @@ -0,0 +1,459 @@ +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 + * @version 1.0 + * @since 2016-01-07 + */ +public final class CommunicationHandler { + + /** + * CommunicationHandler class properties + *

+ * 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 listActiveControllerObj; + private List listFieldObjectID; + private List listObjCrtInfo; + private List listArrFieldValues; + private List listArrFieldClasses; + private Map hmActiveObj; + private Map hmHostAdd; + private Map > hmHostList; + private Map hmComPort; + private Map hmRMIRegPort; + private Map hmRMIStubPort; + private Set hsDevicePort; + private Set 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(); + listFieldObjectID = new ArrayList(); + listObjCrtInfo = new ArrayList(); + listArrFieldValues = new ArrayList(); + listArrFieldClasses = new ArrayList(); + hmActiveObj = new HashMap(); + hmHostAdd = new HashMap(); + hmHostList = new HashMap>(); + hmComPort = new HashMap(); + hmRMIRegPort = new HashMap(); + hmRMIStubPort = new HashMap(); + hsDevicePort = new HashSet(); + hsCallbackPort = new HashSet(); + iNumOfObjects = 0; + iNumOfHosts = 0; + bVerbose = _bVerbose; + RuntimeOutput.print("CommunicationHandler: Creating a new CommunicationHandler object!", bVerbose); + } + + /** + * Method addPortConnection() + *

+ * 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()); + } + 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() + *

+ * 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() + *

+ * 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() + *

+ * 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() + *

+ * 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() + *

+ * User gets the set of hostnames + * + * @return String + */ + public Set getHosts() { + + return hmHostList.keySet(); + + } + + /** + * Method getComPort() + *

+ * 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() + *

+ * 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() + *

+ * 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() + *

+ * 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() + *

+ * 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() + *

+ * 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() + *

+ * 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 + */ + public List 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); + + } + } +} diff --git a/iotjava/iotruntime/master/ObjectCreationInfo.java b/iotjava/iotruntime/master/ObjectCreationInfo.java new file mode 100644 index 0000000..59161be --- /dev/null +++ b/iotjava/iotruntime/master/ObjectCreationInfo.java @@ -0,0 +1,59 @@ +package iotruntime.master; + +/** A class that construct object creation info + * + * @author Rahmadi Trimananda + * @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; + } +} diff --git a/iotjava/iotruntime/master/RuntimeOutput.java b/iotjava/iotruntime/master/RuntimeOutput.java new file mode 100644 index 0000000..5be24d3 --- /dev/null +++ b/iotjava/iotruntime/master/RuntimeOutput.java @@ -0,0 +1,24 @@ +package iotruntime.master; + +/** Class RuntimeOutput is a class that controls the verboseness + * of the runtime system + * + * @author Rahmadi Trimananda + * @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); + } + } +} -- 2.34.1