3 import java_cup.runtime.ComplexSymbolFactory;
4 import java_cup.runtime.ScannerBuffer;
6 import java.util.Arrays;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.Iterator;
13 import java.util.List;
17 import iotpolicy.parser.Lexer;
18 import iotpolicy.parser.Parser;
19 import iotpolicy.tree.ParseNode;
20 import iotpolicy.tree.ParseNodeVector;
21 import iotpolicy.tree.ParseTreeHandler;
22 import iotpolicy.tree.Declaration;
23 import iotpolicy.tree.DeclarationHandler;
24 import iotpolicy.tree.CapabilityDecl;
25 import iotpolicy.tree.InterfaceDecl;
26 import iotpolicy.tree.RequiresDecl;
27 import iotpolicy.tree.EnumDecl;
28 import iotpolicy.tree.StructDecl;
30 import iotrmi.Java.IoTRMITypes;
33 /** Class IoTCompiler is the main interface/stub compiler for
34 * files generation. This class calls helper classes
35 * such as Parser, Lexer, InterfaceDecl, CapabilityDecl,
36 * RequiresDecl, ParseTreeHandler, etc.
38 * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
42 public class IoTCompiler {
47 // Maps multiple interfaces to multiple objects of ParseTreeHandler
48 private Map<String,ParseTreeHandler> mapIntfacePTH;
49 private Map<String,DeclarationHandler> mapIntDeclHand;
50 private Map<String,Map<String,Set<String>>> mapInt2NewInts;
51 private Map<String,String> mapInt2NewIntName;
52 // Data structure to store our types (primitives and non-primitives) for compilation
53 private Map<String,String> mapPrimitives;
54 private Map<String,String> mapNonPrimitivesJava;
55 private Map<String,String> mapNonPrimitivesCplus;
56 // Other data structures
57 private Map<String,Integer> mapIntfaceObjId; // Maps interface name to object Id
58 private Map<String,Integer> mapNewIntfaceObjId; // Maps new interface name to its object Id (keep track of stubs)
59 private PrintWriter pw;
61 private String subdir;
62 private Map<String,Integer> mapPortCount; // Counter for ports
63 private static int portCount = 0;
69 private final static String OUTPUT_DIRECTORY = "output_files";
71 private enum ParamCategory {
73 PRIMITIVES, // All the primitive types, e.g. byte, short, int, long, etc.
74 NONPRIMITIVES, // Non-primitive types, e.g. Set, Map, List, etc.
76 STRUCT, // Struct type
77 USERDEFINED // Assumed as driver classes
84 public IoTCompiler() {
86 mapIntfacePTH = new HashMap<String,ParseTreeHandler>();
87 mapIntDeclHand = new HashMap<String,DeclarationHandler>();
88 mapInt2NewInts = new HashMap<String,Map<String,Set<String>>>();
89 mapInt2NewIntName = new HashMap<String,String>();
90 mapIntfaceObjId = new HashMap<String,Integer>();
91 mapNewIntfaceObjId = new HashMap<String,Integer>();
92 mapPrimitives = new HashMap<String,String>();
93 arraysToMap(mapPrimitives, IoTRMITypes.primitivesJava, IoTRMITypes.primitivesCplus);
94 mapNonPrimitivesJava = new HashMap<String,String>();
95 arraysToMap(mapNonPrimitivesJava, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitiveJavaLibs);
96 mapNonPrimitivesCplus = new HashMap<String,String>();
97 arraysToMap(mapNonPrimitivesCplus, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus);
98 mapPortCount = new HashMap<String,Integer>();
100 dir = OUTPUT_DIRECTORY;
106 * setDataStructures() sets parse tree and other data structures based on policy files.
108 * It also generates parse tree (ParseTreeHandler) and
109 * copies useful information from parse tree into
110 * InterfaceDecl, CapabilityDecl, and RequiresDecl
112 * Additionally, the data structure handles are
113 * returned from tree-parsing for further process.
115 public void setDataStructures(String origInt, ParseNode pnPol, ParseNode pnReq) {
117 ParseTreeHandler ptHandler = new ParseTreeHandler(origInt, pnPol, pnReq);
118 DeclarationHandler decHandler = new DeclarationHandler();
119 // Process ParseNode and generate Declaration objects
121 ptHandler.processInterfaceDecl();
122 InterfaceDecl intDecl = ptHandler.getInterfaceDecl();
123 decHandler.addInterfaceDecl(origInt, intDecl);
125 ptHandler.processCapabilityDecl();
126 CapabilityDecl capDecl = ptHandler.getCapabilityDecl();
127 decHandler.addCapabilityDecl(origInt, capDecl);
129 ptHandler.processRequiresDecl();
130 RequiresDecl reqDecl = ptHandler.getRequiresDecl();
131 decHandler.addRequiresDecl(origInt, reqDecl);
133 ptHandler.processEnumDecl();
134 EnumDecl enumDecl = ptHandler.getEnumDecl();
135 decHandler.addEnumDecl(origInt, enumDecl);
137 ptHandler.processStructDecl();
138 StructDecl structDecl = ptHandler.getStructDecl();
139 decHandler.addStructDecl(origInt, structDecl);
141 mapIntfacePTH.put(origInt, ptHandler);
142 mapIntDeclHand.put(origInt, decHandler);
143 // Set object Id counter to 0 for each interface
144 mapIntfaceObjId.put(origInt, new Integer(0));
149 * getMethodsForIntface() reads for methods in the data structure
151 * It is going to give list of methods for a certain interface
152 * based on the declaration of capabilities.
154 public void getMethodsForIntface(String origInt) {
156 ParseTreeHandler ptHandler = mapIntfacePTH.get(origInt);
157 Map<String,Set<String>> mapNewIntMethods = new HashMap<String,Set<String>>();
158 // Get set of new interfaces, e.g. CameraWithCaptureAndData
159 // Generate this new interface with all the methods it needs
160 // from different capabilities it declares
161 DeclarationHandler decHandler = mapIntDeclHand.get(origInt);
162 RequiresDecl reqDecl = (RequiresDecl) decHandler.getRequiresDecl(origInt);
163 Set<String> setIntfaces = reqDecl.getInterfaces();
164 for (String strInt : setIntfaces) {
166 // Initialize a set of methods
167 Set<String> setMethods = new HashSet<String>();
168 // Get list of capabilities, e.g. ImageCapture, VideoRecording, etc.
169 List<String> listCapab = reqDecl.getCapabList(strInt);
170 for (String strCap : listCapab) {
172 // Get list of methods for each capability
173 CapabilityDecl capDecl = (CapabilityDecl) decHandler.getCapabilityDecl(origInt);
174 List<String> listCapabMeth = capDecl.getMethods(strCap);
175 for (String strMeth : listCapabMeth) {
177 // Add methods into setMethods
178 // This is to also handle redundancies (say two capabilities
179 // share the same methods)
180 setMethods.add(strMeth);
183 // Add interface and methods information into map
184 mapNewIntMethods.put(strInt, setMethods);
185 // Map new interface method name to the original interface
186 // TODO: perhaps need to check in the future if we have more than 1 stub interface for one original interface
187 mapInt2NewIntName.put(origInt, strInt);
189 // Map the map of interface-methods to the original interface
190 mapInt2NewInts.put(origInt, mapNewIntMethods);
195 * HELPER: writeMethodJavaLocalInterface() writes the method of the local interface
197 private void writeMethodJavaLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
199 for (String method : methods) {
201 List<String> methParams = intDecl.getMethodParams(method);
202 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
203 print("public " + intDecl.getMethodType(method) + " " +
204 intDecl.getMethodId(method) + "(");
205 for (int i = 0; i < methParams.size(); i++) {
206 // Check for params with driver class types and exchange it
207 // with its remote interface
208 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
209 print(paramType + " " + methParams.get(i));
210 // Check if this is the last element (don't print a comma)
211 if (i != methParams.size() - 1) {
221 * HELPER: writeMethodJavaInterface() writes the method of the interface
223 private void writeMethodJavaInterface(Collection<String> methods, InterfaceDecl intDecl) {
225 for (String method : methods) {
227 List<String> methParams = intDecl.getMethodParams(method);
228 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
229 print("public " + intDecl.getMethodType(method) + " " +
230 intDecl.getMethodId(method) + "(");
231 for (int i = 0; i < methParams.size(); i++) {
232 // Check for params with driver class types and exchange it
233 // with its remote interface
234 String paramType = methPrmTypes.get(i);
235 print(paramType + " " + methParams.get(i));
236 // Check if this is the last element (don't print a comma)
237 if (i != methParams.size() - 1) {
247 * HELPER: generateEnumJava() writes the enumeration declaration
249 private void generateEnumJava() throws IOException {
251 // Create a new directory
252 createDirectory(dir);
253 for (String intface : mapIntfacePTH.keySet()) {
254 // Get the right EnumDecl
255 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
256 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
257 Set<String> enumTypes = enumDecl.getEnumDeclarations();
258 // Iterate over enum declarations
259 for (String enType : enumTypes) {
260 // Open a new file to write into
261 FileWriter fw = new FileWriter(dir + "/" + enType + ".java");
262 pw = new PrintWriter(new BufferedWriter(fw));
263 println("public enum " + enType + " {");
264 List<String> enumMembers = enumDecl.getMembers(enType);
265 for (int i = 0; i < enumMembers.size(); i++) {
267 String member = enumMembers.get(i);
269 // Check if this is the last element (don't print a comma)
270 if (i != enumMembers.size() - 1)
277 System.out.println("IoTCompiler: Generated enum class " + enType + ".java...");
284 * HELPER: generateStructJava() writes the struct declaration
286 private void generateStructJava() throws IOException {
288 // Create a new directory
289 createDirectory(dir);
290 for (String intface : mapIntfacePTH.keySet()) {
291 // Get the right StructDecl
292 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
293 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
294 List<String> structTypes = structDecl.getStructTypes();
295 // Iterate over enum declarations
296 for (String stType : structTypes) {
297 // Open a new file to write into
298 FileWriter fw = new FileWriter(dir + "/" + stType + ".java");
299 pw = new PrintWriter(new BufferedWriter(fw));
300 println("public class " + stType + " {");
301 List<String> structMemberTypes = structDecl.getMemberTypes(stType);
302 List<String> structMembers = structDecl.getMembers(stType);
303 for (int i = 0; i < structMembers.size(); i++) {
305 String memberType = structMemberTypes.get(i);
306 String member = structMembers.get(i);
307 println("public static " + memberType + " " + member + ";");
311 System.out.println("IoTCompiler: Generated struct class " + stType + ".java...");
318 * generateJavaLocalInterface() writes the local interface and provides type-checking.
320 * It needs to rewrite and exchange USERDEFINED types in input parameters of stub
321 * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording.
322 * The local interface has to be the input parameter for the stub and the stub
323 * interface has to be the input parameter for the local class.
325 public void generateJavaLocalInterfaces() throws IOException {
327 // Create a new directory
328 createDirectory(dir);
329 for (String intface : mapIntfacePTH.keySet()) {
330 // Open a new file to write into
331 FileWriter fw = new FileWriter(dir + "/" + intface + ".java");
332 pw = new PrintWriter(new BufferedWriter(fw));
333 // Pass in set of methods and get import classes
334 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
335 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
336 List<String> methods = intDecl.getMethods();
337 Set<String> importClasses = getImportClasses(methods, intDecl);
338 List<String> stdImportClasses = getStandardJavaIntfaceImportClasses();
339 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
340 printImportStatements(allImportClasses);
341 // Write interface header
343 println("public interface " + intface + " {");
345 writeMethodJavaLocalInterface(methods, intDecl);
348 System.out.println("IoTCompiler: Generated local interface " + intface + ".java...");
354 * HELPER: updateIntfaceObjIdMap() updates the mapping between new interface and object Id
356 private void updateIntfaceObjIdMap(String intface, String newIntface) {
358 Integer objId = mapIntfaceObjId.get(intface);
359 mapNewIntfaceObjId.put(newIntface, objId);
360 mapIntfaceObjId.put(intface, objId++);
365 * generateJavaInterfaces() generate stub interfaces based on the methods list in Java
367 public void generateJavaInterfaces() throws IOException {
369 // Create a new directory
370 String path = createDirectories(dir, subdir);
371 for (String intface : mapIntfacePTH.keySet()) {
373 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
374 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
376 // Open a new file to write into
377 String newIntface = intMeth.getKey();
378 FileWriter fw = new FileWriter(path + "/" + newIntface + ".java");
379 pw = new PrintWriter(new BufferedWriter(fw));
380 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
381 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
382 // Pass in set of methods and get import classes
383 Set<String> methods = intMeth.getValue();
384 Set<String> importClasses = getImportClasses(methods, intDecl);
385 List<String> stdImportClasses = getStandardJavaIntfaceImportClasses();
386 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
387 printImportStatements(allImportClasses);
388 // Write interface header
390 println("public interface " + newIntface + " {\n");
391 updateIntfaceObjIdMap(intface, newIntface);
393 writeMethodJavaInterface(methods, intDecl);
396 System.out.println("IoTCompiler: Generated interface " + newIntface + ".java...");
403 * HELPER: writePropertiesJavaPermission() writes the permission in properties
405 private void writePropertiesJavaPermission(String intface, InterfaceDecl intDecl) {
407 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
408 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
409 String newIntface = intMeth.getKey();
410 int newObjectId = getNewIntfaceObjectId(newIntface);
411 println("private final static int object" + newObjectId + "Id = " +
412 newObjectId + ";\t//" + newIntface);
413 Set<String> methodIds = intMeth.getValue();
414 print("private static Integer[] object" + newObjectId + "Permission = { ");
416 for (String methodId : methodIds) {
417 int methodNumId = intDecl.getMethodNumId(methodId);
418 print(Integer.toString(methodNumId));
419 // Check if this is the last element (don't print a comma)
420 if (i != methodIds.size() - 1) {
426 println("private static List<Integer> set" + newObjectId + "Allowed;");
432 * HELPER: writePropertiesJavaStub() writes the properties of the stub class
434 private void writePropertiesJavaStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
436 println("private IoTRMICall rmiCall;");
437 println("private String callbackAddress;");
438 println("private int[] ports;\n");
440 Integer objId = mapIntfaceObjId.get(intface);
441 println("private final static int objectId = " + objId + ";");
442 //mapNewIntfaceObjId.put(newIntface, objId);
443 //mapIntfaceObjId.put(intface, objId++);
445 // We assume that each class only has one callback interface for now
446 Iterator it = callbackClasses.iterator();
447 String callbackType = (String) it.next();
448 println("// Callback properties");
449 println("private IoTRMIObject rmiObj;");
450 println("List<" + callbackType + "> listCallbackObj;");
451 println("private int objIdCnt = 0;");
452 // Generate permission stuff for callback stubs
453 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
454 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
455 writePropertiesJavaPermission(callbackType, intDecl);
462 * HELPER: writeConstructorJavaPermission() writes the permission in constructor
464 private void writeConstructorJavaPermission(String intface) {
466 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
467 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
468 String newIntface = intMeth.getKey();
469 int newObjectId = getNewIntfaceObjectId(newIntface);
470 println("set" + newObjectId + "Allowed = new ArrayList<Integer>(Arrays.asList(object" + newObjectId +"Permission));");
476 * HELPER: writeConstructorJavaStub() writes the constructor of the stub class
478 private void writeConstructorJavaStub(String intface, String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
480 println("public " + newStubClass + "(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception {");
481 println("callbackAddress = _callbackAddress;");
482 println("ports = _ports;");
483 println("rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev);");
485 Iterator it = callbackClasses.iterator();
486 String callbackType = (String) it.next();
487 writeConstructorJavaPermission(callbackType);
488 println("listCallbackObj = new ArrayList<" + callbackType + ">();");
489 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
490 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
491 writeJavaInitCallbackPermission(callbackType, intDecl, callbackExist);
492 println("___initCallBack();");
499 * HELPER: writeJavaMethodCallbackPermission() writes permission checks in stub for callbacks
501 private void writeJavaMethodCallbackPermission(String intface) {
503 println("int methodId = IoTRMIObject.getMethodId(method);");
504 // Get all the different stubs
505 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
506 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
507 String newIntface = intMeth.getKey();
508 int newObjectId = getNewIntfaceObjectId(newIntface);
509 println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
510 println("throw new Error(\"Callback object for " + intface + " is not allowed to access method: \" + methodId);");
517 * HELPER: writeJavaInitCallbackPermission() writes the permission for callback
519 private void writeJavaInitCallbackPermission(String intface, InterfaceDecl intDecl, boolean callbackExist) {
522 String method = "___initCallBack()";
523 int methodNumId = intDecl.getHelperMethodNumId(method);
524 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
525 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
526 String newIntface = intMeth.getKey();
527 int newObjectId = getNewIntfaceObjectId(newIntface);
528 println("set" + newObjectId + "Allowed.add(" + methodNumId + ");");
535 * HELPER: getPortCount() gets port count for different stubs and skeletons
537 private int getPortCount(String intface) {
539 if (!mapPortCount.containsKey(intface))
540 mapPortCount.put(intface, portCount++);
541 return mapPortCount.get(intface);
546 * HELPER: writeInitCallbackJavaStub() writes callback initialization in stub
548 private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl, String newStubClass) {
550 println("public void ___initCallBack() {");
551 // Generate main thread for callbacks
552 println("Thread thread = new Thread() {");
553 println("public void run() {");
555 int port = getPortCount(newStubClass);
556 println("rmiObj = new IoTRMIObject(ports[" + port + "]);");
557 println("while (true) {");
558 println("byte[] method = rmiObj.getMethodBytes();");
559 println("int objId = IoTRMIObject.getObjectId(method);");
560 println(intface + "_CallbackSkeleton skel = (" + intface + "_CallbackSkeleton) listCallbackObj.get(objId);");
561 println("if (skel != null) {");
562 writeJavaMethodCallbackPermission(intface);
563 println("skel.invokeMethod(rmiObj);");
566 println("throw new Error(\"" + intface + ": Object with Id \" + objId + \" not found!\");");
570 println(" catch (Exception ex) {");
571 println("ex.printStackTrace();");
572 println("throw new Error(\"Error instantiating class " + intface + "_CallbackSkeleton!\");");
576 println("thread.start();\n");
577 // Generate info sending part
578 String method = "___initCallBack()";
579 int methodNumId = intDecl.getHelperMethodNumId(method);
580 println("int methodId = " + methodNumId + ";");
581 println("Class<?> retType = void.class;");
582 println("Class<?>[] paramCls = new Class<?>[] { int[].class, String.class, int.class };");
583 println("Object[] paramObj = new Object[] { ports, callbackAddress, 0 };");
584 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
590 * HELPER: checkAndWriteEnumTypeJavaStub() writes the enum type (convert from enum to int)
592 private void checkAndWriteEnumTypeJavaStub(List<String> methParams, List<String> methPrmTypes) {
594 // Iterate and find enum declarations
595 for (int i = 0; i < methParams.size(); i++) {
596 String paramType = methPrmTypes.get(i);
597 String param = methParams.get(i);
598 String simpleType = getGenericType(paramType);
599 if (isEnumClass(simpleType)) {
600 // Check if this is enum type
601 if (isArray(param)) { // An array
602 println("int len" + i + " = " + getSimpleIdentifier(param) + ".length;");
603 println("int paramEnum" + i + "[] = new int[len" + i + "];");
604 println("for (int i = 0; i < len" + i + "; i++) {");
605 println("paramEnum" + i + "[i] = " + getSimpleIdentifier(param) + "[i].ordinal();");
607 } else if (isList(paramType)) { // A list
608 println("int len" + i + " = " + getSimpleIdentifier(param) + ".size();");
609 println("int paramEnum" + i + "[] = new int[len" + i + "];");
610 println("for (int i = 0; i < len" + i + "; i++) {");
611 println("paramEnum" + i + "[i] = " + getSimpleIdentifier(param) + ".get(i).ordinal();");
613 } else { // Just one element
614 println("int paramEnum" + i + "[] = new int[1];");
615 println("paramEnum" + i + "[0] = " + param + ".ordinal();");
623 * HELPER: checkAndWriteEnumRetTypeJavaStub() writes the enum return type (convert from enum to int)
625 private void checkAndWriteEnumRetTypeJavaStub(String retType) {
627 // Strips off array "[]" for return type
628 String pureType = getSimpleArrayType(getGenericType(retType));
629 // Take the inner type of generic
630 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
631 pureType = getGenericType(retType);
632 if (isEnumClass(pureType)) {
633 // Check if this is enum type
635 println("int[] retEnum = (int[]) retObj;");
636 println(pureType + "[] enumVals = " + pureType + ".values();");
637 if (isArray(retType)) { // An array
638 println("int retLen = retEnum.length;");
639 println(pureType + "[] enumRetVal = new " + pureType + "[retLen];");
640 println("for (int i = 0; i < retLen; i++) {");
641 println("enumRetVal[i] = enumVals[retEnum[i]];");
643 } else if (isList(retType)) { // A list
644 println("int retLen = retEnum.length;");
645 println("List<" + pureType + "> enumRetVal = new ArrayList<" + pureType + ">();");
646 println("for (int i = 0; i < retLen; i++) {");
647 println("enumRetVal.add(enumVals[retEnum[i]]);");
649 } else { // Just one element
650 println(pureType + " enumRetVal = enumVals[retEnum[0]];");
652 println("return enumRetVal;");
658 * HELPER: checkAndWriteStructSetupJavaStub() writes the struct type setup
660 private void checkAndWriteStructSetupJavaStub(List<String> methParams, List<String> methPrmTypes,
661 InterfaceDecl intDecl, String method) {
663 // Iterate and find struct declarations
664 for (int i = 0; i < methParams.size(); i++) {
665 String paramType = methPrmTypes.get(i);
666 String param = methParams.get(i);
667 String simpleType = getGenericType(paramType);
668 if (isStructClass(simpleType)) {
669 // Check if this is enum type
670 int methodNumId = intDecl.getMethodNumId(method);
671 String helperMethod = methodNumId + "struct" + i;
672 println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
673 println("Class<?> retTypeStruct" + i + " = void.class;");
674 println("Class<?>[] paramClsStruct" + i + " = new Class<?>[] { int.class };");
675 if (isArray(param)) { // An array
676 println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".length };");
677 } else if (isList(paramType)) { // A list
678 println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".size() };");
679 } else { // Just one element
680 println("Object[] paramObjStruct" + i + " = new Object[] { new Integer(1) };");
682 println("rmiCall.remoteCall(objectId, methodIdStruct" + i +
683 ", retTypeStruct" + i + ", null, paramClsStruct" + i +
684 ", paramObjStruct" + i + ");\n");
691 * HELPER: isStructPresent() checks presence of struct
693 private boolean isStructPresent(List<String> methParams, List<String> methPrmTypes) {
695 // Iterate and find enum declarations
696 for (int i = 0; i < methParams.size(); i++) {
697 String paramType = methPrmTypes.get(i);
698 String param = methParams.get(i);
699 String simpleType = getGenericType(paramType);
700 if (isStructClass(simpleType))
708 * HELPER: writeLengthStructParamClassJavaStub() writes lengths of parameters
710 private void writeLengthStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
712 // Iterate and find struct declarations - count number of params
713 for (int i = 0; i < methParams.size(); i++) {
714 String paramType = methPrmTypes.get(i);
715 String param = methParams.get(i);
716 String simpleType = getGenericType(paramType);
717 if (isStructClass(simpleType)) {
718 int members = getNumOfMembers(simpleType);
719 if (isArray(param)) { // An array
720 String structLen = getSimpleArrayType(param) + ".length";
721 print(members + "*" + structLen);
722 } else if (isList(paramType)) { // A list
723 String structLen = getSimpleArrayType(param) + ".size()";
724 print(members + "*" + structLen);
726 print(Integer.toString(members));
729 if (i != methParams.size() - 1) {
737 * HELPER: writeStructMembersJavaStub() writes parameters of struct
739 private void writeStructMembersJavaStub(String simpleType, String paramType, String param) {
741 // Get the struct declaration for this struct and generate initialization code
742 StructDecl structDecl = getStructDecl(simpleType);
743 List<String> memTypes = structDecl.getMemberTypes(simpleType);
744 List<String> members = structDecl.getMembers(simpleType);
745 if (isArray(param)) { // An array
746 println("for(int i = 0; i < " + getSimpleIdentifier(param) + ".length; i++) {");
747 for (int i = 0; i < members.size(); i++) {
748 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
749 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
750 print("paramObj[pos++] = " + getSimpleIdentifier(param) + "[i].");
751 print(getSimpleIdentifier(members.get(i)));
755 } else if (isList(paramType)) { // A list
756 println("for(int i = 0; i < " + getSimpleIdentifier(param) + ".size(); i++) {");
757 for (int i = 0; i < members.size(); i++) {
758 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
759 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
760 print("paramObj[pos++] = " + getSimpleIdentifier(param) + ".get(i).");
761 print(getSimpleIdentifier(members.get(i)));
765 } else { // Just one struct element
766 for (int i = 0; i < members.size(); i++) {
767 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
768 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
769 print("paramObj[pos++] = " + getSimpleIdentifier(param) + ".");
770 print(getSimpleIdentifier(members.get(i)));
778 * HELPER: writeStructParamClassJavaStub() writes parameters if struct is present
780 private void writeStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes, String callbackType) {
782 print("int paramLen = ");
783 writeLengthStructParamClassJavaStub(methParams, methPrmTypes);
785 println("Object[] paramObj = new Object[paramLen];");
786 println("Class<?>[] paramCls = new Class<?>[paramLen];");
787 println("int pos = 0;");
788 // Iterate again over the parameters
789 for (int i = 0; i < methParams.size(); i++) {
790 String paramType = methPrmTypes.get(i);
791 String param = methParams.get(i);
792 String simpleType = getGenericType(paramType);
793 if (isStructClass(simpleType)) {
794 writeStructMembersJavaStub(simpleType, paramType, param);
795 } else if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
796 println("paramCls[pos] = int.class;");
797 print("paramObj[pos++] = ");
798 if (isArray(methParams.get(i)))
799 print(getSimpleIdentifier(methParams.get(i)) + ".length");
800 else if (isList(methPrmTypes.get(i)))
801 print(getSimpleIdentifier(methParams.get(i)) + ".size()");
803 print("new Integer(1)");
806 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
807 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
808 print("paramObj[pos++] = ");
809 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
818 * HELPER: writeStructRetMembersJavaStub() writes parameters of struct for return statement
820 private void writeStructRetMembersJavaStub(String simpleType, String retType) {
822 // Get the struct declaration for this struct and generate initialization code
823 StructDecl structDecl = getStructDecl(simpleType);
824 List<String> memTypes = structDecl.getMemberTypes(simpleType);
825 List<String> members = structDecl.getMembers(simpleType);
826 if (isArrayOrList(retType, retType)) { // An array or list
827 println("for(int i = 0; i < retLen; i++) {");
829 if (isArray(retType)) { // An array
830 for (int i = 0; i < members.size(); i++) {
831 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
832 print("structRet[i]." + getSimpleIdentifier(members.get(i)));
833 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
836 } else if (isList(retType)) { // A list
837 println(simpleType + " structRetMem = new " + simpleType + "();");
838 for (int i = 0; i < members.size(); i++) {
839 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
840 print("structRetMem." + getSimpleIdentifier(members.get(i)));
841 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
843 println("structRet.add(structRetMem);");
845 } else { // Just one struct element
846 for (int i = 0; i < members.size(); i++) {
847 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
848 print("structRet." + getSimpleIdentifier(members.get(i)));
849 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
852 println("return structRet;");
857 * HELPER: writeStructReturnJavaStub() writes parameters if struct is present for return statement
859 private void writeStructReturnJavaStub(String simpleType, String retType) {
861 // Handle the returned struct!!!
862 println("Object retLenObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
863 // Minimum retLen is 1 if this is a single struct object
864 println("int retLen = (int) retLenObj;");
865 int numMem = getNumOfMembers(simpleType);
866 println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
867 println("Class<?>[] retClsVal = new Class<?>[" + numMem + "*retLen];");
868 println("int retPos = 0;");
869 // Get the struct declaration for this struct and generate initialization code
870 StructDecl structDecl = getStructDecl(simpleType);
871 List<String> memTypes = structDecl.getMemberTypes(simpleType);
872 List<String> members = structDecl.getMembers(simpleType);
873 if (isArrayOrList(retType, retType)) { // An array or list
874 println("for(int i = 0; i < retLen; i++) {");
875 for (int i = 0; i < members.size(); i++) {
876 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
877 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
878 println("retClsVal[retPos++] = null;");
881 } else { // Just one struct element
882 for (int i = 0; i < members.size(); i++) {
883 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
884 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
885 println("retClsVal[retPos++] = null;");
888 println("Object[] retObj = rmiCall.getStructObjects(retCls, retClsVal);");
889 if (isArray(retType)) { // An array
890 println(simpleType + "[] structRet = new " + simpleType + "[retLen];");
891 println("for(int i = 0; i < retLen; i++) {");
892 println("structRet[i] = new " + simpleType + "();");
894 } else if (isList(retType)) { // A list
895 println("List<" + simpleType + "> structRet = new ArrayList<" + simpleType + ">();");
897 println(simpleType + " structRet = new " + simpleType + "();");
898 println("int retObjPos = 0;");
899 writeStructRetMembersJavaStub(simpleType, retType);
904 * HELPER: writeStdMethodBodyJavaStub() writes the standard method body in the stub class
906 private void writeStdMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
907 List<String> methPrmTypes, String method, String callbackType) {
909 checkAndWriteStructSetupJavaStub(methParams, methPrmTypes, intDecl, method);
910 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
911 String retType = intDecl.getMethodType(method);
912 println("Class<?> retType = " + getSimpleType(getStructType(getEnumType(retType))) + ".class;");
913 checkAndWriteEnumTypeJavaStub(methParams, methPrmTypes);
914 // Generate array of parameter types
915 if (isStructPresent(methParams, methPrmTypes)) {
916 writeStructParamClassJavaStub(methParams, methPrmTypes, callbackType);
918 print("Class<?>[] paramCls = new Class<?>[] { ");
919 for (int i = 0; i < methParams.size(); i++) {
920 String prmType = methPrmTypes.get(i);
921 if (checkCallbackType(prmType, callbackType)) { // Check if this has callback object
923 } else { // Generate normal classes if it's not a callback object
924 String paramType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
925 print(getSimpleType(getEnumType(paramType)) + ".class");
927 // Check if this is the last element (don't print a comma)
928 if (i != methParams.size() - 1) {
933 // Generate array of parameter objects
934 print("Object[] paramObj = new Object[] { ");
935 for (int i = 0; i < methParams.size(); i++) {
936 String paramType = methPrmTypes.get(i);
937 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
938 //if (isArray(methPrmTypes.get(i), methParams.get(i)))
939 if (isArray(methParams.get(i)))
940 print(getSimpleIdentifier(methParams.get(i)) + ".length");
941 else if (isList(methPrmTypes.get(i)))
942 print(getSimpleIdentifier(methParams.get(i)) + ".size()");
944 print("new Integer(1)");
946 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
947 // Check if this is the last element (don't print a comma)
948 if (i != methParams.size() - 1) {
954 // Check if this is "void"
955 if (retType.equals("void")) {
956 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
957 } else { // We do have a return value
958 // Generate array of parameter types
959 if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
960 writeStructReturnJavaStub(getGenericType(getSimpleArrayType(retType)), retType);
962 // This is an enum type
963 if (getParamCategory(getGenericType(getSimpleArrayType(retType))) == ParamCategory.ENUM) {
964 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
965 checkAndWriteEnumRetTypeJavaStub(retType);
966 } else if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) {
967 // Check if the return value NONPRIMITIVES
968 String retGenValType = getGenericType(retType);
969 println("Class<?> retGenValType = " + retGenValType + ".class;");
970 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);");
971 println("return (" + retType + ")retObj;");
973 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
974 println("return (" + retType + ")retObj;");
982 * HELPER: returnGenericCallbackType() returns the callback type
984 private String returnGenericCallbackType(String paramType) {
986 if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES)
987 return getGenericType(paramType);
994 * HELPER: checkCallbackType() checks the callback type
996 private boolean checkCallbackType(String paramType, String callbackType) {
998 String prmType = returnGenericCallbackType(paramType);
999 if (callbackType == null) // If there is no callbackType it means not a callback method
1002 return callbackType.equals(prmType);
1007 * HELPER: writeCallbackMethodBodyJavaStub() writes the callback method of the stub class
1009 private void writeCallbackMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
1010 List<String> methPrmTypes, String method, String callbackType) {
1013 // Check if this is single object, array, or list of objects
1014 for (int i = 0; i < methParams.size(); i++) {
1015 String paramType = methPrmTypes.get(i);
1016 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
1017 String param = methParams.get(i);
1018 if (isArrayOrList(paramType, param)) { // Generate loop
1019 println("for (" + getGenericType(paramType) + " cb : " + getSimpleIdentifier(param) + ") {");
1020 println(callbackType + "_CallbackSkeleton skel" + i + " = new " + callbackType + "_CallbackSkeleton(cb, callbackAddress, objIdCnt++);");
1022 println(callbackType + "_CallbackSkeleton skel" + i + " = new " + callbackType + "_CallbackSkeleton(" +
1023 getSimpleIdentifier(param) + ", callbackAddress, objIdCnt++);");
1024 println("listCallbackObj.add(skel" + i + ");");
1025 if (isArrayOrList(paramType, param))
1030 println(" catch (Exception ex) {");
1031 println("ex.printStackTrace();");
1032 println("throw new Error(\"Exception when generating skeleton objects!\");");
1038 * HELPER: writeMethodJavaStub() writes the methods of the stub class
1040 private void writeMethodJavaStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, String newStubClass) {
1042 boolean isDefined = false;
1043 for (String method : methods) {
1045 List<String> methParams = intDecl.getMethodParams(method);
1046 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1047 print("public " + intDecl.getMethodType(method) + " " +
1048 intDecl.getMethodId(method) + "(");
1049 boolean isCallbackMethod = false;
1050 String callbackType = null;
1051 for (int i = 0; i < methParams.size(); i++) {
1053 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
1054 // Check if this has callback object
1055 if (callbackClasses.contains(paramType)) {
1056 isCallbackMethod = true;
1057 callbackType = paramType;
1058 // Even if there're 2 callback arguments, we expect them to be of the same interface
1060 print(methPrmTypes.get(i) + " " + methParams.get(i));
1061 // Check if this is the last element (don't print a comma)
1062 if (i != methParams.size() - 1) {
1067 // Now, write the body of stub!
1068 if (isCallbackMethod)
1069 writeCallbackMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
1071 writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
1073 // Write the init callback helper method
1074 if (isCallbackMethod && !isDefined) {
1075 writeInitCallbackJavaStub(callbackType, intDecl, newStubClass);
1083 * HELPER: getStubInterface() gets stub interface name based on original interface
1085 public String getStubInterface(String intface) {
1087 return mapInt2NewIntName.get(intface);
1092 * generateJavaStubClasses() generate stubs based on the methods list in Java
1094 public void generateJavaStubClasses() throws IOException {
1096 // Create a new directory
1097 String path = createDirectories(dir, subdir);
1098 for (String intface : mapIntfacePTH.keySet()) {
1100 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1101 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1103 // Open a new file to write into
1104 String newIntface = intMeth.getKey();
1105 String newStubClass = newIntface + "_Stub";
1106 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
1107 pw = new PrintWriter(new BufferedWriter(fw));
1108 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
1109 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
1110 // Pass in set of methods and get import classes
1111 Set<String> methods = intMeth.getValue();
1112 Set<String> importClasses = getImportClasses(methods, intDecl);
1113 List<String> stdImportClasses = getStandardJavaImportClasses();
1114 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
1115 printImportStatements(allImportClasses); println("");
1116 // Find out if there are callback objects
1117 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
1118 boolean callbackExist = !callbackClasses.isEmpty();
1119 // Write class header
1120 println("public class " + newStubClass + " implements " + newIntface + " {\n");
1122 writePropertiesJavaStub(intface, newIntface, callbackExist, callbackClasses);
1123 // Write constructor
1124 writeConstructorJavaStub(intface, newStubClass, callbackExist, callbackClasses);
1126 writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, newStubClass);
1129 System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java...");
1136 * HELPER: writePropertiesJavaCallbackStub() writes the properties of the callback stub class
1138 private void writePropertiesJavaCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
1140 println("private IoTRMICall rmiCall;");
1141 println("private String callbackAddress;");
1142 println("private int[] ports;\n");
1143 // Get the object Id
1144 println("private int objectId = 0;");
1145 if (callbackExist) {
1146 // We assume that each class only has one callback interface for now
1147 Iterator it = callbackClasses.iterator();
1148 String callbackType = (String) it.next();
1149 println("// Callback properties");
1150 println("private IoTRMIObject rmiObj;");
1151 println("List<" + callbackType + "> listCallbackObj;");
1152 println("private int objIdCnt = 0;");
1153 // Generate permission stuff for callback stubs
1154 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
1155 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
1156 writePropertiesJavaPermission(callbackType, intDecl);
1163 * HELPER: writeConstructorJavaCallbackStub() writes the constructor of the callback stub class
1165 private void writeConstructorJavaCallbackStub(String intface, String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
1167 // TODO: If we want callback in callback, then we need to add address and port initializations
1168 println("public " + newStubClass + "(IoTRMICall _rmiCall, String _callbackAddress, int _objectId, int[] _ports) throws Exception {");
1169 println("callbackAddress = _callbackAddress;");
1170 println("objectId = _objectId;");
1171 println("rmiCall = _rmiCall;");
1172 println("ports = _ports;");
1173 if (callbackExist) {
1174 Iterator it = callbackClasses.iterator();
1175 String callbackType = (String) it.next();
1176 writeConstructorJavaPermission(callbackType);
1177 println("listCallbackObj = new ArrayList<" + callbackType + ">();");
1178 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
1179 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
1180 writeJavaInitCallbackPermission(callbackType, intDecl, callbackExist);
1181 println("___initCallBack();");
1188 * generateJavaCallbackStubClasses() generate callback stubs based on the methods list in Java
1190 * Callback stubs gets the IoTRMICall objects from outside of the class as contructor input
1191 * because all these stubs are populated by the class that takes in this object as a callback
1192 * object. In such a class, we only use one socket, hence one IoTRMICall, for all callback objects.
1194 public void generateJavaCallbackStubClasses() throws IOException {
1196 // Create a new directory
1197 String path = createDirectories(dir, subdir);
1198 for (String intface : mapIntfacePTH.keySet()) {
1200 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1201 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1203 // Open a new file to write into
1204 String newIntface = intMeth.getKey();
1205 String newStubClass = newIntface + "_CallbackStub";
1206 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
1207 pw = new PrintWriter(new BufferedWriter(fw));
1208 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
1209 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
1210 // Pass in set of methods and get import classes
1211 Set<String> methods = intMeth.getValue();
1212 Set<String> importClasses = getImportClasses(methods, intDecl);
1213 List<String> stdImportClasses = getStandardJavaImportClasses();
1214 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
1215 printImportStatements(allImportClasses); println("");
1216 // Find out if there are callback objects
1217 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
1218 boolean callbackExist = !callbackClasses.isEmpty();
1219 // Write class header
1220 println("public class " + newStubClass + " implements " + newIntface + " {\n");
1222 writePropertiesJavaCallbackStub(intface, newIntface, callbackExist, callbackClasses);
1223 // Write constructor
1224 writeConstructorJavaCallbackStub(intface, newStubClass, callbackExist, callbackClasses);
1226 // TODO: perhaps need to generate callback for callback
1227 writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, newStubClass);
1230 System.out.println("IoTCompiler: Generated callback stub class " + newStubClass + ".java...");
1237 * HELPER: writePropertiesJavaSkeleton() writes the properties of the skeleton class
1239 private void writePropertiesJavaSkeleton(String intface, boolean callbackExist, InterfaceDecl intDecl) {
1241 println("private " + intface + " mainObj;");
1242 //println("private int ports;");
1243 println("private IoTRMIObject rmiObj;\n");
1244 println("private String callbackAddress;");
1246 if (callbackExist) {
1247 println("private int objIdCnt = 0;");
1248 println("private IoTRMICall rmiCall;");
1249 println("private int[] ports;\n");
1251 writePropertiesJavaPermission(intface, intDecl);
1257 * HELPER: writeStructPermissionJavaSkeleton() writes permission for struct helper
1259 private void writeStructPermissionJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, String intface) {
1261 // Use this set to handle two same methodIds
1262 for (String method : methods) {
1263 List<String> methParams = intDecl.getMethodParams(method);
1264 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1265 // Check for params with structs
1266 for (int i = 0; i < methParams.size(); i++) {
1267 String paramType = methPrmTypes.get(i);
1268 String param = methParams.get(i);
1269 String simpleType = getGenericType(paramType);
1270 if (isStructClass(simpleType)) {
1271 int methodNumId = intDecl.getMethodNumId(method);
1272 String helperMethod = methodNumId + "struct" + i;
1273 int methodHelperNumId = intDecl.getHelperMethodNumId(helperMethod);
1274 // Iterate over interfaces to give permissions to
1275 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1276 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1277 String newIntface = intMeth.getKey();
1278 int newObjectId = getNewIntfaceObjectId(newIntface);
1279 println("set" + newObjectId + "Allowed.add(" + methodHelperNumId + ");");
1288 * HELPER: writeConstructorJavaSkeleton() writes the constructor of the skeleton class
1290 private void writeConstructorJavaSkeleton(String newSkelClass, String intface, InterfaceDecl intDecl, Collection<String> methods, boolean callbackExist) {
1292 println("public " + newSkelClass + "(" + intface + " _mainObj, String _callbackAddress, int _port) throws Exception {");
1293 println("mainObj = _mainObj;");
1294 println("callbackAddress = _callbackAddress;");
1295 println("rmiObj = new IoTRMIObject(_port);");
1296 // Generate permission control initialization
1297 writeConstructorJavaPermission(intface);
1298 writeJavaInitCallbackPermission(intface, intDecl, callbackExist);
1299 writeStructPermissionJavaSkeleton(methods, intDecl, intface);
1300 println("___waitRequestInvokeMethod();");
1306 * HELPER: writeStdMethodBodyJavaSkeleton() writes the standard method body in the skeleton class
1308 private void writeStdMethodBodyJavaSkeleton(List<String> methParams, String methodId, String methodType) {
1310 if (methodType.equals("void"))
1311 print("mainObj." + methodId + "(");
1313 print("return mainObj." + methodId + "(");
1314 for (int i = 0; i < methParams.size(); i++) {
1316 print(getSimpleIdentifier(methParams.get(i)));
1317 // Check if this is the last element (don't print a comma)
1318 if (i != methParams.size() - 1) {
1327 * HELPER: writeInitCallbackJavaSkeleton() writes the init callback method for skeleton class
1329 private void writeInitCallbackJavaSkeleton(boolean callbackSkeleton, String intface) {
1331 // This is a callback skeleton generation
1332 if (callbackSkeleton)
1333 println("public void ___regCB(IoTRMIObject rmiObj) throws IOException {");
1335 println("public void ___regCB() throws IOException {");
1336 print("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int[].class, String.class, int.class },");
1337 println("new Class<?>[] { null, null, null });");
1338 println("ports = (int[]) paramObj[0];");
1339 String stubInt = null;
1340 if (callbackSkeleton)
1341 stubInt = getStubInterface(intface) + "_CallbackStub";
1343 stubInt = getStubInterface(intface) + "_Stub";
1344 int port = getPortCount(stubInt);
1345 println("rmiCall = new IoTRMICall(ports[" + port + "], (String) paramObj[1], (int) paramObj[2]);");
1351 * HELPER: writeMethodJavaSkeleton() writes the method of the skeleton class
1353 private void writeMethodJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses,
1354 boolean callbackSkeleton, String intface) {
1356 boolean isDefined = false;
1357 for (String method : methods) {
1359 List<String> methParams = intDecl.getMethodParams(method);
1360 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1361 String methodId = intDecl.getMethodId(method);
1362 print("public " + intDecl.getMethodType(method) + " " + methodId + "(");
1363 boolean isCallbackMethod = false;
1364 String callbackType = null;
1365 for (int i = 0; i < methParams.size(); i++) {
1367 String origParamType = methPrmTypes.get(i);
1368 String paramType = checkAndGetParamClass(origParamType);
1369 if (callbackClasses.contains(origParamType)) { // Check if this has callback object
1370 isCallbackMethod = true;
1371 callbackType = origParamType;
1373 print(paramType + " " + methParams.get(i));
1374 // Check if this is the last element (don't print a comma)
1375 if (i != methParams.size() - 1) {
1380 // Now, write the body of skeleton!
1381 writeStdMethodBodyJavaSkeleton(methParams, methodId, intDecl.getMethodType(method));
1383 if (isCallbackMethod && !isDefined) { // Make sure that this function is only defined once!
1384 writeInitCallbackJavaSkeleton(callbackSkeleton, intface);
1392 * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part
1394 private Map<Integer,String> writeCallbackJavaStubGeneration(List<String> methParams, List<String> methPrmTypes,
1395 String callbackType, boolean isStructMethod) {
1397 Map<Integer,String> mapStubParam = new HashMap<Integer,String>();
1398 String offsetPfx = "";
1400 offsetPfx = "offset";
1401 // Iterate over callback objects
1402 for (int i = 0; i < methParams.size(); i++) {
1403 String paramType = methPrmTypes.get(i);
1404 String param = methParams.get(i);
1405 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
1406 String exchParamType = checkAndGetParamClass(getGenericType(paramType));
1407 // Print array if this is array or list if this is a list of callback objects
1408 if (isArray(param)) {
1409 println("int numStubs" + i + " = (int) paramObj[" + offsetPfx + i + "];");
1410 println(exchParamType + "[] stub" + i + " = new " + exchParamType + "[numStubs" + i + "];");
1411 } else if (isList(paramType)) {
1412 println("int numStubs" + i + " = (int) paramObj[" + offsetPfx + i + "];");
1413 println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();");
1415 println(exchParamType + " stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);");
1416 println("objIdCnt++;");
1419 // Generate a loop if needed
1420 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
1421 String exchParamType = checkAndGetParamClass(getGenericType(paramType));
1422 if (isArray(param)) {
1423 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
1424 println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);");
1425 println("objIdCnt++;");
1427 } else if (isList(paramType)) {
1428 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
1429 println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports));");
1430 println("objIdCnt++;");
1433 mapStubParam.put(i, "stub" + i); // List of all stub parameters
1436 return mapStubParam;
1441 * HELPER: checkAndWriteEnumTypeJavaSkeleton() writes the enum type (convert from enum to int)
1443 private void checkAndWriteEnumTypeJavaSkeleton(List<String> methParams, List<String> methPrmTypes, boolean isStructMethod) {
1445 String offsetPfx = "";
1447 offsetPfx = "offset";
1448 // Iterate and find enum declarations
1449 boolean printed = false;
1450 for (int i = 0; i < methParams.size(); i++) {
1451 String paramType = methPrmTypes.get(i);
1452 String param = methParams.get(i);
1453 String simpleType = getGenericType(paramType);
1454 if (isEnumClass(simpleType)) {
1455 // Check if this is enum type
1456 println("int paramInt" + i + "[] = (int[]) paramObj[" + offsetPfx + i + "];");
1458 println(simpleType + "[] enumVals = " + simpleType + ".values();");
1461 if (isArray(param)) { // An array
1462 println("int len" + i + " = paramInt" + i + ".length;");
1463 println(simpleType + "[] paramEnum" + i + " = new " + simpleType + "[len" + i + "];");
1464 println("for (int i = 0; i < len" + i + "; i++) {");
1465 println("paramEnum" + i + "[i] = enumVals[paramInt" + i + "[i]];");
1467 } else if (isList(paramType)) { // A list
1468 println("int len" + i + " = paramInt" + i + ".length;");
1469 println("List<" + simpleType + "> paramEnum" + i + " = new ArrayList<" + simpleType + ">();");
1470 println("for (int i = 0; i < len" + i + "; i++) {");
1471 println("paramEnum" + i + ".add(enumVals[paramInt" + i + "[i]]);");
1473 } else { // Just one element
1474 println(simpleType + " paramEnum" + i + " = enumVals[paramInt" + i + "[0]];");
1482 * HELPER: checkAndWriteEnumRetTypeJavaSkeleton() writes the enum return type (convert from enum to int)
1484 private void checkAndWriteEnumRetTypeJavaSkeleton(String retType, String methodId) {
1486 // Strips off array "[]" for return type
1487 String pureType = getSimpleArrayType(getGenericType(retType));
1488 // Take the inner type of generic
1489 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
1490 pureType = getGenericType(retType);
1491 if (isEnumClass(pureType)) {
1492 // Check if this is enum type
1494 if (isArray(retType)) { // An array
1495 print(pureType + "[] retEnum = " + methodId + "(");
1496 } else if (isList(retType)) { // A list
1497 print("List<" + pureType + "> retEnum = " + methodId + "(");
1498 } else { // Just one element
1499 print(pureType + " retEnum = " + methodId + "(");
1506 * HELPER: checkAndWriteEnumRetConvJavaSkeleton() writes the enum return type (convert from enum to int)
1508 private void checkAndWriteEnumRetConvJavaSkeleton(String retType) {
1510 // Strips off array "[]" for return type
1511 String pureType = getSimpleArrayType(getGenericType(retType));
1512 // Take the inner type of generic
1513 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
1514 pureType = getGenericType(retType);
1515 if (isEnumClass(pureType)) {
1516 // Check if this is enum type
1517 if (isArray(retType)) { // An array
1518 println("int retLen = retEnum.length;");
1519 println("int[] retEnumVal = new int[retLen];");
1520 println("for (int i = 0; i < retLen; i++) {");
1521 println("retEnumVal[i] = retEnum[i].ordinal();");
1523 } else if (isList(retType)) { // A list
1524 println("int retLen = retEnum.size();");
1525 println("int[] retEnumVal = new int[retLen];");
1526 println("for (int i = 0; i < retLen; i++) {");
1527 println("retEnumVal[i] = retEnum.get(i).ordinal();");
1529 } else { // Just one element
1530 println("int[] retEnumVal = new int[1];");
1531 println("retEnumVal[0] = retEnum.ordinal();");
1533 println("Object retObj = retEnumVal;");
1539 * HELPER: writeLengthStructParamClassSkeleton() writes lengths of params
1541 private void writeLengthStructParamClassSkeleton(List<String> methParams, List<String> methPrmTypes,
1542 String method, InterfaceDecl intDecl) {
1544 // Iterate and find struct declarations - count number of params
1545 for (int i = 0; i < methParams.size(); i++) {
1546 String paramType = methPrmTypes.get(i);
1547 String param = methParams.get(i);
1548 String simpleType = getGenericType(paramType);
1549 if (isStructClass(simpleType)) {
1550 int members = getNumOfMembers(simpleType);
1551 print(Integer.toString(members) + "*");
1552 int methodNumId = intDecl.getMethodNumId(method);
1553 print("struct" + methodNumId + "Size" + i);
1556 if (i != methParams.size() - 1) {
1564 * HELPER: writeStructMembersJavaSkeleton() writes member parameters of struct
1566 private void writeStructMembersJavaSkeleton(String simpleType, String paramType,
1567 String param, String method, InterfaceDecl intDecl, int iVar) {
1569 // Get the struct declaration for this struct and generate initialization code
1570 StructDecl structDecl = getStructDecl(simpleType);
1571 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1572 List<String> members = structDecl.getMembers(simpleType);
1573 if (isArrayOrList(paramType, param)) { // An array or list
1574 int methodNumId = intDecl.getMethodNumId(method);
1575 String counter = "struct" + methodNumId + "Size" + iVar;
1576 println("for(int i = 0; i < " + counter + "; i++) {");
1578 if (isArrayOrList(paramType, param)) { // An array or list
1579 for (int i = 0; i < members.size(); i++) {
1580 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1581 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1582 println("paramClsGen[pos++] = null;");
1585 } else { // Just one struct element
1586 for (int i = 0; i < members.size(); i++) {
1587 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1588 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1589 println("paramClsGen[pos++] = null;");
1596 * HELPER: writeStructMembersInitJavaSkeleton() writes member parameters initialization of struct
1598 private void writeStructMembersInitJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1599 List<String> methPrmTypes, String method) {
1601 println("int objPos = 0;");
1602 for (int i = 0; i < methParams.size(); i++) {
1603 String paramType = methPrmTypes.get(i);
1604 String param = methParams.get(i);
1605 String simpleType = getGenericType(paramType);
1606 if (isStructClass(simpleType)) {
1607 int methodNumId = intDecl.getMethodNumId(method);
1608 String counter = "struct" + methodNumId + "Size" + i;
1610 if (isArray(param)) { // An array
1611 println(simpleType + "[] paramStruct" + i + " = new " + simpleType + "[" + counter + "];");
1612 println("for(int i = 0; i < " + counter + "; i++) {");
1613 println("paramStruct" + i + "[i] = new " + simpleType + "();");
1615 } else if (isList(paramType)) { // A list
1616 println("List<" + simpleType + "> paramStruct" + i + " = new ArrayList<" + simpleType + ">();");
1618 println(simpleType + " paramStruct" + i + " = new " + simpleType + "();");
1619 // Initialize members
1620 StructDecl structDecl = getStructDecl(simpleType);
1621 List<String> members = structDecl.getMembers(simpleType);
1622 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1623 if (isArrayOrList(paramType, param)) { // An array or list
1624 println("for(int i = 0; i < " + counter + "; i++) {");
1626 if (isArray(param)) { // An array
1627 for (int j = 0; j < members.size(); j++) {
1628 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1629 print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j)));
1630 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1633 } else if (isList(paramType)) { // A list
1634 println(simpleType + " paramStructMem = new " + simpleType + "();");
1635 for (int j = 0; j < members.size(); j++) {
1636 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1637 print("paramStructMem." + getSimpleIdentifier(members.get(j)));
1638 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1640 println("paramStruct" + i + ".add(paramStructMem);");
1642 } else { // Just one struct element
1643 for (int j = 0; j < members.size(); j++) {
1644 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1645 print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j)));
1646 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1650 // Take offsets of parameters
1651 println("int offset" + i +" = objPos++;");
1658 * HELPER: writeStructReturnJavaSkeleton() writes struct for return statement
1660 private void writeStructReturnJavaSkeleton(String simpleType, String retType) {
1662 // Minimum retLen is 1 if this is a single struct object
1663 if (isArray(retType))
1664 println("int retLen = retStruct.length;");
1665 else if (isList(retType))
1666 println("int retLen = retStruct.size();");
1667 else // Just single struct object
1668 println("int retLen = 1;");
1669 println("Object retLenObj = retLen;");
1670 println("rmiObj.sendReturnObj(retLenObj);");
1671 int numMem = getNumOfMembers(simpleType);
1672 println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
1673 println("Object[] retObj = new Object[" + numMem + "*retLen];");
1674 println("int retPos = 0;");
1675 // Get the struct declaration for this struct and generate initialization code
1676 StructDecl structDecl = getStructDecl(simpleType);
1677 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1678 List<String> members = structDecl.getMembers(simpleType);
1679 if (isArray(retType)) { // An array or list
1680 println("for(int i = 0; i < retLen; i++) {");
1681 for (int i = 0; i < members.size(); i++) {
1682 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1683 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1684 print("retObj[retPos++] = retStruct[i].");
1685 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
1689 } else if (isList(retType)) { // An array or list
1690 println("for(int i = 0; i < retLen; i++) {");
1691 for (int i = 0; i < members.size(); i++) {
1692 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1693 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1694 print("retObj[retPos++] = retStruct.get(i).");
1695 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
1699 } else { // Just one struct element
1700 for (int i = 0; i < members.size(); i++) {
1701 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1702 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1703 print("retObj[retPos++] = retStruct.");
1704 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
1713 * HELPER: writeMethodHelperReturnJavaSkeleton() writes return statement part in skeleton
1715 private void writeMethodHelperReturnJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1716 List<String> methPrmTypes, String method, boolean isCallbackMethod, String callbackType,
1717 boolean isStructMethod) {
1719 checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes, isStructMethod);
1720 Map<Integer,String> mapStubParam = null;
1721 if (isCallbackMethod) {
1723 mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType, isStructMethod);
1725 // Check if this is "void"
1726 String retType = intDecl.getMethodType(method);
1727 if (retType.equals("void")) {
1728 print(intDecl.getMethodId(method) + "(");
1729 } else if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) { // Enum type
1730 checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method));
1731 } else if (isStructClass(getSimpleArrayType(getGenericType(retType)))) { // Struct type
1732 print(retType + " retStruct = " + intDecl.getMethodId(method) + "(");
1733 } else { // We do have a return value
1734 print("Object retObj = " + intDecl.getMethodId(method) + "(");
1736 for (int i = 0; i < methParams.size(); i++) {
1738 String paramType = methPrmTypes.get(i);
1739 if (isCallbackMethod && checkCallbackType(paramType, callbackType)) {
1740 print(mapStubParam.get(i)); // Get the callback parameter
1741 } else if (isEnumClass(getGenericType(paramType))) { // Enum class
1742 print(getEnumParam(paramType, methParams.get(i), i));
1743 } else if (isStructClass(getGenericType(paramType))) {
1744 print("paramStruct" + i);
1746 String prmType = checkAndGetArray(paramType, methParams.get(i));
1748 print("(" + prmType + ") paramObj[offset" + i + "]");
1750 print("(" + prmType + ") paramObj[" + i + "]");
1752 if (i != methParams.size() - 1)
1756 if (!retType.equals("void")) {
1757 if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) { // Enum type
1758 checkAndWriteEnumRetConvJavaSkeleton(retType);
1759 println("rmiObj.sendReturnObj(retObj);");
1760 } else if (isStructClass(getSimpleArrayType(getGenericType(retType)))) { // Struct type
1761 writeStructReturnJavaSkeleton(getSimpleArrayType(getGenericType(retType)), retType);
1762 println("rmiObj.sendReturnObj(retCls, retObj);");
1764 println("rmiObj.sendReturnObj(retObj);");
1766 if (isCallbackMethod) { // Catch exception if this is callback
1768 println(" catch(Exception ex) {");
1769 println("ex.printStackTrace();");
1770 println("throw new Error(\"Exception from callback object instantiation!\");");
1777 * HELPER: writeMethodHelperStructJavaSkeleton() writes the struct in skeleton
1779 private void writeMethodHelperStructJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1780 List<String> methPrmTypes, String method, Set<String> callbackClasses) {
1782 // Generate array of parameter objects
1783 boolean isCallbackMethod = false;
1784 String callbackType = null;
1785 print("int paramLen = ");
1786 writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
1788 println("Class<?>[] paramCls = new Class<?>[paramLen];");
1789 println("Class<?>[] paramClsGen = new Class<?>[paramLen];");
1790 println("int pos = 0;");
1791 // Iterate again over the parameters
1792 for (int i = 0; i < methParams.size(); i++) {
1793 String paramType = methPrmTypes.get(i);
1794 String param = methParams.get(i);
1795 String simpleType = getGenericType(paramType);
1796 if (isStructClass(simpleType)) {
1797 writeStructMembersJavaSkeleton(simpleType, paramType, param, method, intDecl, i);
1799 String prmType = returnGenericCallbackType(methPrmTypes.get(i));
1800 if (callbackClasses.contains(prmType)) {
1801 isCallbackMethod = true;
1802 callbackType = prmType;
1803 println("paramCls[pos] = int.class;");
1804 println("paramClsGen[pos++] = null;");
1805 } else { // Generate normal classes if it's not a callback object
1806 String paramTypeOth = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1807 println("paramCls[pos] = " + getSimpleType(getEnumType(paramTypeOth)) + ".class;");
1808 print("paramClsGen[pos++] = ");
1809 String prmTypeOth = methPrmTypes.get(i);
1810 if (getParamCategory(prmTypeOth) == ParamCategory.NONPRIMITIVES)
1811 println(getTypeOfGeneric(prmType)[0] + ".class;");
1817 println("Object[] paramObj = rmiObj.getMethodParams(paramCls, paramClsGen);");
1818 writeStructMembersInitJavaSkeleton(intDecl, methParams, methPrmTypes, method);
1819 // Write the return value part
1820 writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, true);
1825 * HELPER: writeStdMethodHelperBodyJavaSkeleton() writes the standard method body helper in the skeleton class
1827 private void writeStdMethodHelperBodyJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1828 List<String> methPrmTypes, String method, Set<String> callbackClasses) {
1830 // Generate array of parameter objects
1831 boolean isCallbackMethod = false;
1832 String callbackType = null;
1833 print("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { ");
1834 for (int i = 0; i < methParams.size(); i++) {
1836 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
1837 if (callbackClasses.contains(paramType)) {
1838 isCallbackMethod = true;
1839 callbackType = paramType;
1841 } else { // Generate normal classes if it's not a callback object
1842 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1843 print(getSimpleType(getEnumType(prmType)) + ".class");
1845 if (i != methParams.size() - 1)
1849 // Generate generic class if it's a generic type.. null otherwise
1850 print("new Class<?>[] { ");
1851 for (int i = 0; i < methParams.size(); i++) {
1852 String prmType = methPrmTypes.get(i);
1853 if ((getParamCategory(prmType) == ParamCategory.NONPRIMITIVES) &&
1854 !isEnumClass(getGenericType(prmType)) &&
1855 !callbackClasses.contains(getGenericType(prmType)))
1856 print(getGenericType(prmType) + ".class");
1859 if (i != methParams.size() - 1)
1863 // Write the return value part
1864 writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, false);
1869 * HELPER: writeMethodHelperJavaSkeleton() writes the method helper of the skeleton class
1871 private void writeMethodHelperJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
1873 // Use this set to handle two same methodIds
1874 Set<String> uniqueMethodIds = new HashSet<String>();
1875 for (String method : methods) {
1877 List<String> methParams = intDecl.getMethodParams(method);
1878 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1879 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
1880 String methodId = intDecl.getMethodId(method);
1881 print("public void ___");
1882 String helperMethod = methodId;
1883 if (uniqueMethodIds.contains(methodId))
1884 helperMethod = helperMethod + intDecl.getMethodNumId(method);
1886 uniqueMethodIds.add(methodId);
1887 String retType = intDecl.getMethodType(method);
1888 print(helperMethod + "(");
1889 boolean begin = true;
1890 for (int i = 0; i < methParams.size(); i++) { // Print size variables
1891 String paramType = methPrmTypes.get(i);
1892 String param = methParams.get(i);
1893 String simpleType = getGenericType(paramType);
1894 if (isStructClass(simpleType)) {
1895 if (!begin) // Generate comma for not the beginning variable
1899 int methodNumId = intDecl.getMethodNumId(method);
1900 print("int struct" + methodNumId + "Size" + i);
1903 // Check if this is "void"
1904 if (retType.equals("void"))
1907 println(") throws IOException {");
1908 writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
1911 String methodId = intDecl.getMethodId(method);
1912 print("public void ___");
1913 String helperMethod = methodId;
1914 if (uniqueMethodIds.contains(methodId))
1915 helperMethod = helperMethod + intDecl.getMethodNumId(method);
1917 uniqueMethodIds.add(methodId);
1918 // Check if this is "void"
1919 String retType = intDecl.getMethodType(method);
1920 if (retType.equals("void"))
1921 println(helperMethod + "() {");
1923 println(helperMethod + "() throws IOException {");
1924 // Now, write the helper body of skeleton!
1925 writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
1929 // Write method helper for structs
1930 writeMethodHelperStructSetupJavaSkeleton(methods, intDecl);
1935 * HELPER: writeMethodHelperStructSetupJavaSkeleton() writes the method helper of struct setup in skeleton class
1937 private void writeMethodHelperStructSetupJavaSkeleton(Collection<String> methods,
1938 InterfaceDecl intDecl) {
1940 // Use this set to handle two same methodIds
1941 for (String method : methods) {
1943 List<String> methParams = intDecl.getMethodParams(method);
1944 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1945 // Check for params with structs
1946 for (int i = 0; i < methParams.size(); i++) {
1947 String paramType = methPrmTypes.get(i);
1948 String param = methParams.get(i);
1949 String simpleType = getGenericType(paramType);
1950 if (isStructClass(simpleType)) {
1951 int methodNumId = intDecl.getMethodNumId(method);
1952 print("public int ___");
1953 String helperMethod = methodNumId + "struct" + i;
1954 println(helperMethod + "() {");
1955 // Now, write the helper body of skeleton!
1956 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
1957 println("return (int) paramObj[0];");
1966 * HELPER: writeMethodHelperStructSetupJavaCallbackSkeleton() writes the method helper of struct setup in callback skeleton class
1968 private void writeMethodHelperStructSetupJavaCallbackSkeleton(Collection<String> methods,
1969 InterfaceDecl intDecl) {
1971 // Use this set to handle two same methodIds
1972 for (String method : methods) {
1974 List<String> methParams = intDecl.getMethodParams(method);
1975 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1976 // Check for params with structs
1977 for (int i = 0; i < methParams.size(); i++) {
1978 String paramType = methPrmTypes.get(i);
1979 String param = methParams.get(i);
1980 String simpleType = getGenericType(paramType);
1981 if (isStructClass(simpleType)) {
1982 int methodNumId = intDecl.getMethodNumId(method);
1983 print("public int ___");
1984 String helperMethod = methodNumId + "struct" + i;
1985 println(helperMethod + "(IoTRMIObject rmiObj) {");
1986 // Now, write the helper body of skeleton!
1987 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
1988 println("return (int) paramObj[0];");
1997 * HELPER: writeCountVarStructSkeleton() writes counter variable of struct for skeleton
1999 private void writeCountVarStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
2001 // Use this set to handle two same methodIds
2002 for (String method : methods) {
2004 List<String> methParams = intDecl.getMethodParams(method);
2005 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2006 // Check for params with structs
2007 for (int i = 0; i < methParams.size(); i++) {
2008 String paramType = methPrmTypes.get(i);
2009 String param = methParams.get(i);
2010 String simpleType = getGenericType(paramType);
2011 if (isStructClass(simpleType)) {
2012 int methodNumId = intDecl.getMethodNumId(method);
2013 println("int struct" + methodNumId + "Size" + i + " = 0;");
2021 * HELPER: writeInputCountVarStructSkeleton() writes input counter variable of struct for skeleton
2023 private boolean writeInputCountVarStructSkeleton(String method, InterfaceDecl intDecl) {
2025 List<String> methParams = intDecl.getMethodParams(method);
2026 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2027 boolean structExist = false;
2028 boolean begin = true;
2029 // Check for params with structs
2030 for (int i = 0; i < methParams.size(); i++) {
2031 String paramType = methPrmTypes.get(i);
2032 String param = methParams.get(i);
2033 String simpleType = getGenericType(paramType);
2034 if (isStructClass(simpleType)) {
2040 int methodNumId = intDecl.getMethodNumId(method);
2041 print("struct" + methodNumId + "Size" + i);
2049 * HELPER: writeMethodCallStructSkeleton() writes method call for wait invoke in skeleton
2051 private void writeMethodCallStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
2053 // Use this set to handle two same methodIds
2054 for (String method : methods) {
2056 List<String> methParams = intDecl.getMethodParams(method);
2057 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2058 // Check for params with structs
2059 for (int i = 0; i < methParams.size(); i++) {
2060 String paramType = methPrmTypes.get(i);
2061 String param = methParams.get(i);
2062 String simpleType = getGenericType(paramType);
2063 if (isStructClass(simpleType)) {
2064 int methodNumId = intDecl.getMethodNumId(method);
2066 String helperMethod = methodNumId + "struct" + i;
2067 String tempVar = "struct" + methodNumId + "Size" + i;
2068 print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
2069 print(tempVar + " = ___");
2070 println(helperMethod + "(); break;");
2078 * HELPER: writeMethodCallStructCallbackSkeleton() writes method call for wait invoke in skeleton
2080 private void writeMethodCallStructCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
2082 // Use this set to handle two same methodIds
2083 for (String method : methods) {
2085 List<String> methParams = intDecl.getMethodParams(method);
2086 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2087 // Check for params with structs
2088 for (int i = 0; i < methParams.size(); i++) {
2089 String paramType = methPrmTypes.get(i);
2090 String param = methParams.get(i);
2091 String simpleType = getGenericType(paramType);
2092 if (isStructClass(simpleType)) {
2093 int methodNumId = intDecl.getMethodNumId(method);
2095 String helperMethod = methodNumId + "struct" + i;
2096 String tempVar = "struct" + methodNumId + "Size" + i;
2097 print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
2098 print(tempVar + " = ___");
2099 println(helperMethod + "(rmiObj); break;");
2107 * HELPER: writeJavaMethodPermission() writes permission checks in skeleton
2109 private void writeJavaMethodPermission(String intface) {
2111 // Get all the different stubs
2112 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
2113 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
2114 String newIntface = intMeth.getKey();
2115 int newObjectId = getNewIntfaceObjectId(newIntface);
2116 println("if (_objectId == object" + newObjectId + "Id) {");
2117 println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
2118 println("throw new Error(\"Object with object Id: \" + _objectId + \" is not allowed to access method: \" + methodId);");
2122 println("throw new Error(\"Object Id: \" + _objectId + \" not recognized!\");");
2129 * HELPER: writeJavaWaitRequestInvokeMethod() writes the main loop of the skeleton class
2131 private void writeJavaWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
2133 // Use this set to handle two same methodIds
2134 Set<String> uniqueMethodIds = new HashSet<String>();
2135 println("private void ___waitRequestInvokeMethod() throws IOException {");
2136 // Write variables here if we have callbacks or enums or structs
2137 writeCountVarStructSkeleton(methods, intDecl);
2138 println("while (true) {");
2139 println("rmiObj.getMethodBytes();");
2140 println("int _objectId = rmiObj.getObjectId();");
2141 println("int methodId = rmiObj.getMethodId();");
2142 // Generate permission check
2143 writeJavaMethodPermission(intface);
2144 println("switch (methodId) {");
2145 // Print methods and method Ids
2146 for (String method : methods) {
2147 String methodId = intDecl.getMethodId(method);
2148 int methodNumId = intDecl.getMethodNumId(method);
2149 print("case " + methodNumId + ": ___");
2150 String helperMethod = methodId;
2151 if (uniqueMethodIds.contains(methodId))
2152 helperMethod = helperMethod + methodNumId;
2154 uniqueMethodIds.add(methodId);
2155 print(helperMethod + "(");
2156 writeInputCountVarStructSkeleton(method, intDecl);
2157 println("); break;");
2159 String method = "___initCallBack()";
2160 // Print case -9999 (callback handler) if callback exists
2161 if (callbackExist) {
2162 int methodId = intDecl.getHelperMethodNumId(method);
2163 println("case " + methodId + ": ___regCB(); break;");
2165 writeMethodCallStructSkeleton(methods, intDecl);
2166 println("default: ");
2167 println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
2175 * generateJavaSkeletonClass() generate skeletons based on the methods list in Java
2177 public void generateJavaSkeletonClass() throws IOException {
2179 // Create a new directory
2180 String path = createDirectories(dir, subdir);
2181 for (String intface : mapIntfacePTH.keySet()) {
2182 // Open a new file to write into
2183 String newSkelClass = intface + "_Skeleton";
2184 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
2185 pw = new PrintWriter(new BufferedWriter(fw));
2186 // Pass in set of methods and get import classes
2187 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2188 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2189 List<String> methods = intDecl.getMethods();
2190 Set<String> importClasses = getImportClasses(methods, intDecl);
2191 List<String> stdImportClasses = getStandardJavaImportClasses();
2192 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
2193 printImportStatements(allImportClasses);
2194 // Find out if there are callback objects
2195 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
2196 boolean callbackExist = !callbackClasses.isEmpty();
2197 // Write class header
2199 println("public class " + newSkelClass + " implements " + intface + " {\n");
2201 writePropertiesJavaSkeleton(intface, callbackExist, intDecl);
2202 // Write constructor
2203 writeConstructorJavaSkeleton(newSkelClass, intface, intDecl, methods, callbackExist);
2205 writeMethodJavaSkeleton(methods, intDecl, callbackClasses, false, intface);
2206 // Write method helper
2207 writeMethodHelperJavaSkeleton(methods, intDecl, callbackClasses);
2208 // Write waitRequestInvokeMethod() - main loop
2209 writeJavaWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
2212 System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".java...");
2218 * HELPER: writePropertiesJavaCallbackSkeleton() writes the properties of the callback skeleton class
2220 private void writePropertiesJavaCallbackSkeleton(String intface, boolean callbackExist) {
2222 println("private " + intface + " mainObj;");
2223 // For callback skeletons, this is its own object Id
2224 println("private int objectId = 0;");
2225 println("private String callbackAddress;");
2227 if (callbackExist) {
2229 println("private int objIdCnt = 0;");
2230 println("private IoTRMICall rmiCall;");
2231 println("private int[] ports;\n");
2238 * HELPER: writeConstructorJavaCallbackSkeleton() writes the constructor of the skeleton class
2240 private void writeConstructorJavaCallbackSkeleton(String newSkelClass, String intface, InterfaceDecl intDecl, Collection<String> methods) {
2242 println("public " + newSkelClass + "(" + intface + " _mainObj, String _callbackAddress, int _objectId) throws Exception {");
2243 println("callbackAddress = _callbackAddress;");
2244 println("mainObj = _mainObj;");
2245 println("objectId = _objectId;");
2251 * HELPER: writeMethodHelperJavaCallbackSkeleton() writes the method helper of the callback skeleton class
2253 private void writeMethodHelperJavaCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
2255 // Use this set to handle two same methodIds
2256 Set<String> uniqueMethodIds = new HashSet<String>();
2257 for (String method : methods) {
2259 List<String> methParams = intDecl.getMethodParams(method);
2260 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2261 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
2262 String methodId = intDecl.getMethodId(method);
2263 print("public void ___");
2264 String helperMethod = methodId;
2265 if (uniqueMethodIds.contains(methodId))
2266 helperMethod = helperMethod + intDecl.getMethodNumId(method);
2268 uniqueMethodIds.add(methodId);
2269 String retType = intDecl.getMethodType(method);
2270 print(helperMethod + "(");
2271 boolean begin = true;
2272 for (int i = 0; i < methParams.size(); i++) { // Print size variables
2273 String paramType = methPrmTypes.get(i);
2274 String param = methParams.get(i);
2275 String simpleType = getGenericType(paramType);
2276 if (isStructClass(simpleType)) {
2277 if (!begin) // Generate comma for not the beginning variable
2281 int methodNumId = intDecl.getMethodNumId(method);
2282 print("int struct" + methodNumId + "Size" + i);
2285 // Check if this is "void"
2286 if (retType.equals("void"))
2287 println(", IoTRMIObject rmiObj) {");
2289 println(", IoTRMIObject rmiObj) throws IOException {");
2290 writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
2293 String methodId = intDecl.getMethodId(method);
2294 print("public void ___");
2295 String helperMethod = methodId;
2296 if (uniqueMethodIds.contains(methodId))
2297 helperMethod = helperMethod + intDecl.getMethodNumId(method);
2299 uniqueMethodIds.add(methodId);
2300 // Check if this is "void"
2301 String retType = intDecl.getMethodType(method);
2302 if (retType.equals("void"))
2303 println(helperMethod + "(IoTRMIObject rmiObj) {");
2305 println(helperMethod + "(IoTRMIObject rmiObj) throws IOException {");
2306 // Now, write the helper body of skeleton!
2307 writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
2311 // Write method helper for structs
2312 writeMethodHelperStructSetupJavaCallbackSkeleton(methods, intDecl);
2317 * HELPER: writeJavaCallbackWaitRequestInvokeMethod() writes the request invoke method of the callback skeleton class
2319 private void writeJavaCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist) {
2321 // Use this set to handle two same methodIds
2322 Set<String> uniqueMethodIds = new HashSet<String>();
2323 println("public void invokeMethod(IoTRMIObject rmiObj) throws IOException {");
2324 // Write variables here if we have callbacks or enums or structs
2325 writeCountVarStructSkeleton(methods, intDecl);
2326 // Write variables here if we have callbacks or enums or structs
2327 println("int methodId = rmiObj.getMethodId();");
2328 // TODO: code the permission check here!
2329 println("switch (methodId) {");
2330 // Print methods and method Ids
2331 for (String method : methods) {
2332 String methodId = intDecl.getMethodId(method);
2333 int methodNumId = intDecl.getMethodNumId(method);
2334 print("case " + methodNumId + ": ___");
2335 String helperMethod = methodId;
2336 if (uniqueMethodIds.contains(methodId))
2337 helperMethod = helperMethod + methodNumId;
2339 uniqueMethodIds.add(methodId);
2340 print(helperMethod + "(");
2341 if (writeInputCountVarStructSkeleton(method, intDecl))
2342 println(", rmiObj); break;");
2344 println("rmiObj); break;");
2346 String method = "___initCallBack()";
2347 // Print case -9999 (callback handler) if callback exists
2348 if (callbackExist) {
2349 int methodId = intDecl.getHelperMethodNumId(method);
2350 println("case " + methodId + ": ___regCB(rmiObj); break;");
2352 writeMethodCallStructCallbackSkeleton(methods, intDecl);
2353 println("default: ");
2354 println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
2361 * generateJavaCallbackSkeletonClass() generate callback skeletons based on the methods list in Java
2363 public void generateJavaCallbackSkeletonClass() throws IOException {
2365 // Create a new directory
2366 String path = createDirectories(dir, subdir);
2367 for (String intface : mapIntfacePTH.keySet()) {
2368 // Open a new file to write into
2369 String newSkelClass = intface + "_CallbackSkeleton";
2370 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
2371 pw = new PrintWriter(new BufferedWriter(fw));
2372 // Pass in set of methods and get import classes
2373 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2374 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2375 List<String> methods = intDecl.getMethods();
2376 Set<String> importClasses = getImportClasses(methods, intDecl);
2377 List<String> stdImportClasses = getStandardJavaImportClasses();
2378 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
2379 printImportStatements(allImportClasses);
2380 // Find out if there are callback objects
2381 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
2382 boolean callbackExist = !callbackClasses.isEmpty();
2383 // Write class header
2385 println("public class " + newSkelClass + " implements " + intface + " {\n");
2387 writePropertiesJavaCallbackSkeleton(intface, callbackExist);
2388 // Write constructor
2389 writeConstructorJavaCallbackSkeleton(newSkelClass, intface, intDecl, methods);
2391 writeMethodJavaSkeleton(methods, intDecl, callbackClasses, true, intface);
2392 // Write method helper
2393 writeMethodHelperJavaCallbackSkeleton(methods, intDecl, callbackClasses);
2394 // Write waitRequestInvokeMethod() - main loop
2395 writeJavaCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
2398 System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".java...");
2404 * HELPER: writeMethodCplusLocalInterface() writes the method of the local interface
2406 private void writeMethodCplusLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
2408 for (String method : methods) {
2410 List<String> methParams = intDecl.getMethodParams(method);
2411 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2412 print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2413 intDecl.getMethodId(method) + "(");
2414 for (int i = 0; i < methParams.size(); i++) {
2415 // Check for params with driver class types and exchange it
2416 // with its remote interface
2417 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
2418 paramType = checkAndGetCplusType(paramType);
2419 // Check for arrays - translate into vector in C++
2420 String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
2421 print(paramComplete);
2422 // Check if this is the last element (don't print a comma)
2423 if (i != methParams.size() - 1) {
2433 * HELPER: writeMethodCplusInterface() writes the method of the interface
2435 private void writeMethodCplusInterface(Collection<String> methods, InterfaceDecl intDecl) {
2437 for (String method : methods) {
2439 List<String> methParams = intDecl.getMethodParams(method);
2440 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2441 print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2442 intDecl.getMethodId(method) + "(");
2443 for (int i = 0; i < methParams.size(); i++) {
2444 // Check for params with driver class types and exchange it
2445 // with its remote interface
2446 String paramType = methPrmTypes.get(i);
2447 paramType = checkAndGetCplusType(paramType);
2448 // Check for arrays - translate into vector in C++
2449 String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
2450 print(paramComplete);
2451 // Check if this is the last element (don't print a comma)
2452 if (i != methParams.size() - 1) {
2462 * HELPER: generateEnumCplus() writes the enumeration declaration
2464 public void generateEnumCplus() throws IOException {
2466 // Create a new directory
2467 createDirectory(dir);
2468 for (String intface : mapIntfacePTH.keySet()) {
2469 // Get the right StructDecl
2470 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2471 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
2472 Set<String> enumTypes = enumDecl.getEnumDeclarations();
2473 // Iterate over enum declarations
2474 for (String enType : enumTypes) {
2475 // Open a new file to write into
2476 FileWriter fw = new FileWriter(dir + "/" + enType + ".hpp");
2477 pw = new PrintWriter(new BufferedWriter(fw));
2478 // Write file headers
2479 println("#ifndef _" + enType.toUpperCase() + "_HPP__");
2480 println("#define _" + enType.toUpperCase() + "_HPP__");
2481 println("enum " + enType + " {");
2482 List<String> enumMembers = enumDecl.getMembers(enType);
2483 for (int i = 0; i < enumMembers.size(); i++) {
2485 String member = enumMembers.get(i);
2487 // Check if this is the last element (don't print a comma)
2488 if (i != enumMembers.size() - 1)
2496 System.out.println("IoTCompiler: Generated enum " + enType + ".hpp...");
2503 * HELPER: generateStructCplus() writes the struct declaration
2505 public void generateStructCplus() throws IOException {
2507 // Create a new directory
2508 createDirectory(dir);
2509 for (String intface : mapIntfacePTH.keySet()) {
2510 // Get the right StructDecl
2511 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2512 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
2513 List<String> structTypes = structDecl.getStructTypes();
2514 // Iterate over enum declarations
2515 for (String stType : structTypes) {
2516 // Open a new file to write into
2517 FileWriter fw = new FileWriter(dir + "/" + stType + ".hpp");
2518 pw = new PrintWriter(new BufferedWriter(fw));
2519 // Write file headers
2520 println("#ifndef _" + stType.toUpperCase() + "_HPP__");
2521 println("#define _" + stType.toUpperCase() + "_HPP__");
2522 println("using namespace std;");
2523 println("struct " + stType + " {");
2524 List<String> structMemberTypes = structDecl.getMemberTypes(stType);
2525 List<String> structMembers = structDecl.getMembers(stType);
2526 for (int i = 0; i < structMembers.size(); i++) {
2528 String memberType = structMemberTypes.get(i);
2529 String member = structMembers.get(i);
2530 String structTypeC = checkAndGetCplusType(memberType);
2531 String structComplete = checkAndGetCplusArray(structTypeC, member);
2532 println(structComplete + ";");
2537 System.out.println("IoTCompiler: Generated struct " + stType + ".hpp...");
2544 * generateCplusLocalInterfaces() writes the local interfaces and provides type-checking.
2546 * It needs to rewrite and exchange USERDEFINED types in input parameters of stub
2547 * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording.
2548 * The local interface has to be the input parameter for the stub and the stub
2549 * interface has to be the input parameter for the local class.
2551 public void generateCplusLocalInterfaces() throws IOException {
2553 // Create a new directory
2554 createDirectory(dir);
2555 for (String intface : mapIntfacePTH.keySet()) {
2556 // Open a new file to write into
2557 FileWriter fw = new FileWriter(dir + "/" + intface + ".hpp");
2558 pw = new PrintWriter(new BufferedWriter(fw));
2559 // Write file headers
2560 println("#ifndef _" + intface.toUpperCase() + "_HPP__");
2561 println("#define _" + intface.toUpperCase() + "_HPP__");
2562 println("#include <iostream>");
2563 // Pass in set of methods and get include classes
2564 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2565 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2566 List<String> methods = intDecl.getMethods();
2567 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
2568 printIncludeStatements(includeClasses); println("");
2569 println("using namespace std;\n");
2570 //writeStructCplus(structDecl);
2571 println("class " + intface); println("{");
2574 writeMethodCplusLocalInterface(methods, intDecl);
2578 System.out.println("IoTCompiler: Generated local interface " + intface + ".hpp...");
2584 * generateCPlusInterfaces() generate stub interfaces based on the methods list in C++
2586 * For C++ we use virtual classe as interface
2588 public void generateCPlusInterfaces() throws IOException {
2590 // Create a new directory
2591 String path = createDirectories(dir, subdir);
2592 for (String intface : mapIntfacePTH.keySet()) {
2594 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
2595 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
2597 // Open a new file to write into
2598 String newIntface = intMeth.getKey();
2599 FileWriter fw = new FileWriter(path + "/" + newIntface + ".hpp");
2600 pw = new PrintWriter(new BufferedWriter(fw));
2601 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2602 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2603 // Write file headers
2604 println("#ifndef _" + newIntface.toUpperCase() + "_HPP__");
2605 println("#define _" + newIntface.toUpperCase() + "_HPP__");
2606 println("#include <iostream>");
2607 updateIntfaceObjIdMap(intface, newIntface);
2608 // Pass in set of methods and get import classes
2609 Set<String> methods = intMeth.getValue();
2610 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, false);
2611 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
2612 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
2613 printIncludeStatements(allIncludeClasses); println("");
2614 println("using namespace std;\n");
2615 println("class " + newIntface);
2619 writeMethodCplusInterface(methods, intDecl);
2623 System.out.println("IoTCompiler: Generated interface " + newIntface + ".hpp...");
2630 * HELPER: writeMethodCplusStub() writes the methods of the stub
2632 private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, String newStubClass) {
2634 boolean isDefined = false;
2635 for (String method : methods) {
2637 List<String> methParams = intDecl.getMethodParams(method);
2638 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2639 print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2640 intDecl.getMethodId(method) + "(");
2641 boolean isCallbackMethod = false;
2642 String callbackType = null;
2643 for (int i = 0; i < methParams.size(); i++) {
2645 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
2646 // Check if this has callback object
2647 if (callbackClasses.contains(paramType)) {
2648 isCallbackMethod = true;
2649 callbackType = paramType;
2650 // Even if there're 2 callback arguments, we expect them to be of the same interface
2652 String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
2653 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
2654 print(methParamComplete);
2655 // Check if this is the last element (don't print a comma)
2656 if (i != methParams.size() - 1) {
2661 if (isCallbackMethod)
2662 writeCallbackMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType);
2663 writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType, isCallbackMethod);
2665 // Write the init callback helper method
2666 if (isCallbackMethod && !isDefined) {
2667 writeInitCallbackCplusStub(callbackType, intDecl, newStubClass);
2668 writeInitCallbackSendInfoCplusStub(intDecl);
2676 * HELPER: writeCallbackMethodBodyCplusStub() writes the callback method of the stub class
2678 private void writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
2679 List<String> methPrmTypes, String method, String callbackType) {
2681 // Check if this is single object, array, or list of objects
2682 boolean isArrayOrList = false;
2683 String callbackParam = null;
2684 for (int i = 0; i < methParams.size(); i++) {
2686 String paramType = methPrmTypes.get(i);
2687 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2688 String param = methParams.get(i);
2689 if (isArrayOrList(paramType, param)) { // Generate loop
2690 println("for (" + getGenericType(paramType) + "* cb : " + getSimpleIdentifier(param) + ") {");
2691 println(callbackType + "_CallbackSkeleton* skel" + i + " = new " + callbackType + "_CallbackSkeleton(cb, callbackAddress, objIdCnt++);");
2692 isArrayOrList = true;
2693 callbackParam = getSimpleIdentifier(param);
2695 println(callbackType + "_CallbackSkeleton* skel" + i + " = new " + callbackType + "_CallbackSkeleton(" +
2696 getSimpleIdentifier(param) + ", callbackAddress, objIdCnt++);");
2697 println("vecCallbackObj.push_back(skel" + i + ");");
2700 print("int ___paramCB" + i + " = ");
2702 println(callbackParam + ".size();");
2711 * HELPER: checkAndWriteEnumTypeCplusStub() writes the enum type (convert from enum to int)
2713 private void checkAndWriteEnumTypeCplusStub(List<String> methParams, List<String> methPrmTypes) {
2715 // Iterate and find enum declarations
2716 for (int i = 0; i < methParams.size(); i++) {
2717 String paramType = methPrmTypes.get(i);
2718 String param = methParams.get(i);
2719 if (isEnumClass(getGenericType(paramType))) {
2720 // Check if this is enum type
2721 if (isArrayOrList(paramType, param)) { // An array or vector
2722 println("int len" + i + " = " + getSimpleIdentifier(param) + ".size();");
2723 println("vector<int> paramEnum" + i + "(len" + i + ");");
2724 println("for (int i = 0; i < len" + i + "; i++) {");
2725 println("paramEnum" + i + "[i] = (int) " + getSimpleIdentifier(param) + "[i];");
2727 } else { // Just one element
2728 println("vector<int> paramEnum" + i + "(1);");
2729 println("paramEnum" + i + "[0] = (int) " + param + ";");
2737 * HELPER: checkAndWriteEnumRetTypeCplusStub() writes the enum return type (convert from enum to int)
2739 private void checkAndWriteEnumRetTypeCplusStub(String retType) {
2741 // Strips off array "[]" for return type
2742 String pureType = getSimpleArrayType(getGenericType(retType));
2743 // Take the inner type of generic
2744 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2745 pureType = getGenericType(retType);
2746 if (isEnumClass(pureType)) {
2747 // Check if this is enum type
2748 println("vector<int> retEnumInt;");
2749 println("void* retObj = &retEnumInt;");
2750 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2751 if (isArrayOrList(retType, retType)) { // An array or vector
2752 println("int retLen = retEnumInt.size();");
2753 println("vector<" + pureType + "> retVal(retLen);");
2754 println("for (int i = 0; i < retLen; i++) {");
2755 println("retVal[i] = (" + pureType + ") retEnumInt[i];");
2757 } else { // Just one element
2758 println(pureType + " retVal = (" + pureType + ") retEnumInt[0];");
2760 println("return retVal;");
2766 * HELPER: checkAndWriteStructSetupCplusStub() writes the struct type setup
2768 private void checkAndWriteStructSetupCplusStub(List<String> methParams, List<String> methPrmTypes,
2769 InterfaceDecl intDecl, String method) {
2771 // Iterate and find struct declarations
2772 for (int i = 0; i < methParams.size(); i++) {
2773 String paramType = methPrmTypes.get(i);
2774 String param = methParams.get(i);
2775 String simpleType = getGenericType(paramType);
2776 if (isStructClass(simpleType)) {
2777 // Check if this is enum type
2778 println("int numParam" + i + " = 1;");
2779 int methodNumId = intDecl.getMethodNumId(method);
2780 String helperMethod = methodNumId + "struct" + i;
2781 println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
2782 println("string retTypeStruct" + i + " = \"void\";");
2783 println("string paramClsStruct" + i + "[] = { \"int\" };");
2784 print("int structLen" + i + " = ");
2785 if (isArrayOrList(paramType, param)) { // An array
2786 println(getSimpleArrayType(param) + ".size();");
2787 } else { // Just one element
2790 println("void* paramObjStruct" + i + "[] = { &structLen" + i + " };");
2791 println("void* retStructLen" + i + " = NULL;");
2792 println("rmiCall->remoteCall(objectId, methodIdStruct" + i +
2793 ", retTypeStruct" + i + ", paramClsStruct" + i + ", paramObjStruct" + i +
2794 ", numParam" + i + ", retStructLen" + i + ");\n");
2801 * HELPER: writeLengthStructParamClassCplusStub() writes lengths of params
2803 private void writeLengthStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes) {
2805 // Iterate and find struct declarations - count number of params
2806 for (int i = 0; i < methParams.size(); i++) {
2807 String paramType = methPrmTypes.get(i);
2808 String param = methParams.get(i);
2809 String simpleType = getGenericType(paramType);
2810 if (isStructClass(simpleType)) {
2811 int members = getNumOfMembers(simpleType);
2812 if (isArrayOrList(paramType, param)) { // An array or list
2813 String structLen = getSimpleIdentifier(param) + ".size()";
2814 print(members + "*" + structLen);
2816 print(Integer.toString(members));
2819 if (i != methParams.size() - 1) {
2827 * HELPER: writeStructMembersCplusStub() writes member parameters of struct
2829 private void writeStructMembersCplusStub(String simpleType, String paramType, String param) {
2831 // Get the struct declaration for this struct and generate initialization code
2832 StructDecl structDecl = getStructDecl(simpleType);
2833 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2834 List<String> members = structDecl.getMembers(simpleType);
2835 if (isArrayOrList(paramType, param)) { // An array or list
2836 println("for(int i = 0; i < " + getSimpleIdentifier(param) + ".size(); i++) {");
2838 if (isArrayOrList(paramType, param)) { // An array or list
2839 for (int i = 0; i < members.size(); i++) {
2840 String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
2841 println("paramCls[pos] = \"" + prmTypeC + "\";");
2842 print("paramObj[pos++] = &" + getSimpleIdentifier(param) + "[i].");
2843 print(getSimpleIdentifier(members.get(i)));
2847 } else { // Just one struct element
2848 for (int i = 0; i < members.size(); i++) {
2849 String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
2850 println("paramCls[pos] = \"" + prmTypeC + "\";");
2851 print("paramObj[pos++] = &" + param + ".");
2852 print(getSimpleIdentifier(members.get(i)));
2860 * HELPER: writeStructParamClassCplusStub() writes member parameters of struct
2862 private void writeStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes, String callbackType) {
2864 print("int numParam = ");
2865 writeLengthStructParamClassCplusStub(methParams, methPrmTypes);
2867 println("void* paramObj[numParam];");
2868 println("string paramCls[numParam];");
2869 println("int pos = 0;");
2870 // Iterate again over the parameters
2871 for (int i = 0; i < methParams.size(); i++) {
2872 String paramType = methPrmTypes.get(i);
2873 String param = methParams.get(i);
2874 String simpleType = getGenericType(paramType);
2875 if (isStructClass(simpleType)) {
2876 writeStructMembersCplusStub(simpleType, paramType, param);
2877 } else if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2878 println("paramCls[pos] = \"int\";");
2879 println("paramObj[pos++] = &___paramCB" + i + ";");
2881 String prmTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
2882 println("paramCls[pos] = \"" + prmTypeC + "\";");
2883 print("paramObj[pos++] = &");
2884 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
2893 * HELPER: writeStructRetMembersCplusStub() writes member parameters of struct for return statement
2895 private void writeStructRetMembersCplusStub(String simpleType, String retType) {
2897 // Get the struct declaration for this struct and generate initialization code
2898 StructDecl structDecl = getStructDecl(simpleType);
2899 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2900 List<String> members = structDecl.getMembers(simpleType);
2901 if (isArrayOrList(retType, retType)) { // An array or list
2902 println("for(int i = 0; i < retLen; i++) {");
2904 if (isArrayOrList(retType, retType)) { // An array or list
2905 for (int i = 0; i < members.size(); i++) {
2906 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
2907 print("structRet[i]." + getSimpleIdentifier(members.get(i)));
2908 println(" = retParam" + i + "[i];");
2911 } else { // Just one struct element
2912 for (int i = 0; i < members.size(); i++) {
2913 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
2914 print("structRet." + getSimpleIdentifier(members.get(i)));
2915 println(" = retParam" + i + ";");
2918 println("return structRet;");
2923 * HELPER: writeStructReturnCplusStub() writes member parameters of struct for return statement
2925 private void writeStructReturnCplusStub(String simpleType, String retType) {
2927 // Minimum retLen is 1 if this is a single struct object
2928 println("int retLen = 0;");
2929 println("void* retLenObj = { &retLen };");
2930 // Handle the returned struct!!!
2931 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retLenObj);");
2932 int numMem = getNumOfMembers(simpleType);
2933 println("int numRet = " + numMem + "*retLen;");
2934 println("string retCls[numRet];");
2935 println("void* retObj[numRet];");
2936 StructDecl structDecl = getStructDecl(simpleType);
2937 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2938 List<String> members = structDecl.getMembers(simpleType);
2940 if (isArrayOrList(retType, retType)) { // An array or list
2941 for (int i = 0; i < members.size(); i++) {
2942 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2943 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2944 println(getSimpleType(getEnumType(prmType)) + " retParam" + i + "[retLen];");
2946 } else { // Just one struct element
2947 for (int i = 0; i < members.size(); i++) {
2948 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2949 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2950 println(getSimpleType(getEnumType(prmType)) + " retParam" + i + ";");
2953 println("int retPos = 0;");
2954 // Get the struct declaration for this struct and generate initialization code
2955 if (isArrayOrList(retType, retType)) { // An array or list
2956 println("for(int i = 0; i < retLen; i++) {");
2957 for (int i = 0; i < members.size(); i++) {
2958 String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
2959 println("retCls[retPos] = \"" + prmTypeC + "\";");
2960 println("retObj[retPos++] = &retParam" + i + "[i];");
2963 } else { // Just one struct element
2964 for (int i = 0; i < members.size(); i++) {
2965 String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
2966 println("retCls[retPos] = \"" + prmTypeC + "\";");
2967 println("retObj[retPos++] = &retParam" + i + ";");
2970 println("rmiCall->getStructObjects(retCls, numRet, retObj);");
2971 if (isArrayOrList(retType, retType)) { // An array or list
2972 println("vector<" + simpleType + "> structRet(retLen);");
2974 println(simpleType + " structRet;");
2975 writeStructRetMembersCplusStub(simpleType, retType);
2980 * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class
2982 private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
2983 List<String> methPrmTypes, String method, String callbackType, boolean isCallbackMethod) {
2985 checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method);
2986 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
2987 String retType = intDecl.getMethodType(method);
2988 println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";");
2989 checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes);
2990 // Generate array of parameter types
2991 if (isStructPresent(methParams, methPrmTypes)) {
2992 writeStructParamClassCplusStub(methParams, methPrmTypes, callbackType);
2994 println("int numParam = " + methParams.size() + ";");
2995 print("string paramCls[] = { ");
2996 for (int i = 0; i < methParams.size(); i++) {
2997 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
2998 if (checkCallbackType(paramType, callbackType)) {
3001 String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
3002 print("\"" + paramTypeC + "\"");
3004 // Check if this is the last element (don't print a comma)
3005 if (i != methParams.size() - 1) {
3010 // Generate array of parameter objects
3011 print("void* paramObj[] = { ");
3012 for (int i = 0; i < methParams.size(); i++) {
3013 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3014 if (checkCallbackType(paramType, callbackType)) // Check if this has callback object
3015 print("&___paramCB" + i);
3017 print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
3018 // Check if this is the last element (don't print a comma)
3019 if (i != methParams.size() - 1) {
3025 // Check if this is "void"
3026 if (retType.equals("void")) {
3027 println("void* retObj = NULL;");
3028 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
3029 } else { // We do have a return value
3030 // Generate array of parameter types
3031 if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
3032 writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType);
3034 // Check if the return value NONPRIMITIVES
3035 if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) {
3036 checkAndWriteEnumRetTypeCplusStub(retType);
3038 //if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
3039 if (isArrayOrList(retType,retType))
3040 println(checkAndGetCplusType(retType) + " retVal;");
3042 println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
3044 println("void* retObj = &retVal;");
3045 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
3046 println("return retVal;");
3054 * HELPER: writePropertiesCplusStub() writes the properties of the stub class
3056 private void writePropertiesCplusPermission(String intface) {
3058 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3059 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3060 String newIntface = intMeth.getKey();
3061 int newObjectId = getNewIntfaceObjectId(newIntface);
3062 println("const static int object" + newObjectId + "Id = " + newObjectId + ";\t//" + newIntface);
3063 println("static set<int> set" + newObjectId + "Allowed;");
3068 * HELPER: writePropertiesCplusStub() writes the properties of the stub class
3070 private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
3072 println("IoTRMICall *rmiCall;");
3073 println("string callbackAddress;");
3074 println("vector<int> ports;\n");
3075 // Get the object Id
3076 Integer objId = mapIntfaceObjId.get(intface);
3077 println("const static int objectId = " + objId + ";");
3078 if (callbackExist) {
3079 // We assume that each class only has one callback interface for now
3080 Iterator it = callbackClasses.iterator();
3081 String callbackType = (String) it.next();
3082 println("// Callback properties");
3083 println("IoTRMIObject *rmiObj;");
3084 println("vector<" + callbackType + "*> vecCallbackObj;");
3085 println("static int objIdCnt;");
3086 // Generate permission stuff for callback stubs
3087 writePropertiesCplusPermission(callbackType);
3094 * HELPER: writeConstructorCplusStub() writes the constructor of the stub class
3096 private void writeConstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3098 println(newStubClass +
3099 "(int _port, const char* _skeletonAddress, string _callbackAddress, int _rev, bool* _bResult, vector<int> _ports) {");
3100 println("callbackAddress = _callbackAddress;");
3101 println("ports = _ports;");
3102 println("rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev, _bResult);");
3103 if (callbackExist) {
3104 Iterator it = callbackClasses.iterator();
3105 String callbackType = (String) it.next();
3106 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
3107 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
3108 writeCplusInitCallbackPermission(callbackType, intDecl, callbackExist);
3109 println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
3110 println("th1.detach();");
3111 println("___regCB();");
3118 * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
3120 private void writeDeconstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3122 println("~" + newStubClass + "() {");
3123 println("if (rmiCall != NULL) {");
3124 println("delete rmiCall;");
3125 println("rmiCall = NULL;");
3127 if (callbackExist) {
3128 // We assume that each class only has one callback interface for now
3129 println("if (rmiObj != NULL) {");
3130 println("delete rmiObj;");
3131 println("rmiObj = NULL;");
3133 Iterator it = callbackClasses.iterator();
3134 String callbackType = (String) it.next();
3135 println("for(" + callbackType + "* cb : vecCallbackObj) {");
3136 println("delete cb;");
3137 println("cb = NULL;");
3146 * HELPER: writeCplusMethodCallbackPermission() writes permission checks in stub for callbacks
3148 private void writeCplusMethodCallbackPermission(String intface) {
3150 println("int methodId = IoTRMIObject::getMethodId(method);");
3151 // Get all the different stubs
3152 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3153 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3154 String newIntface = intMeth.getKey();
3155 int newObjectId = getNewIntfaceObjectId(newIntface);
3156 println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
3157 println("cerr << \"Callback object for " + intface + " is not allowed to access method: \" << methodId;");
3165 * HELPER: writeInitCallbackCplusStub() writes the initialization of callback
3167 private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl, String newStubClass) {
3169 println("void ___initCallBack() {");
3170 println("bool bResult = false;");
3171 int port = getPortCount(newStubClass);
3172 println("rmiObj = new IoTRMIObject(ports[" + port + "], &bResult);");
3173 println("while (true) {");
3174 println("char* method = rmiObj->getMethodBytes();");
3175 //writeCplusMethodCallbackPermission(intface);
3176 println("int objId = IoTRMIObject::getObjectId(method);");
3177 println("if (objId < vecCallbackObj.size()) { // Check if still within range");
3178 println(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface +
3179 "_CallbackSkeleton*> (vecCallbackObj.at(objId));");
3180 writeCplusMethodCallbackPermission(intface);
3181 println("skel->invokeMethod(rmiObj);");
3184 println("cerr << \"Illegal object Id: \" << to_string(objId);");
3185 // TODO: perhaps need to change this into "throw" to make it cleaner (allow stack unfolding)
3194 * HELPER: writeCplusInitCallbackPermission() writes the permission for callback
3196 private void writeCplusInitCallbackPermission(String intface, InterfaceDecl intDecl, boolean callbackExist) {
3198 if (callbackExist) {
3199 String method = "___initCallBack()";
3200 int methodNumId = intDecl.getHelperMethodNumId(method);
3201 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3202 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3203 String newIntface = intMeth.getKey();
3204 int newObjectId = getNewIntfaceObjectId(newIntface);
3205 println("set" + newObjectId + "Allowed.insert(" + methodNumId + ");");
3212 * HELPER: writeInitCallbackSendInfoCplusStub() writes the initialization (send info part) of callback
3214 private void writeInitCallbackSendInfoCplusStub(InterfaceDecl intDecl) {
3216 // Generate info sending part
3217 println("void ___regCB() {");
3218 println("int numParam = 3;");
3219 String method = "___initCallBack()";
3220 int methodNumId = intDecl.getHelperMethodNumId(method);
3221 println("int methodId = " + methodNumId + ";");
3222 println("string retType = \"void\";");
3223 println("string paramCls[] = { \"int*\", \"String\", \"int\" };");
3224 println("int rev = 0;");
3225 println("void* paramObj[] = { &ports, &callbackAddress, &rev };");
3226 println("void* retObj = NULL;");
3227 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
3233 * generateCPlusStubClasses() generate stubs based on the methods list in C++
3235 public void generateCPlusStubClasses() throws IOException {
3237 // Create a new directory
3238 String path = createDirectories(dir, subdir);
3239 for (String intface : mapIntfacePTH.keySet()) {
3241 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3242 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3243 // Open a new file to write into
3244 String newIntface = intMeth.getKey();
3245 String newStubClass = newIntface + "_Stub";
3246 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
3247 pw = new PrintWriter(new BufferedWriter(fw));
3248 // Write file headers
3249 println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
3250 println("#define _" + newStubClass.toUpperCase() + "_HPP__");
3251 println("#include <iostream>");
3252 // Find out if there are callback objects
3253 Set<String> methods = intMeth.getValue();
3254 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
3255 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
3256 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
3257 boolean callbackExist = !callbackClasses.isEmpty();
3258 if (callbackExist) // Need thread library if this has callback
3259 println("#include <thread>");
3260 println("#include \"" + newIntface + ".hpp\""); println("");
3261 println("using namespace std;"); println("");
3262 println("class " + newStubClass + " : public " + newIntface); println("{");
3263 println("private:\n");
3264 writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses);
3265 println("public:\n");
3266 // Add default constructor and destructor
3267 println(newStubClass + "() { }"); println("");
3268 writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3269 writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3271 writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass);
3272 print("}"); println(";");
3273 if (callbackExist) {
3274 Iterator it = callbackClasses.iterator();
3275 String callbackType = (String) it.next();
3276 // Generate permission stuff for callback stubs
3277 DeclarationHandler decHandlerCallback = mapIntDeclHand.get(callbackType);
3278 InterfaceDecl intDeclCallback = (InterfaceDecl) decHandlerCallback.getInterfaceDecl(callbackType);
3279 writePermissionInitializationCplus(callbackType, newStubClass, intDeclCallback);
3281 writeObjectIdCountInitializationCplus(newStubClass, callbackExist);
3284 System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
3291 * HELPER: writePropertiesCplusCallbackStub() writes the properties of the stub class
3293 private void writePropertiesCplusCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
3295 println("IoTRMICall *rmiCall;");
3296 // Get the object Id
3297 println("int objectId;");
3298 println("vector<int> ports;\n");
3299 println("string callbackAddress;");
3300 if (callbackExist) {
3301 // We assume that each class only has one callback interface for now
3302 Iterator it = callbackClasses.iterator();
3303 String callbackType = (String) it.next();
3304 println("// Callback properties");
3305 println("IoTRMIObject *rmiObj;");
3306 println("vector<" + callbackType + "*> vecCallbackObj;");
3307 println("static int objIdCnt;");
3308 // TODO: Need to initialize address and ports if we want to have callback-in-callback
3309 writePropertiesCplusPermission(callbackType);
3316 * HELPER: writeConstructorCplusCallbackStub() writes the constructor of the stub class
3318 private void writeConstructorCplusCallbackStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3320 println(newStubClass + "(IoTRMICall* _rmiCall, string _callbackAddress, int _objectId, vector<int> _ports) {");
3321 println("objectId = _objectId;");
3322 println("callbackAddress = _callbackAddress;");
3323 println("rmiCall = _rmiCall;");
3324 println("ports = _ports;");
3325 if (callbackExist) {
3326 Iterator it = callbackClasses.iterator();
3327 String callbackType = (String) it.next();
3328 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
3329 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
3330 writeCplusInitCallbackPermission(callbackType, intDecl, callbackExist);
3331 println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
3332 println("th1.detach();");
3333 println("___regCB();");
3340 * generateCPlusCallbackStubClasses() generate callback stubs based on the methods list in C++
3342 public void generateCPlusCallbackStubClasses() throws IOException {
3344 // Create a new directory
3345 String path = createDirectories(dir, subdir);
3346 for (String intface : mapIntfacePTH.keySet()) {
3348 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3349 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3350 // Open a new file to write into
3351 String newIntface = intMeth.getKey();
3352 String newStubClass = newIntface + "_CallbackStub";
3353 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
3354 pw = new PrintWriter(new BufferedWriter(fw));
3355 // Find out if there are callback objects
3356 Set<String> methods = intMeth.getValue();
3357 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
3358 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
3359 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
3360 boolean callbackExist = !callbackClasses.isEmpty();
3361 // Write file headers
3362 println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
3363 println("#define _" + newStubClass.toUpperCase() + "_HPP__");
3364 println("#include <iostream>");
3366 println("#include <thread>");
3367 println("#include \"" + newIntface + ".hpp\""); println("");
3368 println("using namespace std;"); println("");
3369 println("class " + newStubClass + " : public " + newIntface); println("{");
3370 println("private:\n");
3371 writePropertiesCplusCallbackStub(intface, newIntface, callbackExist, callbackClasses);
3372 println("public:\n");
3373 // Add default constructor and destructor
3374 println(newStubClass + "() { }"); println("");
3375 writeConstructorCplusCallbackStub(newStubClass, callbackExist, callbackClasses);
3376 writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3378 writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass);
3380 if (callbackExist) {
3381 Iterator it = callbackClasses.iterator();
3382 String callbackType = (String) it.next();
3383 // Generate permission stuff for callback stubs
3384 DeclarationHandler decHandlerCallback = mapIntDeclHand.get(callbackType);
3385 InterfaceDecl intDeclCallback = (InterfaceDecl) decHandlerCallback.getInterfaceDecl(callbackType);
3386 writePermissionInitializationCplus(callbackType, newStubClass, intDeclCallback);
3388 writeObjectIdCountInitializationCplus(newStubClass, callbackExist);
3391 System.out.println("IoTCompiler: Generated callback stub class " + newIntface + ".hpp...");
3398 * HELPER: writePropertiesCplusSkeleton() writes the properties of the skeleton class
3400 private void writePropertiesCplusSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
3402 println(intface + " *mainObj;");
3403 println("vector<int> ports;");
3404 println("string callbackAddress;");
3406 if (callbackExist) {
3407 Iterator it = callbackClasses.iterator();
3408 String callbackType = (String) it.next();
3409 String exchangeType = checkAndGetParamClass(callbackType);
3410 println("// Callback properties");
3411 println("static int objIdCnt;");
3412 println("vector<" + exchangeType + "*> vecCallbackObj;");
3413 println("IoTRMICall *rmiCall;");
3415 println("IoTRMIObject *rmiObj;\n");
3416 // Keep track of object Ids of all stubs registered to this interface
3417 writePropertiesCplusPermission(intface);
3423 * HELPER: writeObjectIdCountInitializationCplus() writes the initialization of objIdCnt variable
3425 private void writeObjectIdCountInitializationCplus(String newSkelClass, boolean callbackExist) {
3428 println("int " + newSkelClass + "::objIdCnt = 0;");
3433 * HELPER: writePermissionInitializationCplus() writes the initialization of permission set
3435 private void writePermissionInitializationCplus(String intface, String newSkelClass, InterfaceDecl intDecl) {
3437 // Keep track of object Ids of all stubs registered to this interface
3438 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3439 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3440 String newIntface = intMeth.getKey();
3441 int newObjectId = getNewIntfaceObjectId(newIntface);
3442 print("set<int> " + newSkelClass + "::set" + newObjectId + "Allowed { ");
3443 Set<String> methodIds = intMeth.getValue();
3445 for (String methodId : methodIds) {
3446 int methodNumId = intDecl.getMethodNumId(methodId);
3447 print(Integer.toString(methodNumId));
3448 // Check if this is the last element (don't print a comma)
3449 if (i != methodIds.size() - 1) {
3460 * HELPER: writeStructPermissionCplusSkeleton() writes permission for struct helper
3462 private void writeStructPermissionCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, String intface) {
3464 // Use this set to handle two same methodIds
3465 for (String method : methods) {
3466 List<String> methParams = intDecl.getMethodParams(method);
3467 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3468 // Check for params with structs
3469 for (int i = 0; i < methParams.size(); i++) {
3470 String paramType = methPrmTypes.get(i);
3471 String param = methParams.get(i);
3472 String simpleType = getGenericType(paramType);
3473 if (isStructClass(simpleType)) {
3474 int methodNumId = intDecl.getMethodNumId(method);
3475 String helperMethod = methodNumId + "struct" + i;
3476 int helperMethodNumId = intDecl.getHelperMethodNumId(helperMethod);
3477 // Iterate over interfaces to give permissions to
3478 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3479 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3480 String newIntface = intMeth.getKey();
3481 int newObjectId = getNewIntfaceObjectId(newIntface);
3482 println("set" + newObjectId + "Allowed.insert(" + helperMethodNumId + ");");
3491 * HELPER: writeConstructorCplusSkeleton() writes the constructor of the skeleton class
3493 private void writeConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist, InterfaceDecl intDecl, Collection<String> methods) {
3495 println(newSkelClass + "(" + intface + " *_mainObj, string _callbackAddress, int _port) {");
3496 println("bool _bResult = false;");
3497 println("mainObj = _mainObj;");
3498 println("callbackAddress = _callbackAddress;");
3499 println("rmiObj = new IoTRMIObject(_port, &_bResult);");
3500 writeCplusInitCallbackPermission(intface, intDecl, callbackExist);
3501 writeStructPermissionCplusSkeleton(methods, intDecl, intface);
3502 println("___waitRequestInvokeMethod();");
3508 * HELPER: writeDeconstructorCplusSkeleton() writes the deconstructor of the skeleton class
3510 private void writeDeconstructorCplusSkeleton(String newSkelClass, boolean callbackExist, Set<String> callbackClasses) {
3512 println("~" + newSkelClass + "() {");
3513 println("if (rmiObj != NULL) {");
3514 println("delete rmiObj;");
3515 println("rmiObj = NULL;");
3517 if (callbackExist) {
3518 // We assume that each class only has one callback interface for now
3519 println("if (rmiCall != NULL) {");
3520 println("delete rmiCall;");
3521 println("rmiCall = NULL;");
3523 Iterator it = callbackClasses.iterator();
3524 String callbackType = (String) it.next();
3525 String exchangeType = checkAndGetParamClass(callbackType);
3526 println("for(" + exchangeType + "* cb : vecCallbackObj) {");
3527 println("delete cb;");
3528 println("cb = NULL;");
3537 * HELPER: writeStdMethodBodyCplusSkeleton() writes the standard method body in the skeleton class
3539 private void writeStdMethodBodyCplusSkeleton(List<String> methParams, String methodId, String methodType) {
3541 if (methodType.equals("void"))
3542 print("mainObj->" + methodId + "(");
3544 print("return mainObj->" + methodId + "(");
3545 for (int i = 0; i < methParams.size(); i++) {
3547 print(getSimpleIdentifier(methParams.get(i)));
3548 // Check if this is the last element (don't print a comma)
3549 if (i != methParams.size() - 1) {
3558 * HELPER: writeInitCallbackCplusSkeleton() writes the init callback method for skeleton class
3560 private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton, String intface) {
3562 // This is a callback skeleton generation
3563 if (callbackSkeleton)
3564 println("void ___regCB(IoTRMIObject* rmiObj) {");
3566 println("void ___regCB() {");
3567 println("int numParam = 3;");
3568 println("vector<int> param1;");
3569 println("string param2 = \"\";");
3570 println("int param3 = 0;");
3571 println("string paramCls[] = { \"int*\", \"String\", \"int\" };");
3572 println("void* paramObj[] = { ¶m1, ¶m2, ¶m3 };");
3573 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3574 println("bool bResult = false;");
3575 String stubInt = null;
3576 if (callbackSkeleton)
3577 stubInt = getStubInterface(intface) + "_CallbackStub";
3579 stubInt = getStubInterface(intface) + "_Stub";
3580 int port = getPortCount(stubInt);
3581 println("rmiCall = new IoTRMICall(param1[" + port + "], param2.c_str(), param3, &bResult);");
3587 * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
3589 private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
3590 Set<String> callbackClasses, boolean callbackSkeleton, String intface) {
3592 boolean isDefined = false;
3593 for (String method : methods) {
3595 List<String> methParams = intDecl.getMethodParams(method);
3596 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3597 String methodId = intDecl.getMethodId(method);
3598 String methodType = checkAndGetCplusType(intDecl.getMethodType(method));
3599 print(methodType + " " + methodId + "(");
3600 boolean isCallbackMethod = false;
3601 String callbackType = null;
3602 for (int i = 0; i < methParams.size(); i++) {
3604 String origParamType = methPrmTypes.get(i);
3605 if (callbackClasses.contains(origParamType)) { // Check if this has callback object
3606 isCallbackMethod = true;
3607 callbackType = origParamType;
3609 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
3610 String methPrmType = checkAndGetCplusType(paramType);
3611 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
3612 print(methParamComplete);
3613 // Check if this is the last element (don't print a comma)
3614 if (i != methParams.size() - 1) {
3619 // Now, write the body of skeleton!
3620 writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method));
3622 if (isCallbackMethod && !isDefined) {
3623 writeInitCallbackCplusSkeleton(callbackSkeleton, intface);
3631 * HELPER: writeCallbackCplusNumStubs() writes the numStubs variable
3633 private void writeCallbackCplusNumStubs(List<String> methParams, List<String> methPrmTypes, String callbackType) {
3635 for (int i = 0; i < methParams.size(); i++) {
3636 String paramType = methPrmTypes.get(i);
3637 String param = methParams.get(i);
3638 //if (callbackType.equals(paramType)) {
3639 if (checkCallbackType(paramType, callbackType)) // Check if this has callback object
3640 println("int numStubs" + i + " = 0;");
3646 * HELPER: writeCallbackCplusStubGeneration() writes the callback stub generation part
3648 private void writeCallbackCplusStubGeneration(List<String> methParams, List<String> methPrmTypes, String callbackType) {
3650 // Iterate over callback objects
3651 for (int i = 0; i < methParams.size(); i++) {
3652 String paramType = methPrmTypes.get(i);
3653 String param = methParams.get(i);
3654 // Generate a loop if needed
3655 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
3656 String exchParamType = checkAndGetParamClass(getGenericType(paramType));
3657 if (isArrayOrList(paramType, param)) {
3658 println("vector<" + exchParamType + "*> stub" + i + ";");
3659 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
3660 println(exchParamType + "* cb" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);");
3661 println("stub" + i + ".push_back(cb" + i + ");");
3662 println("vecCallbackObj.push_back(cb" + i + ");");
3663 println("objIdCnt++;");
3666 println(exchParamType + "* stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);");
3667 println("vecCallbackObj.push_back(stub" + i + ");");
3668 println("objIdCnt++;");
3676 * HELPER: checkAndWriteEnumTypeCplusSkeleton() writes the enum type (convert from enum to int)
3678 private void checkAndWriteEnumTypeCplusSkeleton(List<String> methParams, List<String> methPrmTypes) {
3680 // Iterate and find enum declarations
3681 for (int i = 0; i < methParams.size(); i++) {
3682 String paramType = methPrmTypes.get(i);
3683 String param = methParams.get(i);
3684 String simpleType = getGenericType(paramType);
3685 if (isEnumClass(simpleType)) {
3686 // Check if this is enum type
3687 if (isArrayOrList(paramType, param)) { // An array
3688 println("int len" + i + " = paramEnumInt" + i + ".size();");
3689 println("vector<" + simpleType + "> paramEnum" + i + "(len" + i + ");");
3690 println("for (int i=0; i < len" + i + "; i++) {");
3691 println("paramEnum" + i + "[i] = (" + simpleType + ") paramEnumInt" + i + "[i];");
3693 } else { // Just one element
3694 println(simpleType + " paramEnum" + i + ";");
3695 println("paramEnum" + i + " = (" + simpleType + ") paramEnumInt" + i + "[0];");
3703 * HELPER: checkAndWriteEnumRetTypeCplusSkeleton() writes the enum return type (convert from enum to int)
3705 private void checkAndWriteEnumRetTypeCplusSkeleton(String retType) {
3707 // Strips off array "[]" for return type
3708 String pureType = getSimpleArrayType(getGenericType(retType));
3709 // Take the inner type of generic
3710 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
3711 pureType = getGenericType(retType);
3712 if (isEnumClass(pureType)) {
3713 // Check if this is enum type
3715 if (isArrayOrList(retType, retType)) { // An array
3716 println("int retLen = retEnum.size();");
3717 println("vector<int> retEnumInt(retLen);");
3718 println("for (int i=0; i < retLen; i++) {");
3719 println("retEnumInt[i] = (int) retEnum[i];");
3721 } else { // Just one element
3722 println("vector<int> retEnumInt(1);");
3723 println("retEnumInt[0] = (int) retEnum;");
3730 * HELPER: writeMethodInputParameters() writes the parameter variables for C++ skeleton
3732 private void writeMethodInputParameters(List<String> methParams, List<String> methPrmTypes,
3733 Set<String> callbackClasses, String methodId) {
3735 print(methodId + "(");
3736 for (int i = 0; i < methParams.size(); i++) {
3737 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3738 if (callbackClasses.contains(paramType))
3740 else if (isEnumClass(getGenericType(paramType))) // Check if this is enum type
3741 print("paramEnum" + i);
3742 else if (isStructClass(getGenericType(paramType))) // Struct type
3743 print("paramStruct" + i);
3745 print(getSimpleIdentifier(methParams.get(i)));
3746 if (i != methParams.size() - 1) {
3755 * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton
3757 private void writeMethodHelperReturnCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3758 List<String> methPrmTypes, String method, boolean isCallbackMethod, String callbackType,
3759 String methodId, Set<String> callbackClasses) {
3761 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3762 if (isCallbackMethod)
3763 writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType);
3764 checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes);
3765 writeStructMembersInitCplusSkeleton(intDecl, methParams, methPrmTypes, method);
3766 // Check if this is "void"
3767 String retType = intDecl.getMethodType(method);
3768 // Check if this is "void"
3769 if (retType.equals("void")) {
3770 writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
3771 } else { // We do have a return value
3772 if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) // Enum type
3773 print(checkAndGetCplusType(retType) + " retEnum = ");
3774 else if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type
3775 print(checkAndGetCplusType(retType) + " retStruct = ");
3777 print(checkAndGetCplusType(retType) + " retVal = ");
3778 writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
3779 checkAndWriteEnumRetTypeCplusSkeleton(retType);
3780 if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type
3781 writeStructReturnCplusSkeleton(getSimpleArrayType(getGenericType(retType)), retType);
3782 if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) // Enum type
3783 println("void* retObj = &retEnumInt;");
3785 if (!isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type
3786 println("void* retObj = &retVal;");
3787 String retTypeC = checkAndGetCplusType(retType);
3788 if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type
3789 println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);");
3791 println("rmiObj->sendReturnObj(retObj, \"" + checkAndGetCplusRetClsType(getEnumType(retType)) + "\");");
3797 * HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class
3799 private void writeStdMethodHelperBodyCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3800 List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
3802 // Generate array of parameter types
3803 boolean isCallbackMethod = false;
3804 String callbackType = null;
3805 print("string paramCls[] = { ");
3806 for (int i = 0; i < methParams.size(); i++) {
3807 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3808 if (callbackClasses.contains(paramType)) {
3809 isCallbackMethod = true;
3810 callbackType = paramType;
3812 } else { // Generate normal classes if it's not a callback object
3813 String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
3814 print("\"" + paramTypeC + "\"");
3816 if (i != methParams.size() - 1) {
3821 println("int numParam = " + methParams.size() + ";");
3822 if (isCallbackMethod)
3823 writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType);
3824 // Generate parameters
3825 for (int i = 0; i < methParams.size(); i++) {
3826 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3827 if (!callbackClasses.contains(paramType)) {
3828 String methParamType = methPrmTypes.get(i);
3829 if (isEnumClass(getSimpleArrayType(getGenericType(methParamType)))) {
3830 // Check if this is enum type
3831 println("vector<int> paramEnumInt" + i + ";");
3833 String methPrmType = checkAndGetCplusType(methParamType);
3834 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
3835 println(methParamComplete + ";");
3839 // Generate array of parameter objects
3840 print("void* paramObj[] = { ");
3841 for (int i = 0; i < methParams.size(); i++) {
3842 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3843 if (callbackClasses.contains(paramType))
3844 print("&numStubs" + i);
3845 else if (isEnumClass(getGenericType(paramType))) // Check if this is enum type
3846 print("¶mEnumInt" + i);
3848 print("&" + getSimpleIdentifier(methParams.get(i)));
3849 if (i != methParams.size() - 1) {
3854 // Write the return value part
3855 writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
3856 callbackType, methodId, callbackClasses);
3861 * HELPER: writeStructMembersCplusSkeleton() writes member parameters of struct
3863 private void writeStructMembersCplusSkeleton(String simpleType, String paramType,
3864 String param, String method, InterfaceDecl intDecl, int iVar) {
3866 // Get the struct declaration for this struct and generate initialization code
3867 StructDecl structDecl = getStructDecl(simpleType);
3868 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3869 List<String> members = structDecl.getMembers(simpleType);
3870 int methodNumId = intDecl.getMethodNumId(method);
3871 String counter = "struct" + methodNumId + "Size" + iVar;
3873 if (isArrayOrList(paramType, param)) { // An array or list
3874 for (int i = 0; i < members.size(); i++) {
3875 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3876 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3877 println(getSimpleType(getEnumType(prmType)) + " param" + iVar + i + "[" + counter + "];");
3879 } else { // Just one struct element
3880 for (int i = 0; i < members.size(); i++) {
3881 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3882 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3883 println(getSimpleType(getEnumType(prmType)) + " param" + iVar + i + ";");
3886 if (isArrayOrList(paramType, param)) { // An array or list
3887 println("for(int i = 0; i < " + counter + "; i++) {");
3889 if (isArrayOrList(paramType, param)) { // An array or list
3890 for (int i = 0; i < members.size(); i++) {
3891 String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
3892 println("paramCls[pos] = \"" + prmTypeC + "\";");
3893 println("paramObj[pos++] = ¶m" + iVar + i + "[i];");
3896 } else { // Just one struct element
3897 for (int i = 0; i < members.size(); i++) {
3898 String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
3899 println("paramCls[pos] = \"" + prmTypeC + "\";");
3900 println("paramObj[pos++] = ¶m" + iVar + i + ";");
3907 * HELPER: writeStructMembersInitCplusSkeleton() writes member parameters initialization of struct
3909 private void writeStructMembersInitCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3910 List<String> methPrmTypes, String method) {
3912 for (int i = 0; i < methParams.size(); i++) {
3913 String paramType = methPrmTypes.get(i);
3914 String param = methParams.get(i);
3915 String simpleType = getGenericType(paramType);
3916 if (isStructClass(simpleType)) {
3917 int methodNumId = intDecl.getMethodNumId(method);
3918 String counter = "struct" + methodNumId + "Size" + i;
3920 if (isArrayOrList(paramType, param)) { // An array or list
3921 println("vector<" + simpleType + "> paramStruct" + i + "(" + counter + ");");
3923 println(simpleType + " paramStruct" + i + ";");
3924 // Initialize members
3925 StructDecl structDecl = getStructDecl(simpleType);
3926 List<String> members = structDecl.getMembers(simpleType);
3927 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3928 if (isArrayOrList(paramType, param)) { // An array or list
3929 println("for(int i = 0; i < " + counter + "; i++) {");
3930 for (int j = 0; j < members.size(); j++) {
3931 print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j)));
3932 println(" = param" + i + j + "[i];");
3935 } else { // Just one struct element
3936 for (int j = 0; j < members.size(); j++) {
3937 print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j)));
3938 println(" = param" + i + j + ";");
3947 * HELPER: writeStructReturnCplusSkeleton() writes parameters of struct for return statement
3949 private void writeStructReturnCplusSkeleton(String simpleType, String retType) {
3951 // Minimum retLen is 1 if this is a single struct object
3952 if (isArrayOrList(retType, retType))
3953 println("int retLen = retStruct.size();");
3954 else // Just single struct object
3955 println("int retLen = 1;");
3956 println("void* retLenObj = &retLen;");
3957 println("rmiObj->sendReturnObj(retLenObj, \"int\");");
3958 int numMem = getNumOfMembers(simpleType);
3959 println("int numRetObj = " + numMem + "*retLen;");
3960 println("string retCls[numRetObj];");
3961 println("void* retObj[numRetObj];");
3962 println("int retPos = 0;");
3963 // Get the struct declaration for this struct and generate initialization code
3964 StructDecl structDecl = getStructDecl(simpleType);
3965 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3966 List<String> members = structDecl.getMembers(simpleType);
3967 if (isArrayOrList(retType, retType)) { // An array or list
3968 println("for(int i = 0; i < retLen; i++) {");
3969 for (int i = 0; i < members.size(); i++) {
3970 String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
3971 println("retCls[retPos] = \"" + prmTypeC + "\";");
3972 print("retObj[retPos++] = &retStruct[i].");
3973 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
3977 } else { // Just one struct element
3978 for (int i = 0; i < members.size(); i++) {
3979 String prmTypeC = checkAndGetCplusArgClsType(memTypes.get(i), members.get(i));
3980 println("retCls[retPos] = \"" + prmTypeC + "\";");
3981 print("retObj[retPos++] = &retStruct.");
3982 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
3991 * HELPER: writeMethodHelperStructCplusSkeleton() writes the struct in skeleton
3993 private void writeMethodHelperStructCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3994 List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
3996 // Generate array of parameter objects
3997 boolean isCallbackMethod = false;
3998 String callbackType = null;
3999 print("int numParam = ");
4000 writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
4002 println("string paramCls[numParam];");
4003 println("void* paramObj[numParam];");
4004 println("int pos = 0;");
4005 // Iterate again over the parameters
4006 for (int i = 0; i < methParams.size(); i++) {
4007 String paramType = methPrmTypes.get(i);
4008 String param = methParams.get(i);
4009 String simpleType = getGenericType(paramType);
4010 if (isStructClass(simpleType)) {
4011 writeStructMembersCplusSkeleton(simpleType, paramType, param, method, intDecl, i);
4013 String prmType = returnGenericCallbackType(methPrmTypes.get(i));
4014 if (callbackClasses.contains(prmType)) {
4015 isCallbackMethod = true;
4016 callbackType = prmType;
4017 println("int numStubs" + i + " = 0;");
4018 println("paramCls[pos] = \"int\";");
4019 println("paramObj[pos++] = &numStubs" + i + ";");
4020 } else { // Generate normal classes if it's not a callback object
4021 String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
4022 if (isEnumClass(getGenericType(paramTypeC))) { // Check if this is enum type
4023 println("vector<int> paramEnumInt" + i + ";");
4025 String methParamComplete = checkAndGetCplusArray(paramTypeC, methParams.get(i));
4026 println(methParamComplete + ";");
4028 String prmTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
4029 println("paramCls[pos] = \"" + prmTypeC + "\";");
4030 if (isEnumClass(getGenericType(paramType))) // Check if this is enum type
4031 println("paramObj[pos++] = ¶mEnumInt" + i + ";");
4033 println("paramObj[pos++] = &" + getSimpleIdentifier(methParams.get(i)) + ";");
4037 // Write the return value part
4038 writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
4039 callbackType, methodId, callbackClasses);
4044 * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
4046 private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
4048 // Use this set to handle two same methodIds
4049 Set<String> uniqueMethodIds = new HashSet<String>();
4050 for (String method : methods) {
4052 List<String> methParams = intDecl.getMethodParams(method);
4053 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4054 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
4055 String methodId = intDecl.getMethodId(method);
4057 String helperMethod = methodId;
4058 if (uniqueMethodIds.contains(methodId))
4059 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4061 uniqueMethodIds.add(methodId);
4062 String retType = intDecl.getMethodType(method);
4063 print(helperMethod + "(");
4064 boolean begin = true;
4065 for (int i = 0; i < methParams.size(); i++) { // Print size variables
4066 String paramType = methPrmTypes.get(i);
4067 String param = methParams.get(i);
4068 String simpleType = getGenericType(paramType);
4069 if (isStructClass(simpleType)) {
4070 if (!begin) // Generate comma for not the beginning variable
4074 int methodNumId = intDecl.getMethodNumId(method);
4075 print("int struct" + methodNumId + "Size" + i);
4079 writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4082 String methodId = intDecl.getMethodId(method);
4084 String helperMethod = methodId;
4085 if (uniqueMethodIds.contains(methodId))
4086 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4088 uniqueMethodIds.add(methodId);
4089 // Check if this is "void"
4090 String retType = intDecl.getMethodType(method);
4091 println(helperMethod + "() {");
4092 // Now, write the helper body of skeleton!
4093 writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4097 // Write method helper for structs
4098 writeMethodHelperStructSetupCplusSkeleton(methods, intDecl);
4103 * HELPER: writeMethodHelperStructSetupCplusSkeleton() writes the method helper of struct in skeleton class
4105 private void writeMethodHelperStructSetupCplusSkeleton(Collection<String> methods,
4106 InterfaceDecl intDecl) {
4108 // Use this set to handle two same methodIds
4109 for (String method : methods) {
4111 List<String> methParams = intDecl.getMethodParams(method);
4112 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4113 // Check for params with structs
4114 for (int i = 0; i < methParams.size(); i++) {
4115 String paramType = methPrmTypes.get(i);
4116 String param = methParams.get(i);
4117 String simpleType = getGenericType(paramType);
4118 if (isStructClass(simpleType)) {
4119 int methodNumId = intDecl.getMethodNumId(method);
4121 String helperMethod = methodNumId + "struct" + i;
4122 println(helperMethod + "() {");
4123 // Now, write the helper body of skeleton!
4124 println("string paramCls[] = { \"int\" };");
4125 println("int numParam = 1;");
4126 println("int param0 = 0;");
4127 println("void* paramObj[] = { ¶m0 };");
4128 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
4129 println("return param0;");
4138 * HELPER: writeMethodHelperStructSetupCplusCallbackSkeleton() writes the method helper of struct in skeleton class
4140 private void writeMethodHelperStructSetupCplusCallbackSkeleton(Collection<String> methods,
4141 InterfaceDecl intDecl) {
4143 // Use this set to handle two same methodIds
4144 for (String method : methods) {
4146 List<String> methParams = intDecl.getMethodParams(method);
4147 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4148 // Check for params with structs
4149 for (int i = 0; i < methParams.size(); i++) {
4150 String paramType = methPrmTypes.get(i);
4151 String param = methParams.get(i);
4152 String simpleType = getGenericType(paramType);
4153 if (isStructClass(simpleType)) {
4154 int methodNumId = intDecl.getMethodNumId(method);
4156 String helperMethod = methodNumId + "struct" + i;
4157 println(helperMethod + "(IoTRMIObject* rmiObj) {");
4158 // Now, write the helper body of skeleton!
4159 println("string paramCls[] = { \"int\" };");
4160 println("int numParam = 1;");
4161 println("int param0 = 0;");
4162 println("void* paramObj[] = { ¶m0 };");
4163 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
4164 println("return param0;");
4173 * HELPER: writeCplusMethodPermission() writes permission checks in skeleton
4175 private void writeCplusMethodPermission(String intface) {
4177 // Get all the different stubs
4178 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
4179 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
4180 String newIntface = intMeth.getKey();
4181 int newObjectId = getNewIntfaceObjectId(newIntface);
4182 println("if (_objectId == object" + newObjectId + "Id) {");
4183 println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
4184 println("cerr << \"Object with object Id: \" << _objectId << \" is not allowed to access method: \" << methodId << endl;");
4189 println("cerr << \"Object Id: \" << _objectId << \" not recognized!\" << endl;");
4197 * HELPER: writeCplusWaitRequestInvokeMethod() writes the main loop of the skeleton class
4199 private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
4201 // Use this set to handle two same methodIds
4202 Set<String> uniqueMethodIds = new HashSet<String>();
4203 println("void ___waitRequestInvokeMethod() {");
4204 // Write variables here if we have callbacks or enums or structs
4205 writeCountVarStructSkeleton(methods, intDecl);
4206 println("while (true) {");
4207 println("rmiObj->getMethodBytes();");
4208 println("int _objectId = rmiObj->getObjectId();");
4209 println("int methodId = rmiObj->getMethodId();");
4210 // Generate permission check
4211 writeCplusMethodPermission(intface);
4212 println("switch (methodId) {");
4213 // Print methods and method Ids
4214 for (String method : methods) {
4215 String methodId = intDecl.getMethodId(method);
4216 int methodNumId = intDecl.getMethodNumId(method);
4217 print("case " + methodNumId + ": ___");
4218 String helperMethod = methodId;
4219 if (uniqueMethodIds.contains(methodId))
4220 helperMethod = helperMethod + methodNumId;
4222 uniqueMethodIds.add(methodId);
4223 print(helperMethod + "(");
4224 writeInputCountVarStructSkeleton(method, intDecl);
4225 println("); break;");
4227 String method = "___initCallBack()";
4228 // Print case -9999 (callback handler) if callback exists
4229 if (callbackExist) {
4230 int methodId = intDecl.getHelperMethodNumId(method);
4231 println("case " + methodId + ": ___regCB(); break;");
4233 writeMethodCallStructSkeleton(methods, intDecl);
4234 println("default: ");
4235 println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
4236 println("throw exception();");
4244 * generateCplusSkeletonClass() generate skeletons based on the methods list in C++
4246 public void generateCplusSkeletonClass() throws IOException {
4248 // Create a new directory
4249 String path = createDirectories(dir, subdir);
4250 for (String intface : mapIntfacePTH.keySet()) {
4251 // Open a new file to write into
4252 String newSkelClass = intface + "_Skeleton";
4253 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
4254 pw = new PrintWriter(new BufferedWriter(fw));
4255 // Write file headers
4256 println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
4257 println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
4258 println("#include <iostream>");
4259 println("#include \"" + intface + ".hpp\"\n");
4260 // Pass in set of methods and get import classes
4261 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4262 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
4263 List<String> methods = intDecl.getMethods();
4264 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
4265 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
4266 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
4267 printIncludeStatements(allIncludeClasses); println("");
4268 println("using namespace std;\n");
4269 // Find out if there are callback objects
4270 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
4271 boolean callbackExist = !callbackClasses.isEmpty();
4272 // Write class header
4273 println("class " + newSkelClass + " : public " + intface); println("{");
4274 println("private:\n");
4276 writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses);
4277 println("public:\n");
4278 // Write constructor
4279 writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
4280 // Write deconstructor
4281 writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
4283 writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false, intface);
4284 // Write method helper
4285 writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses);
4286 // Write waitRequestInvokeMethod() - main loop
4287 writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
4289 writePermissionInitializationCplus(intface, newSkelClass, intDecl);
4290 writeObjectIdCountInitializationCplus(newSkelClass, callbackExist);
4293 System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
4299 * HELPER: writePropertiesCplusCallbackSkeleton() writes the properties of the callback skeleton class
4301 private void writePropertiesCplusCallbackSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
4303 println(intface + " *mainObj;");
4304 // Keep track of object Ids of all stubs registered to this interface
4305 println("int objectId;");
4306 println("vector<int> ports;\n");
4307 println("string callbackAddress;");
4309 if (callbackExist) {
4310 Iterator it = callbackClasses.iterator();
4311 String callbackType = (String) it.next();
4312 String exchangeType = checkAndGetParamClass(callbackType);
4313 println("// Callback properties");
4314 println("IoTRMICall* rmiCall;");
4315 println("vector<" + exchangeType + "*> vecCallbackObj;");
4316 println("static int objIdCnt;");
4323 * HELPER: writeConstructorCplusCallbackSkeleton() writes the constructor of the skeleton class
4325 private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface, boolean callbackExist, InterfaceDecl intDecl, Collection<String> methods) {
4327 println(newSkelClass + "(" + intface + " *_mainObj, string _callbackAddress, int _objectId) {");
4328 println("mainObj = _mainObj;");
4329 println("callbackAddress = _callbackAddress;");
4330 println("objectId = _objectId;");
4336 * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
4338 private void writeDeconstructorCplusCallbackSkeleton(String newStubClass, boolean callbackExist,
4339 Set<String> callbackClasses) {
4341 println("~" + newStubClass + "() {");
4342 if (callbackExist) {
4343 // We assume that each class only has one callback interface for now
4344 println("if (rmiCall != NULL) {");
4345 println("delete rmiCall;");
4346 println("rmiCall = NULL;");
4348 Iterator it = callbackClasses.iterator();
4349 String callbackType = (String) it.next();
4350 String exchangeType = checkAndGetParamClass(callbackType);
4351 println("for(" + exchangeType + "* cb : vecCallbackObj) {");
4352 println("delete cb;");
4353 println("cb = NULL;");
4362 * HELPER: writeMethodHelperCplusCallbackSkeleton() writes the method helper of callback skeleton class
4364 private void writeMethodHelperCplusCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl,
4365 Set<String> callbackClasses) {
4367 // Use this set to handle two same methodIds
4368 Set<String> uniqueMethodIds = new HashSet<String>();
4369 for (String method : methods) {
4371 List<String> methParams = intDecl.getMethodParams(method);
4372 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4373 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
4374 String methodId = intDecl.getMethodId(method);
4376 String helperMethod = methodId;
4377 if (uniqueMethodIds.contains(methodId))
4378 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4380 uniqueMethodIds.add(methodId);
4381 String retType = intDecl.getMethodType(method);
4382 print(helperMethod + "(");
4383 boolean begin = true;
4384 for (int i = 0; i < methParams.size(); i++) { // Print size variables
4385 String paramType = methPrmTypes.get(i);
4386 String param = methParams.get(i);
4387 String simpleType = getGenericType(paramType);
4388 if (isStructClass(simpleType)) {
4389 if (!begin) // Generate comma for not the beginning variable
4393 int methodNumId = intDecl.getMethodNumId(method);
4394 print("int struct" + methodNumId + "Size" + i);
4397 println(", IoTRMIObject* rmiObj) {");
4398 writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4401 String methodId = intDecl.getMethodId(method);
4403 String helperMethod = methodId;
4404 if (uniqueMethodIds.contains(methodId))
4405 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4407 uniqueMethodIds.add(methodId);
4408 // Check if this is "void"
4409 String retType = intDecl.getMethodType(method);
4410 println(helperMethod + "(IoTRMIObject* rmiObj) {");
4411 // Now, write the helper body of skeleton!
4412 writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4416 // Write method helper for structs
4417 writeMethodHelperStructSetupCplusCallbackSkeleton(methods, intDecl);
4422 * HELPER: writeCplusCallbackWaitRequestInvokeMethod() writes the request invoke method of the skeleton callback class
4424 private void writeCplusCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl,
4425 boolean callbackExist) {
4427 // Use this set to handle two same methodIds
4428 Set<String> uniqueMethodIds = new HashSet<String>();
4429 println("void invokeMethod(IoTRMIObject* rmiObj) {");
4430 // Write variables here if we have callbacks or enums or structs
4431 writeCountVarStructSkeleton(methods, intDecl);
4432 // Write variables here if we have callbacks or enums or structs
4433 println("int methodId = rmiObj->getMethodId();");
4434 // TODO: code the permission check here!
4435 println("switch (methodId) {");
4436 // Print methods and method Ids
4437 for (String method : methods) {
4438 String methodId = intDecl.getMethodId(method);
4439 int methodNumId = intDecl.getMethodNumId(method);
4440 print("case " + methodNumId + ": ___");
4441 String helperMethod = methodId;
4442 if (uniqueMethodIds.contains(methodId))
4443 helperMethod = helperMethod + methodNumId;
4445 uniqueMethodIds.add(methodId);
4446 print(helperMethod + "(");
4447 if (writeInputCountVarStructSkeleton(method, intDecl))
4448 println(", rmiObj); break;");
4450 println("rmiObj); break;");
4452 String method = "___initCallBack()";
4453 // Print case -9999 (callback handler) if callback exists
4454 if (callbackExist) {
4455 int methodId = intDecl.getHelperMethodNumId(method);
4456 println("case " + methodId + ": ___regCB(rmiObj); break;");
4458 writeMethodCallStructCallbackSkeleton(methods, intDecl);
4459 println("default: ");
4460 println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
4461 println("throw exception();");
4468 * generateCplusCallbackSkeletonClass() generate callback skeletons based on the methods list in C++
4470 public void generateCplusCallbackSkeletonClass() throws IOException {
4472 // Create a new directory
4473 String path = createDirectories(dir, subdir);
4474 for (String intface : mapIntfacePTH.keySet()) {
4475 // Open a new file to write into
4476 String newSkelClass = intface + "_CallbackSkeleton";
4477 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
4478 pw = new PrintWriter(new BufferedWriter(fw));
4479 // Write file headers
4480 println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
4481 println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
4482 println("#include <iostream>");
4483 println("#include \"" + intface + ".hpp\"\n");
4484 // Pass in set of methods and get import classes
4485 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4486 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
4487 List<String> methods = intDecl.getMethods();
4488 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
4489 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
4490 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
4491 printIncludeStatements(allIncludeClasses); println("");
4492 // Find out if there are callback objects
4493 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
4494 boolean callbackExist = !callbackClasses.isEmpty();
4495 println("using namespace std;\n");
4496 // Write class header
4497 println("class " + newSkelClass + " : public " + intface); println("{");
4498 println("private:\n");
4500 writePropertiesCplusCallbackSkeleton(intface, callbackExist, callbackClasses);
4501 println("public:\n");
4502 // Write constructor
4503 writeConstructorCplusCallbackSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
4504 // Write deconstructor
4505 writeDeconstructorCplusCallbackSkeleton(newSkelClass, callbackExist, callbackClasses);
4507 writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true, intface);
4508 // Write method helper
4509 writeMethodHelperCplusCallbackSkeleton(methods, intDecl, callbackClasses);
4510 // Write waitRequestInvokeMethod() - main loop
4511 writeCplusCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
4513 writeObjectIdCountInitializationCplus(newSkelClass, callbackExist);
4516 System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".hpp...");
4522 * generateInitializer() generate initializer based on type
4524 public String generateCplusInitializer(String type) {
4526 // Generate dummy returns for now
4527 if (type.equals("short")||
4528 type.equals("int") ||
4529 type.equals("long") ||
4530 type.equals("float")||
4531 type.equals("double")) {
4534 } else if ( type.equals("String") ||
4535 type.equals("string")) {
4538 } else if ( type.equals("char") ||
4539 type.equals("byte")) {
4542 } else if ( type.equals("boolean")) {
4552 * setDirectory() sets a new directory for stub files
4554 public void setDirectory(String _subdir) {
4561 * printUsage() prints the usage of this compiler
4563 public static void printUsage() {
4565 System.out.println();
4566 System.out.println("Sentinel interface and stub compiler version 1.0");
4567 System.out.println("Copyright (c) 2015-2016 University of California, Irvine - Programming Language Group.");
4568 System.out.println("All rights reserved.");
4569 System.out.println("Usage:");
4570 System.out.println("\tjava IoTCompiler -help / --help / -h\n");
4571 System.out.println("\t\tDisplay this help texts\n\n");
4572 System.out.println("\tjava IoTCompiler [<main-policy-file> <req-policy-file>]");
4573 System.out.println("\tjava IoTCompiler [<main-policy-file> <req-policy-file>] [options]\n");
4574 System.out.println("\t\tTake one or more pairs of main-req policy files, and generate Java and/or C++ files\n");
4575 System.out.println("Options:");
4576 System.out.println("\t-java\t<directory>\tGenerate Java stub files");
4577 System.out.println("\t-cplus\t<directory>\tGenerate C++ stub files");
4578 System.out.println();
4583 * parseFile() prepares Lexer and Parser objects, then parses the file
4585 public static ParseNode parseFile(String file) {
4587 ParseNode pn = null;
4589 ComplexSymbolFactory csf = new ComplexSymbolFactory();
4590 ScannerBuffer lexer =
4591 new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(file)),csf));
4592 Parser parse = new Parser(lexer,csf);
4593 pn = (ParseNode) parse.parse().value;
4594 } catch (Exception e) {
4595 e.printStackTrace();
4596 throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file + "\n");
4604 * Basic helper functions
4607 boolean newline=true;
4610 private void print(String str) {
4613 if (str.equals("}"))
4615 for(int i=0; i<tab; i++)
4625 * This function converts Java to C++ type for compilation
4627 private String convertType(String type) {
4629 if (mapPrimitives.containsKey(type))
4630 return mapPrimitives.get(type);
4637 * A collection of methods with print-to-file functionality
4639 private void println(String str) {
4642 if (str.contains("}") && !str.contains("{"))
4644 for(int i=0; i<tab; i++)
4653 private void updatetabbing(String str) {
4655 tablevel+=count(str,'{')-count(str,'}');
4659 private int count(String str, char key) {
4660 char[] array = str.toCharArray();
4662 for(int i=0; i<array.length; i++) {
4663 if (array[i] == key)
4670 private void createDirectory(String dirName) {
4672 File file = new File(dirName);
4673 if (!file.exists()) {
4675 System.out.println("IoTCompiler: Directory " + dirName + " has been created!");
4677 System.out.println("IoTCompiler: Failed to create directory " + dirName + "!");
4680 System.out.println("IoTCompiler: Directory " + dirName + " exists...");
4685 // Create a directory and possibly a sub directory
4686 private String createDirectories(String dir, String subdir) {
4689 createDirectory(path);
4690 if (subdir != null) {
4691 path = path + "/" + subdir;
4692 createDirectory(path);
4698 // Inserting array members into a Map object
4699 // that maps arrKey to arrVal objects
4700 private void arraysToMap(Map map, Object[] arrKey, Object[] arrVal) {
4702 for(int i = 0; i < arrKey.length; i++) {
4704 map.put(arrKey[i], arrVal[i]);
4709 // Check and find object Id for new interface in mapNewIntfaceObjId (callbacks)
4710 // Throw an error if the new interface is not found!
4711 // Basically the compiler needs to parse the policy (and requires) files for callback class first
4712 private int getNewIntfaceObjectId(String newIntface) {
4714 // if (!mapNewIntfaceObjId.containsKey(newIntface)) {
4715 // throw new Error("IoTCompiler: Need to parse policy and requires files for callback class first! " +
4716 // "Please place the two files for callback class in front...\n");
4719 int retObjId = mapNewIntfaceObjId.get(newIntface);
4725 // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, USERDEFINED, ENUM, or STRUCT
4726 private ParamCategory getParamCategory(String paramType) {
4728 if (mapPrimitives.containsKey(paramType)) {
4729 return ParamCategory.PRIMITIVES;
4730 // We can either use mapNonPrimitivesJava or mapNonPrimitivesCplus here
4731 } else if (mapNonPrimitivesJava.containsKey(getSimpleType(paramType))) {
4732 return ParamCategory.NONPRIMITIVES;
4733 } else if (isEnumClass(paramType)) {
4734 return ParamCategory.ENUM;
4735 } else if (isStructClass(paramType)) {
4736 return ParamCategory.STRUCT;
4738 return ParamCategory.USERDEFINED;
4742 // Return full class name for non-primitives to generate Java import statements
4743 // e.g. java.util.Set for Set
4744 private String getNonPrimitiveJavaClass(String paramNonPrimitives) {
4746 return mapNonPrimitivesJava.get(paramNonPrimitives);
4750 // Return full class name for non-primitives to generate Cplus include statements
4751 // e.g. #include <set> for Set
4752 private String getNonPrimitiveCplusClass(String paramNonPrimitives) {
4754 return mapNonPrimitivesCplus.get(paramNonPrimitives);
4758 // Get simple types, e.g. HashSet for HashSet<...>
4759 // Basically strip off the "<...>"
4760 private String getSimpleType(String paramType) {
4762 // Check if this is generics
4763 if(paramType.contains("<")) {
4764 String[] type = paramType.split("<");
4771 // Generate a set of standard classes for import statements
4772 private List<String> getStandardJavaIntfaceImportClasses() {
4774 List<String> importClasses = new ArrayList<String>();
4775 // Add the standard list first
4776 importClasses.add("java.util.List");
4777 importClasses.add("java.util.ArrayList");
4779 return importClasses;
4783 // Generate a set of standard classes for import statements
4784 private List<String> getStandardJavaImportClasses() {
4786 List<String> importClasses = new ArrayList<String>();
4787 // Add the standard list first
4788 importClasses.add("java.io.IOException");
4789 importClasses.add("java.util.List");
4790 importClasses.add("java.util.ArrayList");
4791 importClasses.add("java.util.Arrays");
4792 importClasses.add("iotrmi.Java.IoTRMICall");
4793 importClasses.add("iotrmi.Java.IoTRMIObject");
4795 return importClasses;
4799 // Generate a set of standard classes for import statements
4800 private List<String> getStandardCplusIncludeClasses() {
4802 List<String> importClasses = new ArrayList<String>();
4803 // Add the standard list first
4804 importClasses.add("<vector>");
4805 importClasses.add("<set>");
4806 importClasses.add("\"IoTRMICall.hpp\"");
4807 importClasses.add("\"IoTRMIObject.hpp\"");
4809 return importClasses;
4813 // Combine all classes for import statements
4814 private List<String> getAllLibClasses(Collection<String> stdLibClasses, Collection<String> libClasses) {
4816 List<String> allLibClasses = new ArrayList<String>(stdLibClasses);
4817 // Iterate over the list of import classes
4818 for (String str : libClasses) {
4819 if (!allLibClasses.contains(str)) {
4820 allLibClasses.add(str);
4823 return allLibClasses;
4828 // Generate a set of classes for import statements
4829 private Set<String> getImportClasses(Collection<String> methods, InterfaceDecl intDecl) {
4831 Set<String> importClasses = new HashSet<String>();
4832 for (String method : methods) {
4833 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4834 for (String paramType : methPrmTypes) {
4836 String simpleType = getSimpleType(paramType);
4837 if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
4838 importClasses.add(getNonPrimitiveJavaClass(simpleType));
4842 return importClasses;
4846 // Handle and return the correct enum declaration
4847 // In Java, if we declare enum in Camera interface, then it becomes "Camera.<enum>"
4848 private String getEnumParamDecl(String type, InterfaceDecl intDecl) {
4850 // Strips off array "[]" for return type
4851 String pureType = getSimpleArrayType(type);
4852 // Take the inner type of generic
4853 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4854 pureType = getTypeOfGeneric(type)[0];
4855 if (isEnumClass(pureType)) {
4856 String enumType = intDecl.getInterface() + "." + type;
4863 // Handle and return the correct type
4864 private String getEnumParam(String type, String param, int i) {
4866 // Strips off array "[]" for return type
4867 String pureType = getSimpleArrayType(type);
4868 // Take the inner type of generic
4869 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4870 pureType = getTypeOfGeneric(type)[0];
4871 if (isEnumClass(pureType)) {
4872 String enumParam = "paramEnum" + i;
4879 // Handle and return the correct enum declaration translate into int[]
4880 private String getEnumType(String type) {
4882 // Strips off array "[]" for return type
4883 String pureType = getSimpleArrayType(type);
4884 // Take the inner type of generic
4885 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4886 pureType = getGenericType(type);
4887 if (isEnumClass(pureType)) {
4888 String enumType = "int[]";
4894 // Handle and return the correct enum declaration translate into int* for C
4895 private String getEnumCplusClsType(String type) {
4897 // Strips off array "[]" for return type
4898 String pureType = getSimpleArrayType(type);
4899 // Take the inner type of generic
4900 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4901 pureType = getGenericType(type);
4902 if (isEnumClass(pureType)) {
4903 String enumType = "int*";
4910 // Handle and return the correct struct declaration
4911 private String getStructType(String type) {
4913 // Strips off array "[]" for return type
4914 String pureType = getSimpleArrayType(type);
4915 // Take the inner type of generic
4916 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4917 pureType = getGenericType(type);
4918 if (isStructClass(pureType)) {
4919 String structType = "int";
4926 // Check if this an enum declaration
4927 private boolean isEnumClass(String type) {
4929 // Just iterate over the set of interfaces
4930 for (String intface : mapIntfacePTH.keySet()) {
4931 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4932 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
4933 Set<String> setEnumDecl = enumDecl.getEnumDeclarations();
4934 if (setEnumDecl.contains(type))
4941 // Check if this an struct declaration
4942 private boolean isStructClass(String type) {
4944 // Just iterate over the set of interfaces
4945 for (String intface : mapIntfacePTH.keySet()) {
4946 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4947 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4948 List<String> listStructDecl = structDecl.getStructTypes();
4949 if (listStructDecl.contains(type))
4956 // Return a struct declaration
4957 private StructDecl getStructDecl(String type) {
4959 // Just iterate over the set of interfaces
4960 for (String intface : mapIntfacePTH.keySet()) {
4961 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4962 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4963 List<String> listStructDecl = structDecl.getStructTypes();
4964 if (listStructDecl.contains(type))
4971 // Return number of members (-1 if not found)
4972 private int getNumOfMembers(String type) {
4974 // Just iterate over the set of interfaces
4975 for (String intface : mapIntfacePTH.keySet()) {
4976 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4977 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4978 List<String> listStructDecl = structDecl.getStructTypes();
4979 if (listStructDecl.contains(type))
4980 return structDecl.getNumOfMembers(type);
4986 // Generate a set of classes for include statements
4987 private Set<String> getIncludeClasses(Collection<String> methods, InterfaceDecl intDecl, String intface, boolean needExchange) {
4989 Set<String> includeClasses = new HashSet<String>();
4990 for (String method : methods) {
4992 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4993 List<String> methParams = intDecl.getMethodParams(method);
4994 for (int i = 0; i < methPrmTypes.size(); i++) {
4996 String simpleType = getSimpleType(methPrmTypes.get(i));
4997 String param = methParams.get(i);
4998 if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
4999 includeClasses.add("<" + getNonPrimitiveCplusClass(simpleType) + ">");
5000 } else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) {
5001 // For original interface, we need it exchanged... not for stub interfaces
5003 includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
5004 includeClasses.add("\"" + exchangeParamType(simpleType) + "_CallbackStub.hpp\"");
5006 includeClasses.add("\"" + simpleType + ".hpp\"");
5007 includeClasses.add("\"" + simpleType + "_CallbackSkeleton.hpp\"");
5009 } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.ENUM) {
5010 includeClasses.add("\"" + simpleType + ".hpp\"");
5011 } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.STRUCT) {
5012 includeClasses.add("\"" + simpleType + ".hpp\"");
5013 } else if (param.contains("[]")) {
5014 // Check if this is array for C++; translate into vector
5015 includeClasses.add("<vector>");
5019 return includeClasses;
5023 // Generate a set of callback classes
5024 private Set<String> getCallbackClasses(Collection<String> methods, InterfaceDecl intDecl) {
5026 Set<String> callbackClasses = new HashSet<String>();
5027 for (String method : methods) {
5029 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
5030 List<String> methParams = intDecl.getMethodParams(method);
5031 for (int i = 0; i < methPrmTypes.size(); i++) {
5033 String type = methPrmTypes.get(i);
5034 if (getParamCategory(type) == ParamCategory.USERDEFINED) {
5035 callbackClasses.add(type);
5036 } else if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) {
5037 // Can be a List<...> of callback objects ...
5038 String genericType = getTypeOfGeneric(type)[0];
5039 if (getParamCategory(type) == ParamCategory.USERDEFINED) {
5040 callbackClasses.add(type);
5045 return callbackClasses;
5049 // Print import statements into file
5050 private void printImportStatements(Collection<String> importClasses) {
5052 for(String cls : importClasses) {
5053 println("import " + cls + ";");
5058 // Print include statements into file
5059 private void printIncludeStatements(Collection<String> includeClasses) {
5061 for(String cls : includeClasses) {
5062 println("#include " + cls);
5067 // Get the C++ version of a non-primitive type
5068 // e.g. set for Set and map for Map
5069 // Input nonPrimitiveType has to be generics in format
5070 private String[] getTypeOfGeneric(String nonPrimitiveType) {
5072 // Handle <, >, and , for 2-type generic/template
5073 String[] substr = nonPrimitiveType.split("<")[1].split(">")[0].split(",");
5078 // Gets generic type inside "<" and ">"
5079 private String getGenericType(String type) {
5081 // Handle <, >, and , for 2-type generic/template
5082 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) {
5083 String[] substr = type.split("<")[1].split(">")[0].split(",");
5090 // This helper function strips off array declaration, e.g. int[] becomes int
5091 private String getSimpleArrayType(String type) {
5093 // Handle [ for array declaration
5094 String substr = type;
5095 if (type.contains("[]")) {
5096 substr = type.split("\\[\\]")[0];
5102 // This helper function strips off array declaration, e.g. D[] becomes D
5103 private String getSimpleIdentifier(String ident) {
5105 // Handle [ for array declaration
5106 String substr = ident;
5107 if (ident.contains("[]")) {
5108 substr = ident.split("\\[\\]")[0];
5114 // Checks and gets type in C++
5115 private String checkAndGetCplusType(String paramType) {
5117 if (getParamCategory(paramType) == ParamCategory.PRIMITIVES) {
5118 return convertType(paramType);
5119 } else if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES) {
5121 // Check for generic/template format
5122 if (paramType.contains("<") && paramType.contains(">")) {
5124 String genericClass = getSimpleType(paramType);
5125 String genericType = getGenericType(paramType);
5126 String cplusTemplate = null;
5127 cplusTemplate = getNonPrimitiveCplusClass(genericClass);
5128 if(getParamCategory(getGenericType(paramType)) == ParamCategory.USERDEFINED) {
5129 cplusTemplate = cplusTemplate + "<" + genericType + "*>";
5131 cplusTemplate = cplusTemplate + "<" + convertType(genericType) + ">";
5133 return cplusTemplate;
5135 return getNonPrimitiveCplusClass(paramType);
5136 } else if(paramType.contains("[]")) { // Array type (used for return type only)
5137 String cArray = "vector<" + convertType(getSimpleArrayType(paramType)) + ">";
5139 } else if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
5140 return paramType + "*";
5142 // Just return it as is if it's not non-primitives
5147 // Detect array declaration, e.g. int A[],
5148 // then generate "int A[]" in C++ as "vector<int> A"
5149 private String checkAndGetCplusArray(String paramType, String param) {
5151 String paramComplete = null;
5152 // Check for array declaration
5153 if (param.contains("[]")) {
5154 paramComplete = "vector<" + paramType + "> " + param.replace("[]","");
5156 // Just return it as is if it's not an array
5157 paramComplete = paramType + " " + param;
5159 return paramComplete;
5163 // Detect array declaration, e.g. int A[],
5164 // then generate "int A[]" in C++ as "vector<int> A"
5165 // This method just returns the type
5166 private String checkAndGetCplusArrayType(String paramType) {
5168 String paramTypeRet = null;
5169 // Check for array declaration
5170 if (paramType.contains("[]")) {
5171 String type = paramType.split("\\[\\]")[0];
5172 paramTypeRet = checkAndGetCplusType(type) + "[]";
5173 } else if (paramType.contains("vector")) {
5174 // Just return it as is if it's not an array
5175 String type = paramType.split("<")[1].split(">")[0];
5176 paramTypeRet = checkAndGetCplusType(type) + "[]";
5178 paramTypeRet = paramType;
5180 return paramTypeRet;
5184 // Detect array declaration, e.g. int A[],
5185 // then generate "int A[]" in C++ as "vector<int> A"
5186 // This method just returns the type
5187 private String checkAndGetCplusArrayType(String paramType, String param) {
5189 String paramTypeRet = null;
5190 // Check for array declaration
5191 if (param.contains("[]")) {
5192 paramTypeRet = checkAndGetCplusType(paramType) + "[]";
5193 } else if (paramType.contains("vector")) {
5194 // Just return it as is if it's not an array
5195 String type = paramType.split("<")[1].split(">")[0];
5196 paramTypeRet = checkAndGetCplusType(type) + "[]";
5198 paramTypeRet = paramType;
5200 return paramTypeRet;
5204 // Return the class type for class resolution (for return value)
5205 // - Check and return C++ array class, e.g. int A[] into int*
5206 // - Check and return C++ vector class, e.g. List<Integer> A into vector<int>
5207 private String checkAndGetCplusRetClsType(String paramType) {
5209 String paramTypeRet = null;
5210 // Check for array declaration
5211 if (paramType.contains("[]")) {
5212 String type = paramType.split("\\[\\]")[0];
5213 paramTypeRet = getSimpleArrayType(type) + "*";
5214 } else if (paramType.contains("<") && paramType.contains(">")) {
5215 // Just return it as is if it's not an array
5216 String type = paramType.split("<")[1].split(">")[0];
5217 paramTypeRet = "vector<" + getGenericType(type) + ">";
5219 paramTypeRet = paramType;
5221 return paramTypeRet;
5225 // Return the class type for class resolution (for method arguments)
5226 // - Check and return C++ array class, e.g. int A[] into int*
5227 // - Check and return C++ vector class, e.g. List<Integer> A into vector<int>
5228 private String checkAndGetCplusArgClsType(String paramType, String param) {
5230 String paramTypeRet = getEnumCplusClsType(paramType);
5231 if (!paramTypeRet.equals(paramType))
5232 // Just return if it is an enum type
5233 // Type will still be the same if it's not an enum type
5234 return paramTypeRet;
5236 // Check for array declaration
5237 if (param.contains("[]")) {
5238 paramTypeRet = getSimpleArrayType(paramType) + "*";
5239 } else if (paramType.contains("<") && paramType.contains(">")) {
5240 // Just return it as is if it's not an array
5241 String type = paramType.split("<")[1].split(">")[0];
5242 paramTypeRet = "vector<" + getGenericType(type) + ">";
5244 paramTypeRet = paramType;
5246 return paramTypeRet;
5250 // Detect array declaration, e.g. int A[],
5251 // then generate type "int[]"
5252 private String checkAndGetArray(String paramType, String param) {
5254 String paramTypeRet = null;
5255 // Check for array declaration
5256 if (param.contains("[]")) {
5257 paramTypeRet = paramType + "[]";
5259 // Just return it as is if it's not an array
5260 paramTypeRet = paramType;
5262 return paramTypeRet;
5266 // Is array or list?
5267 private boolean isArrayOrList(String paramType, String param) {
5269 // Check for array declaration
5272 else if (isList(paramType))
5280 // For return type we use retType as input parameter
5281 private boolean isArray(String param) {
5283 // Check for array declaration
5284 if (param.contains("[]"))
5292 private boolean isList(String paramType) {
5294 // Check for array declaration
5295 if (paramType.contains("List"))
5302 // Get the right type for a callback object
5303 private String checkAndGetParamClass(String paramType) {
5305 // Check if this is generics
5306 if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
5307 return exchangeParamType(paramType);
5308 } else if (isList(paramType) &&
5309 (getParamCategory(getGenericType(paramType)) == ParamCategory.USERDEFINED)) {
5310 return "List<" + exchangeParamType(getGenericType(paramType)) + ">";
5316 // Returns the other interface for type-checking purposes for USERDEFINED
5317 // classes based on the information provided in multiple policy files
5318 // e.g. return CameraWithXXX instead of Camera
5319 private String exchangeParamType(String intface) {
5321 // Param type that's passed is the interface name we need to look for
5322 // in the map of interfaces, based on available policy files.
5323 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
5324 if (decHandler != null) {
5325 // We've found the required interface policy files
5326 RequiresDecl reqDecl = (RequiresDecl) decHandler.getRequiresDecl(intface);
5327 Set<String> setExchInt = reqDecl.getInterfaces();
5328 if (setExchInt.size() == 1) {
5329 Iterator iter = setExchInt.iterator();
5330 return (String) iter.next();
5332 throw new Error("IoTCompiler: Ambiguous stub interfaces: " + setExchInt.toString() +
5333 ". Only one new interface can be declared if the object " + intface +
5334 " needs to be passed in as an input parameter!\n");
5337 // NULL value - this means policy files missing
5338 throw new Error("IoTCompiler: Parameter type lookup failed for " + intface +
5339 "... Please provide the necessary policy files for user-defined types." +
5340 " If this is an array please type the brackets after the variable name," +
5341 " e.g. \"String str[]\", not \"String[] str\"." +
5342 " If this is a Collections (Java) / STL (C++) type, this compiler only" +
5343 " supports List/ArrayList (Java) or list (C++).\n");
5348 public static void main(String[] args) throws Exception {
5350 // If there is no argument or just "--help" or "-h", then invoke printUsage()
5351 if ((args[0].equals("-help") ||
5352 args[0].equals("--help")||
5353 args[0].equals("-h")) ||
5354 (args.length == 0)) {
5356 IoTCompiler.printUsage();
5358 } else if (args.length > 1) {
5360 IoTCompiler comp = new IoTCompiler();
5363 // Parse main policy file
5364 ParseNode pnPol = IoTCompiler.parseFile(args[i]);
5365 // Parse "requires" policy file
5366 ParseNode pnReq = IoTCompiler.parseFile(args[i+1]);
5367 // Get interface name
5368 String intface = ParseTreeHandler.getOrigIntface(pnPol);
5369 comp.setDataStructures(intface, pnPol, pnReq);
5370 comp.getMethodsForIntface(intface);
5372 // 1) Check if this is the last option before "-java" or "-cplus"
5373 // 2) Check if this is really the last option (no "-java" or "-cplus")
5374 } while(!args[i].equals("-java") &&
5375 !args[i].equals("-cplus") &&
5378 // Generate everything if we don't see "-java" or "-cplus"
5379 if (i == args.length) {
5380 comp.generateEnumJava();
5381 comp.generateStructJava();
5382 comp.generateJavaLocalInterfaces();
5383 comp.generateJavaInterfaces();
5384 comp.generateJavaStubClasses();
5385 comp.generateJavaCallbackStubClasses();
5386 comp.generateJavaSkeletonClass();
5387 comp.generateJavaCallbackSkeletonClass();
5388 comp.generateEnumCplus();
5389 comp.generateStructCplus();
5390 comp.generateCplusLocalInterfaces();
5391 comp.generateCPlusInterfaces();
5392 comp.generateCPlusStubClasses();
5393 comp.generateCPlusCallbackStubClasses();
5394 comp.generateCplusSkeletonClass();
5395 comp.generateCplusCallbackSkeletonClass();
5397 // Check other options
5398 while(i < args.length) {
5400 if (!args[i].equals("-java") &&
5401 !args[i].equals("-cplus")) {
5402 throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i] + "\n");
5404 if (i + 1 < args.length) {
5405 comp.setDirectory(args[i+1]);
5407 throw new Error("IoTCompiler: ERROR - please provide <directory> after option: " + args[i] + "\n");
5409 if (args[i].equals("-java")) {
5410 comp.generateEnumJava();
5411 comp.generateStructJava();
5412 comp.generateJavaLocalInterfaces();
5413 comp.generateJavaInterfaces();
5414 comp.generateJavaStubClasses();
5415 comp.generateJavaCallbackStubClasses();
5416 comp.generateJavaSkeletonClass();
5417 comp.generateJavaCallbackSkeletonClass();
5419 comp.generateEnumCplus();
5420 comp.generateStructCplus();
5421 comp.generateCplusLocalInterfaces();
5422 comp.generateCPlusInterfaces();
5423 comp.generateCPlusStubClasses();
5424 comp.generateCPlusCallbackStubClasses();
5425 comp.generateCplusSkeletonClass();
5426 comp.generateCplusCallbackSkeletonClass();
5433 // Need to at least have exactly 2 parameters, i.e. main policy file and requires file
5434 IoTCompiler.printUsage();
5435 throw new Error("IoTCompiler: At least two arguments (main and requires policy files) have to be provided!\n");