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 // Data structure to store our types (primitives and non-primitives) for compilation
52 private Map<String,String> mapPrimitives;
53 private Map<String,String> mapNonPrimitivesJava;
54 private Map<String,String> mapNonPrimitivesCplus;
55 // Other data structures
56 private Map<String,Integer> mapIntfaceObjId; // Maps interface name to object Id
57 private Map<String,Integer> mapNewIntfaceObjId; // Maps new interface name to its object Id (keep track of stubs)
58 private PrintWriter pw;
60 private String subdir;
66 private final static String OUTPUT_DIRECTORY = "output_files";
68 private enum ParamCategory {
70 PRIMITIVES, // All the primitive types, e.g. byte, short, int, long, etc.
71 NONPRIMITIVES, // Non-primitive types, e.g. Set, Map, List, etc.
73 STRUCT, // Struct type
74 USERDEFINED // Assumed as driver classes
81 public IoTCompiler() {
83 mapIntfacePTH = new HashMap<String,ParseTreeHandler>();
84 mapIntDeclHand = new HashMap<String,DeclarationHandler>();
85 mapInt2NewInts = new HashMap<String,Map<String,Set<String>>>();
86 mapIntfaceObjId = new HashMap<String,Integer>();
87 mapNewIntfaceObjId = new HashMap<String,Integer>();
88 mapPrimitives = new HashMap<String,String>();
89 arraysToMap(mapPrimitives, IoTRMITypes.primitivesJava, IoTRMITypes.primitivesCplus);
90 mapNonPrimitivesJava = new HashMap<String,String>();
91 arraysToMap(mapNonPrimitivesJava, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitiveJavaLibs);
92 mapNonPrimitivesCplus = new HashMap<String,String>();
93 arraysToMap(mapNonPrimitivesCplus, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus);
95 dir = OUTPUT_DIRECTORY;
101 * setDataStructures() sets parse tree and other data structures based on policy files.
103 * It also generates parse tree (ParseTreeHandler) and
104 * copies useful information from parse tree into
105 * InterfaceDecl, CapabilityDecl, and RequiresDecl
107 * Additionally, the data structure handles are
108 * returned from tree-parsing for further process.
110 public void setDataStructures(String origInt, ParseNode pnPol, ParseNode pnReq) {
112 ParseTreeHandler ptHandler = new ParseTreeHandler(origInt, pnPol, pnReq);
113 DeclarationHandler decHandler = new DeclarationHandler();
114 // Process ParseNode and generate Declaration objects
116 ptHandler.processInterfaceDecl();
117 InterfaceDecl intDecl = ptHandler.getInterfaceDecl();
118 decHandler.addInterfaceDecl(origInt, intDecl);
120 ptHandler.processCapabilityDecl();
121 CapabilityDecl capDecl = ptHandler.getCapabilityDecl();
122 decHandler.addCapabilityDecl(origInt, capDecl);
124 ptHandler.processRequiresDecl();
125 RequiresDecl reqDecl = ptHandler.getRequiresDecl();
126 decHandler.addRequiresDecl(origInt, reqDecl);
128 ptHandler.processEnumDecl();
129 EnumDecl enumDecl = ptHandler.getEnumDecl();
130 decHandler.addEnumDecl(origInt, enumDecl);
132 ptHandler.processStructDecl();
133 StructDecl structDecl = ptHandler.getStructDecl();
134 decHandler.addStructDecl(origInt, structDecl);
136 mapIntfacePTH.put(origInt, ptHandler);
137 mapIntDeclHand.put(origInt, decHandler);
138 // Set object Id counter to 0 for each interface
139 mapIntfaceObjId.put(origInt, new Integer(0));
144 * getMethodsForIntface() reads for methods in the data structure
146 * It is going to give list of methods for a certain interface
147 * based on the declaration of capabilities.
149 public void getMethodsForIntface(String origInt) {
151 ParseTreeHandler ptHandler = mapIntfacePTH.get(origInt);
152 Map<String,Set<String>> mapNewIntMethods = new HashMap<String,Set<String>>();
153 // Get set of new interfaces, e.g. CameraWithCaptureAndData
154 // Generate this new interface with all the methods it needs
155 // from different capabilities it declares
156 DeclarationHandler decHandler = mapIntDeclHand.get(origInt);
157 RequiresDecl reqDecl = (RequiresDecl) decHandler.getRequiresDecl(origInt);
158 Set<String> setIntfaces = reqDecl.getInterfaces();
159 for (String strInt : setIntfaces) {
161 // Initialize a set of methods
162 Set<String> setMethods = new HashSet<String>();
163 // Get list of capabilities, e.g. ImageCapture, VideoRecording, etc.
164 List<String> listCapab = reqDecl.getCapabList(strInt);
165 for (String strCap : listCapab) {
167 // Get list of methods for each capability
168 CapabilityDecl capDecl = (CapabilityDecl) decHandler.getCapabilityDecl(origInt);
169 List<String> listCapabMeth = capDecl.getMethods(strCap);
170 for (String strMeth : listCapabMeth) {
172 // Add methods into setMethods
173 // This is to also handle redundancies (say two capabilities
174 // share the same methods)
175 setMethods.add(strMeth);
178 // Add interface and methods information into map
179 mapNewIntMethods.put(strInt, setMethods);
181 // Map the map of interface-methods to the original interface
182 mapInt2NewInts.put(origInt, mapNewIntMethods);
187 * HELPER: writeMethodJavaLocalInterface() writes the method of the local interface
189 private void writeMethodJavaLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
191 for (String method : methods) {
193 List<String> methParams = intDecl.getMethodParams(method);
194 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
195 print("public " + intDecl.getMethodType(method) + " " +
196 intDecl.getMethodId(method) + "(");
197 for (int i = 0; i < methParams.size(); i++) {
198 // Check for params with driver class types and exchange it
199 // with its remote interface
200 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
201 print(paramType + " " + methParams.get(i));
202 // Check if this is the last element (don't print a comma)
203 if (i != methParams.size() - 1) {
213 * HELPER: writeMethodJavaInterface() writes the method of the interface
215 private void writeMethodJavaInterface(Collection<String> methods, InterfaceDecl intDecl) {
217 for (String method : methods) {
219 List<String> methParams = intDecl.getMethodParams(method);
220 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
221 print("public " + intDecl.getMethodType(method) + " " +
222 intDecl.getMethodId(method) + "(");
223 for (int i = 0; i < methParams.size(); i++) {
224 // Check for params with driver class types and exchange it
225 // with its remote interface
226 String paramType = methPrmTypes.get(i);
227 print(paramType + " " + methParams.get(i));
228 // Check if this is the last element (don't print a comma)
229 if (i != methParams.size() - 1) {
239 * HELPER: generateEnumJava() writes the enumeration declaration
241 private void generateEnumJava() throws IOException {
243 // Create a new directory
244 createDirectory(dir);
245 for (String intface : mapIntfacePTH.keySet()) {
246 // Get the right EnumDecl
247 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
248 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
249 Set<String> enumTypes = enumDecl.getEnumDeclarations();
250 // Iterate over enum declarations
251 for (String enType : enumTypes) {
252 // Open a new file to write into
253 FileWriter fw = new FileWriter(dir + "/" + enType + ".java");
254 pw = new PrintWriter(new BufferedWriter(fw));
255 println("public enum " + enType + " {");
256 List<String> enumMembers = enumDecl.getMembers(enType);
257 for (int i = 0; i < enumMembers.size(); i++) {
259 String member = enumMembers.get(i);
261 // Check if this is the last element (don't print a comma)
262 if (i != enumMembers.size() - 1)
269 System.out.println("IoTCompiler: Generated enum class " + enType + ".java...");
276 * HELPER: generateStructJava() writes the struct declaration
278 private void generateStructJava() throws IOException {
280 // Create a new directory
281 createDirectory(dir);
282 for (String intface : mapIntfacePTH.keySet()) {
283 // Get the right StructDecl
284 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
285 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
286 List<String> structTypes = structDecl.getStructTypes();
287 // Iterate over enum declarations
288 for (String stType : structTypes) {
289 // Open a new file to write into
290 FileWriter fw = new FileWriter(dir + "/" + stType + ".java");
291 pw = new PrintWriter(new BufferedWriter(fw));
292 println("public class " + stType + " {");
293 List<String> structMemberTypes = structDecl.getMemberTypes(stType);
294 List<String> structMembers = structDecl.getMembers(stType);
295 for (int i = 0; i < structMembers.size(); i++) {
297 String memberType = structMemberTypes.get(i);
298 String member = structMembers.get(i);
299 println("public static " + memberType + " " + member + ";");
303 System.out.println("IoTCompiler: Generated struct class " + stType + ".java...");
310 * generateJavaLocalInterface() writes the local interface and provides type-checking.
312 * It needs to rewrite and exchange USERDEFINED types in input parameters of stub
313 * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording.
314 * The local interface has to be the input parameter for the stub and the stub
315 * interface has to be the input parameter for the local class.
317 public void generateJavaLocalInterfaces() throws IOException {
319 // Create a new directory
320 createDirectory(dir);
321 for (String intface : mapIntfacePTH.keySet()) {
322 // Open a new file to write into
323 FileWriter fw = new FileWriter(dir + "/" + intface + ".java");
324 pw = new PrintWriter(new BufferedWriter(fw));
325 // Pass in set of methods and get import classes
326 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
327 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
328 List<String> methods = intDecl.getMethods();
329 Set<String> importClasses = getImportClasses(methods, intDecl);
330 printImportStatements(importClasses);
331 // Write interface header
333 println("public interface " + intface + " {");
335 writeMethodJavaLocalInterface(methods, intDecl);
338 System.out.println("IoTCompiler: Generated local interface " + intface + ".java...");
344 * generateJavaInterfaces() generate stub interfaces based on the methods list in Java
346 public void generateJavaInterfaces() throws IOException {
348 // Create a new directory
349 String path = createDirectories(dir, subdir);
350 for (String intface : mapIntfacePTH.keySet()) {
352 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
353 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
355 // Open a new file to write into
356 String newIntface = intMeth.getKey();
357 FileWriter fw = new FileWriter(path + "/" + newIntface + ".java");
358 pw = new PrintWriter(new BufferedWriter(fw));
359 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
360 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
361 // Pass in set of methods and get import classes
362 Set<String> importClasses = getImportClasses(intMeth.getValue(), intDecl);
363 printImportStatements(importClasses);
364 // Write interface header
366 println("public interface " + newIntface + " {\n");
368 writeMethodJavaInterface(intMeth.getValue(), intDecl);
371 System.out.println("IoTCompiler: Generated interface " + newIntface + ".java...");
378 * HELPER: writePropertiesJavaPermission() writes the permission in properties
380 private void writePropertiesJavaPermission(String intface, InterfaceDecl intDecl) {
382 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
383 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
384 String newIntface = intMeth.getKey();
385 int newObjectId = mapNewIntfaceObjId.get(newIntface);
386 println("private final static int object" + newObjectId + "Id = " +
387 newObjectId + ";\t//" + newIntface);
388 Set<String> methodIds = intMeth.getValue();
389 print("private static Integer[] object" + newObjectId + "Permission = { ");
391 for (String methodId : methodIds) {
392 int methodNumId = intDecl.getMethodNumId(methodId);
393 print(Integer.toString(methodNumId));
394 // Check if this is the last element (don't print a comma)
395 if (i != methodIds.size() - 1) {
401 println("private List<Integer> set" + newObjectId + "Allowed;");
407 * HELPER: writePropertiesJavaStub() writes the properties of the stub class
409 private void writePropertiesJavaStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
411 println("private IoTRMICall rmiCall;");
412 println("private String address;");
413 println("private int[] ports;\n");
415 Integer objId = mapIntfaceObjId.get(intface);
416 println("private final static int objectId = " + objId + ";");
417 mapNewIntfaceObjId.put(newIntface, objId);
418 mapIntfaceObjId.put(intface, objId++);
420 // We assume that each class only has one callback interface for now
421 Iterator it = callbackClasses.iterator();
422 String callbackType = (String) it.next();
423 println("// Callback properties");
424 println("private IoTRMIObject rmiObj;");
425 println("List<" + callbackType + "> listCallbackObj;");
426 println("private static int objIdCnt = 0;");
427 // Generate permission stuff for callback stubs
428 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
429 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
430 writePropertiesJavaPermission(callbackType, intDecl);
437 * HELPER: writeConstructorJavaPermission() writes the permission in constructor
439 private void writeConstructorJavaPermission(String intface) {
441 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
442 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
443 String newIntface = intMeth.getKey();
444 int newObjectId = mapNewIntfaceObjId.get(newIntface);
445 println("set" + newObjectId + "Allowed = Arrays.asList(object" + newObjectId +"Permission);");
451 * HELPER: writeConstructorJavaStub() writes the constructor of the stub class
453 private void writeConstructorJavaStub(String intface, String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
455 println("public " + newStubClass + "(int _port, String _address, int _rev, int[] _ports) throws Exception {");
456 println("address = _address;");
457 println("ports = _ports;");
458 println("rmiCall = new IoTRMICall(_port, _address, _rev);");
460 Iterator it = callbackClasses.iterator();
461 String callbackType = (String) it.next();
462 writeConstructorJavaPermission(intface);
463 println("listCallbackObj = new ArrayList<" + callbackType + ">();");
464 println("___initCallBack();");
471 * HELPER: writeJavaMethodCallbackPermission() writes permission checks in stub for callbacks
473 private void writeJavaMethodCallbackPermission(String intface) {
475 println("int methodId = IoTRMIObject.getMethodId(method);");
476 // Get all the different stubs
477 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
478 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
479 String newIntface = intMeth.getKey();
480 int newObjectId = mapNewIntfaceObjId.get(newIntface);
481 println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
482 println("throw new Error(\"Callback object for " + intface + " is not allowed to access method: \" + methodId);");
489 * HELPER: writeInitCallbackJavaStub() writes callback initialization in stub
491 private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl) {
493 println("public void ___initCallBack() {");
494 // Generate main thread for callbacks
495 println("Thread thread = new Thread() {");
496 println("public void run() {");
498 println("rmiObj = new IoTRMIObject(ports[0]);");
499 println("while (true) {");
500 println("byte[] method = rmiObj.getMethodBytes();");
501 writeJavaMethodCallbackPermission(intface);
502 println("int objId = IoTRMIObject.getObjectId(method);");
503 println(intface + "_CallbackSkeleton skel = (" + intface + "_CallbackSkeleton) listCallbackObj.get(objId);");
504 println("if (skel != null) {");
505 println("skel.invokeMethod(rmiObj);");
507 println("throw new Error(\"" + intface + ": Object with Id \" + objId + \" not found!\");");
510 println("} catch (Exception ex) {");
511 println("ex.printStackTrace();");
512 println("throw new Error(\"Error instantiating class " + intface + "_CallbackSkeleton!\");");
516 println("thread.start();\n");
517 // Generate info sending part
518 String method = "___initCallBack()";
519 println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";");
520 println("Class<?> retType = void.class;");
521 println("Class<?>[] paramCls = new Class<?>[] { int.class, String.class, int.class };");
522 println("Object[] paramObj = new Object[] { ports[0], address, 0 };");
523 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
529 * HELPER: checkAndWriteEnumTypeJavaStub() writes the enum type (convert from enum to int)
531 private void checkAndWriteEnumTypeJavaStub(List<String> methParams, List<String> methPrmTypes) {
533 // Iterate and find enum declarations
534 for (int i = 0; i < methParams.size(); i++) {
535 String paramType = methPrmTypes.get(i);
536 String param = methParams.get(i);
537 String simpleType = getSimpleType(paramType);
538 if (isEnumClass(simpleType)) {
539 // Check if this is enum type
540 if (isArray(param)) { // An array
541 println("int len" + i + " = " + param + ".length;");
542 println("int paramEnum" + i + "[] = new int[len];");
543 println("for (int i = 0; i < len" + i + "; i++) {");
544 println("paramEnum" + i + "[i] = " + param + "[i].ordinal();");
546 } else if (isList(paramType)) { // A list
547 println("int len" + i + " = " + param + ".size();");
548 println("int paramEnum" + i + "[] = new int[len];");
549 println("for (int i = 0; i < len" + i + "; i++) {");
550 println("paramEnum" + i + "[i] = " + param + ".get(i).ordinal();");
552 } else { // Just one element
553 println("int paramEnum" + i + "[] = new int[1];");
554 println("paramEnum" + i + "[0] = " + param + ".ordinal();");
562 * HELPER: checkAndWriteEnumRetTypeJavaStub() writes the enum return type (convert from enum to int)
564 private void checkAndWriteEnumRetTypeJavaStub(String retType) {
566 // Strips off array "[]" for return type
567 String pureType = getSimpleArrayType(getSimpleType(retType));
568 // Take the inner type of generic
569 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
570 pureType = getTypeOfGeneric(retType)[0];
571 if (isEnumClass(pureType)) {
572 // Check if this is enum type
574 println("int[] retEnum = (int[]) retObj;");
575 println(pureType + "[] enumVals = " + pureType + ".values();");
576 if (isArray(retType)) { // An array
577 println("int retLen = retEnum.length;");
578 println(pureType + "[] enumRetVal = new " + pureType + "[retLen];");
579 println("for (int i = 0; i < retLen; i++) {");
580 println("enumRetVal[i] = enumVals[retEnum[i]];");
582 } else if (isList(retType)) { // A list
583 println("int retLen = retEnum.length;");
584 println("List<" + pureType + "> enumRetVal = new ArrayList<" + pureType + ">();");
585 println("for (int i = 0; i < retLen; i++) {");
586 println("enumRetVal.add(enumVals[retEnum[i]]);");
588 } else { // Just one element
589 println(pureType + " enumRetVal = enumVals[retEnum[0]];");
591 println("return enumRetVal;");
597 * HELPER: checkAndWriteStructSetupJavaStub() writes the struct type setup
599 private void checkAndWriteStructSetupJavaStub(List<String> methParams, List<String> methPrmTypes,
600 InterfaceDecl intDecl, String method) {
602 // Iterate and find struct declarations
603 for (int i = 0; i < methParams.size(); i++) {
604 String paramType = methPrmTypes.get(i);
605 String param = methParams.get(i);
606 String simpleType = getSimpleType(paramType);
607 if (isStructClass(simpleType)) {
608 // Check if this is enum type
609 int methodNumId = intDecl.getMethodNumId(method);
610 String helperMethod = methodNumId + "struct" + i;
611 println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
612 println("Class<?> retTypeStruct" + i + " = void.class;");
613 println("Class<?>[] paramClsStruct" + i + " = new Class<?>[] { int.class };");
614 if (isArray(param)) { // An array
615 println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".length };");
616 } else if (isList(paramType)) { // A list
617 println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".size() };");
618 } else { // Just one element
619 println("Object[] paramObjStruct" + i + " = new Object[] { new Integer(1) };");
621 println("rmiCall.remoteCall(objectId, methodIdStruct" + i +
622 ", retTypeStruct" + i + ", null, paramClsStruct" + i +
623 ", paramObjStruct" + i + ");\n");
630 * HELPER: isStructPresent() checks presence of struct
632 private boolean isStructPresent(List<String> methParams, List<String> methPrmTypes) {
634 // Iterate and find enum declarations
635 for (int i = 0; i < methParams.size(); i++) {
636 String paramType = methPrmTypes.get(i);
637 String param = methParams.get(i);
638 String simpleType = getSimpleType(paramType);
639 if (isStructClass(simpleType))
647 * HELPER: writeLengthStructParamClassJavaStub() writes lengths of parameters
649 private void writeLengthStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
651 // Iterate and find struct declarations - count number of params
652 for (int i = 0; i < methParams.size(); i++) {
653 String paramType = methPrmTypes.get(i);
654 String param = methParams.get(i);
655 String simpleType = getGenericType(paramType);
656 if (isStructClass(simpleType)) {
657 int members = getNumOfMembers(simpleType);
658 if (isArray(param)) { // An array
659 String structLen = param + ".length";
660 print(members + "*" + structLen);
661 } else if (isList(paramType)) { // A list
662 String structLen = param + ".size()";
663 print(members + "*" + structLen);
665 print(Integer.toString(members));
668 if (i != methParams.size() - 1) {
676 * HELPER: writeStructMembersJavaStub() writes parameters of struct
678 private void writeStructMembersJavaStub(String simpleType, String paramType, String param) {
680 // Get the struct declaration for this struct and generate initialization code
681 StructDecl structDecl = getStructDecl(simpleType);
682 List<String> memTypes = structDecl.getMemberTypes(simpleType);
683 List<String> members = structDecl.getMembers(simpleType);
684 if (isArray(param)) { // An array
685 println("for(int i = 0; i < " + param + ".length; i++) {");
686 } else if (isList(paramType)) { // A list
687 println("for(int i = 0; i < " + param + ".size(); i++) {");
689 if (isArrayOrList(param, paramType)) { // An array or list
690 for (int i = 0; i < members.size(); i++) {
691 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
692 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
693 print("paramObj[pos++] = " + param + "[i].");
694 print(getSimpleIdentifier(members.get(i)));
698 } else { // Just one struct element
699 for (int i = 0; i < members.size(); i++) {
700 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
701 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
702 print("paramObj[pos++] = " + param + ".");
703 print(getSimpleIdentifier(members.get(i)));
711 * HELPER: writeStructParamClassJavaStub() writes parameters if struct is present
713 private void writeStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
715 print("int paramLen = ");
716 writeLengthStructParamClassJavaStub(methParams, methPrmTypes);
718 println("Object[] paramObj = new Object[paramLen];");
719 println("Class<?>[] paramCls = new Class<?>[paramLen];");
720 println("int pos = 0;");
721 // Iterate again over the parameters
722 for (int i = 0; i < methParams.size(); i++) {
723 String paramType = methPrmTypes.get(i);
724 String param = methParams.get(i);
725 String simpleType = getGenericType(paramType);
726 if (isStructClass(simpleType)) {
727 writeStructMembersJavaStub(simpleType, paramType, param);
729 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
730 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
731 print("paramObj[pos++] = ");
732 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
741 * HELPER: writeStructRetMembersJavaStub() writes parameters of struct for return statement
743 private void writeStructRetMembersJavaStub(String simpleType, String retType) {
745 // Get the struct declaration for this struct and generate initialization code
746 StructDecl structDecl = getStructDecl(simpleType);
747 List<String> memTypes = structDecl.getMemberTypes(simpleType);
748 List<String> members = structDecl.getMembers(simpleType);
749 if (isArrayOrList(retType, retType)) { // An array or list
750 println("for(int i = 0; i < retLen; i++) {");
752 if (isArray(retType)) { // An array
753 for (int i = 0; i < members.size(); i++) {
754 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
755 print("structRet[i]." + getSimpleIdentifier(members.get(i)));
756 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
759 } else if (isList(retType)) { // A list
760 println(simpleType + " structRetMem = new " + simpleType + "();");
761 for (int i = 0; i < members.size(); i++) {
762 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
763 print("structRetMem." + getSimpleIdentifier(members.get(i)));
764 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
766 println("structRet.add(structRetMem);");
768 } else { // Just one struct element
769 for (int i = 0; i < members.size(); i++) {
770 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
771 print("structRet." + getSimpleIdentifier(members.get(i)));
772 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
775 println("return structRet;");
780 * HELPER: writeStructReturnJavaStub() writes parameters if struct is present for return statement
782 private void writeStructReturnJavaStub(String simpleType, String retType) {
784 // Handle the returned struct!!!
785 println("Object retLenObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
786 // Minimum retLen is 1 if this is a single struct object
787 println("int retLen = (int) retLenObj;");
788 int numMem = getNumOfMembers(simpleType);
789 println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
790 println("Class<?>[] retClsVal = new Class<?>[" + numMem + "*retLen];");
791 println("int retPos = 0;");
792 // Get the struct declaration for this struct and generate initialization code
793 StructDecl structDecl = getStructDecl(simpleType);
794 List<String> memTypes = structDecl.getMemberTypes(simpleType);
795 List<String> members = structDecl.getMembers(simpleType);
796 if (isArrayOrList(retType, retType)) { // An array or list
797 println("for(int i = 0; i < retLen; i++) {");
798 for (int i = 0; i < members.size(); i++) {
799 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
800 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
801 println("retClsVal[retPos++] = null;");
804 } else { // Just one struct element
805 for (int i = 0; i < members.size(); i++) {
806 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
807 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
808 println("retClsVal[retPos++] = null;");
811 println("Object[] retObj = rmiCall.getStructObjects(retCls, retClsVal);");
812 if (isArray(retType)) { // An array
813 println(simpleType + "[] structRet = new " + simpleType + "[retLen];");
814 println("for(int i = 0; i < retLen; i++) {");
815 println("structRet[i] = new " + simpleType + "();");
817 } else if (isList(retType)) { // A list
818 println("List<" + simpleType + "> structRet = new ArrayList<" + simpleType + ">();");
820 println(simpleType + " structRet = new " + simpleType + "();");
821 println("int retObjPos = 0;");
822 writeStructRetMembersJavaStub(simpleType, retType);
827 * HELPER: writeStdMethodBodyJavaStub() writes the standard method body in the stub class
829 private void writeStdMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
830 List<String> methPrmTypes, String method) {
832 checkAndWriteStructSetupJavaStub(methParams, methPrmTypes, intDecl, method);
833 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
834 String retType = intDecl.getMethodType(method);
835 println("Class<?> retType = " + getSimpleType(getStructType(getEnumType(retType))) + ".class;");
836 checkAndWriteEnumTypeJavaStub(methParams, methPrmTypes);
837 // Generate array of parameter types
838 if (isStructPresent(methParams, methPrmTypes)) {
839 writeStructParamClassJavaStub(methParams, methPrmTypes);
841 print("Class<?>[] paramCls = new Class<?>[] { ");
842 for (int i = 0; i < methParams.size(); i++) {
843 String paramType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
844 print(getSimpleType(getEnumType(paramType)) + ".class");
845 // Check if this is the last element (don't print a comma)
846 if (i != methParams.size() - 1) {
851 // Generate array of parameter objects
852 print("Object[] paramObj = new Object[] { ");
853 for (int i = 0; i < methParams.size(); i++) {
854 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
855 // Check if this is the last element (don't print a comma)
856 if (i != methParams.size() - 1) {
862 // Check if this is "void"
863 if (retType.equals("void")) {
864 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
865 } else { // We do have a return value
866 // Generate array of parameter types
867 if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
868 writeStructReturnJavaStub(getGenericType(getSimpleArrayType(retType)), retType);
870 // Check if the return value NONPRIMITIVES
871 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) {
872 String[] retGenValType = getTypeOfGeneric(retType);
873 println("Class<?> retGenValType = " + retGenValType[0] + ".class;");
874 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);");
875 println("return (" + retType + ")retObj;");
876 } else if (getParamCategory(retType) == ParamCategory.ENUM) {
877 // This is an enum type
878 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
879 checkAndWriteEnumRetTypeJavaStub(retType);
881 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
882 println("return (" + retType + ")retObj;");
890 * HELPER: returnGenericCallbackType() returns the callback type
892 private String returnGenericCallbackType(String paramType) {
894 if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES)
895 return getTypeOfGeneric(paramType)[0];
902 * HELPER: checkCallbackType() checks the callback type
904 private boolean checkCallbackType(String paramType, String callbackType) {
906 String prmType = returnGenericCallbackType(paramType);
907 return callbackType.equals(prmType);
912 * HELPER: writeCallbackMethodBodyJavaStub() writes the callback method of the stub class
914 private void writeCallbackMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
915 List<String> methPrmTypes, String method, String callbackType) {
918 // Check if this is single object, array, or list of objects
919 for (int i = 0; i < methParams.size(); i++) {
920 String paramType = methPrmTypes.get(i);
921 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
922 String param = methParams.get(i);
923 if (isArrayOrList(paramType, param)) { // Generate loop
924 println("for (" + paramType + " cb : " + getSimpleIdentifier(param) + ") {");
925 println(callbackType + "_CallbackSkeleton skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
927 println(callbackType + "_CallbackSkeleton skel = new " + callbackType + "_CallbackSkeleton(" +
928 getSimpleIdentifier(param) + ", objIdCnt++);");
929 println("listCallbackObj.add(skel);");
930 if (isArrayOrList(paramType, param))
934 println("} catch (Exception ex) {");
935 println("ex.printStackTrace();");
936 println("throw new Error(\"Exception when generating skeleton objects!\");");
938 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
939 String retType = intDecl.getMethodType(method);
940 println("Class<?> retType = " + getSimpleType(getEnumType(retType)) + ".class;");
941 // Generate array of parameter types
942 print("Class<?>[] paramCls = new Class<?>[] { ");
943 for (int i = 0; i < methParams.size(); i++) {
944 String paramType = methPrmTypes.get(i);
945 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
947 } else { // Generate normal classes if it's not a callback object
948 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
949 print(getSimpleType(prmType) + ".class");
951 if (i != methParams.size() - 1) // Check if this is the last element
955 // Generate array of parameter objects
956 print("Object[] paramObj = new Object[] { ");
957 for (int i = 0; i < methParams.size(); i++) {
958 String paramType = methPrmTypes.get(i);
959 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
960 //if (isArray(methPrmTypes.get(i), methParams.get(i)))
961 if (isArray(methParams.get(i)))
962 print(getSimpleIdentifier(methParams.get(i)) + ".length");
963 else if (isList(methPrmTypes.get(i)))
964 print(getSimpleIdentifier(methParams.get(i)) + ".size()");
966 print("new Integer(1)");
968 print(getSimpleIdentifier(methParams.get(i)));
969 if (i != methParams.size() - 1)
973 // Check if this is "void"
974 if (retType.equals("void")) {
975 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
976 } else { // We do have a return value
977 // Check if the return value NONPRIMITIVES
978 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) {
979 String[] retGenValType = getTypeOfGeneric(retType);
980 println("Class<?> retGenValType = " + retGenValType[0] + ".class;");
981 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);");
982 println("return (" + retType + ")retObj;");
984 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
985 println("return (" + retType + ")retObj;");
992 * HELPER: writeMethodJavaStub() writes the methods of the stub class
994 private void writeMethodJavaStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
996 for (String method : methods) {
998 List<String> methParams = intDecl.getMethodParams(method);
999 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1000 print("public " + intDecl.getMethodType(method) + " " +
1001 intDecl.getMethodId(method) + "(");
1002 boolean isCallbackMethod = false;
1003 String callbackType = null;
1004 for (int i = 0; i < methParams.size(); i++) {
1006 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
1007 // Check if this has callback object
1008 if (callbackClasses.contains(paramType)) {
1009 isCallbackMethod = true;
1010 callbackType = paramType;
1011 // Even if there're 2 callback arguments, we expect them to be of the same interface
1013 print(methPrmTypes.get(i) + " " + methParams.get(i));
1014 // Check if this is the last element (don't print a comma)
1015 if (i != methParams.size() - 1) {
1020 // Now, write the body of stub!
1021 if (isCallbackMethod)
1022 writeCallbackMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
1024 writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method);
1026 // Write the init callback helper method
1027 if (isCallbackMethod)
1028 writeInitCallbackJavaStub(callbackType, intDecl);
1034 * generateJavaStubClasses() generate stubs based on the methods list in Java
1036 public void generateJavaStubClasses() throws IOException {
1038 // Create a new directory
1039 String path = createDirectories(dir, subdir);
1040 for (String intface : mapIntfacePTH.keySet()) {
1042 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1043 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1045 // Open a new file to write into
1046 String newIntface = intMeth.getKey();
1047 String newStubClass = newIntface + "_Stub";
1048 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
1049 pw = new PrintWriter(new BufferedWriter(fw));
1050 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
1051 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
1052 // Pass in set of methods and get import classes
1053 Set<String> methods = intMeth.getValue();
1054 Set<String> importClasses = getImportClasses(methods, intDecl);
1055 List<String> stdImportClasses = getStandardJavaImportClasses();
1056 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
1057 printImportStatements(allImportClasses); println("");
1058 // Find out if there are callback objects
1059 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
1060 boolean callbackExist = !callbackClasses.isEmpty();
1061 // Write class header
1062 println("public class " + newStubClass + " implements " + newIntface + " {\n");
1064 writePropertiesJavaStub(intface, newIntface, callbackExist, callbackClasses);
1065 // Write constructor
1066 writeConstructorJavaStub(intface, newStubClass, callbackExist, callbackClasses);
1068 writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses);
1071 System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java...");
1078 * HELPER: writePropertiesJavaCallbackStub() writes the properties of the callback stub class
1080 private void writePropertiesJavaCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
1082 println("private IoTRMICall rmiCall;");
1083 println("private String address;");
1084 println("private int[] ports;\n");
1085 // Get the object Id
1086 println("private static int objectId = 0;");
1087 if (callbackExist) {
1088 // We assume that each class only has one callback interface for now
1089 Iterator it = callbackClasses.iterator();
1090 String callbackType = (String) it.next();
1091 println("// Callback properties");
1092 println("private IoTRMIObject rmiObj;");
1093 println("List<" + callbackType + "> listCallbackObj;");
1094 println("private static int objIdCnt = 0;");
1095 // Generate permission stuff for callback stubs
1096 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
1097 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
1098 writePropertiesJavaPermission(callbackType, intDecl);
1105 * HELPER: writeConstructorJavaCallbackStub() writes the constructor of the callback stub class
1107 private void writeConstructorJavaCallbackStub(String intface, String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
1109 // TODO: If we want callback in callback, then we need to add address and port initializations
1110 println("public " + newStubClass + "(IoTRMICall _rmiCall, int _objectId) throws Exception {");
1111 println("objectId = _objectId;");
1112 println("rmiCall = _rmiCall;");
1113 if (callbackExist) {
1114 Iterator it = callbackClasses.iterator();
1115 String callbackType = (String) it.next();
1116 writeConstructorJavaPermission(intface);
1117 println("listCallbackObj = new ArrayList<" + callbackType + ">();");
1118 println("___initCallBack();");
1119 println("// TODO: Add address and port initialization here if we want callback in callback!");
1126 * generateJavaCallbackStubClasses() generate callback stubs based on the methods list in Java
1128 * Callback stubs gets the IoTRMICall objects from outside of the class as contructor input
1129 * because all these stubs are populated by the class that takes in this object as a callback
1130 * object. In such a class, we only use one socket, hence one IoTRMICall, for all callback objects.
1132 public void generateJavaCallbackStubClasses() throws IOException {
1134 // Create a new directory
1135 String path = createDirectories(dir, subdir);
1136 for (String intface : mapIntfacePTH.keySet()) {
1138 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1139 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1141 // Open a new file to write into
1142 String newIntface = intMeth.getKey();
1143 String newStubClass = newIntface + "_CallbackStub";
1144 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
1145 pw = new PrintWriter(new BufferedWriter(fw));
1146 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
1147 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
1148 // Pass in set of methods and get import classes
1149 Set<String> methods = intMeth.getValue();
1150 Set<String> importClasses = getImportClasses(methods, intDecl);
1151 List<String> stdImportClasses = getStandardJavaImportClasses();
1152 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
1153 printImportStatements(allImportClasses); println("");
1154 // Find out if there are callback objects
1155 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
1156 boolean callbackExist = !callbackClasses.isEmpty();
1157 // Write class header
1158 println("public class " + newStubClass + " implements " + newIntface + " {\n");
1160 writePropertiesJavaCallbackStub(intface, newIntface, callbackExist, callbackClasses);
1161 // Write constructor
1162 writeConstructorJavaCallbackStub(intface, newStubClass, callbackExist, callbackClasses);
1164 // TODO: perhaps need to generate callback for callback
1165 writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses);
1168 System.out.println("IoTCompiler: Generated callback stub class " + newStubClass + ".java...");
1175 * HELPER: writePropertiesJavaSkeleton() writes the properties of the skeleton class
1177 private void writePropertiesJavaSkeleton(String intface, boolean callbackExist, InterfaceDecl intDecl) {
1179 println("private " + intface + " mainObj;");
1180 //println("private int ports;");
1181 println("private IoTRMIObject rmiObj;\n");
1183 if (callbackExist) {
1184 println("private static int objIdCnt = 0;");
1185 println("private IoTRMICall rmiCall;");
1187 writePropertiesJavaPermission(intface, intDecl);
1193 * HELPER: writeConstructorJavaSkeleton() writes the constructor of the skeleton class
1195 private void writeConstructorJavaSkeleton(String newSkelClass, String intface) {
1197 println("public " + newSkelClass + "(" + intface + " _mainObj, int _port) throws Exception {");
1198 println("mainObj = _mainObj;");
1199 println("rmiObj = new IoTRMIObject(_port);");
1200 // Generate permission control initialization
1201 writeConstructorJavaPermission(intface);
1202 println("___waitRequestInvokeMethod();");
1208 * HELPER: writeStdMethodBodyJavaSkeleton() writes the standard method body in the skeleton class
1210 private void writeStdMethodBodyJavaSkeleton(List<String> methParams, String methodId, String methodType) {
1212 if (methodType.equals("void"))
1213 print("mainObj." + methodId + "(");
1215 print("return mainObj." + methodId + "(");
1216 for (int i = 0; i < methParams.size(); i++) {
1218 print(getSimpleIdentifier(methParams.get(i)));
1219 // Check if this is the last element (don't print a comma)
1220 if (i != methParams.size() - 1) {
1229 * HELPER: writeInitCallbackJavaSkeleton() writes the init callback method for skeleton class
1231 private void writeInitCallbackJavaSkeleton(boolean callbackSkeleton) {
1233 // This is a callback skeleton generation
1234 if (callbackSkeleton)
1235 println("public void ___regCB(IoTRMIObject rmiObj) throws IOException {");
1237 println("public void ___regCB() throws IOException {");
1238 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class, String.class, int.class },");
1239 println("\tnew Class<?>[] { null, null, null });");
1240 println("rmiCall = new IoTRMICall((int) paramObj[0], (String) paramObj[1], (int) paramObj[2]);");
1246 * HELPER: writeMethodJavaSkeleton() writes the method of the skeleton class
1248 private void writeMethodJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses,
1249 boolean callbackSkeleton) {
1251 for (String method : methods) {
1253 List<String> methParams = intDecl.getMethodParams(method);
1254 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1255 String methodId = intDecl.getMethodId(method);
1256 print("public " + intDecl.getMethodType(method) + " " + methodId + "(");
1257 boolean isCallbackMethod = false;
1258 String callbackType = null;
1259 for (int i = 0; i < methParams.size(); i++) {
1261 String origParamType = methPrmTypes.get(i);
1262 String paramType = checkAndGetParamClass(origParamType);
1263 if (callbackClasses.contains(origParamType)) { // Check if this has callback object
1264 isCallbackMethod = true;
1265 callbackType = origParamType;
1267 print(paramType + " " + methParams.get(i));
1268 // Check if this is the last element (don't print a comma)
1269 if (i != methParams.size() - 1) {
1274 // Now, write the body of skeleton!
1275 writeStdMethodBodyJavaSkeleton(methParams, methodId, intDecl.getMethodType(method));
1277 if (isCallbackMethod)
1278 writeInitCallbackJavaSkeleton(callbackSkeleton);
1284 * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part
1286 private Map<Integer,String> writeCallbackJavaStubGeneration(List<String> methParams, List<String> methPrmTypes,
1287 String callbackType) {
1289 Map<Integer,String> mapStubParam = new HashMap<Integer,String>();
1290 // Iterate over callback objects
1291 for (int i = 0; i < methParams.size(); i++) {
1292 String paramType = methPrmTypes.get(i);
1293 String param = methParams.get(i);
1294 //if (callbackType.equals(paramType)) {
1295 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
1297 String exchParamType = checkAndGetParamClass(paramType);
1298 // Print array if this is array or list if this is a list of callback objects
1299 if (isArray(param)) {
1300 println("int numStubs" + i + " = (int) paramObj[" + i + "];");
1301 println(exchParamType + "[] stub" + i + " = new " + exchParamType + "[numStubs" + i + "];");
1302 } else if (isList(paramType)) {
1303 println("int numStubs" + i + " = (int) paramObj[" + i + "];");
1304 println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();");
1306 println(exchParamType + " stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
1307 println("objIdCnt++;");
1310 // Generate a loop if needed
1311 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
1312 String exchParamType = checkAndGetParamClass(paramType);
1313 if (isArray(param)) {
1314 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
1315 println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
1316 println("objIdCnt++;");
1318 } else if (isList(paramType)) {
1319 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
1320 println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt));");
1321 println("objIdCnt++;");
1324 mapStubParam.put(i, "stub" + i); // List of all stub parameters
1327 return mapStubParam;
1332 * HELPER: checkAndWriteEnumTypeJavaSkeleton() writes the enum type (convert from enum to int)
1334 private void checkAndWriteEnumTypeJavaSkeleton(List<String> methParams, List<String> methPrmTypes) {
1336 // Iterate and find enum declarations
1337 for (int i = 0; i < methParams.size(); i++) {
1338 String paramType = methPrmTypes.get(i);
1339 String param = methParams.get(i);
1340 String simpleType = getSimpleType(paramType);
1341 if (isEnumClass(simpleType)) {
1342 // Check if this is enum type
1343 println("int paramInt" + i + "[] = (int[]) paramObj[" + i + "];");
1344 println(simpleType + "[] enumVals = " + simpleType + ".values();");
1345 if (isArray(param)) { // An array
1346 println("int len" + i + " = paramInt" + i + ".length;");
1347 println(simpleType + "[] paramEnum = new " + simpleType + "[len];");
1348 println("for (int i = 0; i < len" + i + "; i++) {");
1349 println("paramEnum[i] = enumVals[paramInt" + i + "[i]];");
1351 } else if (isList(paramType)) { // A list
1352 println("int len" + i + " = paramInt" + i + ".length;");
1353 println("List<" + simpleType + "> paramEnum = new ArrayList<" + simpleType + ">();");
1354 println("for (int i = 0; i < len" + i + "; i++) {");
1355 println("paramEnum.add(enumVals[paramInt" + i + "[i]]);");
1357 } else { // Just one element
1358 println(simpleType + " paramEnum" + i + " = enumVals[paramInt" + i + "[0]];");
1366 * HELPER: checkAndWriteEnumRetTypeJavaSkeleton() writes the enum return type (convert from enum to int)
1368 private void checkAndWriteEnumRetTypeJavaSkeleton(String retType, String methodId) {
1370 // Strips off array "[]" for return type
1371 String pureType = getSimpleArrayType(getSimpleType(retType));
1372 // Take the inner type of generic
1373 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
1374 pureType = getTypeOfGeneric(retType)[0];
1375 if (isEnumClass(pureType)) {
1376 // Check if this is enum type
1378 if (isArray(retType)) { // An array
1379 print(pureType + "[] retEnum = " + methodId + "(");
1380 } else if (isList(retType)) { // A list
1381 print("List<" + pureType + "> retEnum = " + methodId + "(");
1382 } else { // Just one element
1383 print(pureType + " retEnum = " + methodId + "(");
1390 * HELPER: checkAndWriteEnumRetConvJavaSkeleton() writes the enum return type (convert from enum to int)
1392 private void checkAndWriteEnumRetConvJavaSkeleton(String retType) {
1394 // Strips off array "[]" for return type
1395 String pureType = getSimpleArrayType(getSimpleType(retType));
1396 // Take the inner type of generic
1397 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
1398 pureType = getTypeOfGeneric(retType)[0];
1399 if (isEnumClass(pureType)) {
1400 // Check if this is enum type
1401 if (isArray(retType)) { // An array
1402 println("int retLen = retEnum.length;");
1403 println("int[] retEnumVal = new int[retLen];");
1404 println("for (int i = 0; i < retLen; i++) {");
1405 println("retEnumVal[i] = retEnum[i].ordinal();");
1407 } else if (isList(retType)) { // A list
1408 println("int retLen = retEnum.size();");
1409 println("List<" + pureType + "> retEnumVal = new ArrayList<" + pureType + ">();");
1410 println("for (int i = 0; i < retLen; i++) {");
1411 println("retEnumVal.add(retEnum[i].ordinal());");
1413 } else { // Just one element
1414 println("int[] retEnumVal = new int[1];");
1415 println("retEnumVal[0] = retEnum.ordinal();");
1417 println("Object retObj = retEnumVal;");
1423 * HELPER: writeLengthStructParamClassSkeleton() writes lengths of params
1425 private void writeLengthStructParamClassSkeleton(List<String> methParams, List<String> methPrmTypes,
1426 String method, InterfaceDecl intDecl) {
1428 // Iterate and find struct declarations - count number of params
1429 for (int i = 0; i < methParams.size(); i++) {
1430 String paramType = methPrmTypes.get(i);
1431 String param = methParams.get(i);
1432 String simpleType = getGenericType(paramType);
1433 if (isStructClass(simpleType)) {
1434 int members = getNumOfMembers(simpleType);
1435 print(Integer.toString(members) + "*");
1436 int methodNumId = intDecl.getMethodNumId(method);
1437 print("struct" + methodNumId + "Size" + i);
1440 if (i != methParams.size() - 1) {
1448 * HELPER: writeStructMembersJavaSkeleton() writes member parameters of struct
1450 private void writeStructMembersJavaSkeleton(String simpleType, String paramType,
1451 String param, String method, InterfaceDecl intDecl, int iVar) {
1453 // Get the struct declaration for this struct and generate initialization code
1454 StructDecl structDecl = getStructDecl(simpleType);
1455 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1456 List<String> members = structDecl.getMembers(simpleType);
1457 if (isArrayOrList(param, paramType)) { // An array or list
1458 int methodNumId = intDecl.getMethodNumId(method);
1459 String counter = "struct" + methodNumId + "Size" + iVar;
1460 println("for(int i = 0; i < " + counter + "; i++) {");
1462 println("int pos = 0;");
1463 if (isArrayOrList(param, paramType)) { // An array or list
1464 println("for(int i = 0; i < retLen; i++) {");
1465 for (int i = 0; i < members.size(); i++) {
1466 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1467 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1468 println("paramClsGen[pos++] = null;");
1471 } else { // Just one struct element
1472 for (int i = 0; i < members.size(); i++) {
1473 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1474 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1475 println("paramClsGen[pos++] = null;");
1482 * HELPER: writeStructMembersInitJavaSkeleton() writes member parameters initialization of struct
1484 private void writeStructMembersInitJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1485 List<String> methPrmTypes, String method) {
1487 for (int i = 0; i < methParams.size(); i++) {
1488 String paramType = methPrmTypes.get(i);
1489 String param = methParams.get(i);
1490 String simpleType = getGenericType(paramType);
1491 if (isStructClass(simpleType)) {
1492 int methodNumId = intDecl.getMethodNumId(method);
1493 String counter = "struct" + methodNumId + "Size" + i;
1495 if (isArray(param)) { // An array
1496 println(simpleType + "[] paramStruct" + i + " = new " + simpleType + "[" + counter + "];");
1497 println("for(int i = 0; i < " + counter + "; i++) {");
1498 println("paramStruct" + i + "[i] = new " + simpleType + "();");
1500 } else if (isList(paramType)) { // A list
1501 println("List<" + simpleType + "> paramStruct" + i + " = new ArrayList<" + simpleType + ">();");
1503 println(simpleType + " paramStruct" + i + " = new " + simpleType + "();");
1504 println("int objPos = 0;");
1505 // Initialize members
1506 StructDecl structDecl = getStructDecl(simpleType);
1507 List<String> members = structDecl.getMembers(simpleType);
1508 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1509 if (isArrayOrList(param, paramType)) { // An array or list
1510 println("for(int i = 0; i < " + counter + "; i++) {");
1512 if (isArray(param)) { // An array
1513 for (int j = 0; j < members.size(); j++) {
1514 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1515 print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j)));
1516 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1519 } else if (isList(paramType)) { // A list
1520 println(simpleType + " paramStructMem = new " + simpleType + "();");
1521 for (int j = 0; j < members.size(); j++) {
1522 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1523 print("paramStructMem." + getSimpleIdentifier(members.get(j)));
1524 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1526 println("paramStruct" + i + ".add(paramStructMem);");
1528 } else { // Just one struct element
1529 for (int j = 0; j < members.size(); j++) {
1530 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1531 print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j)));
1532 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1536 // Take offsets of parameters
1537 println("int offset" + i +" = objPos;");
1544 * HELPER: writeStructReturnJavaSkeleton() writes struct for return statement
1546 private void writeStructReturnJavaSkeleton(String simpleType, String retType) {
1548 // Minimum retLen is 1 if this is a single struct object
1549 if (isArray(retType))
1550 println("int retLen = retStruct.length;");
1551 else if (isList(retType))
1552 println("int retLen = retStruct.size();");
1553 else // Just single struct object
1554 println("int retLen = 1;");
1555 println("Object retLenObj = retLen;");
1556 println("rmiObj.sendReturnObj(retLenObj);");
1557 int numMem = getNumOfMembers(simpleType);
1558 println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
1559 println("Object[] retObj = new Object[" + numMem + "*retLen];");
1560 println("int retPos = 0;");
1561 // Get the struct declaration for this struct and generate initialization code
1562 StructDecl structDecl = getStructDecl(simpleType);
1563 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1564 List<String> members = structDecl.getMembers(simpleType);
1565 if (isArrayOrList(retType, retType)) { // An array or list
1566 println("for(int i = 0; i < retLen; i++) {");
1567 for (int i = 0; i < members.size(); i++) {
1568 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1569 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1570 print("retObj[retPos++] = retStruct[i].");
1571 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
1575 } else { // Just one struct element
1576 for (int i = 0; i < members.size(); i++) {
1577 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1578 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1579 print("retObj[retPos++] = retStruct.");
1580 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
1589 * HELPER: writeMethodHelperReturnJavaSkeleton() writes return statement part in skeleton
1591 private void writeMethodHelperReturnJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1592 List<String> methPrmTypes, String method, boolean isCallbackMethod, String callbackType,
1593 boolean isStructMethod) {
1595 checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes);
1596 Map<Integer,String> mapStubParam = null;
1597 if (isCallbackMethod)
1598 mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType);
1599 // Check if this is "void"
1600 String retType = intDecl.getMethodType(method);
1601 if (retType.equals("void")) {
1602 print(intDecl.getMethodId(method) + "(");
1603 } else if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
1604 checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method));
1605 } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
1606 print(retType + " retStruct = " + intDecl.getMethodId(method) + "(");
1607 } else { // We do have a return value
1608 print("Object retObj = " + intDecl.getMethodId(method) + "(");
1610 for (int i = 0; i < methParams.size(); i++) {
1612 if (isCallbackMethod) {
1613 print(mapStubParam.get(i)); // Get the callback parameter
1614 } else if (isEnumClass(getSimpleType(methPrmTypes.get(i)))) { // Enum class
1615 print(getEnumParam(methPrmTypes.get(i), methParams.get(i), i));
1616 } else if (isStructClass(getSimpleType(methPrmTypes.get(i)))) {
1617 print("paramStruct" + i);
1619 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1621 print("(" + prmType + ") paramObj[offset" + i + "]");
1623 print("(" + prmType + ") paramObj[" + i + "]");
1625 if (i != methParams.size() - 1)
1629 if (!retType.equals("void")) {
1630 if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
1631 checkAndWriteEnumRetConvJavaSkeleton(retType);
1632 println("rmiObj.sendReturnObj(retObj);");
1633 } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
1634 writeStructReturnJavaSkeleton(getSimpleArrayType(getSimpleType(retType)), retType);
1635 println("rmiObj.sendReturnObj(retCls, retObj);");
1637 println("rmiObj.sendReturnObj(retObj);");
1639 if (isCallbackMethod) { // Catch exception if this is callback
1640 println("} catch(Exception ex) {");
1641 println("ex.printStackTrace();");
1642 println("throw new Error(\"Exception from callback object instantiation!\");");
1649 * HELPER: writeMethodHelperStructJavaSkeleton() writes the struct in skeleton
1651 private void writeMethodHelperStructJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1652 List<String> methPrmTypes, String method, Set<String> callbackClasses) {
1654 // Generate array of parameter objects
1655 boolean isCallbackMethod = false;
1656 String callbackType = null;
1657 print("int paramLen = ");
1658 writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
1660 println("Class<?>[] paramCls = new Class<?>[paramLen];");
1661 println("Class<?>[] paramClsGen = new Class<?>[paramLen];");
1662 // Iterate again over the parameters
1663 for (int i = 0; i < methParams.size(); i++) {
1664 String paramType = methPrmTypes.get(i);
1665 String param = methParams.get(i);
1666 String simpleType = getGenericType(paramType);
1667 if (isStructClass(simpleType)) {
1668 writeStructMembersJavaSkeleton(simpleType, paramType, param, method, intDecl, i);
1670 String prmType = returnGenericCallbackType(methPrmTypes.get(i));
1671 if (callbackClasses.contains(prmType)) {
1672 isCallbackMethod = true;
1673 callbackType = prmType;
1674 println("paramCls[pos] = int.class;");
1675 println("paramClsGen[pos++] = null;");
1676 } else { // Generate normal classes if it's not a callback object
1677 String paramTypeOth = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1678 println("paramCls[pos] = " + getSimpleType(getEnumType(paramTypeOth)) + ".class;");
1679 print("paramClsGen[pos++] = ");
1680 String prmTypeOth = methPrmTypes.get(i);
1681 if (getParamCategory(prmTypeOth) == ParamCategory.NONPRIMITIVES)
1682 println(getTypeOfGeneric(prmType)[0] + ".class;");
1688 println("Object[] paramObj = rmiObj.getMethodParams(paramCls, paramClsGen);");
1689 writeStructMembersInitJavaSkeleton(intDecl, methParams, methPrmTypes, method);
1690 // Write the return value part
1691 writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, true);
1696 * HELPER: writeStdMethodHelperBodyJavaSkeleton() writes the standard method body helper in the skeleton class
1698 private void writeStdMethodHelperBodyJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1699 List<String> methPrmTypes, String method, Set<String> callbackClasses) {
1701 // Generate array of parameter objects
1702 boolean isCallbackMethod = false;
1703 String callbackType = null;
1704 print("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { ");
1705 for (int i = 0; i < methParams.size(); i++) {
1707 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
1708 if (callbackClasses.contains(paramType)) {
1709 isCallbackMethod = true;
1710 callbackType = paramType;
1712 } else { // Generate normal classes if it's not a callback object
1713 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1714 print(getSimpleType(getEnumType(prmType)) + ".class");
1716 if (i != methParams.size() - 1)
1720 // Generate generic class if it's a generic type.. null otherwise
1721 print("new Class<?>[] { ");
1722 for (int i = 0; i < methParams.size(); i++) {
1723 String prmType = methPrmTypes.get(i);
1724 if (getParamCategory(prmType) == ParamCategory.NONPRIMITIVES)
1725 print(getTypeOfGeneric(prmType)[0] + ".class");
1728 if (i != methParams.size() - 1)
1732 // Write the return value part
1733 writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, false);
1738 * HELPER: writeMethodHelperJavaSkeleton() writes the method helper of the skeleton class
1740 private void writeMethodHelperJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
1742 // Use this set to handle two same methodIds
1743 Set<String> uniqueMethodIds = new HashSet<String>();
1744 for (String method : methods) {
1746 List<String> methParams = intDecl.getMethodParams(method);
1747 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1748 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
1749 String methodId = intDecl.getMethodId(method);
1750 print("public void ___");
1751 String helperMethod = methodId;
1752 if (uniqueMethodIds.contains(methodId))
1753 helperMethod = helperMethod + intDecl.getMethodNumId(method);
1755 uniqueMethodIds.add(methodId);
1756 String retType = intDecl.getMethodType(method);
1757 print(helperMethod + "(");
1758 boolean begin = true;
1759 for (int i = 0; i < methParams.size(); i++) { // Print size variables
1760 String paramType = methPrmTypes.get(i);
1761 String param = methParams.get(i);
1762 String simpleType = getSimpleType(paramType);
1763 if (isStructClass(simpleType)) {
1764 if (!begin) { // Generate comma for not the beginning variable
1765 print(", "); begin = false;
1767 int methodNumId = intDecl.getMethodNumId(method);
1768 print("int struct" + methodNumId + "Size" + i);
1771 // Check if this is "void"
1772 if (retType.equals("void"))
1775 println(") throws IOException {");
1776 writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
1779 String methodId = intDecl.getMethodId(method);
1780 print("public void ___");
1781 String helperMethod = methodId;
1782 if (uniqueMethodIds.contains(methodId))
1783 helperMethod = helperMethod + intDecl.getMethodNumId(method);
1785 uniqueMethodIds.add(methodId);
1786 // Check if this is "void"
1787 String retType = intDecl.getMethodType(method);
1788 if (retType.equals("void"))
1789 println(helperMethod + "() {");
1791 println(helperMethod + "() throws IOException {");
1792 // Now, write the helper body of skeleton!
1793 writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
1797 // Write method helper for structs
1798 writeMethodHelperStructSetupJavaSkeleton(methods, intDecl);
1803 * HELPER: writeMethodHelperStructSetupJavaSkeleton() writes the method helper of struct setup in skeleton class
1805 private void writeMethodHelperStructSetupJavaSkeleton(Collection<String> methods,
1806 InterfaceDecl intDecl) {
1808 // Use this set to handle two same methodIds
1809 for (String method : methods) {
1811 List<String> methParams = intDecl.getMethodParams(method);
1812 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1813 // Check for params with structs
1814 for (int i = 0; i < methParams.size(); i++) {
1815 String paramType = methPrmTypes.get(i);
1816 String param = methParams.get(i);
1817 String simpleType = getSimpleType(paramType);
1818 if (isStructClass(simpleType)) {
1819 int methodNumId = intDecl.getMethodNumId(method);
1820 print("public int ___");
1821 String helperMethod = methodNumId + "struct" + i;
1822 println(helperMethod + "() {");
1823 // Now, write the helper body of skeleton!
1824 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
1825 println("return (int) paramObj[0];");
1834 * HELPER: writeMethodHelperStructSetupJavaCallbackSkeleton() writes the method helper of struct setup in callback skeleton class
1836 private void writeMethodHelperStructSetupJavaCallbackSkeleton(Collection<String> methods,
1837 InterfaceDecl intDecl) {
1839 // Use this set to handle two same methodIds
1840 for (String method : methods) {
1842 List<String> methParams = intDecl.getMethodParams(method);
1843 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1844 // Check for params with structs
1845 for (int i = 0; i < methParams.size(); i++) {
1846 String paramType = methPrmTypes.get(i);
1847 String param = methParams.get(i);
1848 String simpleType = getSimpleType(paramType);
1849 if (isStructClass(simpleType)) {
1850 int methodNumId = intDecl.getMethodNumId(method);
1851 print("public int ___");
1852 String helperMethod = methodNumId + "struct" + i;
1853 println(helperMethod + "(IoTRMIObject rmiObj) {");
1854 // Now, write the helper body of skeleton!
1855 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
1856 println("return (int) paramObj[0];");
1865 * HELPER: writeCountVarStructSkeleton() writes counter variable of struct for skeleton
1867 private void writeCountVarStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
1869 // Use this set to handle two same methodIds
1870 for (String method : methods) {
1872 List<String> methParams = intDecl.getMethodParams(method);
1873 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1874 // Check for params with structs
1875 for (int i = 0; i < methParams.size(); i++) {
1876 String paramType = methPrmTypes.get(i);
1877 String param = methParams.get(i);
1878 String simpleType = getSimpleType(paramType);
1879 if (isStructClass(simpleType)) {
1880 int methodNumId = intDecl.getMethodNumId(method);
1881 println("int struct" + methodNumId + "Size" + i + " = 0;");
1889 * HELPER: writeInputCountVarStructSkeleton() writes input counter variable of struct for skeleton
1891 private boolean writeInputCountVarStructSkeleton(String method, InterfaceDecl intDecl) {
1893 List<String> methParams = intDecl.getMethodParams(method);
1894 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1895 boolean structExist = false;
1896 // Check for params with structs
1897 for (int i = 0; i < methParams.size(); i++) {
1898 String paramType = methPrmTypes.get(i);
1899 String param = methParams.get(i);
1900 String simpleType = getSimpleType(paramType);
1901 boolean begin = true;
1902 if (isStructClass(simpleType)) {
1905 print(", "); begin = false;
1907 int methodNumId = intDecl.getMethodNumId(method);
1908 print("struct" + methodNumId + "Size" + i);
1916 * HELPER: writeMethodCallStructSkeleton() writes method call for wait invoke in skeleton
1918 private void writeMethodCallStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
1920 // Use this set to handle two same methodIds
1921 for (String method : methods) {
1923 List<String> methParams = intDecl.getMethodParams(method);
1924 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1925 // Check for params with structs
1926 for (int i = 0; i < methParams.size(); i++) {
1927 String paramType = methPrmTypes.get(i);
1928 String param = methParams.get(i);
1929 String simpleType = getSimpleType(paramType);
1930 if (isStructClass(simpleType)) {
1931 int methodNumId = intDecl.getMethodNumId(method);
1933 String helperMethod = methodNumId + "struct" + i;
1934 String tempVar = "struct" + methodNumId + "Size" + i;
1935 print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
1936 print(tempVar + " = ___");
1937 println(helperMethod + "(); break;");
1945 * HELPER: writeMethodCallStructCallbackSkeleton() writes method call for wait invoke in skeleton
1947 private void writeMethodCallStructCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
1949 // Use this set to handle two same methodIds
1950 for (String method : methods) {
1952 List<String> methParams = intDecl.getMethodParams(method);
1953 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1954 // Check for params with structs
1955 for (int i = 0; i < methParams.size(); i++) {
1956 String paramType = methPrmTypes.get(i);
1957 String param = methParams.get(i);
1958 String simpleType = getSimpleType(paramType);
1959 if (isStructClass(simpleType)) {
1960 int methodNumId = intDecl.getMethodNumId(method);
1962 String helperMethod = methodNumId + "struct" + i;
1963 String tempVar = "struct" + methodNumId + "Size" + i;
1964 print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
1965 print(tempVar + " = ___");
1966 println(helperMethod + "(rmiObj); break;");
1974 * HELPER: writeJavaMethodPermission() writes permission checks in skeleton
1976 private void writeJavaMethodPermission(String intface) {
1978 // Get all the different stubs
1979 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1980 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1981 String newIntface = intMeth.getKey();
1982 int newObjectId = mapNewIntfaceObjId.get(newIntface);
1983 println("if (_objectId == object" + newObjectId + "Id) {");
1984 println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
1985 println("throw new Error(\"Object with object Id: \" + _objectId + \" is not allowed to access method: \" + methodId);");
1989 println("throw new Error(\"Object Id: \" + _objectId + \" not recognized!\");");
1996 * HELPER: writeJavaWaitRequestInvokeMethod() writes the main loop of the skeleton class
1998 private void writeJavaWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
2000 // Use this set to handle two same methodIds
2001 Set<String> uniqueMethodIds = new HashSet<String>();
2002 println("private void ___waitRequestInvokeMethod() throws IOException {");
2003 // Write variables here if we have callbacks or enums or structs
2004 writeCountVarStructSkeleton(methods, intDecl);
2005 println("while (true) {");
2006 println("rmiObj.getMethodBytes();");
2007 println("int _objectId = rmiObj.getObjectId();");
2008 println("int methodId = rmiObj.getMethodId();");
2009 // Generate permission check
2010 writeJavaMethodPermission(intface);
2011 println("switch (methodId) {");
2012 // Print methods and method Ids
2013 for (String method : methods) {
2014 String methodId = intDecl.getMethodId(method);
2015 int methodNumId = intDecl.getMethodNumId(method);
2016 print("case " + methodNumId + ": ___");
2017 String helperMethod = methodId;
2018 if (uniqueMethodIds.contains(methodId))
2019 helperMethod = helperMethod + methodNumId;
2021 uniqueMethodIds.add(methodId);
2022 print(helperMethod + "(");
2023 writeInputCountVarStructSkeleton(method, intDecl);
2024 println("); break;");
2026 String method = "___initCallBack()";
2027 // Print case -9999 (callback handler) if callback exists
2028 if (callbackExist) {
2029 int methodId = intDecl.getHelperMethodNumId(method);
2030 println("case " + methodId + ": ___regCB(); break;");
2032 writeMethodCallStructSkeleton(methods, intDecl);
2033 println("default: ");
2034 println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
2042 * generateJavaSkeletonClass() generate skeletons based on the methods list in Java
2044 public void generateJavaSkeletonClass() throws IOException {
2046 // Create a new directory
2047 String path = createDirectories(dir, subdir);
2048 for (String intface : mapIntfacePTH.keySet()) {
2049 // Open a new file to write into
2050 String newSkelClass = intface + "_Skeleton";
2051 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
2052 pw = new PrintWriter(new BufferedWriter(fw));
2053 // Pass in set of methods and get import classes
2054 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2055 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2056 List<String> methods = intDecl.getMethods();
2057 Set<String> importClasses = getImportClasses(methods, intDecl);
2058 List<String> stdImportClasses = getStandardJavaImportClasses();
2059 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
2060 printImportStatements(allImportClasses);
2061 // Find out if there are callback objects
2062 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
2063 boolean callbackExist = !callbackClasses.isEmpty();
2064 // Write class header
2066 println("public class " + newSkelClass + " implements " + intface + " {\n");
2068 writePropertiesJavaSkeleton(intface, callbackExist, intDecl);
2069 // Write constructor
2070 writeConstructorJavaSkeleton(newSkelClass, intface);
2072 writeMethodJavaSkeleton(methods, intDecl, callbackClasses, false);
2073 // Write method helper
2074 writeMethodHelperJavaSkeleton(methods, intDecl, callbackClasses);
2075 // Write waitRequestInvokeMethod() - main loop
2076 writeJavaWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
2079 System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".java...");
2085 * HELPER: writePropertiesJavaCallbackSkeleton() writes the properties of the callback skeleton class
2087 private void writePropertiesJavaCallbackSkeleton(String intface, boolean callbackExist) {
2089 println("private " + intface + " mainObj;");
2090 // For callback skeletons, this is its own object Id
2091 println("private static int objectId = 0;");
2093 if (callbackExist) {
2094 println("private static int objIdCnt = 0;");
2095 println("private IoTRMICall rmiCall;");
2102 * HELPER: writeConstructorJavaCallbackSkeleton() writes the constructor of the skeleton class
2104 private void writeConstructorJavaCallbackSkeleton(String newSkelClass, String intface) {
2106 println("public " + newSkelClass + "(" + intface + " _mainObj, int _objectId) throws Exception {");
2107 println("mainObj = _mainObj;");
2108 println("objectId = _objectId;");
2114 * HELPER: writeMethodHelperJavaCallbackSkeleton() writes the method helper of the callback skeleton class
2116 private void writeMethodHelperJavaCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
2118 // Use this set to handle two same methodIds
2119 Set<String> uniqueMethodIds = new HashSet<String>();
2120 for (String method : methods) {
2122 List<String> methParams = intDecl.getMethodParams(method);
2123 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2124 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
2125 String methodId = intDecl.getMethodId(method);
2126 print("public void ___");
2127 String helperMethod = methodId;
2128 if (uniqueMethodIds.contains(methodId))
2129 helperMethod = helperMethod + intDecl.getMethodNumId(method);
2131 uniqueMethodIds.add(methodId);
2132 String retType = intDecl.getMethodType(method);
2133 print(helperMethod + "(");
2134 boolean begin = true;
2135 for (int i = 0; i < methParams.size(); i++) { // Print size variables
2136 String paramType = methPrmTypes.get(i);
2137 String param = methParams.get(i);
2138 String simpleType = getSimpleType(paramType);
2139 if (isStructClass(simpleType)) {
2140 if (!begin) { // Generate comma for not the beginning variable
2141 print(", "); begin = false;
2143 int methodNumId = intDecl.getMethodNumId(method);
2144 print("int struct" + methodNumId + "Size" + i);
2147 // Check if this is "void"
2148 if (retType.equals("void"))
2149 println(", IoTRMIObject rmiObj) {");
2151 println(", IoTRMIObject rmiObj) throws IOException {");
2152 writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
2155 String methodId = intDecl.getMethodId(method);
2156 print("public void ___");
2157 String helperMethod = methodId;
2158 if (uniqueMethodIds.contains(methodId))
2159 helperMethod = helperMethod + intDecl.getMethodNumId(method);
2161 uniqueMethodIds.add(methodId);
2162 // Check if this is "void"
2163 String retType = intDecl.getMethodType(method);
2164 if (retType.equals("void"))
2165 println(helperMethod + "(IoTRMIObject rmiObj) {");
2167 println(helperMethod + "(IoTRMIObject rmiObj) throws IOException {");
2168 // Now, write the helper body of skeleton!
2169 writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
2173 // Write method helper for structs
2174 writeMethodHelperStructSetupJavaCallbackSkeleton(methods, intDecl);
2179 * HELPER: writeJavaCallbackWaitRequestInvokeMethod() writes the request invoke method of the callback skeleton class
2181 private void writeJavaCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist) {
2183 // Use this set to handle two same methodIds
2184 Set<String> uniqueMethodIds = new HashSet<String>();
2185 println("public void invokeMethod(IoTRMIObject rmiObj) throws IOException {");
2186 // Write variables here if we have callbacks or enums or structs
2187 writeCountVarStructSkeleton(methods, intDecl);
2188 // Write variables here if we have callbacks or enums or structs
2189 println("int methodId = rmiObj.getMethodId();");
2190 // TODO: code the permission check here!
2191 println("switch (methodId) {");
2192 // Print methods and method Ids
2193 for (String method : methods) {
2194 String methodId = intDecl.getMethodId(method);
2195 int methodNumId = intDecl.getMethodNumId(method);
2196 print("case " + methodNumId + ": ___");
2197 String helperMethod = methodId;
2198 if (uniqueMethodIds.contains(methodId))
2199 helperMethod = helperMethod + methodNumId;
2201 uniqueMethodIds.add(methodId);
2202 print(helperMethod + "(");
2203 if (writeInputCountVarStructSkeleton(method, intDecl))
2204 println(", rmiObj); break;");
2206 println("rmiObj); break;");
2208 String method = "___initCallBack()";
2209 // Print case -9999 (callback handler) if callback exists
2210 if (callbackExist) {
2211 int methodId = intDecl.getHelperMethodNumId(method);
2212 println("case " + methodId + ": ___regCB(rmiObj); break;");
2214 writeMethodCallStructCallbackSkeleton(methods, intDecl);
2215 println("default: ");
2216 println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
2223 * generateJavaCallbackSkeletonClass() generate callback skeletons based on the methods list in Java
2225 public void generateJavaCallbackSkeletonClass() throws IOException {
2227 // Create a new directory
2228 String path = createDirectories(dir, subdir);
2229 for (String intface : mapIntfacePTH.keySet()) {
2230 // Open a new file to write into
2231 String newSkelClass = intface + "_CallbackSkeleton";
2232 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
2233 pw = new PrintWriter(new BufferedWriter(fw));
2234 // Pass in set of methods and get import classes
2235 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2236 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2237 List<String> methods = intDecl.getMethods();
2238 Set<String> importClasses = getImportClasses(methods, intDecl);
2239 List<String> stdImportClasses = getStandardJavaImportClasses();
2240 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
2241 printImportStatements(allImportClasses);
2242 // Find out if there are callback objects
2243 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
2244 boolean callbackExist = !callbackClasses.isEmpty();
2245 // Write class header
2247 println("public class " + newSkelClass + " implements " + intface + " {\n");
2249 writePropertiesJavaCallbackSkeleton(intface, callbackExist);
2250 // Write constructor
2251 writeConstructorJavaCallbackSkeleton(newSkelClass, intface);
2253 writeMethodJavaSkeleton(methods, intDecl, callbackClasses, true);
2254 // Write method helper
2255 writeMethodHelperJavaCallbackSkeleton(methods, intDecl, callbackClasses);
2256 // Write waitRequestInvokeMethod() - main loop
2257 writeJavaCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
2260 System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".java...");
2266 * HELPER: writeMethodCplusLocalInterface() writes the method of the local interface
2268 private void writeMethodCplusLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
2270 for (String method : methods) {
2272 List<String> methParams = intDecl.getMethodParams(method);
2273 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2274 print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2275 intDecl.getMethodId(method) + "(");
2276 for (int i = 0; i < methParams.size(); i++) {
2277 // Check for params with driver class types and exchange it
2278 // with its remote interface
2279 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
2280 paramType = checkAndGetCplusType(paramType);
2281 // Check for arrays - translate into vector in C++
2282 String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
2283 print(paramComplete);
2284 // Check if this is the last element (don't print a comma)
2285 if (i != methParams.size() - 1) {
2295 * HELPER: writeMethodCplusInterface() writes the method of the interface
2297 private void writeMethodCplusInterface(Collection<String> methods, InterfaceDecl intDecl) {
2299 for (String method : methods) {
2301 List<String> methParams = intDecl.getMethodParams(method);
2302 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2303 print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2304 intDecl.getMethodId(method) + "(");
2305 for (int i = 0; i < methParams.size(); i++) {
2306 // Check for params with driver class types and exchange it
2307 // with its remote interface
2308 String paramType = methPrmTypes.get(i);
2309 paramType = checkAndGetCplusType(paramType);
2310 // Check for arrays - translate into vector in C++
2311 String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
2312 print(paramComplete);
2313 // Check if this is the last element (don't print a comma)
2314 if (i != methParams.size() - 1) {
2324 * HELPER: generateEnumCplus() writes the enumeration declaration
2326 public void generateEnumCplus() throws IOException {
2328 // Create a new directory
2329 createDirectory(dir);
2330 for (String intface : mapIntfacePTH.keySet()) {
2331 // Get the right StructDecl
2332 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2333 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
2334 Set<String> enumTypes = enumDecl.getEnumDeclarations();
2335 // Iterate over enum declarations
2336 for (String enType : enumTypes) {
2337 // Open a new file to write into
2338 FileWriter fw = new FileWriter(dir + "/" + enType + ".hpp");
2339 pw = new PrintWriter(new BufferedWriter(fw));
2340 // Write file headers
2341 println("#ifndef _" + enType.toUpperCase() + "_HPP__");
2342 println("#define _" + enType.toUpperCase() + "_HPP__");
2343 println("enum " + enType + " {");
2344 List<String> enumMembers = enumDecl.getMembers(enType);
2345 for (int i = 0; i < enumMembers.size(); i++) {
2347 String member = enumMembers.get(i);
2349 // Check if this is the last element (don't print a comma)
2350 if (i != enumMembers.size() - 1)
2358 System.out.println("IoTCompiler: Generated enum " + enType + ".hpp...");
2365 * HELPER: generateStructCplus() writes the struct declaration
2367 public void generateStructCplus() throws IOException {
2369 // Create a new directory
2370 createDirectory(dir);
2371 for (String intface : mapIntfacePTH.keySet()) {
2372 // Get the right StructDecl
2373 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2374 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
2375 List<String> structTypes = structDecl.getStructTypes();
2376 // Iterate over enum declarations
2377 for (String stType : structTypes) {
2378 // Open a new file to write into
2379 FileWriter fw = new FileWriter(dir + "/" + stType + ".hpp");
2380 pw = new PrintWriter(new BufferedWriter(fw));
2381 // Write file headers
2382 println("#ifndef _" + stType.toUpperCase() + "_HPP__");
2383 println("#define _" + stType.toUpperCase() + "_HPP__");
2384 println("struct " + stType + " {");
2385 List<String> structMemberTypes = structDecl.getMemberTypes(stType);
2386 List<String> structMembers = structDecl.getMembers(stType);
2387 for (int i = 0; i < structMembers.size(); i++) {
2389 String memberType = structMemberTypes.get(i);
2390 String member = structMembers.get(i);
2391 String structTypeC = checkAndGetCplusType(memberType);
2392 String structComplete = checkAndGetCplusArray(structTypeC, member);
2393 println(structComplete + ";");
2398 System.out.println("IoTCompiler: Generated struct " + stType + ".hpp...");
2405 * generateCplusLocalInterfaces() writes the local interfaces and provides type-checking.
2407 * It needs to rewrite and exchange USERDEFINED types in input parameters of stub
2408 * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording.
2409 * The local interface has to be the input parameter for the stub and the stub
2410 * interface has to be the input parameter for the local class.
2412 public void generateCplusLocalInterfaces() throws IOException {
2414 // Create a new directory
2415 createDirectory(dir);
2416 for (String intface : mapIntfacePTH.keySet()) {
2417 // Open a new file to write into
2418 FileWriter fw = new FileWriter(dir + "/" + intface + ".hpp");
2419 pw = new PrintWriter(new BufferedWriter(fw));
2420 // Write file headers
2421 println("#ifndef _" + intface.toUpperCase() + "_HPP__");
2422 println("#define _" + intface.toUpperCase() + "_HPP__");
2423 println("#include <iostream>");
2424 // Pass in set of methods and get include classes
2425 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2426 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2427 List<String> methods = intDecl.getMethods();
2428 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
2429 printIncludeStatements(includeClasses); println("");
2430 println("using namespace std;\n");
2431 //writeStructCplus(structDecl);
2432 println("class " + intface); println("{");
2435 writeMethodCplusLocalInterface(methods, intDecl);
2439 System.out.println("IoTCompiler: Generated local interface " + intface + ".hpp...");
2445 * generateCPlusInterfaces() generate stub interfaces based on the methods list in C++
2447 * For C++ we use virtual classe as interface
2449 public void generateCPlusInterfaces() throws IOException {
2451 // Create a new directory
2452 String path = createDirectories(dir, subdir);
2453 for (String intface : mapIntfacePTH.keySet()) {
2455 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
2456 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
2458 // Open a new file to write into
2459 String newIntface = intMeth.getKey();
2460 FileWriter fw = new FileWriter(path + "/" + newIntface + ".hpp");
2461 pw = new PrintWriter(new BufferedWriter(fw));
2462 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2463 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2464 // Write file headers
2465 println("#ifndef _" + newIntface.toUpperCase() + "_HPP__");
2466 println("#define _" + newIntface.toUpperCase() + "_HPP__");
2467 println("#include <iostream>");
2468 // Pass in set of methods and get import classes
2469 Set<String> includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, intface, false);
2470 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
2471 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
2472 printIncludeStatements(allIncludeClasses); println("");
2473 println("using namespace std;\n");
2474 println("class " + newIntface);
2478 writeMethodCplusInterface(intMeth.getValue(), intDecl);
2482 System.out.println("IoTCompiler: Generated interface " + newIntface + ".hpp...");
2489 * HELPER: writeMethodCplusStub() writes the methods of the stub
2491 private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
2493 for (String method : methods) {
2495 List<String> methParams = intDecl.getMethodParams(method);
2496 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2497 print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2498 intDecl.getMethodId(method) + "(");
2499 boolean isCallbackMethod = false;
2500 String callbackType = null;
2501 for (int i = 0; i < methParams.size(); i++) {
2503 String paramType = methPrmTypes.get(i);
2504 // Check if this has callback object
2505 if (callbackClasses.contains(paramType)) {
2506 isCallbackMethod = true;
2507 callbackType = paramType;
2508 // Even if there're 2 callback arguments, we expect them to be of the same interface
2510 String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
2511 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
2512 print(methParamComplete);
2513 // Check if this is the last element (don't print a comma)
2514 if (i != methParams.size() - 1) {
2519 if (isCallbackMethod)
2520 writeCallbackMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType);
2522 writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method);
2524 // Write the init callback helper method
2525 if (isCallbackMethod) {
2526 writeInitCallbackCplusStub(callbackType, intDecl);
2527 writeInitCallbackSendInfoCplusStub(intDecl);
2534 * HELPER: writeCallbackMethodBodyCplusStub() writes the callback method of the stub class
2536 private void writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
2537 List<String> methPrmTypes, String method, String callbackType) {
2539 // Check if this is single object, array, or list of objects
2540 boolean isArrayOrList = false;
2541 String callbackParam = null;
2542 for (int i = 0; i < methParams.size(); i++) {
2544 String paramType = methPrmTypes.get(i);
2545 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2546 String param = methParams.get(i);
2547 if (isArrayOrList(paramType, param)) { // Generate loop
2548 println("for (" + paramType + "* cb : " + getSimpleIdentifier(param) + ") {");
2549 println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
2550 isArrayOrList = true;
2551 callbackParam = getSimpleIdentifier(param);
2553 println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(" +
2554 getSimpleIdentifier(param) + ", objIdCnt++);");
2555 println("vecCallbackObj.push_back(skel);");
2556 if (isArrayOrList(paramType, param))
2560 println("int numParam = " + methParams.size() + ";");
2561 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
2562 String retType = intDecl.getMethodType(method);
2563 String retTypeC = checkAndGetCplusType(retType);
2564 println("string retType = \"" + checkAndGetCplusArrayType(retTypeC) + "\";");
2565 // Generate array of parameter types
2566 print("string paramCls[] = { ");
2567 for (int i = 0; i < methParams.size(); i++) {
2568 String paramType = methPrmTypes.get(i);
2569 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2571 } else { // Generate normal classes if it's not a callback object
2572 String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
2573 String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
2574 print("\"" + prmType + "\"");
2576 if (i != methParams.size() - 1) // Check if this is the last element
2580 print("int ___paramCB = ");
2582 println(callbackParam + ".size();");
2585 // Generate array of parameter objects
2586 print("void* paramObj[] = { ");
2587 for (int i = 0; i < methParams.size(); i++) {
2588 String paramType = methPrmTypes.get(i);
2589 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2590 print("&___paramCB");
2592 print(getSimpleIdentifier(methParams.get(i)));
2593 if (i != methParams.size() - 1)
2597 // Check if this is "void"
2598 if (retType.equals("void")) {
2599 println("void* retObj = NULL;");
2600 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2601 } else { // We do have a return value
2602 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2603 println(checkAndGetCplusType(retType) + " retVal;");
2605 println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
2606 println("void* retObj = &retVal;");
2607 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2608 println("return retVal;");
2614 * HELPER: checkAndWriteEnumTypeCplusStub() writes the enum type (convert from enum to int)
2616 private void checkAndWriteEnumTypeCplusStub(List<String> methParams, List<String> methPrmTypes) {
2618 // Iterate and find enum declarations
2619 for (int i = 0; i < methParams.size(); i++) {
2620 String paramType = methPrmTypes.get(i);
2621 String param = methParams.get(i);
2622 String simpleType = getSimpleType(paramType);
2623 if (isEnumClass(simpleType)) {
2624 // Check if this is enum type
2625 if (isArrayOrList(paramType, param)) { // An array or vector
2626 println("int len" + i + " = " + param + ".size();");
2627 println("vector<int> paramEnum" + i + "(len);");
2628 println("for (int i = 0; i < len" + i + "; i++) {");
2629 println("paramEnum" + i + "[i] = (int) " + param + "[i];");
2631 } else { // Just one element
2632 println("vector<int> paramEnum" + i + "(1);");
2633 println("paramEnum" + i + "[0] = (int) " + param + ";");
2641 * HELPER: checkAndWriteEnumRetTypeCplusStub() writes the enum return type (convert from enum to int)
2643 private void checkAndWriteEnumRetTypeCplusStub(String retType) {
2645 // Strips off array "[]" for return type
2646 String pureType = getSimpleArrayType(getSimpleType(retType));
2647 // Take the inner type of generic
2648 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2649 pureType = getTypeOfGeneric(retType)[0];
2650 if (isEnumClass(pureType)) {
2651 // Check if this is enum type
2652 println("vector<int> retEnumInt;");
2653 println("void* retObj = &retEnumInt;");
2654 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2655 if (isArrayOrList(retType, retType)) { // An array or vector
2656 println("int retLen = retEnumInt.size();");
2657 println("vector<" + pureType + "> retVal(retLen);");
2658 println("for (int i = 0; i < retLen; i++) {");
2659 println("retVal[i] = (" + pureType + ") retEnumInt[i];");
2661 } else { // Just one element
2662 println(pureType + " retVal = (" + pureType + ") retEnumInt[0];");
2664 println("return retVal;");
2670 * HELPER: checkAndWriteStructSetupCplusStub() writes the struct type setup
2672 private void checkAndWriteStructSetupCplusStub(List<String> methParams, List<String> methPrmTypes,
2673 InterfaceDecl intDecl, String method) {
2675 // Iterate and find struct declarations
2676 for (int i = 0; i < methParams.size(); i++) {
2677 String paramType = methPrmTypes.get(i);
2678 String param = methParams.get(i);
2679 String simpleType = getSimpleType(paramType);
2680 if (isStructClass(simpleType)) {
2681 // Check if this is enum type
2682 println("int numParam" + i + " = 1;");
2683 int methodNumId = intDecl.getMethodNumId(method);
2684 String helperMethod = methodNumId + "struct" + i;
2685 println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
2686 println("string retTypeStruct" + i + " = \"void\";");
2687 println("string paramClsStruct" + i + "[] = { \"int\" };");
2688 print("int structLen" + i + " = ");
2689 if (isArrayOrList(param, paramType)) { // An array
2690 println(getSimpleArrayType(param) + ".size();");
2691 } else { // Just one element
2694 println("void* paramObjStruct" + i + "[] = { &structLen" + i + " };");
2695 println("void* retStructLen" + i + " = NULL;");
2696 println("rmiCall->remoteCall(objectId, methodIdStruct" + i +
2697 ", retTypeStruct" + i + ", paramClsStruct" + i + ", paramObjStruct" + i +
2698 ", numParam" + i + ", retStructLen" + i + ");\n");
2705 * HELPER: writeLengthStructParamClassCplusStub() writes lengths of params
2707 private void writeLengthStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes) {
2709 // Iterate and find struct declarations - count number of params
2710 for (int i = 0; i < methParams.size(); i++) {
2711 String paramType = methPrmTypes.get(i);
2712 String param = methParams.get(i);
2713 String simpleType = getGenericType(paramType);
2714 if (isStructClass(simpleType)) {
2715 int members = getNumOfMembers(simpleType);
2716 if (isArrayOrList(param, paramType)) { // An array
2717 String structLen = param + ".size()";
2718 print(members + "*" + structLen);
2720 print(Integer.toString(members));
2723 if (i != methParams.size() - 1) {
2731 * HELPER: writeStructMembersCplusStub() writes member parameters of struct
2733 private void writeStructMembersCplusStub(String simpleType, String paramType, String param) {
2735 // Get the struct declaration for this struct and generate initialization code
2736 StructDecl structDecl = getStructDecl(simpleType);
2737 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2738 List<String> members = structDecl.getMembers(simpleType);
2739 if (isArrayOrList(param, paramType)) { // An array or list
2740 println("for(int i = 0; i < " + param + ".size(); i++) {");
2742 if (isArrayOrList(param, paramType)) { // An array or list
2743 for (int i = 0; i < members.size(); i++) {
2744 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2745 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2746 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2747 print("paramObj[pos++] = &" + param + "[i].");
2748 print(getSimpleIdentifier(members.get(i)));
2752 } else { // Just one struct element
2753 for (int i = 0; i < members.size(); i++) {
2754 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2755 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2756 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2757 print("paramObj[pos++] = &" + param + ".");
2758 print(getSimpleIdentifier(members.get(i)));
2766 * HELPER: writeStructParamClassCplusStub() writes member parameters of struct
2768 private void writeStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes) {
2770 print("int numParam = ");
2771 writeLengthStructParamClassCplusStub(methParams, methPrmTypes);
2773 println("void* paramObj[numParam];");
2774 println("string paramCls[numParam];");
2775 println("int pos = 0;");
2776 // Iterate again over the parameters
2777 for (int i = 0; i < methParams.size(); i++) {
2778 String paramType = methPrmTypes.get(i);
2779 String param = methParams.get(i);
2780 String simpleType = getGenericType(paramType);
2781 if (isStructClass(simpleType)) {
2782 writeStructMembersCplusStub(simpleType, paramType, param);
2784 String prmTypeC = checkAndGetCplusType(methPrmTypes.get(i));
2785 String prmType = checkAndGetCplusArrayType(prmTypeC, methParams.get(i));
2786 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2787 print("paramObj[pos++] = &");
2788 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
2797 * HELPER: writeStructRetMembersCplusStub() writes member parameters of struct for return statement
2799 private void writeStructRetMembersCplusStub(String simpleType, String retType) {
2801 // Get the struct declaration for this struct and generate initialization code
2802 StructDecl structDecl = getStructDecl(simpleType);
2803 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2804 List<String> members = structDecl.getMembers(simpleType);
2805 if (isArrayOrList(retType, retType)) { // An array or list
2806 println("for(int i = 0; i < retLen; i++) {");
2808 if (isArrayOrList(retType, retType)) { // An array or list
2809 for (int i = 0; i < members.size(); i++) {
2810 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
2811 print("structRet[i]." + getSimpleIdentifier(members.get(i)));
2812 println(" = retParam" + i + "[i];");
2815 } else { // Just one struct element
2816 for (int i = 0; i < members.size(); i++) {
2817 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
2818 print("structRet." + getSimpleIdentifier(members.get(i)));
2819 println(" = retParam" + i + ";");
2822 println("return structRet;");
2827 * HELPER: writeStructReturnCplusStub() writes member parameters of struct for return statement
2829 private void writeStructReturnCplusStub(String simpleType, String retType) {
2831 // Minimum retLen is 1 if this is a single struct object
2832 println("int retLen = 0;");
2833 println("void* retLenObj = { &retLen };");
2834 // Handle the returned struct!!!
2835 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retLenObj);");
2836 int numMem = getNumOfMembers(simpleType);
2837 println("int numRet = " + numMem + "*retLen;");
2838 println("string retCls[numRet];");
2839 println("void* retObj[numRet];");
2840 StructDecl structDecl = getStructDecl(simpleType);
2841 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2842 List<String> members = structDecl.getMembers(simpleType);
2844 if (isArrayOrList(retType, retType)) { // An array or list
2845 for (int i = 0; i < members.size(); i++) {
2846 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2847 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2848 println(getSimpleType(getEnumType(prmType)) + " retParam" + i + "[retLen];");
2850 } else { // Just one struct element
2851 for (int i = 0; i < members.size(); i++) {
2852 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2853 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2854 println(getSimpleType(getEnumType(prmType)) + " retParam" + i + ";");
2857 println("int retPos = 0;");
2858 // Get the struct declaration for this struct and generate initialization code
2859 if (isArrayOrList(retType, retType)) { // An array or list
2860 println("for(int i = 0; i < retLen; i++) {");
2861 for (int i = 0; i < members.size(); i++) {
2862 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2863 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2864 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2865 println("retObj[retPos++] = &retParam" + i + "[i];");
2868 } else { // Just one struct element
2869 for (int i = 0; i < members.size(); i++) {
2870 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2871 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2872 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2873 println("retObj[retPos++] = &retParam" + i + ";");
2876 println("rmiCall->getStructObjects(retCls, numRet, retObj);");
2877 if (isArrayOrList(retType, retType)) { // An array or list
2878 println("vector<" + simpleType + "> structRet(retLen);");
2880 println(simpleType + " structRet;");
2881 writeStructRetMembersCplusStub(simpleType, retType);
2886 * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class
2888 private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
2889 List<String> methPrmTypes, String method) {
2891 checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method);
2892 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
2893 String retType = intDecl.getMethodType(method);
2894 String retTypeC = checkAndGetCplusType(retType);
2895 println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";");
2896 // Generate array of parameter types
2897 if (isStructPresent(methParams, methPrmTypes)) {
2898 writeStructParamClassCplusStub(methParams, methPrmTypes);
2900 println("int numParam = " + methParams.size() + ";");
2901 print("string paramCls[] = { ");
2902 for (int i = 0; i < methParams.size(); i++) {
2903 String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
2904 String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
2905 print("\"" + getEnumType(paramType) + "\"");
2906 // Check if this is the last element (don't print a comma)
2907 if (i != methParams.size() - 1) {
2912 checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes);
2913 // Generate array of parameter objects
2914 print("void* paramObj[] = { ");
2915 for (int i = 0; i < methParams.size(); i++) {
2916 print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
2917 // Check if this is the last element (don't print a comma)
2918 if (i != methParams.size() - 1) {
2924 // Check if this is "void"
2925 if (retType.equals("void")) {
2926 println("void* retObj = NULL;");
2927 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2928 } else { // We do have a return value
2929 // Generate array of parameter types
2930 if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
2931 writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType);
2933 // Check if the return value NONPRIMITIVES
2934 if (getParamCategory(retType) == ParamCategory.ENUM) {
2935 checkAndWriteEnumRetTypeCplusStub(retType);
2937 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2938 println(checkAndGetCplusType(retType) + " retVal;");
2940 println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
2941 println("void* retObj = &retVal;");
2942 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2943 println("return retVal;");
2951 * HELPER: writePropertiesCplusStub() writes the properties of the stub class
2953 private void writePropertiesCplusPermission(String intface) {
2955 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
2956 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
2957 String newIntface = intMeth.getKey();
2958 int newObjectId = mapNewIntfaceObjId.get(newIntface);
2959 println("const static int object" + newObjectId + "Id = " + newObjectId + ";");
2960 println("const static set<int> set" + newObjectId + "Allowed;");
2965 * HELPER: writePropertiesCplusStub() writes the properties of the stub class
2967 private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
2969 println("IoTRMICall *rmiCall;");
2970 //println("IoTRMIObject\t\t\t*rmiObj;");
2971 println("string address;");
2972 println("vector<int> ports;\n");
2973 // Get the object Id
2974 Integer objId = mapIntfaceObjId.get(intface);
2975 println("const static int objectId = " + objId + ";");
2976 mapNewIntfaceObjId.put(newIntface, objId);
2977 mapIntfaceObjId.put(intface, objId++);
2978 if (callbackExist) {
2979 // We assume that each class only has one callback interface for now
2980 Iterator it = callbackClasses.iterator();
2981 String callbackType = (String) it.next();
2982 println("// Callback properties");
2983 println("IoTRMIObject *rmiObj;");
2984 println("vector<" + callbackType + "*> vecCallbackObj;");
2985 println("static int objIdCnt;");
2986 // Generate permission stuff for callback stubs
2987 writePropertiesCplusPermission(callbackType);
2994 * HELPER: writeConstructorCplusStub() writes the constructor of the stub class
2996 private void writeConstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
2998 println(newStubClass +
2999 "(int _port, const char* _address, int _rev, bool* _bResult, vector<int> _ports) {");
3000 println("address = _address;");
3001 println("ports = _ports;");
3002 println("rmiCall = new IoTRMICall(_port, _address, _rev, _bResult);");
3003 if (callbackExist) {
3004 println("objIdCnt = 0;");
3005 Iterator it = callbackClasses.iterator();
3006 String callbackType = (String) it.next();
3007 println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
3008 println("th1.detach();");
3009 println("___regCB();");
3016 * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
3018 private void writeDeconstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3020 println("~" + newStubClass + "() {");
3021 println("if (rmiCall != NULL) {");
3022 println("delete rmiCall;");
3023 println("rmiCall = NULL;");
3025 if (callbackExist) {
3026 // We assume that each class only has one callback interface for now
3027 println("if (rmiObj != NULL) {");
3028 println("delete rmiObj;");
3029 println("rmiObj = NULL;");
3031 Iterator it = callbackClasses.iterator();
3032 String callbackType = (String) it.next();
3033 println("for(" + callbackType + "* cb : vecCallbackObj) {");
3034 println("delete cb;");
3035 println("cb = NULL;");
3044 * HELPER: writeCplusMethodCallbackPermission() writes permission checks in stub for callbacks
3046 private void writeCplusMethodCallbackPermission(String intface) {
3048 println("int methodId = IoTRMIObject::getMethodId(method);");
3049 // Get all the different stubs
3050 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3051 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3052 String newIntface = intMeth.getKey();
3053 int newObjectId = mapNewIntfaceObjId.get(newIntface);
3054 println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
3055 println("cerr << \"Callback object for " + intface + " is not allowed to access method: \" << methodId;");
3056 println("exit(-1);");
3063 * HELPER: writeInitCallbackCplusStub() writes the initialization of callback
3065 private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl) {
3067 println("void ___initCallBack() {");
3068 println("bool bResult = false;");
3069 println("rmiObj = new IoTRMIObject(ports[0], &bResult);");
3070 println("while (true) {");
3071 println("char* method = rmiObj->getMethodBytes();");
3072 writeCplusMethodCallbackPermission(intface);
3073 println("int objId = IoTRMIObject::getObjectId(method);");
3074 println("if (objId < vecCallbackObj.size()) { // Check if still within range");
3075 println(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface +
3076 "_CallbackSkeleton*> (vecCallbackObj.at(objId));");
3077 println("skel->invokeMethod(rmiObj);");
3078 println("} else {");
3079 println("cerr << \"Illegal object Id: \" << to_string(objId);");
3080 // TODO: perhaps need to change this into "throw" to make it cleaner (allow stack unfolding)
3081 println("exit(-1);");
3089 * HELPER: writeInitCallbackSendInfoCplusStub() writes the initialization (send info part) of callback
3091 private void writeInitCallbackSendInfoCplusStub(InterfaceDecl intDecl) {
3093 // Generate info sending part
3094 println("void ___regCB() {");
3095 println("int numParam = 3;");
3096 String method = "___initCallBack()";
3097 println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";");
3098 println("string retType = \"void\";");
3099 println("string paramCls[] = { \"int\", \"string\", \"int\" };");
3100 println("int rev = 0;");
3101 println("void* paramObj[] = { &ports[0], &address, &rev };");
3102 println("void* retObj = NULL;");
3103 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
3109 * generateCPlusStubClasses() generate stubs based on the methods list in C++
3111 public void generateCPlusStubClasses() throws IOException {
3113 // Create a new directory
3114 String path = createDirectories(dir, subdir);
3115 for (String intface : mapIntfacePTH.keySet()) {
3117 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3118 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3119 // Open a new file to write into
3120 String newIntface = intMeth.getKey();
3121 String newStubClass = newIntface + "_Stub";
3122 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
3123 pw = new PrintWriter(new BufferedWriter(fw));
3124 // Write file headers
3125 println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
3126 println("#define _" + newStubClass.toUpperCase() + "_HPP__");
3127 println("#include <iostream>");
3128 // Find out if there are callback objects
3129 Set<String> methods = intMeth.getValue();
3130 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
3131 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
3132 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
3133 boolean callbackExist = !callbackClasses.isEmpty();
3134 if (callbackExist) // Need thread library if this has callback
3135 println("#include <thread>");
3136 println("#include \"" + newIntface + ".hpp\""); println("");
3137 println("using namespace std;"); println("");
3138 println("class " + newStubClass + " : public " + newIntface); println("{");
3139 println("private:\n");
3140 writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses);
3141 println("public:\n");
3142 // Add default constructor and destructor
3143 println(newStubClass + "() { }"); println("");
3144 writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3145 writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3147 writeMethodCplusStub(methods, intDecl, callbackClasses);
3148 print("}"); println(";");
3150 writePermissionInitializationCplus(intface, newStubClass, intDecl);
3153 System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
3160 * HELPER: writePropertiesCplusCallbackStub() writes the properties of the stub class
3162 private void writePropertiesCplusCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
3164 println("IoTRMICall *rmiCall;");
3165 // Get the object Id
3166 println("static int objectId;");
3167 if (callbackExist) {
3168 // We assume that each class only has one callback interface for now
3169 Iterator it = callbackClasses.iterator();
3170 String callbackType = (String) it.next();
3171 println("// Callback properties");
3172 println("IoTRMIObject *rmiObj;");
3173 println("vector<" + callbackType + "*> vecCallbackObj;");
3174 println("static int objIdCnt;");
3175 // TODO: Need to initialize address and ports if we want to have callback-in-callback
3176 println("string address;");
3177 println("vector<int> ports;\n");
3178 writePropertiesCplusPermission(callbackType);
3185 * HELPER: writeConstructorCplusCallbackStub() writes the constructor of the stub class
3187 private void writeConstructorCplusCallbackStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3189 println(newStubClass + "(IoTRMICall* _rmiCall, int _objectId) {");
3190 println("objectId = _objectId;");
3191 println("rmiCall = _rmiCall;");
3192 if (callbackExist) {
3193 Iterator it = callbackClasses.iterator();
3194 String callbackType = (String) it.next();
3195 println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
3196 println("th1.detach();");
3197 println("___regCB();");
3204 * generateCPlusCallbackStubClasses() generate callback stubs based on the methods list in C++
3206 public void generateCPlusCallbackStubClasses() throws IOException {
3208 // Create a new directory
3209 String path = createDirectories(dir, subdir);
3210 for (String intface : mapIntfacePTH.keySet()) {
3212 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3213 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3214 // Open a new file to write into
3215 String newIntface = intMeth.getKey();
3216 String newStubClass = newIntface + "_CallbackStub";
3217 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
3218 pw = new PrintWriter(new BufferedWriter(fw));
3219 // Find out if there are callback objects
3220 Set<String> methods = intMeth.getValue();
3221 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
3222 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
3223 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
3224 boolean callbackExist = !callbackClasses.isEmpty();
3225 // Write file headers
3226 println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
3227 println("#define _" + newStubClass.toUpperCase() + "_HPP__");
3228 println("#include <iostream>");
3230 println("#include <thread>");
3231 println("#include \"" + newIntface + ".hpp\""); println("");
3232 println("using namespace std;"); println("");
3233 println("class " + newStubClass + " : public " + newIntface); println("{");
3234 println("private:\n");
3235 writePropertiesCplusCallbackStub(intface, newIntface, callbackExist, callbackClasses);
3236 println("public:\n");
3237 // Add default constructor and destructor
3238 println(newStubClass + "() { }"); println("");
3239 writeConstructorCplusCallbackStub(newStubClass, callbackExist, callbackClasses);
3240 writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3242 writeMethodCplusStub(methods, intDecl, callbackClasses);
3245 writePermissionInitializationCplus(intface, newStubClass, intDecl);
3248 System.out.println("IoTCompiler: Generated callback stub class " + newIntface + ".hpp...");
3255 * HELPER: writePropertiesCplusSkeleton() writes the properties of the skeleton class
3257 private void writePropertiesCplusSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
3259 println(intface + " *mainObj;");
3261 if (callbackExist) {
3262 Iterator it = callbackClasses.iterator();
3263 String callbackType = (String) it.next();
3264 String exchangeType = checkAndGetParamClass(callbackType);
3265 println("// Callback properties");
3266 println("static int objIdCnt;");
3267 println("vector<" + exchangeType + "*> vecCallbackObj;");
3268 println("IoTRMICall *rmiCall;");
3270 println("IoTRMIObject *rmiObj;\n");
3271 // Keep track of object Ids of all stubs registered to this interface
3272 writePropertiesCplusPermission(intface);
3278 * HELPER: writePermissionInitializationCplus() writes the initialization of permission set
3280 private void writePermissionInitializationCplus(String intface, String newSkelClass, InterfaceDecl intDecl) {
3282 // Keep track of object Ids of all stubs registered to this interface
3283 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3284 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3285 String newIntface = intMeth.getKey();
3286 int newObjectId = mapNewIntfaceObjId.get(newIntface);
3287 print("const set<int> " + newSkelClass + "::set" + newObjectId + "Allowed {");
3288 Set<String> methodIds = intMeth.getValue();
3290 for (String methodId : methodIds) {
3291 int methodNumId = intDecl.getMethodNumId(methodId);
3292 print(Integer.toString(methodNumId));
3293 // Check if this is the last element (don't print a comma)
3294 if (i != methodIds.size() - 1) {
3305 * HELPER: writeConstructorCplusSkeleton() writes the constructor of the skeleton class
3307 private void writeConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist) {
3309 println(newSkelClass + "(" + intface + " *_mainObj, int _port) {");
3310 println("bool _bResult = false;");
3311 println("mainObj = _mainObj;");
3312 println("rmiObj = new IoTRMIObject(_port, &_bResult);");
3314 if (callbackExist) {
3315 println("objIdCnt = 0;");
3317 //println("set0Allowed = Arrays.asList(object0Permission);");
3318 println("___waitRequestInvokeMethod();");
3324 * HELPER: writeDeconstructorCplusSkeleton() writes the deconstructor of the skeleton class
3326 private void writeDeconstructorCplusSkeleton(String newSkelClass, boolean callbackExist, Set<String> callbackClasses) {
3328 println("~" + newSkelClass + "() {");
3329 println("if (rmiObj != NULL) {");
3330 println("delete rmiObj;");
3331 println("rmiObj = NULL;");
3333 if (callbackExist) {
3334 // We assume that each class only has one callback interface for now
3335 println("if (rmiCall != NULL) {");
3336 println("delete rmiCall;");
3337 println("rmiCall = NULL;");
3339 Iterator it = callbackClasses.iterator();
3340 String callbackType = (String) it.next();
3341 String exchangeType = checkAndGetParamClass(callbackType);
3342 println("for(" + exchangeType + "* cb : vecCallbackObj) {");
3343 println("delete cb;");
3344 println("cb = NULL;");
3353 * HELPER: writeStdMethodBodyCplusSkeleton() writes the standard method body in the skeleton class
3355 private void writeStdMethodBodyCplusSkeleton(List<String> methParams, String methodId, String methodType) {
3357 if (methodType.equals("void"))
3358 print("mainObj->" + methodId + "(");
3360 print("return mainObj->" + methodId + "(");
3361 for (int i = 0; i < methParams.size(); i++) {
3363 print(getSimpleIdentifier(methParams.get(i)));
3364 // Check if this is the last element (don't print a comma)
3365 if (i != methParams.size() - 1) {
3374 * HELPER: writeInitCallbackCplusSkeleton() writes the init callback method for skeleton class
3376 private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton) {
3378 // This is a callback skeleton generation
3379 if (callbackSkeleton)
3380 println("void ___regCB(IoTRMIObject* rmiObj) {");
3382 println("void ___regCB() {");
3383 println("int numParam = 3;");
3384 println("int param1 = 0;");
3385 println("string param2 = \"\";");
3386 println("int param3 = 0;");
3387 println("void* paramObj[] = { ¶m1, ¶m2, ¶m3 };");
3388 println("bool bResult = false;");
3389 println("rmiCall = new IoTRMICall(param1, param2.c_str(), param3, &bResult);");
3395 * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
3397 private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
3398 Set<String> callbackClasses, boolean callbackSkeleton) {
3400 for (String method : methods) {
3402 List<String> methParams = intDecl.getMethodParams(method);
3403 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3404 String methodId = intDecl.getMethodId(method);
3405 String methodType = checkAndGetCplusType(intDecl.getMethodType(method));
3406 print(methodType + " " + methodId + "(");
3407 boolean isCallbackMethod = false;
3408 String callbackType = null;
3409 for (int i = 0; i < methParams.size(); i++) {
3411 String origParamType = methPrmTypes.get(i);
3412 if (callbackClasses.contains(origParamType)) { // Check if this has callback object
3413 isCallbackMethod = true;
3414 callbackType = origParamType;
3416 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
3417 String methPrmType = checkAndGetCplusType(paramType);
3418 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
3419 print(methParamComplete);
3420 // Check if this is the last element (don't print a comma)
3421 if (i != methParams.size() - 1) {
3426 // Now, write the body of skeleton!
3427 writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method));
3429 if (isCallbackMethod)
3430 writeInitCallbackCplusSkeleton(callbackSkeleton);
3436 * HELPER: writeCallbackCplusNumStubs() writes the numStubs variable
3438 private void writeCallbackCplusNumStubs(List<String> methParams, List<String> methPrmTypes, String callbackType) {
3440 for (int i = 0; i < methParams.size(); i++) {
3441 String paramType = methPrmTypes.get(i);
3442 String param = methParams.get(i);
3443 //if (callbackType.equals(paramType)) {
3444 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
3445 String exchParamType = checkAndGetParamClass(paramType);
3446 // Print array if this is array or list if this is a list of callback objects
3447 println("int numStubs" + i + " = 0;");
3454 * HELPER: writeCallbackCplusStubGeneration() writes the callback stub generation part
3456 private void writeCallbackCplusStubGeneration(List<String> methParams, List<String> methPrmTypes, String callbackType) {
3458 // Iterate over callback objects
3459 for (int i = 0; i < methParams.size(); i++) {
3460 String paramType = methPrmTypes.get(i);
3461 String param = methParams.get(i);
3462 // Generate a loop if needed
3463 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
3464 String exchParamType = checkAndGetParamClass(paramType);
3465 if (isArrayOrList(paramType, param)) {
3466 println("vector<" + exchParamType + "> stub;");
3467 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
3468 println(exchParamType + "* cb" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
3469 println("stub" + i + ".push_back(cb);");
3470 println("vecCallbackObj.push_back(cb);");
3471 println("objIdCnt++;");
3474 println(exchParamType + "* stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
3475 println("vecCallbackObj.push_back(stub" + i + ");");
3476 println("objIdCnt++;");
3484 * HELPER: checkAndWriteEnumTypeCplusSkeleton() writes the enum type (convert from enum to int)
3486 private void checkAndWriteEnumTypeCplusSkeleton(List<String> methParams, List<String> methPrmTypes) {
3488 // Iterate and find enum declarations
3489 for (int i = 0; i < methParams.size(); i++) {
3490 String paramType = methPrmTypes.get(i);
3491 String param = methParams.get(i);
3492 String simpleType = getSimpleType(paramType);
3493 if (isEnumClass(simpleType)) {
3494 // Check if this is enum type
3495 if (isArrayOrList(paramType, param)) { // An array
3496 println("int len" + i + " = paramEnumInt" + i + ".size();");
3497 println("vector<" + simpleType + "> paramEnum" + i + "(len" + i + ");");
3498 println("for (int i=0; i < len" + i + "; i++) {");
3499 println("paramEnum" + i + "[i] = (" + simpleType + ") paramEnumInt" + i + "[i];");
3501 } else { // Just one element
3502 println(simpleType + " paramEnum" + i + ";");
3503 println("paramEnum" + i + " = (" + simpleType + ") paramEnumInt" + i + "[0];");
3511 * HELPER: checkAndWriteEnumRetTypeCplusSkeleton() writes the enum return type (convert from enum to int)
3513 private void checkAndWriteEnumRetTypeCplusSkeleton(String retType) {
3515 // Strips off array "[]" for return type
3516 String pureType = getSimpleArrayType(getSimpleType(retType));
3517 // Take the inner type of generic
3518 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
3519 pureType = getTypeOfGeneric(retType)[0];
3520 if (isEnumClass(pureType)) {
3521 // Check if this is enum type
3523 if (isArrayOrList(retType, retType)) { // An array
3524 println("int retLen = retEnum.size();");
3525 println("vector<int> retEnumInt(retLen);");
3526 println("for (int i=0; i < retLen; i++) {");
3527 println("retEnumInt[i] = (int) retEnum[i];");
3529 } else { // Just one element
3530 println("vector<int> retEnumInt(1);");
3531 println("retEnumInt[0] = (int) retEnum;");
3538 * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton
3540 private void writeMethodInputParameters(List<String> methParams, List<String> methPrmTypes,
3541 Set<String> callbackClasses, String methodId) {
3543 print(methodId + "(");
3544 for (int i = 0; i < methParams.size(); i++) {
3545 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3546 if (callbackClasses.contains(paramType))
3548 else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
3549 print("paramEnum" + i);
3550 else if (isStructClass(getSimpleType(paramType))) // Struct type
3551 print("paramStruct" + i);
3553 print(getSimpleIdentifier(methParams.get(i)));
3554 if (i != methParams.size() - 1) {
3563 * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton
3565 private void writeMethodHelperReturnCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3566 List<String> methPrmTypes, String method, boolean isCallbackMethod, String callbackType,
3567 String methodId, Set<String> callbackClasses) {
3569 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3570 if (isCallbackMethod)
3571 writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType);
3572 checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes);
3573 writeStructMembersInitCplusSkeleton(intDecl, methParams, methPrmTypes, method);
3574 // Check if this is "void"
3575 String retType = intDecl.getMethodType(method);
3576 // Check if this is "void"
3577 if (retType.equals("void")) {
3578 writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
3579 } else { // We do have a return value
3580 if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type
3581 print(checkAndGetCplusType(retType) + " retEnum = ");
3582 else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3583 print(checkAndGetCplusType(retType) + " retStruct = ");
3585 print(checkAndGetCplusType(retType) + " retVal = ");
3586 writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
3587 checkAndWriteEnumRetTypeCplusSkeleton(retType);
3588 if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3589 writeStructReturnCplusSkeleton(getSimpleArrayType(getSimpleType(retType)), retType);
3590 if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type
3591 println("void* retObj = &retEnumInt;");
3593 if (!isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3594 println("void* retObj = &retVal;");
3595 String retTypeC = checkAndGetCplusType(retType);
3596 if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3597 println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);");
3599 println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");");
3605 * HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class
3607 private void writeStdMethodHelperBodyCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3608 List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
3610 // Generate array of parameter types
3611 boolean isCallbackMethod = false;
3612 String callbackType = null;
3613 print("string paramCls[] = { ");
3614 for (int i = 0; i < methParams.size(); i++) {
3615 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3616 if (callbackClasses.contains(paramType)) {
3617 isCallbackMethod = true;
3618 callbackType = paramType;
3620 } else { // Generate normal classes if it's not a callback object
3621 String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
3622 String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
3623 print("\"" + getEnumType(prmType) + "\"");
3625 if (i != methParams.size() - 1) {
3630 println("int numParam = " + methParams.size() + ";");
3631 if (isCallbackMethod)
3632 writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType);
3633 // Generate parameters
3634 for (int i = 0; i < methParams.size(); i++) {
3635 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3636 if (!callbackClasses.contains(paramType)) {
3637 String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
3638 if (isEnumClass(getSimpleType(methPrmType))) { // Check if this is enum type
3639 println("vector<int> paramEnumInt" + i + ";");
3641 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
3642 //println(methParamComplete + " = " + generateCplusInitializer(methPrmType) + ";");
3643 println(methParamComplete + ";");
3647 // Generate array of parameter objects
3648 print("void* paramObj[] = { ");
3649 for (int i = 0; i < methParams.size(); i++) {
3650 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3651 if (callbackClasses.contains(paramType))
3652 print("&numStubs" + i);
3653 else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
3654 print("¶mEnumInt" + i);
3656 print("&" + getSimpleIdentifier(methParams.get(i)));
3657 if (i != methParams.size() - 1) {
3662 // Write the return value part
3663 writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
3664 callbackType, methodId, callbackClasses);
3669 * HELPER: writeStructMembersCplusSkeleton() writes member parameters of struct
3671 private void writeStructMembersCplusSkeleton(String simpleType, String paramType,
3672 String param, String method, InterfaceDecl intDecl, int iVar) {
3674 // Get the struct declaration for this struct and generate initialization code
3675 StructDecl structDecl = getStructDecl(simpleType);
3676 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3677 List<String> members = structDecl.getMembers(simpleType);
3678 int methodNumId = intDecl.getMethodNumId(method);
3679 String counter = "struct" + methodNumId + "Size" + iVar;
3680 if (isArrayOrList(param, paramType)) { // An array or list
3681 println("for(int i = 0; i < " + counter + "; i++) {");
3684 if (isArrayOrList(param, paramType)) { // An array or list
3685 for (int i = 0; i < members.size(); i++) {
3686 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3687 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3688 println(getSimpleType(getEnumType(prmType)) + " param" + i + "[" + counter + "];");
3690 } else { // Just one struct element
3691 for (int i = 0; i < members.size(); i++) {
3692 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3693 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3694 println(getSimpleType(getEnumType(prmType)) + " param" + i + ";");
3697 println("int pos = 0;");
3698 if (isArrayOrList(param, paramType)) { // An array or list
3699 println("for(int i = 0; i < retLen; i++) {");
3700 for (int i = 0; i < members.size(); i++) {
3701 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3702 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3703 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3704 println("paramObj[pos++] = ¶m" + i + "[i];");
3707 } else { // Just one struct element
3708 for (int i = 0; i < members.size(); i++) {
3709 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3710 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3711 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3712 println("paramObj[pos++] = ¶m" + i + ";");
3719 * HELPER: writeStructMembersInitCplusSkeleton() writes member parameters initialization of struct
3721 private void writeStructMembersInitCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3722 List<String> methPrmTypes, String method) {
3724 for (int i = 0; i < methParams.size(); i++) {
3725 String paramType = methPrmTypes.get(i);
3726 String param = methParams.get(i);
3727 String simpleType = getGenericType(paramType);
3728 if (isStructClass(simpleType)) {
3729 int methodNumId = intDecl.getMethodNumId(method);
3730 String counter = "struct" + methodNumId + "Size" + i;
3732 if (isArrayOrList(param, paramType)) { // An array or list
3733 println("vector<" + simpleType + "> paramStruct" + i + ";");
3735 println(simpleType + " paramStruct" + i + ";");
3736 // Initialize members
3737 StructDecl structDecl = getStructDecl(simpleType);
3738 List<String> members = structDecl.getMembers(simpleType);
3739 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3740 if (isArrayOrList(param, paramType)) { // An array or list
3741 println("for(int i = 0; i < " + counter + "; i++) {");
3742 for (int j = 0; j < members.size(); j++) {
3743 print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j)));
3744 println(" = param" + j + "[i];");
3747 } else { // Just one struct element
3748 for (int j = 0; j < members.size(); j++) {
3749 print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j)));
3750 println(" = param" + j + ";");
3759 * HELPER: writeStructReturnCplusSkeleton() writes parameters of struct for return statement
3761 private void writeStructReturnCplusSkeleton(String simpleType, String retType) {
3763 // Minimum retLen is 1 if this is a single struct object
3764 if (isArrayOrList(retType, retType))
3765 println("int retLen = retStruct.size();");
3766 else // Just single struct object
3767 println("int retLen = 1;");
3768 println("void* retLenObj = &retLen;");
3769 println("rmiObj->sendReturnObj(retLenObj, \"int\");");
3770 int numMem = getNumOfMembers(simpleType);
3771 println("int numRetObj = " + numMem + "*retLen;");
3772 println("string retCls[numRetObj];");
3773 println("void* retObj[numRetObj];");
3774 println("int retPos = 0;");
3775 // Get the struct declaration for this struct and generate initialization code
3776 StructDecl structDecl = getStructDecl(simpleType);
3777 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3778 List<String> members = structDecl.getMembers(simpleType);
3779 if (isArrayOrList(retType, retType)) { // An array or list
3780 println("for(int i = 0; i < retLen; i++) {");
3781 for (int i = 0; i < members.size(); i++) {
3782 String paramTypeC = checkAndGetCplusType(memTypes.get(i));
3783 String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i));
3784 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3785 print("retObj[retPos++] = &retStruct[i].");
3786 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
3790 } else { // Just one struct element
3791 for (int i = 0; i < members.size(); i++) {
3792 String paramTypeC = checkAndGetCplusType(memTypes.get(i));
3793 String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i));
3794 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3795 print("retObj[retPos++] = &retStruct.");
3796 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
3805 * HELPER: writeMethodHelperStructCplusSkeleton() writes the struct in skeleton
3807 private void writeMethodHelperStructCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3808 List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
3810 // Generate array of parameter objects
3811 boolean isCallbackMethod = false;
3812 String callbackType = null;
3813 print("int numParam = ");
3814 writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
3816 println("string paramCls[numParam];");
3817 println("void* paramObj[numParam];");
3818 // Iterate again over the parameters
3819 for (int i = 0; i < methParams.size(); i++) {
3820 String paramType = methPrmTypes.get(i);
3821 String param = methParams.get(i);
3822 String simpleType = getGenericType(paramType);
3823 if (isStructClass(simpleType)) {
3824 writeStructMembersCplusSkeleton(simpleType, paramType, param, method, intDecl, i);
3826 String prmType = returnGenericCallbackType(methPrmTypes.get(i));
3827 if (callbackClasses.contains(prmType)) {
3828 isCallbackMethod = true;
3829 callbackType = paramType;
3830 writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType);
3831 println("paramCls[pos] = \"int\";");
3832 println("paramObj[pos++] = &numStubs" + i + ";");
3833 } else { // Generate normal classes if it's not a callback object
3834 String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
3835 String prmTypeC = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
3836 if (isEnumClass(getSimpleType(paramTypeC))) { // Check if this is enum type
3837 println("vector<int> paramEnumInt" + i + ";");
3839 String methParamComplete = checkAndGetCplusArray(paramTypeC, methParams.get(i));
3840 println(methParamComplete + ";");
3842 println("paramCls[pos] = \"" + getEnumType(prmTypeC) + "\";");
3843 if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
3844 println("paramObj[pos++] = ¶mEnumInt" + i);
3846 println("paramObj[pos++] = &" + getSimpleIdentifier(methParams.get(i)) + ";");
3850 // Write the return value part
3851 writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
3852 callbackType, methodId, callbackClasses);
3857 * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
3859 private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
3861 // Use this set to handle two same methodIds
3862 Set<String> uniqueMethodIds = new HashSet<String>();
3863 for (String method : methods) {
3865 List<String> methParams = intDecl.getMethodParams(method);
3866 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3867 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
3868 String methodId = intDecl.getMethodId(method);
3870 String helperMethod = methodId;
3871 if (uniqueMethodIds.contains(methodId))
3872 helperMethod = helperMethod + intDecl.getMethodNumId(method);
3874 uniqueMethodIds.add(methodId);
3875 String retType = intDecl.getMethodType(method);
3876 print(helperMethod + "(");
3877 boolean begin = true;
3878 for (int i = 0; i < methParams.size(); i++) { // Print size variables
3879 String paramType = methPrmTypes.get(i);
3880 String param = methParams.get(i);
3881 String simpleType = getSimpleType(paramType);
3882 if (isStructClass(simpleType)) {
3883 if (!begin) { // Generate comma for not the beginning variable
3884 print(", "); begin = false;
3886 int methodNumId = intDecl.getMethodNumId(method);
3887 print("int struct" + methodNumId + "Size" + i);
3891 writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
3894 String methodId = intDecl.getMethodId(method);
3896 String helperMethod = methodId;
3897 if (uniqueMethodIds.contains(methodId))
3898 helperMethod = helperMethod + intDecl.getMethodNumId(method);
3900 uniqueMethodIds.add(methodId);
3901 // Check if this is "void"
3902 String retType = intDecl.getMethodType(method);
3903 println(helperMethod + "() {");
3904 // Now, write the helper body of skeleton!
3905 writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
3909 // Write method helper for structs
3910 writeMethodHelperStructSetupCplusSkeleton(methods, intDecl);
3915 * HELPER: writeMethodHelperStructSetupCplusSkeleton() writes the method helper of struct in skeleton class
3917 private void writeMethodHelperStructSetupCplusSkeleton(Collection<String> methods,
3918 InterfaceDecl intDecl) {
3920 // Use this set to handle two same methodIds
3921 for (String method : methods) {
3923 List<String> methParams = intDecl.getMethodParams(method);
3924 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3925 // Check for params with structs
3926 for (int i = 0; i < methParams.size(); i++) {
3927 String paramType = methPrmTypes.get(i);
3928 String param = methParams.get(i);
3929 String simpleType = getSimpleType(paramType);
3930 if (isStructClass(simpleType)) {
3931 int methodNumId = intDecl.getMethodNumId(method);
3933 String helperMethod = methodNumId + "struct" + i;
3934 println(helperMethod + "() {");
3935 // Now, write the helper body of skeleton!
3936 println("string paramCls[] = { \"int\" };");
3937 println("int numParam = 1;");
3938 println("int param0 = 0;");
3939 println("void* paramObj[] = { ¶m0 };");
3940 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3941 println("return param0;");
3950 * HELPER: writeMethodHelperStructSetupCplusCallbackSkeleton() writes the method helper of struct in skeleton class
3952 private void writeMethodHelperStructSetupCplusCallbackSkeleton(Collection<String> methods,
3953 InterfaceDecl intDecl) {
3955 // Use this set to handle two same methodIds
3956 for (String method : methods) {
3958 List<String> methParams = intDecl.getMethodParams(method);
3959 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3960 // Check for params with structs
3961 for (int i = 0; i < methParams.size(); i++) {
3962 String paramType = methPrmTypes.get(i);
3963 String param = methParams.get(i);
3964 String simpleType = getSimpleType(paramType);
3965 if (isStructClass(simpleType)) {
3966 int methodNumId = intDecl.getMethodNumId(method);
3968 String helperMethod = methodNumId + "struct" + i;
3969 println(helperMethod + "(IoTRMIObject* rmiObj) {");
3970 // Now, write the helper body of skeleton!
3971 println("string paramCls[] = { \"int\" };");
3972 println("int numParam = 1;");
3973 println("int param0 = 0;");
3974 println("void* paramObj[] = { ¶m0 };");
3975 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3976 println("return param0;");
3985 * HELPER: writeCplusMethodPermission() writes permission checks in skeleton
3987 private void writeCplusMethodPermission(String intface) {
3989 // Get all the different stubs
3990 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3991 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3992 String newIntface = intMeth.getKey();
3993 int newObjectId = mapNewIntfaceObjId.get(newIntface);
3994 println("if (_objectId == object" + newObjectId + "Id) {");
3995 println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
3996 println("cerr << \"Object with object Id: \" << _objectId << \" is not allowed to access method: \" << methodId << endl;");
3997 println("exit(-1);");
4001 println("cerr << \"Object Id: \" << _objectId << \" not recognized!\" << endl;");
4002 println("exit(-1);");
4009 * HELPER: writeCplusWaitRequestInvokeMethod() writes the main loop of the skeleton class
4011 private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
4013 // Use this set to handle two same methodIds
4014 Set<String> uniqueMethodIds = new HashSet<String>();
4015 println("void ___waitRequestInvokeMethod() {");
4016 // Write variables here if we have callbacks or enums or structs
4017 writeCountVarStructSkeleton(methods, intDecl);
4018 println("while (true) {");
4019 println("rmiObj->getMethodBytes();");
4020 println("int _objectId = rmiObj->getObjectId();");
4021 println("int methodId = rmiObj->getMethodId();");
4022 // Generate permission check
4023 writeCplusMethodPermission(intface);
4024 println("switch (methodId) {");
4025 // Print methods and method Ids
4026 for (String method : methods) {
4027 String methodId = intDecl.getMethodId(method);
4028 int methodNumId = intDecl.getMethodNumId(method);
4029 print("case " + methodNumId + ": ___");
4030 String helperMethod = methodId;
4031 if (uniqueMethodIds.contains(methodId))
4032 helperMethod = helperMethod + methodNumId;
4034 uniqueMethodIds.add(methodId);
4035 print(helperMethod + "(");
4036 writeInputCountVarStructSkeleton(method, intDecl);
4037 println("); break;");
4039 String method = "___initCallBack()";
4040 // Print case -9999 (callback handler) if callback exists
4041 if (callbackExist) {
4042 int methodId = intDecl.getHelperMethodNumId(method);
4043 println("case " + methodId + ": ___regCB(); break;");
4045 writeMethodCallStructSkeleton(methods, intDecl);
4046 println("default: ");
4047 println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
4048 println("throw exception();");
4056 * generateCplusSkeletonClass() generate skeletons based on the methods list in C++
4058 public void generateCplusSkeletonClass() throws IOException {
4060 // Create a new directory
4061 String path = createDirectories(dir, subdir);
4062 for (String intface : mapIntfacePTH.keySet()) {
4063 // Open a new file to write into
4064 String newSkelClass = intface + "_Skeleton";
4065 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
4066 pw = new PrintWriter(new BufferedWriter(fw));
4067 // Write file headers
4068 println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
4069 println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
4070 println("#include <iostream>");
4071 println("#include \"" + intface + ".hpp\"\n");
4072 // Pass in set of methods and get import classes
4073 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4074 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
4075 List<String> methods = intDecl.getMethods();
4076 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
4077 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
4078 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
4079 printIncludeStatements(allIncludeClasses); println("");
4080 println("using namespace std;\n");
4081 // Find out if there are callback objects
4082 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
4083 boolean callbackExist = !callbackClasses.isEmpty();
4084 // Write class header
4085 println("class " + newSkelClass + " : public " + intface); println("{");
4086 println("private:\n");
4088 writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses);
4089 println("public:\n");
4090 // Write constructor
4091 writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist);
4092 // Write deconstructor
4093 writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
4095 writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false);
4096 // Write method helper
4097 writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses);
4098 // Write waitRequestInvokeMethod() - main loop
4099 writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
4101 writePermissionInitializationCplus(intface, newSkelClass, intDecl);
4104 System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
4110 * HELPER: writePropertiesCplusCallbackSkeleton() writes the properties of the callback skeleton class
4112 private void writePropertiesCplusCallbackSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
4114 println(intface + " *mainObj;");
4115 // Keep track of object Ids of all stubs registered to this interface
4116 println("static int objectId;");
4118 if (callbackExist) {
4119 Iterator it = callbackClasses.iterator();
4120 String callbackType = (String) it.next();
4121 String exchangeType = checkAndGetParamClass(callbackType);
4122 println("// Callback properties");
4123 println("IoTRMICall* rmiCall;");
4124 println("vector<" + exchangeType + "*> vecCallbackObj;");
4125 println("static int objIdCnt;");
4132 * HELPER: writeConstructorCplusCallbackSkeleton() writes the constructor of the skeleton class
4134 private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface, boolean callbackExist) {
4136 println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {");
4137 println("mainObj = _mainObj;");
4138 println("objectId = _objectId;");
4140 if (callbackExist) {
4141 println("objIdCnt = 0;");
4148 * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
4150 private void writeDeconstructorCplusCallbackSkeleton(String newStubClass, boolean callbackExist,
4151 Set<String> callbackClasses) {
4153 println("~" + newStubClass + "() {");
4154 if (callbackExist) {
4155 // We assume that each class only has one callback interface for now
4156 println("if (rmiCall != NULL) {");
4157 println("delete rmiCall;");
4158 println("rmiCall = NULL;");
4160 Iterator it = callbackClasses.iterator();
4161 String callbackType = (String) it.next();
4162 String exchangeType = checkAndGetParamClass(callbackType);
4163 println("for(" + exchangeType + "* cb : vecCallbackObj) {");
4164 println("delete cb;");
4165 println("cb = NULL;");
4174 * HELPER: writeMethodHelperCplusCallbackSkeleton() writes the method helper of callback skeleton class
4176 private void writeMethodHelperCplusCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl,
4177 Set<String> callbackClasses) {
4179 // Use this set to handle two same methodIds
4180 Set<String> uniqueMethodIds = new HashSet<String>();
4181 for (String method : methods) {
4183 List<String> methParams = intDecl.getMethodParams(method);
4184 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4185 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
4186 String methodId = intDecl.getMethodId(method);
4188 String helperMethod = methodId;
4189 if (uniqueMethodIds.contains(methodId))
4190 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4192 uniqueMethodIds.add(methodId);
4193 String retType = intDecl.getMethodType(method);
4194 print(helperMethod + "(");
4195 boolean begin = true;
4196 for (int i = 0; i < methParams.size(); i++) { // Print size variables
4197 String paramType = methPrmTypes.get(i);
4198 String param = methParams.get(i);
4199 String simpleType = getSimpleType(paramType);
4200 if (isStructClass(simpleType)) {
4201 if (!begin) { // Generate comma for not the beginning variable
4202 print(", "); begin = false;
4204 int methodNumId = intDecl.getMethodNumId(method);
4205 print("int struct" + methodNumId + "Size" + i);
4208 println(", IoTRMIObject* rmiObj) {");
4209 writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4212 String methodId = intDecl.getMethodId(method);
4214 String helperMethod = methodId;
4215 if (uniqueMethodIds.contains(methodId))
4216 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4218 uniqueMethodIds.add(methodId);
4219 // Check if this is "void"
4220 String retType = intDecl.getMethodType(method);
4221 println(helperMethod + "(IoTRMIObject* rmiObj) {");
4222 // Now, write the helper body of skeleton!
4223 writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4227 // Write method helper for structs
4228 writeMethodHelperStructSetupCplusCallbackSkeleton(methods, intDecl);
4233 * HELPER: writeCplusCallbackWaitRequestInvokeMethod() writes the request invoke method of the skeleton callback class
4235 private void writeCplusCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl,
4236 boolean callbackExist) {
4238 // Use this set to handle two same methodIds
4239 Set<String> uniqueMethodIds = new HashSet<String>();
4240 println("void invokeMethod(IoTRMIObject* rmiObj) {");
4241 // Write variables here if we have callbacks or enums or structs
4242 writeCountVarStructSkeleton(methods, intDecl);
4243 // Write variables here if we have callbacks or enums or structs
4244 println("int methodId = rmiObj->getMethodId();");
4245 // TODO: code the permission check here!
4246 println("switch (methodId) {");
4247 // Print methods and method Ids
4248 for (String method : methods) {
4249 String methodId = intDecl.getMethodId(method);
4250 int methodNumId = intDecl.getMethodNumId(method);
4251 print("case " + methodNumId + ": ___");
4252 String helperMethod = methodId;
4253 if (uniqueMethodIds.contains(methodId))
4254 helperMethod = helperMethod + methodNumId;
4256 uniqueMethodIds.add(methodId);
4257 print(helperMethod + "(");
4258 if (writeInputCountVarStructSkeleton(method, intDecl))
4259 println(", rmiObj); break;");
4261 println("rmiObj); break;");
4263 String method = "___initCallBack()";
4264 // Print case -9999 (callback handler) if callback exists
4265 if (callbackExist) {
4266 int methodId = intDecl.getHelperMethodNumId(method);
4267 println("case " + methodId + ": ___regCB(rmiObj); break;");
4269 writeMethodCallStructCallbackSkeleton(methods, intDecl);
4270 println("default: ");
4271 println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
4272 println("throw exception();");
4279 * generateCplusCallbackSkeletonClass() generate callback skeletons based on the methods list in C++
4281 public void generateCplusCallbackSkeletonClass() throws IOException {
4283 // Create a new directory
4284 String path = createDirectories(dir, subdir);
4285 for (String intface : mapIntfacePTH.keySet()) {
4286 // Open a new file to write into
4287 String newSkelClass = intface + "_CallbackSkeleton";
4288 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
4289 pw = new PrintWriter(new BufferedWriter(fw));
4290 // Write file headers
4291 println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
4292 println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
4293 println("#include <iostream>");
4294 println("#include \"" + intface + ".hpp\"\n");
4295 // Pass in set of methods and get import classes
4296 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4297 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
4298 List<String> methods = intDecl.getMethods();
4299 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
4300 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
4301 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
4302 printIncludeStatements(allIncludeClasses); println("");
4303 // Find out if there are callback objects
4304 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
4305 boolean callbackExist = !callbackClasses.isEmpty();
4306 println("using namespace std;\n");
4307 // Write class header
4308 println("class " + newSkelClass + " : public " + intface); println("{");
4309 println("private:\n");
4311 writePropertiesCplusCallbackSkeleton(intface, callbackExist, callbackClasses);
4312 println("public:\n");
4313 // Write constructor
4314 writeConstructorCplusCallbackSkeleton(newSkelClass, intface, callbackExist);
4315 // Write deconstructor
4316 writeDeconstructorCplusCallbackSkeleton(newSkelClass, callbackExist, callbackClasses);
4318 writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true);
4319 // Write method helper
4320 writeMethodHelperCplusCallbackSkeleton(methods, intDecl, callbackClasses);
4321 // Write waitRequestInvokeMethod() - main loop
4322 writeCplusCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
4326 System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".hpp...");
4332 * generateInitializer() generate initializer based on type
4334 public String generateCplusInitializer(String type) {
4336 // Generate dummy returns for now
4337 if (type.equals("short")||
4338 type.equals("int") ||
4339 type.equals("long") ||
4340 type.equals("float")||
4341 type.equals("double")) {
4344 } else if ( type.equals("String") ||
4345 type.equals("string")) {
4348 } else if ( type.equals("char") ||
4349 type.equals("byte")) {
4352 } else if ( type.equals("boolean")) {
4362 * setDirectory() sets a new directory for stub files
4364 public void setDirectory(String _subdir) {
4371 * printUsage() prints the usage of this compiler
4373 public static void printUsage() {
4375 System.out.println();
4376 System.out.println("Sentinel interface and stub compiler version 1.0");
4377 System.out.println("Copyright (c) 2015-2016 University of California, Irvine - Programming Language Group.");
4378 System.out.println("All rights reserved.");
4379 System.out.println("Usage:");
4380 System.out.println("\tjava IoTCompiler -help / --help / -h\n");
4381 System.out.println("\t\tDisplay this help texts\n\n");
4382 System.out.println("\tjava IoTCompiler [<main-policy-file> <req-policy-file>]");
4383 System.out.println("\tjava IoTCompiler [<main-policy-file> <req-policy-file>] [options]\n");
4384 System.out.println("\t\tTake one or more pairs of main-req policy files, and generate Java and/or C++ files\n");
4385 System.out.println("Options:");
4386 System.out.println("\t-java\t<directory>\tGenerate Java stub files");
4387 System.out.println("\t-cplus\t<directory>\tGenerate C++ stub files");
4388 System.out.println();
4393 * parseFile() prepares Lexer and Parser objects, then parses the file
4395 public static ParseNode parseFile(String file) {
4397 ParseNode pn = null;
4399 ComplexSymbolFactory csf = new ComplexSymbolFactory();
4400 ScannerBuffer lexer =
4401 new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(file)),csf));
4402 Parser parse = new Parser(lexer,csf);
4403 pn = (ParseNode) parse.parse().value;
4404 } catch (Exception e) {
4405 e.printStackTrace();
4406 throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file);
4414 * Basic helper functions
4417 boolean newline=true;
4420 private void print(String str) {
4423 if (str.equals("}"))
4425 for(int i=0; i<tab; i++)
4435 * This function converts Java to C++ type for compilation
4437 private String convertType(String jType) {
4439 return mapPrimitives.get(jType);
4444 * A collection of methods with print-to-file functionality
4446 private void println(String str) {
4449 if (str.contains("}") && !str.contains("{"))
4451 for(int i=0; i<tab; i++)
4460 private void updatetabbing(String str) {
4462 tablevel+=count(str,'{')-count(str,'}');
4466 private int count(String str, char key) {
4467 char[] array = str.toCharArray();
4469 for(int i=0; i<array.length; i++) {
4470 if (array[i] == key)
4477 private void createDirectory(String dirName) {
4479 File file = new File(dirName);
4480 if (!file.exists()) {
4482 System.out.println("IoTCompiler: Directory " + dirName + " has been created!");
4484 System.out.println("IoTCompiler: Failed to create directory " + dirName + "!");
4487 System.out.println("IoTCompiler: Directory " + dirName + " exists...");
4492 // Create a directory and possibly a sub directory
4493 private String createDirectories(String dir, String subdir) {
4496 createDirectory(path);
4497 if (subdir != null) {
4498 path = path + "/" + subdir;
4499 createDirectory(path);
4505 // Inserting array members into a Map object
4506 // that maps arrKey to arrVal objects
4507 private void arraysToMap(Map map, Object[] arrKey, Object[] arrVal) {
4509 for(int i = 0; i < arrKey.length; i++) {
4511 map.put(arrKey[i], arrVal[i]);
4516 // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, USERDEFINED, ENUM, or STRUCT
4517 private ParamCategory getParamCategory(String paramType) {
4519 if (mapPrimitives.containsKey(paramType)) {
4520 return ParamCategory.PRIMITIVES;
4521 // We can either use mapNonPrimitivesJava or mapNonPrimitivesCplus here
4522 } else if (mapNonPrimitivesJava.containsKey(getSimpleType(paramType))) {
4523 return ParamCategory.NONPRIMITIVES;
4524 } else if (isEnumClass(paramType)) {
4525 return ParamCategory.ENUM;
4526 } else if (isStructClass(paramType)) {
4527 return ParamCategory.STRUCT;
4529 return ParamCategory.USERDEFINED;
4533 // Return full class name for non-primitives to generate Java import statements
4534 // e.g. java.util.Set for Set
4535 private String getNonPrimitiveJavaClass(String paramNonPrimitives) {
4537 return mapNonPrimitivesJava.get(paramNonPrimitives);
4541 // Return full class name for non-primitives to generate Cplus include statements
4542 // e.g. #include <set> for Set
4543 private String getNonPrimitiveCplusClass(String paramNonPrimitives) {
4545 return mapNonPrimitivesCplus.get(paramNonPrimitives);
4549 // Get simple types, e.g. HashSet for HashSet<...>
4550 // Basically strip off the "<...>"
4551 private String getSimpleType(String paramType) {
4553 // Check if this is generics
4554 if(paramType.contains("<")) {
4555 String[] type = paramType.split("<");
4562 // Generate a set of standard classes for import statements
4563 private List<String> getStandardJavaImportClasses() {
4565 List<String> importClasses = new ArrayList<String>();
4566 // Add the standard list first
4567 importClasses.add("java.io.IOException");
4568 importClasses.add("java.util.List");
4569 importClasses.add("java.util.ArrayList");
4570 importClasses.add("java.util.Arrays");
4571 importClasses.add("iotrmi.Java.IoTRMICall");
4572 importClasses.add("iotrmi.Java.IoTRMIObject");
4574 return importClasses;
4578 // Generate a set of standard classes for import statements
4579 private List<String> getStandardCplusIncludeClasses() {
4581 List<String> importClasses = new ArrayList<String>();
4582 // Add the standard list first
4583 importClasses.add("<vector>");
4584 importClasses.add("<set>");
4585 importClasses.add("\"IoTRMICall.hpp\"");
4586 importClasses.add("\"IoTRMIObject.hpp\"");
4588 return importClasses;
4592 // Combine all classes for import statements
4593 private List<String> getAllLibClasses(Collection<String> stdLibClasses, Collection<String> libClasses) {
4595 List<String> allLibClasses = new ArrayList<String>(stdLibClasses);
4596 // Iterate over the list of import classes
4597 for (String str : libClasses) {
4598 if (!allLibClasses.contains(str)) {
4599 allLibClasses.add(str);
4602 return allLibClasses;
4607 // Generate a set of classes for import statements
4608 private Set<String> getImportClasses(Collection<String> methods, InterfaceDecl intDecl) {
4610 Set<String> importClasses = new HashSet<String>();
4611 for (String method : methods) {
4612 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4613 for (String paramType : methPrmTypes) {
4615 String simpleType = getSimpleType(paramType);
4616 if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
4617 importClasses.add(getNonPrimitiveJavaClass(simpleType));
4621 return importClasses;
4625 // Handle and return the correct enum declaration
4626 // In Java, if we declare enum in Camera interface, then it becomes "Camera.<enum>"
4627 private String getEnumParamDecl(String type, InterfaceDecl intDecl) {
4629 // Strips off array "[]" for return type
4630 String pureType = getSimpleArrayType(type);
4631 // Take the inner type of generic
4632 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4633 pureType = getTypeOfGeneric(type)[0];
4634 if (isEnumClass(pureType)) {
4635 String enumType = intDecl.getInterface() + "." + type;
4642 // Handle and return the correct type
4643 private String getEnumParam(String type, String param, int i) {
4645 // Strips off array "[]" for return type
4646 String pureType = getSimpleArrayType(type);
4647 // Take the inner type of generic
4648 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4649 pureType = getTypeOfGeneric(type)[0];
4650 if (isEnumClass(pureType)) {
4651 String enumParam = "paramEnum" + i;
4658 // Handle and return the correct enum declaration translate into int[]
4659 private String getEnumType(String type) {
4661 // Strips off array "[]" for return type
4662 String pureType = getSimpleArrayType(type);
4663 // Take the inner type of generic
4664 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4665 pureType = getTypeOfGeneric(type)[0];
4666 if (isEnumClass(pureType)) {
4667 String enumType = "int[]";
4674 // Handle and return the correct struct declaration
4675 private String getStructType(String type) {
4677 // Strips off array "[]" for return type
4678 String pureType = getSimpleArrayType(type);
4679 // Take the inner type of generic
4680 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4681 pureType = getTypeOfGeneric(type)[0];
4682 if (isStructClass(pureType)) {
4683 String structType = "int";
4690 // Check if this an enum declaration
4691 private boolean isEnumClass(String type) {
4693 // Just iterate over the set of interfaces
4694 for (String intface : mapIntfacePTH.keySet()) {
4695 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4696 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
4697 Set<String> setEnumDecl = enumDecl.getEnumDeclarations();
4698 if (setEnumDecl.contains(type))
4705 // Check if this an struct declaration
4706 private boolean isStructClass(String type) {
4708 // Just iterate over the set of interfaces
4709 for (String intface : mapIntfacePTH.keySet()) {
4710 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4711 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4712 List<String> listStructDecl = structDecl.getStructTypes();
4713 if (listStructDecl.contains(type))
4720 // Return a struct declaration
4721 private StructDecl getStructDecl(String type) {
4723 // Just iterate over the set of interfaces
4724 for (String intface : mapIntfacePTH.keySet()) {
4725 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4726 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4727 List<String> listStructDecl = structDecl.getStructTypes();
4728 if (listStructDecl.contains(type))
4735 // Return number of members (-1 if not found)
4736 private int getNumOfMembers(String type) {
4738 // Just iterate over the set of interfaces
4739 for (String intface : mapIntfacePTH.keySet()) {
4740 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4741 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4742 List<String> listStructDecl = structDecl.getStructTypes();
4743 if (listStructDecl.contains(type))
4744 return structDecl.getNumOfMembers(type);
4750 // Generate a set of classes for include statements
4751 private Set<String> getIncludeClasses(Collection<String> methods, InterfaceDecl intDecl, String intface, boolean needExchange) {
4753 Set<String> includeClasses = new HashSet<String>();
4754 for (String method : methods) {
4756 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4757 List<String> methParams = intDecl.getMethodParams(method);
4758 for (int i = 0; i < methPrmTypes.size(); i++) {
4760 String simpleType = getSimpleType(methPrmTypes.get(i));
4761 String param = methParams.get(i);
4762 if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
4763 includeClasses.add("<" + getNonPrimitiveCplusClass(simpleType) + ">");
4764 } else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) {
4765 // For original interface, we need it exchanged... not for stub interfaces
4767 includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
4768 includeClasses.add("\"" + exchangeParamType(simpleType) + "_CallbackStub.hpp\"");
4770 includeClasses.add("\"" + simpleType + ".hpp\"");
4771 includeClasses.add("\"" + simpleType + "_CallbackSkeleton.hpp\"");
4773 } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.ENUM) {
4774 includeClasses.add("\"" + simpleType + ".hpp\"");
4775 } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.STRUCT) {
4776 includeClasses.add("\"" + simpleType + ".hpp\"");
4777 } else if (param.contains("[]")) {
4778 // Check if this is array for C++; translate into vector
4779 includeClasses.add("<vector>");
4783 return includeClasses;
4787 // Generate a set of callback classes
4788 private Set<String> getCallbackClasses(Collection<String> methods, InterfaceDecl intDecl) {
4790 Set<String> callbackClasses = new HashSet<String>();
4791 for (String method : methods) {
4793 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4794 List<String> methParams = intDecl.getMethodParams(method);
4795 for (int i = 0; i < methPrmTypes.size(); i++) {
4797 String type = methPrmTypes.get(i);
4798 if (getParamCategory(type) == ParamCategory.USERDEFINED) {
4799 callbackClasses.add(type);
4800 } else if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) {
4801 // Can be a List<...> of callback objects ...
4802 String genericType = getTypeOfGeneric(type)[0];
4803 if (getParamCategory(type) == ParamCategory.USERDEFINED) {
4804 callbackClasses.add(type);
4809 return callbackClasses;
4813 // Print import statements into file
4814 private void printImportStatements(Collection<String> importClasses) {
4816 for(String cls : importClasses) {
4817 println("import " + cls + ";");
4822 // Print include statements into file
4823 private void printIncludeStatements(Collection<String> includeClasses) {
4825 for(String cls : includeClasses) {
4826 println("#include " + cls);
4831 // Get the C++ version of a non-primitive type
4832 // e.g. set for Set and map for Map
4833 // Input nonPrimitiveType has to be generics in format
4834 private String[] getTypeOfGeneric(String nonPrimitiveType) {
4836 // Handle <, >, and , for 2-type generic/template
4837 String[] substr = nonPrimitiveType.split("<")[1].split(">")[0].split(",");
4842 // Gets generic type inside "<" and ">"
4843 private String getGenericType(String type) {
4845 // Handle <, >, and , for 2-type generic/template
4846 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) {
4847 String[] substr = type.split("<")[1].split(">")[0].split(",");
4854 // This helper function strips off array declaration, e.g. int[] becomes int
4855 private String getSimpleArrayType(String type) {
4857 // Handle [ for array declaration
4858 String substr = type;
4859 if (type.contains("[]")) {
4860 substr = type.split("\\[\\]")[0];
4866 // This helper function strips off array declaration, e.g. D[] becomes D
4867 private String getSimpleIdentifier(String ident) {
4869 // Handle [ for array declaration
4870 String substr = ident;
4871 if (ident.contains("[]")) {
4872 substr = ident.split("\\[\\]")[0];
4878 // Checks and gets type in C++
4879 private String checkAndGetCplusType(String paramType) {
4881 if (getParamCategory(paramType) == ParamCategory.PRIMITIVES) {
4882 return convertType(paramType);
4883 } else if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES) {
4885 // Check for generic/template format
4886 if (paramType.contains("<") && paramType.contains(">")) {
4888 String genericClass = getSimpleType(paramType);
4889 String[] genericType = getTypeOfGeneric(paramType);
4890 String cplusTemplate = null;
4891 if (genericType.length == 1) // Generic/template with one type
4892 cplusTemplate = getNonPrimitiveCplusClass(genericClass) +
4893 "<" + convertType(genericType[0]) + ">";
4894 else // Generic/template with two types
4895 cplusTemplate = getNonPrimitiveCplusClass(genericClass) +
4896 "<" + convertType(genericType[0]) + "," + convertType(genericType[1]) + ">";
4897 return cplusTemplate;
4899 return getNonPrimitiveCplusClass(paramType);
4900 } else if(paramType.contains("[]")) { // Array type (used for return type only)
4901 String cArray = "vector<" + getSimpleArrayType(paramType) + ">";
4903 } else if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
4904 return paramType + "*";
4906 // Just return it as is if it's not non-primitives
4908 //return checkAndGetParamClass(paramType, true);
4912 // Detect array declaration, e.g. int A[],
4913 // then generate "int A[]" in C++ as "vector<int> A"
4914 private String checkAndGetCplusArray(String paramType, String param) {
4916 String paramComplete = null;
4917 // Check for array declaration
4918 if (param.contains("[]")) {
4919 paramComplete = "vector<" + paramType + "> " + param.replace("[]","");
4921 // Just return it as is if it's not an array
4922 paramComplete = paramType + " " + param;
4924 return paramComplete;
4928 // Detect array declaration, e.g. int A[],
4929 // then generate "int A[]" in C++ as "vector<int> A"
4930 // This method just returns the type
4931 private String checkAndGetCplusArrayType(String paramType) {
4933 String paramTypeRet = null;
4934 // Check for array declaration
4935 if (paramType.contains("[]")) {
4936 String type = paramType.split("\\[\\]")[0];
4937 paramTypeRet = checkAndGetCplusType(type) + "[]";
4938 } else if (paramType.contains("vector")) {
4939 // Just return it as is if it's not an array
4940 String type = paramType.split("<")[1].split(">")[0];
4941 paramTypeRet = checkAndGetCplusType(type) + "[]";
4943 paramTypeRet = paramType;
4945 return paramTypeRet;
4949 // Detect array declaration, e.g. int A[],
4950 // then generate "int A[]" in C++ as "vector<int> A"
4951 // This method just returns the type
4952 private String checkAndGetCplusArrayType(String paramType, String param) {
4954 String paramTypeRet = null;
4955 // Check for array declaration
4956 if (param.contains("[]")) {
4957 paramTypeRet = checkAndGetCplusType(paramType) + "[]";
4958 } else if (paramType.contains("vector")) {
4959 // Just return it as is if it's not an array
4960 String type = paramType.split("<")[1].split(">")[0];
4961 paramTypeRet = checkAndGetCplusType(type) + "[]";
4963 paramTypeRet = paramType;
4965 return paramTypeRet;
4969 // Detect array declaration, e.g. int A[],
4970 // then generate type "int[]"
4971 private String checkAndGetArray(String paramType, String param) {
4973 String paramTypeRet = null;
4974 // Check for array declaration
4975 if (param.contains("[]")) {
4976 paramTypeRet = paramType + "[]";
4978 // Just return it as is if it's not an array
4979 paramTypeRet = paramType;
4981 return paramTypeRet;
4985 // Is array or list?
4986 private boolean isArrayOrList(String paramType, String param) {
4988 // Check for array declaration
4991 else if (isList(paramType))
4999 // For return type we use retType as input parameter
5000 private boolean isArray(String param) {
5002 // Check for array declaration
5003 if (param.contains("[]"))
5011 private boolean isList(String paramType) {
5013 // Check for array declaration
5014 if (paramType.contains("List"))
5021 // Get the right type for a callback object
5022 private String checkAndGetParamClass(String paramType) {
5024 // Check if this is generics
5025 if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
5026 return exchangeParamType(paramType);
5032 // Returns the other interface for type-checking purposes for USERDEFINED
5033 // classes based on the information provided in multiple policy files
5034 // e.g. return CameraWithXXX instead of Camera
5035 private String exchangeParamType(String intface) {
5037 // Param type that's passed is the interface name we need to look for
5038 // in the map of interfaces, based on available policy files.
5039 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
5040 if (decHandler != null) {
5041 // We've found the required interface policy files
5042 RequiresDecl reqDecl = (RequiresDecl) decHandler.getRequiresDecl(intface);
5043 Set<String> setExchInt = reqDecl.getInterfaces();
5044 if (setExchInt.size() == 1) {
5045 Iterator iter = setExchInt.iterator();
5046 return (String) iter.next();
5048 throw new Error("IoTCompiler: Ambiguous stub interfaces: " + setExchInt.toString() +
5049 ". Only one new interface can be declared if the object " + intface +
5050 " needs to be passed in as an input parameter!");
5053 // NULL value - this means policy files missing
5054 throw new Error("IoTCompiler: Parameter type lookup failed for " + intface +
5055 "... Please provide the necessary policy files for user-defined types." +
5056 " If this is an array please type the brackets after the variable name," +
5057 " e.g. \"String str[]\", not \"String[] str\"." +
5058 " If this is a Collections (Java) / STL (C++) type, this compiler only" +
5059 " supports List/ArrayList (Java) or list (C++).");
5064 public static void main(String[] args) throws Exception {
5066 // If there is no argument or just "--help" or "-h", then invoke printUsage()
5067 if ((args[0].equals("-help") ||
5068 args[0].equals("--help")||
5069 args[0].equals("-h")) ||
5070 (args.length == 0)) {
5072 IoTCompiler.printUsage();
5074 } else if (args.length > 1) {
5076 IoTCompiler comp = new IoTCompiler();
5079 // Parse main policy file
5080 ParseNode pnPol = IoTCompiler.parseFile(args[i]);
5081 // Parse "requires" policy file
5082 ParseNode pnReq = IoTCompiler.parseFile(args[i+1]);
5083 // Get interface name
5084 String intface = ParseTreeHandler.getOrigIntface(pnPol);
5085 comp.setDataStructures(intface, pnPol, pnReq);
5086 comp.getMethodsForIntface(intface);
5088 // 1) Check if this is the last option before "-java" or "-cplus"
5089 // 2) Check if this is really the last option (no "-java" or "-cplus")
5090 } while(!args[i].equals("-java") &&
5091 !args[i].equals("-cplus") &&
5094 // Generate everything if we don't see "-java" or "-cplus"
5095 if (i == args.length) {
5096 comp.generateEnumJava();
5097 comp.generateStructJava();
5098 comp.generateJavaLocalInterfaces();
5099 comp.generateJavaInterfaces();
5100 comp.generateJavaStubClasses();
5101 comp.generateJavaCallbackStubClasses();
5102 comp.generateJavaSkeletonClass();
5103 comp.generateJavaCallbackSkeletonClass();
5104 comp.generateEnumCplus();
5105 comp.generateStructCplus();
5106 comp.generateCplusLocalInterfaces();
5107 comp.generateCPlusInterfaces();
5108 comp.generateCPlusStubClasses();
5109 comp.generateCPlusCallbackStubClasses();
5110 comp.generateCplusSkeletonClass();
5111 comp.generateCplusCallbackSkeletonClass();
5113 // Check other options
5114 while(i < args.length) {
5116 if (!args[i].equals("-java") &&
5117 !args[i].equals("-cplus")) {
5118 throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i]);
5120 if (i + 1 < args.length) {
5121 comp.setDirectory(args[i+1]);
5123 throw new Error("IoTCompiler: ERROR - please provide <directory> after option: " + args[i]);
5125 if (args[i].equals("-java")) {
5126 comp.generateEnumJava();
5127 comp.generateStructJava();
5128 comp.generateJavaLocalInterfaces();
5129 comp.generateJavaInterfaces();
5130 comp.generateJavaStubClasses();
5131 comp.generateJavaCallbackStubClasses();
5132 comp.generateJavaSkeletonClass();
5133 comp.generateJavaCallbackSkeletonClass();
5135 comp.generateEnumCplus();
5136 comp.generateStructCplus();
5137 comp.generateCplusLocalInterfaces();
5138 comp.generateCPlusInterfaces();
5139 comp.generateCPlusStubClasses();
5140 comp.generateCPlusCallbackStubClasses();
5141 comp.generateCplusSkeletonClass();
5142 comp.generateCplusCallbackSkeletonClass();
5149 // Need to at least have exactly 2 parameters, i.e. main policy file and requires file
5150 IoTCompiler.printUsage();
5151 throw new Error("IoTCompiler: At least two arguments (main and requires policy files) have to be provided!");