Cleaning up code for runtime, installer, RMI, compiler for the Java side
[iot2.git] / iotjava / iotruntime / slave / IoTSlave.java
index 7db7ea79500aa4526589666212f64da520aec237..061de08ff4f2b18530490f8dce557ca2ef0fe391 100644 (file)
@@ -31,6 +31,7 @@ import java.rmi.RemoteException;
 import java.rmi.AlreadyBoundException;
 import java.rmi.NotBoundException;
 import java.rmi.server.UnicastRemoteObject;
+import java.util.Arrays;
 import java.util.Properties;
 import java.util.HashMap;
 import java.util.Map;
@@ -46,7 +47,7 @@ import net.lingala.zip4j.core.ZipFile;
  * @version     1.0
  * @since       2016-06-16
  */
-public class IoTSlave {
+public final class IoTSlave {
 
        /**
         * IoTSlave class properties
@@ -65,6 +66,7 @@ public class IoTSlave {
        private Socket socket;
        private ObjectOutputStream outStream;
        private ObjectInputStream inStream;
+       private Map<String,Object> mapObjNameStub;
 
        /**
         * IoTSet object, e.g. IoTSet<ProximitySensor> proximity_sensors;
@@ -121,6 +123,7 @@ public class IoTSlave {
                socket = null;
                outStream = null;
                inStream = null;
+               mapObjNameStub = new HashMap<String,Object>();
 
                STR_JAR_FILE_PATH = null;
                STR_OBJ_CLS_PFX = null;
@@ -145,10 +148,10 @@ public class IoTSlave {
                        FileInputStream fis = new FileInputStream(file);
                        prop.load(fis);
                } catch (IOException ex) {
-                       System.out.println("IoTMaster: Error reading config file: " + strCfgFileName);
+                       RuntimeOutput.print("IoTMaster: Error reading config file: " + strCfgFileName, BOOL_VERBOSE);
                        ex.printStackTrace();
                }
-               System.out.println("IoTMaster: Extracting information from config file: " + strCfgFileName);
+               RuntimeOutput.print("IoTMaster: Extracting information from config file: " + strCfgFileName, BOOL_VERBOSE);
                // Initialize constants from config file
                STR_JAR_FILE_PATH = prop.getProperty("JAR_FILE_PATH");
                STR_OBJ_CLS_PFX = prop.getProperty("OBJECT_CLASS_PREFIX");
@@ -162,13 +165,13 @@ public class IoTSlave {
                        CAPAB_BASED_RMI = true;
                }
 
-               System.out.println("JAR_FILE_PATH=" + STR_JAR_FILE_PATH);
-               System.out.println("OBJECT_CLASS_PREFIX=" + STR_OBJ_CLS_PFX);
-               System.out.println("INTERFACE_PREFIX=" + STR_INTERFACE_PFX);
-               System.out.println("SKEL_CLASS_SUFFIX=" + SKEL_CLASS_SUFFIX);
-               System.out.println("STUB_CLASS_SUFFIX=" + STUB_CLASS_SUFFIX);
-               System.out.println("CAPAB_BASED_RMI=" + CAPAB_BASED_RMI);
-               System.out.println("IoTMaster: Information extracted successfully!");
+               RuntimeOutput.print("JAR_FILE_PATH=" + STR_JAR_FILE_PATH, BOOL_VERBOSE);
+               RuntimeOutput.print("OBJECT_CLASS_PREFIX=" + STR_OBJ_CLS_PFX, BOOL_VERBOSE);
+               RuntimeOutput.print("INTERFACE_PREFIX=" + STR_INTERFACE_PFX, BOOL_VERBOSE);
+               RuntimeOutput.print("SKEL_CLASS_SUFFIX=" + SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
+               RuntimeOutput.print("STUB_CLASS_SUFFIX=" + STUB_CLASS_SUFFIX, BOOL_VERBOSE);
+               RuntimeOutput.print("CAPAB_BASED_RMI=" + CAPAB_BASED_RMI, BOOL_VERBOSE);
+               RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
        }
 
        /**
@@ -202,7 +205,7 @@ public class IoTSlave {
         * @return  void
         */
        private void createCapabBasedRMIJava(MessageCreateObject sMessage) throws 
-               ClassNotFoundException, NoSuchMethodException {
+               ClassNotFoundException, NoSuchMethodException, UnknownHostException {
 
                // Instantiate the skeleton and put in the object
                String strObjSkelName = STR_OBJ_CLS_PFX + "." + sMessage.getObjectClass() +
@@ -211,9 +214,9 @@ public class IoTSlave {
                Class<?> clsSkel = Class.forName(strObjSkelName);
                Class<?> clsInt = Class.forName(STR_OBJ_CLS_PFX + "." + STR_INTERFACE_PFX + 
                        "." + sMessage.getObjectInterfaceName());
-               Class[] clsSkelParams = { clsInt, int.class };  // Port number is integer
+               Class[] clsSkelParams = { clsInt, int.class, int.class };       // Port number is integer
                Constructor<?> objSkelCons = clsSkel.getDeclaredConstructor(clsSkelParams);
-               Object objSkelParams[] = { objMainCls, iRMIStubPort };
+               Object objSkelParams[] = { objMainCls, iRMIStubPort, iRMIRegPort };
                // Create a new thread for each skeleton
                Thread objectThread = new Thread(new Runnable() {
                        public void run() {
@@ -431,29 +434,33 @@ public class IoTSlave {
 
                // Translating into the actual Message class
                MessageGetObject sMessage = (MessageGetObject) sIoTMasterMsg;
-               // Instantiate the stub and put in the object
-               String strObjStubName = sMainObjectName + "." + sMessage.getObjectStubInterfaceName() + STUB_CLASS_SUFFIX;
-               RuntimeOutput.print("IoTSlave: Stub object: " + strObjStubName, BOOL_VERBOSE);
-               Class<?> clsStub = Class.forName(strObjStubName);       // Port number is integer
-               Class[] clsStubParams = { int.class, String.class, String.class, int.class, int[].class };
-               Constructor<?> objStubCons = clsStub.getDeclaredConstructor(clsStubParams);
-               int[] ports = { sMessage.getRMIRegPort() };             // TODO: Change this temporary use of reg port for callbacks
-               int rev = 0;
-               String callbackAddress = InetAddress.getLocalHost().getHostAddress();   // Callback address is this machine's address
-               Object objStubParams[] = { sMessage.getRMIStubPort(), sMessage.getHostAddress(), callbackAddress,
-                                                                       rev, ports };
-               RuntimeOutput.print("IoTSlave: Creating RMI stub: " +
-                       sMessage.getHostAddress() + ":" + sMessage.getRMIRegPort() +
-                       " with callback address: " + callbackAddress + " and RMI stub port: " + sMessage.getRMIStubPort(), BOOL_VERBOSE);
-               Object stubObj = objStubCons.newInstance(objStubParams);
-               RuntimeOutput.print("IoTSlave: Object name: " + sMessage.getObjectName(), BOOL_VERBOSE);
-               RuntimeOutput.print("IoTSlave: Stub address: " + callbackAddress, BOOL_VERBOSE);
-               // Class conversion to interface class of this class,
-               // e.g. ProximitySensorImpl has ProximitySensor interface
+               Object stubObjConv = null;
+               String strObjectName = sMessage.getObjectName();
                String strObjClassInterfaceName = STR_OBJ_CLS_PFX + "." + STR_INTERFACE_PFX + "." +
                        sMessage.getObjectStubInterfaceName();
                Class<?> clsInf = Class.forName(strObjClassInterfaceName);
-               Object stubObjConv = clsInf.cast(stubObj);
+               if (mapObjNameStub.containsKey(strObjectName)) {
+                       RuntimeOutput.print("IoTSlave: Getting back object on slave: " + strObjectName, BOOL_VERBOSE);
+                       stubObjConv = clsInf.cast(mapObjNameStub.get(strObjectName));
+               } else {
+                       // Instantiate the stub and put in the object
+                       String strObjStubName = sMainObjectName + "." + sMessage.getObjectStubInterfaceName() + STUB_CLASS_SUFFIX;
+                       Class<?> clsStub = Class.forName(strObjStubName);       // Port number is integer
+                       Class[] clsStubParams = { int.class, int.class, int.class, int.class, String.class, int.class };
+                       Constructor<?> objStubCons = clsStub.getDeclaredConstructor(clsStubParams);
+
+                       int rev = 0;
+                       Object objStubParams[] = { 0, 0, sMessage.getRMIStubPort(), sMessage.getRMIRegPort(), sMessage.getHostAddress(), rev };
+                       RuntimeOutput.print("IoTSlave: Creating RMI stub: " +
+                               sMessage.getHostAddress() + ":" + sMessage.getRMIRegPort() + 
+                               " and RMI stub port: " + sMessage.getRMIStubPort(), BOOL_VERBOSE);
+                       Object stubObj = objStubCons.newInstance(objStubParams);
+                       // Class conversion to interface class of this class,
+                       // e.g. ProximitySensorImpl has ProximitySensor interface
+                       RuntimeOutput.print("IoTSlave: Registering new stub object: " + strObjectName, BOOL_VERBOSE);
+                       mapObjNameStub.put(strObjectName, stubObj);
+                       stubObjConv = clsInf.cast(stubObj);
+               }
 
                return stubObjConv;
        }
@@ -466,7 +473,6 @@ public class IoTSlave {
        private void getIoTSetObject() throws IOException,
                ClassNotFoundException, RemoteException, NotBoundException, NoSuchMethodException,
                InstantiationException, IllegalAccessException, InvocationTargetException {
-
                Object objRegistry = null;
                if (CAPAB_BASED_RMI)
                        objRegistry = getObjectFromStub();
@@ -488,7 +494,6 @@ public class IoTSlave {
        private void getIoTRelationFirstObject() throws IOException,
                ClassNotFoundException, RemoteException, NotBoundException, NoSuchMethodException,
                InstantiationException, IllegalAccessException, InvocationTargetException {
-
                Object objRegistry = null;
                if (CAPAB_BASED_RMI)
                        objRegistry = getObjectFromStub();
@@ -510,7 +515,6 @@ public class IoTSlave {
        private void getIoTRelationSecondObject() throws IOException,
                ClassNotFoundException, RemoteException, NotBoundException, NoSuchMethodException,
                InstantiationException, IllegalAccessException, InvocationTargetException {
-
                Object objRegistry = null;
                if (CAPAB_BASED_RMI)
                        objRegistry = getObjectFromStub();
@@ -538,7 +542,6 @@ public class IoTSlave {
 
                // Reinitialize IoTSet field after getting all the objects
                iotsetObject = new IoTSet<Object>(isetObject.values());
-
                // Private fields need getDeclaredField(), while public fields use getField()
                Field fld = clsMain.getDeclaredField(strFieldName);
                boolean bAccess = fld.isAccessible();
@@ -563,7 +566,6 @@ public class IoTSlave {
 
                // Reinitialize IoTSet field after getting all the objects
                iotrelObject = new IoTRelation<Object,Object>(irelObject.relationMap(), irelObject.size());
-
                // Private fields need getDeclaredField(), while public fields use getField()
                Field fld = clsMain.getDeclaredField(strFieldName);
                boolean bAccess = fld.isAccessible();
@@ -589,7 +591,6 @@ public class IoTSlave {
 
                // Translating into the actual Message class
                MessageGetDeviceObject sMessage = (MessageGetDeviceObject) sIoTMasterMsg;
-
                // Get IoTSet objects for IP address set on device driver/controller
                IoTDeviceAddress objDeviceAddress = new IoTDeviceAddress(sMessage.getHostAddress(),
                        sMessage.getSourceDeviceDriverPort(),
@@ -617,7 +618,6 @@ public class IoTSlave {
 
                // Translating into the actual Message class
                MessageGetSimpleDeviceObject sMessage = (MessageGetSimpleDeviceObject) sIoTMasterMsg;
-
                // Get IoTSet objects for IP address set on device driver/controller
                IoTZigbeeAddress objZBDevAddress = new IoTZigbeeAddress(sMessage.getHostAddress());
                RuntimeOutput.print("IoTSlave: Device address transferred: " + sMessage.getHostAddress(), BOOL_VERBOSE);
@@ -640,7 +640,6 @@ public class IoTSlave {
 
                // Translating into the actual Message class
                MessageGetSimpleDeviceObject sMessage = (MessageGetSimpleDeviceObject) sIoTMasterMsg;
-
                // Get IoTSet objects for IP address set on device driver/controller
                IoTAddress objAddress = new IoTAddress(sMessage.getHostAddress());
                RuntimeOutput.print("IoTSlave: Address transferred: " + sMessage.getHostAddress(), BOOL_VERBOSE);
@@ -778,8 +777,6 @@ public class IoTSlave {
                        inStream.close();
                        socket.close();
                        RuntimeOutput.print("IoTSlave: Closing!", BOOL_VERBOSE);
-                       // We have to continuously loop because we are preserving our stubs and skeletons
-                       //while(true) { }
 
                } catch (IOException               |
                                 ClassNotFoundException    |