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 List<String> stdImportClasses = getStandardJavaIntfaceImportClasses();
331 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
332 printImportStatements(allImportClasses);
333 // Write interface header
335 println("public interface " + intface + " {");
337 writeMethodJavaLocalInterface(methods, intDecl);
340 System.out.println("IoTCompiler: Generated local interface " + intface + ".java...");
346 * generateJavaInterfaces() generate stub interfaces based on the methods list in Java
348 public void generateJavaInterfaces() throws IOException {
350 // Create a new directory
351 String path = createDirectories(dir, subdir);
352 for (String intface : mapIntfacePTH.keySet()) {
354 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
355 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
357 // Open a new file to write into
358 String newIntface = intMeth.getKey();
359 FileWriter fw = new FileWriter(path + "/" + newIntface + ".java");
360 pw = new PrintWriter(new BufferedWriter(fw));
361 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
362 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
363 // Pass in set of methods and get import classes
364 List<String> methods = intDecl.getMethods();
365 Set<String> importClasses = getImportClasses(methods, intDecl);
366 List<String> stdImportClasses = getStandardJavaIntfaceImportClasses();
367 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
368 printImportStatements(allImportClasses);
369 // Write interface header
371 println("public interface " + newIntface + " {\n");
373 writeMethodJavaInterface(methods, intDecl);
376 System.out.println("IoTCompiler: Generated interface " + newIntface + ".java...");
383 * HELPER: writePropertiesJavaPermission() writes the permission in properties
385 private void writePropertiesJavaPermission(String intface, InterfaceDecl intDecl) {
387 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
388 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
389 String newIntface = intMeth.getKey();
390 int newObjectId = mapNewIntfaceObjId.get(newIntface);
391 println("private final static int object" + newObjectId + "Id = " +
392 newObjectId + ";\t//" + newIntface);
393 Set<String> methodIds = intMeth.getValue();
394 print("private static Integer[] object" + newObjectId + "Permission = { ");
396 for (String methodId : methodIds) {
397 int methodNumId = intDecl.getMethodNumId(methodId);
398 print(Integer.toString(methodNumId));
399 // Check if this is the last element (don't print a comma)
400 if (i != methodIds.size() - 1) {
406 println("private List<Integer> set" + newObjectId + "Allowed;");
412 * HELPER: writePropertiesJavaStub() writes the properties of the stub class
414 private void writePropertiesJavaStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
416 println("private IoTRMICall rmiCall;");
417 println("private String address;");
418 println("private int[] ports;\n");
420 Integer objId = mapIntfaceObjId.get(intface);
421 println("private final static int objectId = " + objId + ";");
422 mapNewIntfaceObjId.put(newIntface, objId);
423 mapIntfaceObjId.put(intface, objId++);
425 // We assume that each class only has one callback interface for now
426 Iterator it = callbackClasses.iterator();
427 String callbackType = (String) it.next();
428 println("// Callback properties");
429 println("private IoTRMIObject rmiObj;");
430 println("List<" + callbackType + "> listCallbackObj;");
431 println("private static int objIdCnt = 0;");
432 // Generate permission stuff for callback stubs
433 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
434 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
435 writePropertiesJavaPermission(callbackType, intDecl);
442 * HELPER: writeConstructorJavaPermission() writes the permission in constructor
444 private void writeConstructorJavaPermission(String intface) {
446 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
447 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
448 String newIntface = intMeth.getKey();
449 int newObjectId = mapNewIntfaceObjId.get(newIntface);
450 println("set" + newObjectId + "Allowed = Arrays.asList(object" + newObjectId +"Permission);");
456 * HELPER: writeConstructorJavaStub() writes the constructor of the stub class
458 private void writeConstructorJavaStub(String intface, String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
460 println("public " + newStubClass + "(int _port, String _address, int _rev, int[] _ports) throws Exception {");
461 println("address = _address;");
462 println("ports = _ports;");
463 println("rmiCall = new IoTRMICall(_port, _address, _rev);");
465 Iterator it = callbackClasses.iterator();
466 String callbackType = (String) it.next();
467 writeConstructorJavaPermission(intface);
468 println("listCallbackObj = new ArrayList<" + callbackType + ">();");
469 println("___initCallBack();");
476 * HELPER: writeJavaMethodCallbackPermission() writes permission checks in stub for callbacks
478 private void writeJavaMethodCallbackPermission(String intface) {
480 println("int methodId = IoTRMIObject.getMethodId(method);");
481 // Get all the different stubs
482 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
483 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
484 String newIntface = intMeth.getKey();
485 int newObjectId = mapNewIntfaceObjId.get(newIntface);
486 println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
487 println("throw new Error(\"Callback object for " + intface + " is not allowed to access method: \" + methodId);");
494 * HELPER: writeInitCallbackJavaStub() writes callback initialization in stub
496 private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl) {
498 println("public void ___initCallBack() {");
499 // Generate main thread for callbacks
500 println("Thread thread = new Thread() {");
501 println("public void run() {");
503 println("rmiObj = new IoTRMIObject(ports[0]);");
504 println("while (true) {");
505 println("byte[] method = rmiObj.getMethodBytes();");
506 writeJavaMethodCallbackPermission(intface);
507 println("int objId = IoTRMIObject.getObjectId(method);");
508 println(intface + "_CallbackSkeleton skel = (" + intface + "_CallbackSkeleton) listCallbackObj.get(objId);");
509 println("if (skel != null) {");
510 println("skel.invokeMethod(rmiObj);");
512 println("throw new Error(\"" + intface + ": Object with Id \" + objId + \" not found!\");");
515 println("} catch (Exception ex) {");
516 println("ex.printStackTrace();");
517 println("throw new Error(\"Error instantiating class " + intface + "_CallbackSkeleton!\");");
521 println("thread.start();\n");
522 // Generate info sending part
523 String method = "___initCallBack()";
524 println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";");
525 println("Class<?> retType = void.class;");
526 println("Class<?>[] paramCls = new Class<?>[] { int.class, String.class, int.class };");
527 println("Object[] paramObj = new Object[] { ports[0], address, 0 };");
528 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
534 * HELPER: checkAndWriteEnumTypeJavaStub() writes the enum type (convert from enum to int)
536 private void checkAndWriteEnumTypeJavaStub(List<String> methParams, List<String> methPrmTypes) {
538 // Iterate and find enum declarations
539 for (int i = 0; i < methParams.size(); i++) {
540 String paramType = methPrmTypes.get(i);
541 String param = methParams.get(i);
542 String simpleType = getSimpleType(paramType);
543 if (isEnumClass(simpleType)) {
544 // Check if this is enum type
545 if (isArray(param)) { // An array
546 println("int len" + i + " = " + param + ".length;");
547 println("int paramEnum" + i + "[] = new int[len];");
548 println("for (int i = 0; i < len" + i + "; i++) {");
549 println("paramEnum" + i + "[i] = " + param + "[i].ordinal();");
551 } else if (isList(paramType)) { // A list
552 println("int len" + i + " = " + param + ".size();");
553 println("int paramEnum" + i + "[] = new int[len];");
554 println("for (int i = 0; i < len" + i + "; i++) {");
555 println("paramEnum" + i + "[i] = " + param + ".get(i).ordinal();");
557 } else { // Just one element
558 println("int paramEnum" + i + "[] = new int[1];");
559 println("paramEnum" + i + "[0] = " + param + ".ordinal();");
567 * HELPER: checkAndWriteEnumRetTypeJavaStub() writes the enum return type (convert from enum to int)
569 private void checkAndWriteEnumRetTypeJavaStub(String retType) {
571 // Strips off array "[]" for return type
572 String pureType = getSimpleArrayType(getSimpleType(retType));
573 // Take the inner type of generic
574 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
575 pureType = getTypeOfGeneric(retType)[0];
576 if (isEnumClass(pureType)) {
577 // Check if this is enum type
579 println("int[] retEnum = (int[]) retObj;");
580 println(pureType + "[] enumVals = " + pureType + ".values();");
581 if (isArray(retType)) { // An array
582 println("int retLen = retEnum.length;");
583 println(pureType + "[] enumRetVal = new " + pureType + "[retLen];");
584 println("for (int i = 0; i < retLen; i++) {");
585 println("enumRetVal[i] = enumVals[retEnum[i]];");
587 } else if (isList(retType)) { // A list
588 println("int retLen = retEnum.length;");
589 println("List<" + pureType + "> enumRetVal = new ArrayList<" + pureType + ">();");
590 println("for (int i = 0; i < retLen; i++) {");
591 println("enumRetVal.add(enumVals[retEnum[i]]);");
593 } else { // Just one element
594 println(pureType + " enumRetVal = enumVals[retEnum[0]];");
596 println("return enumRetVal;");
602 * HELPER: checkAndWriteStructSetupJavaStub() writes the struct type setup
604 private void checkAndWriteStructSetupJavaStub(List<String> methParams, List<String> methPrmTypes,
605 InterfaceDecl intDecl, String method) {
607 // Iterate and find struct declarations
608 for (int i = 0; i < methParams.size(); i++) {
609 String paramType = methPrmTypes.get(i);
610 String param = methParams.get(i);
611 String simpleType = getSimpleType(paramType);
612 if (isStructClass(simpleType)) {
613 // Check if this is enum type
614 int methodNumId = intDecl.getMethodNumId(method);
615 String helperMethod = methodNumId + "struct" + i;
616 println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
617 println("Class<?> retTypeStruct" + i + " = void.class;");
618 println("Class<?>[] paramClsStruct" + i + " = new Class<?>[] { int.class };");
619 if (isArray(param)) { // An array
620 println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".length };");
621 } else if (isList(paramType)) { // A list
622 println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".size() };");
623 } else { // Just one element
624 println("Object[] paramObjStruct" + i + " = new Object[] { new Integer(1) };");
626 println("rmiCall.remoteCall(objectId, methodIdStruct" + i +
627 ", retTypeStruct" + i + ", null, paramClsStruct" + i +
628 ", paramObjStruct" + i + ");\n");
635 * HELPER: isStructPresent() checks presence of struct
637 private boolean isStructPresent(List<String> methParams, List<String> methPrmTypes) {
639 // Iterate and find enum declarations
640 for (int i = 0; i < methParams.size(); i++) {
641 String paramType = methPrmTypes.get(i);
642 String param = methParams.get(i);
643 String simpleType = getSimpleType(paramType);
644 if (isStructClass(simpleType))
652 * HELPER: writeLengthStructParamClassJavaStub() writes lengths of parameters
654 private void writeLengthStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
656 // Iterate and find struct declarations - count number of params
657 for (int i = 0; i < methParams.size(); i++) {
658 String paramType = methPrmTypes.get(i);
659 String param = methParams.get(i);
660 String simpleType = getGenericType(paramType);
661 if (isStructClass(simpleType)) {
662 int members = getNumOfMembers(simpleType);
663 if (isArray(param)) { // An array
664 String structLen = param + ".length";
665 print(members + "*" + structLen);
666 } else if (isList(paramType)) { // A list
667 String structLen = param + ".size()";
668 print(members + "*" + structLen);
670 print(Integer.toString(members));
673 if (i != methParams.size() - 1) {
681 * HELPER: writeStructMembersJavaStub() writes parameters of struct
683 private void writeStructMembersJavaStub(String simpleType, String paramType, String param) {
685 // Get the struct declaration for this struct and generate initialization code
686 StructDecl structDecl = getStructDecl(simpleType);
687 List<String> memTypes = structDecl.getMemberTypes(simpleType);
688 List<String> members = structDecl.getMembers(simpleType);
689 if (isArray(param)) { // An array
690 println("for(int i = 0; i < " + param + ".length; i++) {");
691 } else if (isList(paramType)) { // A list
692 println("for(int i = 0; i < " + param + ".size(); i++) {");
694 if (isArrayOrList(param, paramType)) { // An array or list
695 for (int i = 0; i < members.size(); i++) {
696 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
697 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
698 print("paramObj[pos++] = " + param + "[i].");
699 print(getSimpleIdentifier(members.get(i)));
703 } else { // Just one struct element
704 for (int i = 0; i < members.size(); i++) {
705 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
706 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
707 print("paramObj[pos++] = " + param + ".");
708 print(getSimpleIdentifier(members.get(i)));
716 * HELPER: writeStructParamClassJavaStub() writes parameters if struct is present
718 private void writeStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
720 print("int paramLen = ");
721 writeLengthStructParamClassJavaStub(methParams, methPrmTypes);
723 println("Object[] paramObj = new Object[paramLen];");
724 println("Class<?>[] paramCls = new Class<?>[paramLen];");
725 println("int pos = 0;");
726 // Iterate again over the parameters
727 for (int i = 0; i < methParams.size(); i++) {
728 String paramType = methPrmTypes.get(i);
729 String param = methParams.get(i);
730 String simpleType = getGenericType(paramType);
731 if (isStructClass(simpleType)) {
732 writeStructMembersJavaStub(simpleType, paramType, param);
734 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
735 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
736 print("paramObj[pos++] = ");
737 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
746 * HELPER: writeStructRetMembersJavaStub() writes parameters of struct for return statement
748 private void writeStructRetMembersJavaStub(String simpleType, String retType) {
750 // Get the struct declaration for this struct and generate initialization code
751 StructDecl structDecl = getStructDecl(simpleType);
752 List<String> memTypes = structDecl.getMemberTypes(simpleType);
753 List<String> members = structDecl.getMembers(simpleType);
754 if (isArrayOrList(retType, retType)) { // An array or list
755 println("for(int i = 0; i < retLen; i++) {");
757 if (isArray(retType)) { // An array
758 for (int i = 0; i < members.size(); i++) {
759 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
760 print("structRet[i]." + getSimpleIdentifier(members.get(i)));
761 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
764 } else if (isList(retType)) { // A list
765 println(simpleType + " structRetMem = new " + simpleType + "();");
766 for (int i = 0; i < members.size(); i++) {
767 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
768 print("structRetMem." + getSimpleIdentifier(members.get(i)));
769 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
771 println("structRet.add(structRetMem);");
773 } else { // Just one struct element
774 for (int i = 0; i < members.size(); i++) {
775 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
776 print("structRet." + getSimpleIdentifier(members.get(i)));
777 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
780 println("return structRet;");
785 * HELPER: writeStructReturnJavaStub() writes parameters if struct is present for return statement
787 private void writeStructReturnJavaStub(String simpleType, String retType) {
789 // Handle the returned struct!!!
790 println("Object retLenObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
791 // Minimum retLen is 1 if this is a single struct object
792 println("int retLen = (int) retLenObj;");
793 int numMem = getNumOfMembers(simpleType);
794 println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
795 println("Class<?>[] retClsVal = new Class<?>[" + numMem + "*retLen];");
796 println("int retPos = 0;");
797 // Get the struct declaration for this struct and generate initialization code
798 StructDecl structDecl = getStructDecl(simpleType);
799 List<String> memTypes = structDecl.getMemberTypes(simpleType);
800 List<String> members = structDecl.getMembers(simpleType);
801 if (isArrayOrList(retType, retType)) { // An array or list
802 println("for(int i = 0; i < retLen; i++) {");
803 for (int i = 0; i < members.size(); i++) {
804 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
805 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
806 println("retClsVal[retPos++] = null;");
809 } else { // Just one struct element
810 for (int i = 0; i < members.size(); i++) {
811 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
812 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
813 println("retClsVal[retPos++] = null;");
816 println("Object[] retObj = rmiCall.getStructObjects(retCls, retClsVal);");
817 if (isArray(retType)) { // An array
818 println(simpleType + "[] structRet = new " + simpleType + "[retLen];");
819 println("for(int i = 0; i < retLen; i++) {");
820 println("structRet[i] = new " + simpleType + "();");
822 } else if (isList(retType)) { // A list
823 println("List<" + simpleType + "> structRet = new ArrayList<" + simpleType + ">();");
825 println(simpleType + " structRet = new " + simpleType + "();");
826 println("int retObjPos = 0;");
827 writeStructRetMembersJavaStub(simpleType, retType);
832 * HELPER: writeStdMethodBodyJavaStub() writes the standard method body in the stub class
834 private void writeStdMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
835 List<String> methPrmTypes, String method) {
837 checkAndWriteStructSetupJavaStub(methParams, methPrmTypes, intDecl, method);
838 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
839 String retType = intDecl.getMethodType(method);
840 println("Class<?> retType = " + getSimpleType(getStructType(getEnumType(retType))) + ".class;");
841 checkAndWriteEnumTypeJavaStub(methParams, methPrmTypes);
842 // Generate array of parameter types
843 if (isStructPresent(methParams, methPrmTypes)) {
844 writeStructParamClassJavaStub(methParams, methPrmTypes);
846 print("Class<?>[] paramCls = new Class<?>[] { ");
847 for (int i = 0; i < methParams.size(); i++) {
848 String paramType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
849 print(getSimpleType(getEnumType(paramType)) + ".class");
850 // Check if this is the last element (don't print a comma)
851 if (i != methParams.size() - 1) {
856 // Generate array of parameter objects
857 print("Object[] paramObj = new Object[] { ");
858 for (int i = 0; i < methParams.size(); i++) {
859 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
860 // Check if this is the last element (don't print a comma)
861 if (i != methParams.size() - 1) {
867 // Check if this is "void"
868 if (retType.equals("void")) {
869 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
870 } else { // We do have a return value
871 // Generate array of parameter types
872 if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
873 writeStructReturnJavaStub(getGenericType(getSimpleArrayType(retType)), retType);
875 // Check if the return value NONPRIMITIVES
876 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) {
877 String[] retGenValType = getTypeOfGeneric(retType);
878 println("Class<?> retGenValType = " + retGenValType[0] + ".class;");
879 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);");
880 println("return (" + retType + ")retObj;");
881 } else if (getParamCategory(retType) == ParamCategory.ENUM) {
882 // This is an enum type
883 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
884 checkAndWriteEnumRetTypeJavaStub(retType);
886 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
887 println("return (" + retType + ")retObj;");
895 * HELPER: returnGenericCallbackType() returns the callback type
897 private String returnGenericCallbackType(String paramType) {
899 if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES)
900 return getTypeOfGeneric(paramType)[0];
907 * HELPER: checkCallbackType() checks the callback type
909 private boolean checkCallbackType(String paramType, String callbackType) {
911 String prmType = returnGenericCallbackType(paramType);
912 return callbackType.equals(prmType);
917 * HELPER: writeCallbackMethodBodyJavaStub() writes the callback method of the stub class
919 private void writeCallbackMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
920 List<String> methPrmTypes, String method, String callbackType) {
923 // Check if this is single object, array, or list of objects
924 for (int i = 0; i < methParams.size(); i++) {
925 String paramType = methPrmTypes.get(i);
926 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
927 String param = methParams.get(i);
928 if (isArrayOrList(paramType, param)) { // Generate loop
929 println("for (" + paramType + " cb : " + getSimpleIdentifier(param) + ") {");
930 println(callbackType + "_CallbackSkeleton skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
932 println(callbackType + "_CallbackSkeleton skel = new " + callbackType + "_CallbackSkeleton(" +
933 getSimpleIdentifier(param) + ", objIdCnt++);");
934 println("listCallbackObj.add(skel);");
935 if (isArrayOrList(paramType, param))
939 println("} catch (Exception ex) {");
940 println("ex.printStackTrace();");
941 println("throw new Error(\"Exception when generating skeleton objects!\");");
943 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
944 String retType = intDecl.getMethodType(method);
945 println("Class<?> retType = " + getSimpleType(getEnumType(retType)) + ".class;");
946 // Generate array of parameter types
947 print("Class<?>[] paramCls = new Class<?>[] { ");
948 for (int i = 0; i < methParams.size(); i++) {
949 String paramType = methPrmTypes.get(i);
950 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
952 } else { // Generate normal classes if it's not a callback object
953 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
954 print(getSimpleType(prmType) + ".class");
956 if (i != methParams.size() - 1) // Check if this is the last element
960 // Generate array of parameter objects
961 print("Object[] paramObj = new Object[] { ");
962 for (int i = 0; i < methParams.size(); i++) {
963 String paramType = methPrmTypes.get(i);
964 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
965 //if (isArray(methPrmTypes.get(i), methParams.get(i)))
966 if (isArray(methParams.get(i)))
967 print(getSimpleIdentifier(methParams.get(i)) + ".length");
968 else if (isList(methPrmTypes.get(i)))
969 print(getSimpleIdentifier(methParams.get(i)) + ".size()");
971 print("new Integer(1)");
973 print(getSimpleIdentifier(methParams.get(i)));
974 if (i != methParams.size() - 1)
978 // Check if this is "void"
979 if (retType.equals("void")) {
980 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
981 } else { // We do have a return value
982 // Check if the return value NONPRIMITIVES
983 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) {
984 String[] retGenValType = getTypeOfGeneric(retType);
985 println("Class<?> retGenValType = " + retGenValType[0] + ".class;");
986 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);");
987 println("return (" + retType + ")retObj;");
989 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
990 println("return (" + retType + ")retObj;");
997 * HELPER: writeMethodJavaStub() writes the methods of the stub class
999 private void writeMethodJavaStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
1001 for (String method : methods) {
1003 List<String> methParams = intDecl.getMethodParams(method);
1004 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1005 print("public " + intDecl.getMethodType(method) + " " +
1006 intDecl.getMethodId(method) + "(");
1007 boolean isCallbackMethod = false;
1008 String callbackType = null;
1009 for (int i = 0; i < methParams.size(); i++) {
1011 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
1012 // Check if this has callback object
1013 if (callbackClasses.contains(paramType)) {
1014 isCallbackMethod = true;
1015 callbackType = paramType;
1016 // Even if there're 2 callback arguments, we expect them to be of the same interface
1018 print(methPrmTypes.get(i) + " " + methParams.get(i));
1019 // Check if this is the last element (don't print a comma)
1020 if (i != methParams.size() - 1) {
1025 // Now, write the body of stub!
1026 if (isCallbackMethod)
1027 writeCallbackMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
1029 writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method);
1031 // Write the init callback helper method
1032 if (isCallbackMethod)
1033 writeInitCallbackJavaStub(callbackType, intDecl);
1039 * generateJavaStubClasses() generate stubs based on the methods list in Java
1041 public void generateJavaStubClasses() throws IOException {
1043 // Create a new directory
1044 String path = createDirectories(dir, subdir);
1045 for (String intface : mapIntfacePTH.keySet()) {
1047 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1048 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1050 // Open a new file to write into
1051 String newIntface = intMeth.getKey();
1052 String newStubClass = newIntface + "_Stub";
1053 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
1054 pw = new PrintWriter(new BufferedWriter(fw));
1055 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
1056 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
1057 // Pass in set of methods and get import classes
1058 Set<String> methods = intMeth.getValue();
1059 Set<String> importClasses = getImportClasses(methods, intDecl);
1060 List<String> stdImportClasses = getStandardJavaImportClasses();
1061 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
1062 printImportStatements(allImportClasses); println("");
1063 // Find out if there are callback objects
1064 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
1065 boolean callbackExist = !callbackClasses.isEmpty();
1066 // Write class header
1067 println("public class " + newStubClass + " implements " + newIntface + " {\n");
1069 writePropertiesJavaStub(intface, newIntface, callbackExist, callbackClasses);
1070 // Write constructor
1071 writeConstructorJavaStub(intface, newStubClass, callbackExist, callbackClasses);
1073 writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses);
1076 System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java...");
1083 * HELPER: writePropertiesJavaCallbackStub() writes the properties of the callback stub class
1085 private void writePropertiesJavaCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
1087 println("private IoTRMICall rmiCall;");
1088 println("private String address;");
1089 println("private int[] ports;\n");
1090 // Get the object Id
1091 println("private static int objectId = 0;");
1092 if (callbackExist) {
1093 // We assume that each class only has one callback interface for now
1094 Iterator it = callbackClasses.iterator();
1095 String callbackType = (String) it.next();
1096 println("// Callback properties");
1097 println("private IoTRMIObject rmiObj;");
1098 println("List<" + callbackType + "> listCallbackObj;");
1099 println("private static int objIdCnt = 0;");
1100 // Generate permission stuff for callback stubs
1101 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
1102 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
1103 writePropertiesJavaPermission(callbackType, intDecl);
1110 * HELPER: writeConstructorJavaCallbackStub() writes the constructor of the callback stub class
1112 private void writeConstructorJavaCallbackStub(String intface, String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
1114 // TODO: If we want callback in callback, then we need to add address and port initializations
1115 println("public " + newStubClass + "(IoTRMICall _rmiCall, int _objectId) throws Exception {");
1116 println("objectId = _objectId;");
1117 println("rmiCall = _rmiCall;");
1118 if (callbackExist) {
1119 Iterator it = callbackClasses.iterator();
1120 String callbackType = (String) it.next();
1121 writeConstructorJavaPermission(intface);
1122 println("listCallbackObj = new ArrayList<" + callbackType + ">();");
1123 println("___initCallBack();");
1124 println("// TODO: Add address and port initialization here if we want callback in callback!");
1131 * generateJavaCallbackStubClasses() generate callback stubs based on the methods list in Java
1133 * Callback stubs gets the IoTRMICall objects from outside of the class as contructor input
1134 * because all these stubs are populated by the class that takes in this object as a callback
1135 * object. In such a class, we only use one socket, hence one IoTRMICall, for all callback objects.
1137 public void generateJavaCallbackStubClasses() throws IOException {
1139 // Create a new directory
1140 String path = createDirectories(dir, subdir);
1141 for (String intface : mapIntfacePTH.keySet()) {
1143 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1144 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1146 // Open a new file to write into
1147 String newIntface = intMeth.getKey();
1148 String newStubClass = newIntface + "_CallbackStub";
1149 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
1150 pw = new PrintWriter(new BufferedWriter(fw));
1151 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
1152 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
1153 // Pass in set of methods and get import classes
1154 Set<String> methods = intMeth.getValue();
1155 Set<String> importClasses = getImportClasses(methods, intDecl);
1156 List<String> stdImportClasses = getStandardJavaImportClasses();
1157 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
1158 printImportStatements(allImportClasses); println("");
1159 // Find out if there are callback objects
1160 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
1161 boolean callbackExist = !callbackClasses.isEmpty();
1162 // Write class header
1163 println("public class " + newStubClass + " implements " + newIntface + " {\n");
1165 writePropertiesJavaCallbackStub(intface, newIntface, callbackExist, callbackClasses);
1166 // Write constructor
1167 writeConstructorJavaCallbackStub(intface, newStubClass, callbackExist, callbackClasses);
1169 // TODO: perhaps need to generate callback for callback
1170 writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses);
1173 System.out.println("IoTCompiler: Generated callback stub class " + newStubClass + ".java...");
1180 * HELPER: writePropertiesJavaSkeleton() writes the properties of the skeleton class
1182 private void writePropertiesJavaSkeleton(String intface, boolean callbackExist, InterfaceDecl intDecl) {
1184 println("private " + intface + " mainObj;");
1185 //println("private int ports;");
1186 println("private IoTRMIObject rmiObj;\n");
1188 if (callbackExist) {
1189 println("private static int objIdCnt = 0;");
1190 println("private IoTRMICall rmiCall;");
1192 writePropertiesJavaPermission(intface, intDecl);
1198 * HELPER: writeConstructorJavaSkeleton() writes the constructor of the skeleton class
1200 private void writeConstructorJavaSkeleton(String newSkelClass, String intface) {
1202 println("public " + newSkelClass + "(" + intface + " _mainObj, int _port) throws Exception {");
1203 println("mainObj = _mainObj;");
1204 println("rmiObj = new IoTRMIObject(_port);");
1205 // Generate permission control initialization
1206 writeConstructorJavaPermission(intface);
1207 println("___waitRequestInvokeMethod();");
1213 * HELPER: writeStdMethodBodyJavaSkeleton() writes the standard method body in the skeleton class
1215 private void writeStdMethodBodyJavaSkeleton(List<String> methParams, String methodId, String methodType) {
1217 if (methodType.equals("void"))
1218 print("mainObj." + methodId + "(");
1220 print("return mainObj." + methodId + "(");
1221 for (int i = 0; i < methParams.size(); i++) {
1223 print(getSimpleIdentifier(methParams.get(i)));
1224 // Check if this is the last element (don't print a comma)
1225 if (i != methParams.size() - 1) {
1234 * HELPER: writeInitCallbackJavaSkeleton() writes the init callback method for skeleton class
1236 private void writeInitCallbackJavaSkeleton(boolean callbackSkeleton) {
1238 // This is a callback skeleton generation
1239 if (callbackSkeleton)
1240 println("public void ___regCB(IoTRMIObject rmiObj) throws IOException {");
1242 println("public void ___regCB() throws IOException {");
1243 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class, String.class, int.class },");
1244 println("\tnew Class<?>[] { null, null, null });");
1245 println("rmiCall = new IoTRMICall((int) paramObj[0], (String) paramObj[1], (int) paramObj[2]);");
1251 * HELPER: writeMethodJavaSkeleton() writes the method of the skeleton class
1253 private void writeMethodJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses,
1254 boolean callbackSkeleton) {
1256 for (String method : methods) {
1258 List<String> methParams = intDecl.getMethodParams(method);
1259 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1260 String methodId = intDecl.getMethodId(method);
1261 print("public " + intDecl.getMethodType(method) + " " + methodId + "(");
1262 boolean isCallbackMethod = false;
1263 String callbackType = null;
1264 for (int i = 0; i < methParams.size(); i++) {
1266 String origParamType = methPrmTypes.get(i);
1267 String paramType = checkAndGetParamClass(origParamType);
1268 if (callbackClasses.contains(origParamType)) { // Check if this has callback object
1269 isCallbackMethod = true;
1270 callbackType = origParamType;
1272 print(paramType + " " + methParams.get(i));
1273 // Check if this is the last element (don't print a comma)
1274 if (i != methParams.size() - 1) {
1279 // Now, write the body of skeleton!
1280 writeStdMethodBodyJavaSkeleton(methParams, methodId, intDecl.getMethodType(method));
1282 if (isCallbackMethod)
1283 writeInitCallbackJavaSkeleton(callbackSkeleton);
1289 * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part
1291 private Map<Integer,String> writeCallbackJavaStubGeneration(List<String> methParams, List<String> methPrmTypes,
1292 String callbackType) {
1294 Map<Integer,String> mapStubParam = new HashMap<Integer,String>();
1295 // Iterate over callback objects
1296 for (int i = 0; i < methParams.size(); i++) {
1297 String paramType = methPrmTypes.get(i);
1298 String param = methParams.get(i);
1299 //if (callbackType.equals(paramType)) {
1300 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
1302 String exchParamType = checkAndGetParamClass(paramType);
1303 // Print array if this is array or list if this is a list of callback objects
1304 if (isArray(param)) {
1305 println("int numStubs" + i + " = (int) paramObj[" + i + "];");
1306 println(exchParamType + "[] stub" + i + " = new " + exchParamType + "[numStubs" + i + "];");
1307 } else if (isList(paramType)) {
1308 println("int numStubs" + i + " = (int) paramObj[" + i + "];");
1309 println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();");
1311 println(exchParamType + " stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
1312 println("objIdCnt++;");
1315 // Generate a loop if needed
1316 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
1317 String exchParamType = checkAndGetParamClass(paramType);
1318 if (isArray(param)) {
1319 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
1320 println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
1321 println("objIdCnt++;");
1323 } else if (isList(paramType)) {
1324 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
1325 println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt));");
1326 println("objIdCnt++;");
1329 mapStubParam.put(i, "stub" + i); // List of all stub parameters
1332 return mapStubParam;
1337 * HELPER: checkAndWriteEnumTypeJavaSkeleton() writes the enum type (convert from enum to int)
1339 private void checkAndWriteEnumTypeJavaSkeleton(List<String> methParams, List<String> methPrmTypes) {
1341 // Iterate and find enum declarations
1342 for (int i = 0; i < methParams.size(); i++) {
1343 String paramType = methPrmTypes.get(i);
1344 String param = methParams.get(i);
1345 String simpleType = getSimpleType(paramType);
1346 if (isEnumClass(simpleType)) {
1347 // Check if this is enum type
1348 println("int paramInt" + i + "[] = (int[]) paramObj[" + i + "];");
1349 println(simpleType + "[] enumVals = " + simpleType + ".values();");
1350 if (isArray(param)) { // An array
1351 println("int len" + i + " = paramInt" + i + ".length;");
1352 println(simpleType + "[] paramEnum = new " + simpleType + "[len];");
1353 println("for (int i = 0; i < len" + i + "; i++) {");
1354 println("paramEnum[i] = enumVals[paramInt" + i + "[i]];");
1356 } else if (isList(paramType)) { // A list
1357 println("int len" + i + " = paramInt" + i + ".length;");
1358 println("List<" + simpleType + "> paramEnum = new ArrayList<" + simpleType + ">();");
1359 println("for (int i = 0; i < len" + i + "; i++) {");
1360 println("paramEnum.add(enumVals[paramInt" + i + "[i]]);");
1362 } else { // Just one element
1363 println(simpleType + " paramEnum" + i + " = enumVals[paramInt" + i + "[0]];");
1371 * HELPER: checkAndWriteEnumRetTypeJavaSkeleton() writes the enum return type (convert from enum to int)
1373 private void checkAndWriteEnumRetTypeJavaSkeleton(String retType, String methodId) {
1375 // Strips off array "[]" for return type
1376 String pureType = getSimpleArrayType(getSimpleType(retType));
1377 // Take the inner type of generic
1378 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
1379 pureType = getTypeOfGeneric(retType)[0];
1380 if (isEnumClass(pureType)) {
1381 // Check if this is enum type
1383 if (isArray(retType)) { // An array
1384 print(pureType + "[] retEnum = " + methodId + "(");
1385 } else if (isList(retType)) { // A list
1386 print("List<" + pureType + "> retEnum = " + methodId + "(");
1387 } else { // Just one element
1388 print(pureType + " retEnum = " + methodId + "(");
1395 * HELPER: checkAndWriteEnumRetConvJavaSkeleton() writes the enum return type (convert from enum to int)
1397 private void checkAndWriteEnumRetConvJavaSkeleton(String retType) {
1399 // Strips off array "[]" for return type
1400 String pureType = getSimpleArrayType(getSimpleType(retType));
1401 // Take the inner type of generic
1402 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
1403 pureType = getTypeOfGeneric(retType)[0];
1404 if (isEnumClass(pureType)) {
1405 // Check if this is enum type
1406 if (isArray(retType)) { // An array
1407 println("int retLen = retEnum.length;");
1408 println("int[] retEnumVal = new int[retLen];");
1409 println("for (int i = 0; i < retLen; i++) {");
1410 println("retEnumVal[i] = retEnum[i].ordinal();");
1412 } else if (isList(retType)) { // A list
1413 println("int retLen = retEnum.size();");
1414 println("List<" + pureType + "> retEnumVal = new ArrayList<" + pureType + ">();");
1415 println("for (int i = 0; i < retLen; i++) {");
1416 println("retEnumVal.add(retEnum[i].ordinal());");
1418 } else { // Just one element
1419 println("int[] retEnumVal = new int[1];");
1420 println("retEnumVal[0] = retEnum.ordinal();");
1422 println("Object retObj = retEnumVal;");
1428 * HELPER: writeLengthStructParamClassSkeleton() writes lengths of params
1430 private void writeLengthStructParamClassSkeleton(List<String> methParams, List<String> methPrmTypes,
1431 String method, InterfaceDecl intDecl) {
1433 // Iterate and find struct declarations - count number of params
1434 for (int i = 0; i < methParams.size(); i++) {
1435 String paramType = methPrmTypes.get(i);
1436 String param = methParams.get(i);
1437 String simpleType = getGenericType(paramType);
1438 if (isStructClass(simpleType)) {
1439 int members = getNumOfMembers(simpleType);
1440 print(Integer.toString(members) + "*");
1441 int methodNumId = intDecl.getMethodNumId(method);
1442 print("struct" + methodNumId + "Size" + i);
1445 if (i != methParams.size() - 1) {
1453 * HELPER: writeStructMembersJavaSkeleton() writes member parameters of struct
1455 private void writeStructMembersJavaSkeleton(String simpleType, String paramType,
1456 String param, String method, InterfaceDecl intDecl, int iVar) {
1458 // Get the struct declaration for this struct and generate initialization code
1459 StructDecl structDecl = getStructDecl(simpleType);
1460 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1461 List<String> members = structDecl.getMembers(simpleType);
1462 if (isArrayOrList(param, paramType)) { // An array or list
1463 int methodNumId = intDecl.getMethodNumId(method);
1464 String counter = "struct" + methodNumId + "Size" + iVar;
1465 println("for(int i = 0; i < " + counter + "; i++) {");
1467 println("int pos = 0;");
1468 if (isArrayOrList(param, paramType)) { // An array or list
1469 println("for(int i = 0; i < retLen; i++) {");
1470 for (int i = 0; i < members.size(); i++) {
1471 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1472 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1473 println("paramClsGen[pos++] = null;");
1476 } else { // Just one struct element
1477 for (int i = 0; i < members.size(); i++) {
1478 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1479 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1480 println("paramClsGen[pos++] = null;");
1487 * HELPER: writeStructMembersInitJavaSkeleton() writes member parameters initialization of struct
1489 private void writeStructMembersInitJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1490 List<String> methPrmTypes, String method) {
1492 for (int i = 0; i < methParams.size(); i++) {
1493 String paramType = methPrmTypes.get(i);
1494 String param = methParams.get(i);
1495 String simpleType = getGenericType(paramType);
1496 if (isStructClass(simpleType)) {
1497 int methodNumId = intDecl.getMethodNumId(method);
1498 String counter = "struct" + methodNumId + "Size" + i;
1500 if (isArray(param)) { // An array
1501 println(simpleType + "[] paramStruct" + i + " = new " + simpleType + "[" + counter + "];");
1502 println("for(int i = 0; i < " + counter + "; i++) {");
1503 println("paramStruct" + i + "[i] = new " + simpleType + "();");
1505 } else if (isList(paramType)) { // A list
1506 println("List<" + simpleType + "> paramStruct" + i + " = new ArrayList<" + simpleType + ">();");
1508 println(simpleType + " paramStruct" + i + " = new " + simpleType + "();");
1509 println("int objPos = 0;");
1510 // Initialize members
1511 StructDecl structDecl = getStructDecl(simpleType);
1512 List<String> members = structDecl.getMembers(simpleType);
1513 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1514 if (isArrayOrList(param, paramType)) { // An array or list
1515 println("for(int i = 0; i < " + counter + "; i++) {");
1517 if (isArray(param)) { // An array
1518 for (int j = 0; j < members.size(); j++) {
1519 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1520 print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j)));
1521 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1524 } else if (isList(paramType)) { // A list
1525 println(simpleType + " paramStructMem = new " + simpleType + "();");
1526 for (int j = 0; j < members.size(); j++) {
1527 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1528 print("paramStructMem." + getSimpleIdentifier(members.get(j)));
1529 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1531 println("paramStruct" + i + ".add(paramStructMem);");
1533 } else { // Just one struct element
1534 for (int j = 0; j < members.size(); j++) {
1535 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1536 print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j)));
1537 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1541 // Take offsets of parameters
1542 println("int offset" + i +" = objPos;");
1549 * HELPER: writeStructReturnJavaSkeleton() writes struct for return statement
1551 private void writeStructReturnJavaSkeleton(String simpleType, String retType) {
1553 // Minimum retLen is 1 if this is a single struct object
1554 if (isArray(retType))
1555 println("int retLen = retStruct.length;");
1556 else if (isList(retType))
1557 println("int retLen = retStruct.size();");
1558 else // Just single struct object
1559 println("int retLen = 1;");
1560 println("Object retLenObj = retLen;");
1561 println("rmiObj.sendReturnObj(retLenObj);");
1562 int numMem = getNumOfMembers(simpleType);
1563 println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
1564 println("Object[] retObj = new Object[" + numMem + "*retLen];");
1565 println("int retPos = 0;");
1566 // Get the struct declaration for this struct and generate initialization code
1567 StructDecl structDecl = getStructDecl(simpleType);
1568 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1569 List<String> members = structDecl.getMembers(simpleType);
1570 if (isArrayOrList(retType, retType)) { // An array or list
1571 println("for(int i = 0; i < retLen; i++) {");
1572 for (int i = 0; i < members.size(); i++) {
1573 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1574 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1575 print("retObj[retPos++] = retStruct[i].");
1576 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
1580 } else { // Just one struct element
1581 for (int i = 0; i < members.size(); i++) {
1582 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1583 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1584 print("retObj[retPos++] = retStruct.");
1585 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
1594 * HELPER: writeMethodHelperReturnJavaSkeleton() writes return statement part in skeleton
1596 private void writeMethodHelperReturnJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1597 List<String> methPrmTypes, String method, boolean isCallbackMethod, String callbackType,
1598 boolean isStructMethod) {
1600 checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes);
1601 Map<Integer,String> mapStubParam = null;
1602 if (isCallbackMethod)
1603 mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType);
1604 // Check if this is "void"
1605 String retType = intDecl.getMethodType(method);
1606 if (retType.equals("void")) {
1607 print(intDecl.getMethodId(method) + "(");
1608 } else if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
1609 checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method));
1610 } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
1611 print(retType + " retStruct = " + intDecl.getMethodId(method) + "(");
1612 } else { // We do have a return value
1613 print("Object retObj = " + intDecl.getMethodId(method) + "(");
1615 for (int i = 0; i < methParams.size(); i++) {
1617 if (isCallbackMethod) {
1618 print(mapStubParam.get(i)); // Get the callback parameter
1619 } else if (isEnumClass(getSimpleType(methPrmTypes.get(i)))) { // Enum class
1620 print(getEnumParam(methPrmTypes.get(i), methParams.get(i), i));
1621 } else if (isStructClass(getSimpleType(methPrmTypes.get(i)))) {
1622 print("paramStruct" + i);
1624 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1626 print("(" + prmType + ") paramObj[offset" + i + "]");
1628 print("(" + prmType + ") paramObj[" + i + "]");
1630 if (i != methParams.size() - 1)
1634 if (!retType.equals("void")) {
1635 if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
1636 checkAndWriteEnumRetConvJavaSkeleton(retType);
1637 println("rmiObj.sendReturnObj(retObj);");
1638 } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
1639 writeStructReturnJavaSkeleton(getSimpleArrayType(getSimpleType(retType)), retType);
1640 println("rmiObj.sendReturnObj(retCls, retObj);");
1642 println("rmiObj.sendReturnObj(retObj);");
1644 if (isCallbackMethod) { // Catch exception if this is callback
1645 println("} catch(Exception ex) {");
1646 println("ex.printStackTrace();");
1647 println("throw new Error(\"Exception from callback object instantiation!\");");
1654 * HELPER: writeMethodHelperStructJavaSkeleton() writes the struct in skeleton
1656 private void writeMethodHelperStructJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1657 List<String> methPrmTypes, String method, Set<String> callbackClasses) {
1659 // Generate array of parameter objects
1660 boolean isCallbackMethod = false;
1661 String callbackType = null;
1662 print("int paramLen = ");
1663 writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
1665 println("Class<?>[] paramCls = new Class<?>[paramLen];");
1666 println("Class<?>[] paramClsGen = new Class<?>[paramLen];");
1667 // Iterate again over the parameters
1668 for (int i = 0; i < methParams.size(); i++) {
1669 String paramType = methPrmTypes.get(i);
1670 String param = methParams.get(i);
1671 String simpleType = getGenericType(paramType);
1672 if (isStructClass(simpleType)) {
1673 writeStructMembersJavaSkeleton(simpleType, paramType, param, method, intDecl, i);
1675 String prmType = returnGenericCallbackType(methPrmTypes.get(i));
1676 if (callbackClasses.contains(prmType)) {
1677 isCallbackMethod = true;
1678 callbackType = prmType;
1679 println("paramCls[pos] = int.class;");
1680 println("paramClsGen[pos++] = null;");
1681 } else { // Generate normal classes if it's not a callback object
1682 String paramTypeOth = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1683 println("paramCls[pos] = " + getSimpleType(getEnumType(paramTypeOth)) + ".class;");
1684 print("paramClsGen[pos++] = ");
1685 String prmTypeOth = methPrmTypes.get(i);
1686 if (getParamCategory(prmTypeOth) == ParamCategory.NONPRIMITIVES)
1687 println(getTypeOfGeneric(prmType)[0] + ".class;");
1693 println("Object[] paramObj = rmiObj.getMethodParams(paramCls, paramClsGen);");
1694 writeStructMembersInitJavaSkeleton(intDecl, methParams, methPrmTypes, method);
1695 // Write the return value part
1696 writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, true);
1701 * HELPER: writeStdMethodHelperBodyJavaSkeleton() writes the standard method body helper in the skeleton class
1703 private void writeStdMethodHelperBodyJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1704 List<String> methPrmTypes, String method, Set<String> callbackClasses) {
1706 // Generate array of parameter objects
1707 boolean isCallbackMethod = false;
1708 String callbackType = null;
1709 print("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { ");
1710 for (int i = 0; i < methParams.size(); i++) {
1712 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
1713 if (callbackClasses.contains(paramType)) {
1714 isCallbackMethod = true;
1715 callbackType = paramType;
1717 } else { // Generate normal classes if it's not a callback object
1718 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1719 print(getSimpleType(getEnumType(prmType)) + ".class");
1721 if (i != methParams.size() - 1)
1725 // Generate generic class if it's a generic type.. null otherwise
1726 print("new Class<?>[] { ");
1727 for (int i = 0; i < methParams.size(); i++) {
1728 String prmType = methPrmTypes.get(i);
1729 if (getParamCategory(prmType) == ParamCategory.NONPRIMITIVES)
1730 print(getTypeOfGeneric(prmType)[0] + ".class");
1733 if (i != methParams.size() - 1)
1737 // Write the return value part
1738 writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, false);
1743 * HELPER: writeMethodHelperJavaSkeleton() writes the method helper of the skeleton class
1745 private void writeMethodHelperJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
1747 // Use this set to handle two same methodIds
1748 Set<String> uniqueMethodIds = new HashSet<String>();
1749 for (String method : methods) {
1751 List<String> methParams = intDecl.getMethodParams(method);
1752 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1753 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
1754 String methodId = intDecl.getMethodId(method);
1755 print("public void ___");
1756 String helperMethod = methodId;
1757 if (uniqueMethodIds.contains(methodId))
1758 helperMethod = helperMethod + intDecl.getMethodNumId(method);
1760 uniqueMethodIds.add(methodId);
1761 String retType = intDecl.getMethodType(method);
1762 print(helperMethod + "(");
1763 boolean begin = true;
1764 for (int i = 0; i < methParams.size(); i++) { // Print size variables
1765 String paramType = methPrmTypes.get(i);
1766 String param = methParams.get(i);
1767 String simpleType = getSimpleType(paramType);
1768 if (isStructClass(simpleType)) {
1769 if (!begin) { // Generate comma for not the beginning variable
1770 print(", "); begin = false;
1772 int methodNumId = intDecl.getMethodNumId(method);
1773 print("int struct" + methodNumId + "Size" + i);
1776 // Check if this is "void"
1777 if (retType.equals("void"))
1780 println(") throws IOException {");
1781 writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
1784 String methodId = intDecl.getMethodId(method);
1785 print("public void ___");
1786 String helperMethod = methodId;
1787 if (uniqueMethodIds.contains(methodId))
1788 helperMethod = helperMethod + intDecl.getMethodNumId(method);
1790 uniqueMethodIds.add(methodId);
1791 // Check if this is "void"
1792 String retType = intDecl.getMethodType(method);
1793 if (retType.equals("void"))
1794 println(helperMethod + "() {");
1796 println(helperMethod + "() throws IOException {");
1797 // Now, write the helper body of skeleton!
1798 writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
1802 // Write method helper for structs
1803 writeMethodHelperStructSetupJavaSkeleton(methods, intDecl);
1808 * HELPER: writeMethodHelperStructSetupJavaSkeleton() writes the method helper of struct setup in skeleton class
1810 private void writeMethodHelperStructSetupJavaSkeleton(Collection<String> methods,
1811 InterfaceDecl intDecl) {
1813 // Use this set to handle two same methodIds
1814 for (String method : methods) {
1816 List<String> methParams = intDecl.getMethodParams(method);
1817 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1818 // Check for params with structs
1819 for (int i = 0; i < methParams.size(); i++) {
1820 String paramType = methPrmTypes.get(i);
1821 String param = methParams.get(i);
1822 String simpleType = getSimpleType(paramType);
1823 if (isStructClass(simpleType)) {
1824 int methodNumId = intDecl.getMethodNumId(method);
1825 print("public int ___");
1826 String helperMethod = methodNumId + "struct" + i;
1827 println(helperMethod + "() {");
1828 // Now, write the helper body of skeleton!
1829 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
1830 println("return (int) paramObj[0];");
1839 * HELPER: writeMethodHelperStructSetupJavaCallbackSkeleton() writes the method helper of struct setup in callback skeleton class
1841 private void writeMethodHelperStructSetupJavaCallbackSkeleton(Collection<String> methods,
1842 InterfaceDecl intDecl) {
1844 // Use this set to handle two same methodIds
1845 for (String method : methods) {
1847 List<String> methParams = intDecl.getMethodParams(method);
1848 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1849 // Check for params with structs
1850 for (int i = 0; i < methParams.size(); i++) {
1851 String paramType = methPrmTypes.get(i);
1852 String param = methParams.get(i);
1853 String simpleType = getSimpleType(paramType);
1854 if (isStructClass(simpleType)) {
1855 int methodNumId = intDecl.getMethodNumId(method);
1856 print("public int ___");
1857 String helperMethod = methodNumId + "struct" + i;
1858 println(helperMethod + "(IoTRMIObject rmiObj) {");
1859 // Now, write the helper body of skeleton!
1860 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
1861 println("return (int) paramObj[0];");
1870 * HELPER: writeCountVarStructSkeleton() writes counter variable of struct for skeleton
1872 private void writeCountVarStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
1874 // Use this set to handle two same methodIds
1875 for (String method : methods) {
1877 List<String> methParams = intDecl.getMethodParams(method);
1878 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1879 // Check for params with structs
1880 for (int i = 0; i < methParams.size(); i++) {
1881 String paramType = methPrmTypes.get(i);
1882 String param = methParams.get(i);
1883 String simpleType = getSimpleType(paramType);
1884 if (isStructClass(simpleType)) {
1885 int methodNumId = intDecl.getMethodNumId(method);
1886 println("int struct" + methodNumId + "Size" + i + " = 0;");
1894 * HELPER: writeInputCountVarStructSkeleton() writes input counter variable of struct for skeleton
1896 private boolean writeInputCountVarStructSkeleton(String method, InterfaceDecl intDecl) {
1898 List<String> methParams = intDecl.getMethodParams(method);
1899 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1900 boolean structExist = false;
1901 // Check for params with structs
1902 for (int i = 0; i < methParams.size(); i++) {
1903 String paramType = methPrmTypes.get(i);
1904 String param = methParams.get(i);
1905 String simpleType = getSimpleType(paramType);
1906 boolean begin = true;
1907 if (isStructClass(simpleType)) {
1910 print(", "); begin = false;
1912 int methodNumId = intDecl.getMethodNumId(method);
1913 print("struct" + methodNumId + "Size" + i);
1921 * HELPER: writeMethodCallStructSkeleton() writes method call for wait invoke in skeleton
1923 private void writeMethodCallStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
1925 // Use this set to handle two same methodIds
1926 for (String method : methods) {
1928 List<String> methParams = intDecl.getMethodParams(method);
1929 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1930 // Check for params with structs
1931 for (int i = 0; i < methParams.size(); i++) {
1932 String paramType = methPrmTypes.get(i);
1933 String param = methParams.get(i);
1934 String simpleType = getSimpleType(paramType);
1935 if (isStructClass(simpleType)) {
1936 int methodNumId = intDecl.getMethodNumId(method);
1938 String helperMethod = methodNumId + "struct" + i;
1939 String tempVar = "struct" + methodNumId + "Size" + i;
1940 print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
1941 print(tempVar + " = ___");
1942 println(helperMethod + "(); break;");
1950 * HELPER: writeMethodCallStructCallbackSkeleton() writes method call for wait invoke in skeleton
1952 private void writeMethodCallStructCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
1954 // Use this set to handle two same methodIds
1955 for (String method : methods) {
1957 List<String> methParams = intDecl.getMethodParams(method);
1958 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1959 // Check for params with structs
1960 for (int i = 0; i < methParams.size(); i++) {
1961 String paramType = methPrmTypes.get(i);
1962 String param = methParams.get(i);
1963 String simpleType = getSimpleType(paramType);
1964 if (isStructClass(simpleType)) {
1965 int methodNumId = intDecl.getMethodNumId(method);
1967 String helperMethod = methodNumId + "struct" + i;
1968 String tempVar = "struct" + methodNumId + "Size" + i;
1969 print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
1970 print(tempVar + " = ___");
1971 println(helperMethod + "(rmiObj); break;");
1979 * HELPER: writeJavaMethodPermission() writes permission checks in skeleton
1981 private void writeJavaMethodPermission(String intface) {
1983 // Get all the different stubs
1984 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1985 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1986 String newIntface = intMeth.getKey();
1987 int newObjectId = mapNewIntfaceObjId.get(newIntface);
1988 println("if (_objectId == object" + newObjectId + "Id) {");
1989 println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
1990 println("throw new Error(\"Object with object Id: \" + _objectId + \" is not allowed to access method: \" + methodId);");
1994 println("throw new Error(\"Object Id: \" + _objectId + \" not recognized!\");");
2001 * HELPER: writeJavaWaitRequestInvokeMethod() writes the main loop of the skeleton class
2003 private void writeJavaWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
2005 // Use this set to handle two same methodIds
2006 Set<String> uniqueMethodIds = new HashSet<String>();
2007 println("private void ___waitRequestInvokeMethod() throws IOException {");
2008 // Write variables here if we have callbacks or enums or structs
2009 writeCountVarStructSkeleton(methods, intDecl);
2010 println("while (true) {");
2011 println("rmiObj.getMethodBytes();");
2012 println("int _objectId = rmiObj.getObjectId();");
2013 println("int methodId = rmiObj.getMethodId();");
2014 // Generate permission check
2015 writeJavaMethodPermission(intface);
2016 println("switch (methodId) {");
2017 // Print methods and method Ids
2018 for (String method : methods) {
2019 String methodId = intDecl.getMethodId(method);
2020 int methodNumId = intDecl.getMethodNumId(method);
2021 print("case " + methodNumId + ": ___");
2022 String helperMethod = methodId;
2023 if (uniqueMethodIds.contains(methodId))
2024 helperMethod = helperMethod + methodNumId;
2026 uniqueMethodIds.add(methodId);
2027 print(helperMethod + "(");
2028 writeInputCountVarStructSkeleton(method, intDecl);
2029 println("); break;");
2031 String method = "___initCallBack()";
2032 // Print case -9999 (callback handler) if callback exists
2033 if (callbackExist) {
2034 int methodId = intDecl.getHelperMethodNumId(method);
2035 println("case " + methodId + ": ___regCB(); break;");
2037 writeMethodCallStructSkeleton(methods, intDecl);
2038 println("default: ");
2039 println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
2047 * generateJavaSkeletonClass() generate skeletons based on the methods list in Java
2049 public void generateJavaSkeletonClass() throws IOException {
2051 // Create a new directory
2052 String path = createDirectories(dir, subdir);
2053 for (String intface : mapIntfacePTH.keySet()) {
2054 // Open a new file to write into
2055 String newSkelClass = intface + "_Skeleton";
2056 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
2057 pw = new PrintWriter(new BufferedWriter(fw));
2058 // Pass in set of methods and get import classes
2059 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2060 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2061 List<String> methods = intDecl.getMethods();
2062 Set<String> importClasses = getImportClasses(methods, intDecl);
2063 List<String> stdImportClasses = getStandardJavaImportClasses();
2064 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
2065 printImportStatements(allImportClasses);
2066 // Find out if there are callback objects
2067 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
2068 boolean callbackExist = !callbackClasses.isEmpty();
2069 // Write class header
2071 println("public class " + newSkelClass + " implements " + intface + " {\n");
2073 writePropertiesJavaSkeleton(intface, callbackExist, intDecl);
2074 // Write constructor
2075 writeConstructorJavaSkeleton(newSkelClass, intface);
2077 writeMethodJavaSkeleton(methods, intDecl, callbackClasses, false);
2078 // Write method helper
2079 writeMethodHelperJavaSkeleton(methods, intDecl, callbackClasses);
2080 // Write waitRequestInvokeMethod() - main loop
2081 writeJavaWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
2084 System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".java...");
2090 * HELPER: writePropertiesJavaCallbackSkeleton() writes the properties of the callback skeleton class
2092 private void writePropertiesJavaCallbackSkeleton(String intface, boolean callbackExist) {
2094 println("private " + intface + " mainObj;");
2095 // For callback skeletons, this is its own object Id
2096 println("private static int objectId = 0;");
2098 if (callbackExist) {
2099 println("private static int objIdCnt = 0;");
2100 println("private IoTRMICall rmiCall;");
2107 * HELPER: writeConstructorJavaCallbackSkeleton() writes the constructor of the skeleton class
2109 private void writeConstructorJavaCallbackSkeleton(String newSkelClass, String intface) {
2111 println("public " + newSkelClass + "(" + intface + " _mainObj, int _objectId) throws Exception {");
2112 println("mainObj = _mainObj;");
2113 println("objectId = _objectId;");
2119 * HELPER: writeMethodHelperJavaCallbackSkeleton() writes the method helper of the callback skeleton class
2121 private void writeMethodHelperJavaCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
2123 // Use this set to handle two same methodIds
2124 Set<String> uniqueMethodIds = new HashSet<String>();
2125 for (String method : methods) {
2127 List<String> methParams = intDecl.getMethodParams(method);
2128 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2129 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
2130 String methodId = intDecl.getMethodId(method);
2131 print("public void ___");
2132 String helperMethod = methodId;
2133 if (uniqueMethodIds.contains(methodId))
2134 helperMethod = helperMethod + intDecl.getMethodNumId(method);
2136 uniqueMethodIds.add(methodId);
2137 String retType = intDecl.getMethodType(method);
2138 print(helperMethod + "(");
2139 boolean begin = true;
2140 for (int i = 0; i < methParams.size(); i++) { // Print size variables
2141 String paramType = methPrmTypes.get(i);
2142 String param = methParams.get(i);
2143 String simpleType = getSimpleType(paramType);
2144 if (isStructClass(simpleType)) {
2145 if (!begin) { // Generate comma for not the beginning variable
2146 print(", "); begin = false;
2148 int methodNumId = intDecl.getMethodNumId(method);
2149 print("int struct" + methodNumId + "Size" + i);
2152 // Check if this is "void"
2153 if (retType.equals("void"))
2154 println(", IoTRMIObject rmiObj) {");
2156 println(", IoTRMIObject rmiObj) throws IOException {");
2157 writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
2160 String methodId = intDecl.getMethodId(method);
2161 print("public void ___");
2162 String helperMethod = methodId;
2163 if (uniqueMethodIds.contains(methodId))
2164 helperMethod = helperMethod + intDecl.getMethodNumId(method);
2166 uniqueMethodIds.add(methodId);
2167 // Check if this is "void"
2168 String retType = intDecl.getMethodType(method);
2169 if (retType.equals("void"))
2170 println(helperMethod + "(IoTRMIObject rmiObj) {");
2172 println(helperMethod + "(IoTRMIObject rmiObj) throws IOException {");
2173 // Now, write the helper body of skeleton!
2174 writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
2178 // Write method helper for structs
2179 writeMethodHelperStructSetupJavaCallbackSkeleton(methods, intDecl);
2184 * HELPER: writeJavaCallbackWaitRequestInvokeMethod() writes the request invoke method of the callback skeleton class
2186 private void writeJavaCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist) {
2188 // Use this set to handle two same methodIds
2189 Set<String> uniqueMethodIds = new HashSet<String>();
2190 println("public void invokeMethod(IoTRMIObject rmiObj) throws IOException {");
2191 // Write variables here if we have callbacks or enums or structs
2192 writeCountVarStructSkeleton(methods, intDecl);
2193 // Write variables here if we have callbacks or enums or structs
2194 println("int methodId = rmiObj.getMethodId();");
2195 // TODO: code the permission check here!
2196 println("switch (methodId) {");
2197 // Print methods and method Ids
2198 for (String method : methods) {
2199 String methodId = intDecl.getMethodId(method);
2200 int methodNumId = intDecl.getMethodNumId(method);
2201 print("case " + methodNumId + ": ___");
2202 String helperMethod = methodId;
2203 if (uniqueMethodIds.contains(methodId))
2204 helperMethod = helperMethod + methodNumId;
2206 uniqueMethodIds.add(methodId);
2207 print(helperMethod + "(");
2208 if (writeInputCountVarStructSkeleton(method, intDecl))
2209 println(", rmiObj); break;");
2211 println("rmiObj); break;");
2213 String method = "___initCallBack()";
2214 // Print case -9999 (callback handler) if callback exists
2215 if (callbackExist) {
2216 int methodId = intDecl.getHelperMethodNumId(method);
2217 println("case " + methodId + ": ___regCB(rmiObj); break;");
2219 writeMethodCallStructCallbackSkeleton(methods, intDecl);
2220 println("default: ");
2221 println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
2228 * generateJavaCallbackSkeletonClass() generate callback skeletons based on the methods list in Java
2230 public void generateJavaCallbackSkeletonClass() throws IOException {
2232 // Create a new directory
2233 String path = createDirectories(dir, subdir);
2234 for (String intface : mapIntfacePTH.keySet()) {
2235 // Open a new file to write into
2236 String newSkelClass = intface + "_CallbackSkeleton";
2237 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
2238 pw = new PrintWriter(new BufferedWriter(fw));
2239 // Pass in set of methods and get import classes
2240 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2241 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2242 List<String> methods = intDecl.getMethods();
2243 Set<String> importClasses = getImportClasses(methods, intDecl);
2244 List<String> stdImportClasses = getStandardJavaImportClasses();
2245 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
2246 printImportStatements(allImportClasses);
2247 // Find out if there are callback objects
2248 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
2249 boolean callbackExist = !callbackClasses.isEmpty();
2250 // Write class header
2252 println("public class " + newSkelClass + " implements " + intface + " {\n");
2254 writePropertiesJavaCallbackSkeleton(intface, callbackExist);
2255 // Write constructor
2256 writeConstructorJavaCallbackSkeleton(newSkelClass, intface);
2258 writeMethodJavaSkeleton(methods, intDecl, callbackClasses, true);
2259 // Write method helper
2260 writeMethodHelperJavaCallbackSkeleton(methods, intDecl, callbackClasses);
2261 // Write waitRequestInvokeMethod() - main loop
2262 writeJavaCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
2265 System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".java...");
2271 * HELPER: writeMethodCplusLocalInterface() writes the method of the local interface
2273 private void writeMethodCplusLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
2275 for (String method : methods) {
2277 List<String> methParams = intDecl.getMethodParams(method);
2278 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2279 print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2280 intDecl.getMethodId(method) + "(");
2281 for (int i = 0; i < methParams.size(); i++) {
2282 // Check for params with driver class types and exchange it
2283 // with its remote interface
2284 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
2285 paramType = checkAndGetCplusType(paramType);
2286 // Check for arrays - translate into vector in C++
2287 String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
2288 print(paramComplete);
2289 // Check if this is the last element (don't print a comma)
2290 if (i != methParams.size() - 1) {
2300 * HELPER: writeMethodCplusInterface() writes the method of the interface
2302 private void writeMethodCplusInterface(Collection<String> methods, InterfaceDecl intDecl) {
2304 for (String method : methods) {
2306 List<String> methParams = intDecl.getMethodParams(method);
2307 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2308 print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2309 intDecl.getMethodId(method) + "(");
2310 for (int i = 0; i < methParams.size(); i++) {
2311 // Check for params with driver class types and exchange it
2312 // with its remote interface
2313 String paramType = methPrmTypes.get(i);
2314 paramType = checkAndGetCplusType(paramType);
2315 // Check for arrays - translate into vector in C++
2316 String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
2317 print(paramComplete);
2318 // Check if this is the last element (don't print a comma)
2319 if (i != methParams.size() - 1) {
2329 * HELPER: generateEnumCplus() writes the enumeration declaration
2331 public void generateEnumCplus() throws IOException {
2333 // Create a new directory
2334 createDirectory(dir);
2335 for (String intface : mapIntfacePTH.keySet()) {
2336 // Get the right StructDecl
2337 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2338 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
2339 Set<String> enumTypes = enumDecl.getEnumDeclarations();
2340 // Iterate over enum declarations
2341 for (String enType : enumTypes) {
2342 // Open a new file to write into
2343 FileWriter fw = new FileWriter(dir + "/" + enType + ".hpp");
2344 pw = new PrintWriter(new BufferedWriter(fw));
2345 // Write file headers
2346 println("#ifndef _" + enType.toUpperCase() + "_HPP__");
2347 println("#define _" + enType.toUpperCase() + "_HPP__");
2348 println("enum " + enType + " {");
2349 List<String> enumMembers = enumDecl.getMembers(enType);
2350 for (int i = 0; i < enumMembers.size(); i++) {
2352 String member = enumMembers.get(i);
2354 // Check if this is the last element (don't print a comma)
2355 if (i != enumMembers.size() - 1)
2363 System.out.println("IoTCompiler: Generated enum " + enType + ".hpp...");
2370 * HELPER: generateStructCplus() writes the struct declaration
2372 public void generateStructCplus() throws IOException {
2374 // Create a new directory
2375 createDirectory(dir);
2376 for (String intface : mapIntfacePTH.keySet()) {
2377 // Get the right StructDecl
2378 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2379 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
2380 List<String> structTypes = structDecl.getStructTypes();
2381 // Iterate over enum declarations
2382 for (String stType : structTypes) {
2383 // Open a new file to write into
2384 FileWriter fw = new FileWriter(dir + "/" + stType + ".hpp");
2385 pw = new PrintWriter(new BufferedWriter(fw));
2386 // Write file headers
2387 println("#ifndef _" + stType.toUpperCase() + "_HPP__");
2388 println("#define _" + stType.toUpperCase() + "_HPP__");
2389 println("struct " + stType + " {");
2390 List<String> structMemberTypes = structDecl.getMemberTypes(stType);
2391 List<String> structMembers = structDecl.getMembers(stType);
2392 for (int i = 0; i < structMembers.size(); i++) {
2394 String memberType = structMemberTypes.get(i);
2395 String member = structMembers.get(i);
2396 String structTypeC = checkAndGetCplusType(memberType);
2397 String structComplete = checkAndGetCplusArray(structTypeC, member);
2398 println(structComplete + ";");
2403 System.out.println("IoTCompiler: Generated struct " + stType + ".hpp...");
2410 * generateCplusLocalInterfaces() writes the local interfaces and provides type-checking.
2412 * It needs to rewrite and exchange USERDEFINED types in input parameters of stub
2413 * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording.
2414 * The local interface has to be the input parameter for the stub and the stub
2415 * interface has to be the input parameter for the local class.
2417 public void generateCplusLocalInterfaces() throws IOException {
2419 // Create a new directory
2420 createDirectory(dir);
2421 for (String intface : mapIntfacePTH.keySet()) {
2422 // Open a new file to write into
2423 FileWriter fw = new FileWriter(dir + "/" + intface + ".hpp");
2424 pw = new PrintWriter(new BufferedWriter(fw));
2425 // Write file headers
2426 println("#ifndef _" + intface.toUpperCase() + "_HPP__");
2427 println("#define _" + intface.toUpperCase() + "_HPP__");
2428 println("#include <iostream>");
2429 // Pass in set of methods and get include classes
2430 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2431 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2432 List<String> methods = intDecl.getMethods();
2433 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
2434 printIncludeStatements(includeClasses); println("");
2435 println("using namespace std;\n");
2436 //writeStructCplus(structDecl);
2437 println("class " + intface); println("{");
2440 writeMethodCplusLocalInterface(methods, intDecl);
2444 System.out.println("IoTCompiler: Generated local interface " + intface + ".hpp...");
2450 * generateCPlusInterfaces() generate stub interfaces based on the methods list in C++
2452 * For C++ we use virtual classe as interface
2454 public void generateCPlusInterfaces() throws IOException {
2456 // Create a new directory
2457 String path = createDirectories(dir, subdir);
2458 for (String intface : mapIntfacePTH.keySet()) {
2460 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
2461 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
2463 // Open a new file to write into
2464 String newIntface = intMeth.getKey();
2465 FileWriter fw = new FileWriter(path + "/" + newIntface + ".hpp");
2466 pw = new PrintWriter(new BufferedWriter(fw));
2467 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2468 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2469 // Write file headers
2470 println("#ifndef _" + newIntface.toUpperCase() + "_HPP__");
2471 println("#define _" + newIntface.toUpperCase() + "_HPP__");
2472 println("#include <iostream>");
2473 // Pass in set of methods and get import classes
2474 Set<String> includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, intface, false);
2475 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
2476 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
2477 printIncludeStatements(allIncludeClasses); println("");
2478 println("using namespace std;\n");
2479 println("class " + newIntface);
2483 writeMethodCplusInterface(intMeth.getValue(), intDecl);
2487 System.out.println("IoTCompiler: Generated interface " + newIntface + ".hpp...");
2494 * HELPER: writeMethodCplusStub() writes the methods of the stub
2496 private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
2498 for (String method : methods) {
2500 List<String> methParams = intDecl.getMethodParams(method);
2501 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2503 //System.out.println("\n\nMethod return type: " + checkAndGetCplusType(intDecl.getMethodType(method)) + "\n\n");
2505 print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2506 intDecl.getMethodId(method) + "(");
2507 boolean isCallbackMethod = false;
2508 String callbackType = null;
2509 for (int i = 0; i < methParams.size(); i++) {
2511 String paramType = methPrmTypes.get(i);
2512 // Check if this has callback object
2513 if (callbackClasses.contains(paramType)) {
2514 isCallbackMethod = true;
2515 callbackType = paramType;
2516 // Even if there're 2 callback arguments, we expect them to be of the same interface
2518 String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
2519 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
2520 print(methParamComplete);
2521 // Check if this is the last element (don't print a comma)
2522 if (i != methParams.size() - 1) {
2527 if (isCallbackMethod)
2528 writeCallbackMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType);
2530 writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method);
2532 // Write the init callback helper method
2533 if (isCallbackMethod) {
2534 writeInitCallbackCplusStub(callbackType, intDecl);
2535 writeInitCallbackSendInfoCplusStub(intDecl);
2542 * HELPER: writeCallbackMethodBodyCplusStub() writes the callback method of the stub class
2544 private void writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
2545 List<String> methPrmTypes, String method, String callbackType) {
2547 // Check if this is single object, array, or list of objects
2548 boolean isArrayOrList = false;
2549 String callbackParam = null;
2550 for (int i = 0; i < methParams.size(); i++) {
2552 String paramType = methPrmTypes.get(i);
2553 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2554 String param = methParams.get(i);
2555 if (isArrayOrList(paramType, param)) { // Generate loop
2556 println("for (" + paramType + "* cb : " + getSimpleIdentifier(param) + ") {");
2557 println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
2558 isArrayOrList = true;
2559 callbackParam = getSimpleIdentifier(param);
2561 println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(" +
2562 getSimpleIdentifier(param) + ", objIdCnt++);");
2563 println("vecCallbackObj.push_back(skel);");
2564 if (isArrayOrList(paramType, param))
2568 println("int numParam = " + methParams.size() + ";");
2569 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
2570 String retType = intDecl.getMethodType(method);
2571 //String retTypeC = checkAndGetCplusType(retType);
2572 //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";");
2573 println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";");
2574 // Generate array of parameter types
2575 print("string paramCls[] = { ");
2576 for (int i = 0; i < methParams.size(); i++) {
2577 String paramType = methPrmTypes.get(i);
2578 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2580 } else { // Generate normal classes if it's not a callback object
2581 //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
2582 //String prmType = getSimpleType(getEnumType(paramTypeC));
2583 String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
2584 String prmType = getEnumType(paramTypeC);
2585 print("\"" + prmType + "\"");
2587 if (i != methParams.size() - 1) // Check if this is the last element
2591 print("int ___paramCB = ");
2593 println(callbackParam + ".size();");
2596 // Generate array of parameter objects
2597 print("void* paramObj[] = { ");
2598 for (int i = 0; i < methParams.size(); i++) {
2599 String paramType = methPrmTypes.get(i);
2600 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2601 print("&___paramCB");
2603 print(getSimpleIdentifier(methParams.get(i)));
2604 if (i != methParams.size() - 1)
2608 // Check if this is "void"
2609 if (retType.equals("void")) {
2610 println("void* retObj = NULL;");
2611 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2612 } else { // We do have a return value
2613 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2614 println(checkAndGetCplusType(retType) + " retVal;");
2616 println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
2617 println("void* retObj = &retVal;");
2618 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2619 println("return retVal;");
2625 * HELPER: checkAndWriteEnumTypeCplusStub() writes the enum type (convert from enum to int)
2627 private void checkAndWriteEnumTypeCplusStub(List<String> methParams, List<String> methPrmTypes) {
2629 // Iterate and find enum declarations
2630 for (int i = 0; i < methParams.size(); i++) {
2631 String paramType = methPrmTypes.get(i);
2632 String param = methParams.get(i);
2633 String simpleType = getSimpleType(paramType);
2634 if (isEnumClass(simpleType)) {
2635 // Check if this is enum type
2636 if (isArrayOrList(paramType, param)) { // An array or vector
2637 println("int len" + i + " = " + param + ".size();");
2638 println("vector<int> paramEnum" + i + "(len);");
2639 println("for (int i = 0; i < len" + i + "; i++) {");
2640 println("paramEnum" + i + "[i] = (int) " + param + "[i];");
2642 } else { // Just one element
2643 println("vector<int> paramEnum" + i + "(1);");
2644 println("paramEnum" + i + "[0] = (int) " + param + ";");
2652 * HELPER: checkAndWriteEnumRetTypeCplusStub() writes the enum return type (convert from enum to int)
2654 private void checkAndWriteEnumRetTypeCplusStub(String retType) {
2656 // Strips off array "[]" for return type
2657 String pureType = getSimpleArrayType(getSimpleType(retType));
2658 // Take the inner type of generic
2659 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2660 pureType = getTypeOfGeneric(retType)[0];
2661 if (isEnumClass(pureType)) {
2662 // Check if this is enum type
2663 println("vector<int> retEnumInt;");
2664 println("void* retObj = &retEnumInt;");
2665 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2666 if (isArrayOrList(retType, retType)) { // An array or vector
2667 println("int retLen = retEnumInt.size();");
2668 println("vector<" + pureType + "> retVal(retLen);");
2669 println("for (int i = 0; i < retLen; i++) {");
2670 println("retVal[i] = (" + pureType + ") retEnumInt[i];");
2672 } else { // Just one element
2673 println(pureType + " retVal = (" + pureType + ") retEnumInt[0];");
2675 println("return retVal;");
2681 * HELPER: checkAndWriteStructSetupCplusStub() writes the struct type setup
2683 private void checkAndWriteStructSetupCplusStub(List<String> methParams, List<String> methPrmTypes,
2684 InterfaceDecl intDecl, String method) {
2686 // Iterate and find struct declarations
2687 for (int i = 0; i < methParams.size(); i++) {
2688 String paramType = methPrmTypes.get(i);
2689 String param = methParams.get(i);
2690 String simpleType = getSimpleType(paramType);
2691 if (isStructClass(simpleType)) {
2692 // Check if this is enum type
2693 println("int numParam" + i + " = 1;");
2694 int methodNumId = intDecl.getMethodNumId(method);
2695 String helperMethod = methodNumId + "struct" + i;
2696 println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
2697 println("string retTypeStruct" + i + " = \"void\";");
2698 println("string paramClsStruct" + i + "[] = { \"int\" };");
2699 print("int structLen" + i + " = ");
2700 if (isArrayOrList(param, paramType)) { // An array
2701 println(getSimpleArrayType(param) + ".size();");
2702 } else { // Just one element
2705 println("void* paramObjStruct" + i + "[] = { &structLen" + i + " };");
2706 println("void* retStructLen" + i + " = NULL;");
2707 println("rmiCall->remoteCall(objectId, methodIdStruct" + i +
2708 ", retTypeStruct" + i + ", paramClsStruct" + i + ", paramObjStruct" + i +
2709 ", numParam" + i + ", retStructLen" + i + ");\n");
2716 * HELPER: writeLengthStructParamClassCplusStub() writes lengths of params
2718 private void writeLengthStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes) {
2720 // Iterate and find struct declarations - count number of params
2721 for (int i = 0; i < methParams.size(); i++) {
2722 String paramType = methPrmTypes.get(i);
2723 String param = methParams.get(i);
2724 String simpleType = getGenericType(paramType);
2725 if (isStructClass(simpleType)) {
2726 int members = getNumOfMembers(simpleType);
2727 if (isArrayOrList(param, paramType)) { // An array
2728 String structLen = param + ".size()";
2729 print(members + "*" + structLen);
2731 print(Integer.toString(members));
2734 if (i != methParams.size() - 1) {
2742 * HELPER: writeStructMembersCplusStub() writes member parameters of struct
2744 private void writeStructMembersCplusStub(String simpleType, String paramType, String param) {
2746 // Get the struct declaration for this struct and generate initialization code
2747 StructDecl structDecl = getStructDecl(simpleType);
2748 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2749 List<String> members = structDecl.getMembers(simpleType);
2750 if (isArrayOrList(param, paramType)) { // An array or list
2751 println("for(int i = 0; i < " + param + ".size(); i++) {");
2753 if (isArrayOrList(param, paramType)) { // An array or list
2754 for (int i = 0; i < members.size(); i++) {
2755 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2756 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2757 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2758 print("paramObj[pos++] = &" + param + "[i].");
2759 print(getSimpleIdentifier(members.get(i)));
2763 } else { // Just one struct element
2764 for (int i = 0; i < members.size(); i++) {
2765 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2766 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2767 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2768 print("paramObj[pos++] = &" + param + ".");
2769 print(getSimpleIdentifier(members.get(i)));
2777 * HELPER: writeStructParamClassCplusStub() writes member parameters of struct
2779 private void writeStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes) {
2781 print("int numParam = ");
2782 writeLengthStructParamClassCplusStub(methParams, methPrmTypes);
2784 println("void* paramObj[numParam];");
2785 println("string paramCls[numParam];");
2786 println("int pos = 0;");
2787 // Iterate again over the parameters
2788 for (int i = 0; i < methParams.size(); i++) {
2789 String paramType = methPrmTypes.get(i);
2790 String param = methParams.get(i);
2791 String simpleType = getGenericType(paramType);
2792 if (isStructClass(simpleType)) {
2793 writeStructMembersCplusStub(simpleType, paramType, param);
2795 String prmTypeC = checkAndGetCplusType(methPrmTypes.get(i));
2796 String prmType = checkAndGetCplusArrayType(prmTypeC, methParams.get(i));
2797 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2798 print("paramObj[pos++] = &");
2799 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
2808 * HELPER: writeStructRetMembersCplusStub() writes member parameters of struct for return statement
2810 private void writeStructRetMembersCplusStub(String simpleType, String retType) {
2812 // Get the struct declaration for this struct and generate initialization code
2813 StructDecl structDecl = getStructDecl(simpleType);
2814 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2815 List<String> members = structDecl.getMembers(simpleType);
2816 if (isArrayOrList(retType, retType)) { // An array or list
2817 println("for(int i = 0; i < retLen; i++) {");
2819 if (isArrayOrList(retType, retType)) { // An array or list
2820 for (int i = 0; i < members.size(); i++) {
2821 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
2822 print("structRet[i]." + getSimpleIdentifier(members.get(i)));
2823 println(" = retParam" + i + "[i];");
2826 } else { // Just one struct element
2827 for (int i = 0; i < members.size(); i++) {
2828 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
2829 print("structRet." + getSimpleIdentifier(members.get(i)));
2830 println(" = retParam" + i + ";");
2833 println("return structRet;");
2838 * HELPER: writeStructReturnCplusStub() writes member parameters of struct for return statement
2840 private void writeStructReturnCplusStub(String simpleType, String retType) {
2842 // Minimum retLen is 1 if this is a single struct object
2843 println("int retLen = 0;");
2844 println("void* retLenObj = { &retLen };");
2845 // Handle the returned struct!!!
2846 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retLenObj);");
2847 int numMem = getNumOfMembers(simpleType);
2848 println("int numRet = " + numMem + "*retLen;");
2849 println("string retCls[numRet];");
2850 println("void* retObj[numRet];");
2851 StructDecl structDecl = getStructDecl(simpleType);
2852 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2853 List<String> members = structDecl.getMembers(simpleType);
2855 if (isArrayOrList(retType, retType)) { // An array or list
2856 for (int i = 0; i < members.size(); i++) {
2857 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2858 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2859 println(getSimpleType(getEnumType(prmType)) + " retParam" + i + "[retLen];");
2861 } else { // Just one struct element
2862 for (int i = 0; i < members.size(); i++) {
2863 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2864 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2865 println(getSimpleType(getEnumType(prmType)) + " retParam" + i + ";");
2868 println("int retPos = 0;");
2869 // Get the struct declaration for this struct and generate initialization code
2870 if (isArrayOrList(retType, retType)) { // An array or list
2871 println("for(int i = 0; i < retLen; i++) {");
2872 for (int i = 0; i < members.size(); i++) {
2873 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2874 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2875 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2876 println("retObj[retPos++] = &retParam" + i + "[i];");
2879 } else { // Just one struct element
2880 for (int i = 0; i < members.size(); i++) {
2881 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2882 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2883 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2884 println("retObj[retPos++] = &retParam" + i + ";");
2887 println("rmiCall->getStructObjects(retCls, numRet, retObj);");
2888 if (isArrayOrList(retType, retType)) { // An array or list
2889 println("vector<" + simpleType + "> structRet(retLen);");
2891 println(simpleType + " structRet;");
2892 writeStructRetMembersCplusStub(simpleType, retType);
2897 * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class
2899 private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
2900 List<String> methPrmTypes, String method) {
2902 checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method);
2903 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
2904 String retType = intDecl.getMethodType(method);
2905 //String retTypeC = checkAndGetCplusType(retType);
2906 //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";");
2907 println("string retType = \"" + checkAndGetCplusRetClsType(getStructType(getEnumType(retType))) + "\";");
2908 // Generate array of parameter types
2909 if (isStructPresent(methParams, methPrmTypes)) {
2910 writeStructParamClassCplusStub(methParams, methPrmTypes);
2912 println("int numParam = " + methParams.size() + ";");
2913 print("string paramCls[] = { ");
2914 for (int i = 0; i < methParams.size(); i++) {
2915 //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
2916 //String prmType = getSimpleType(getEnumType(paramTypeC));
2917 String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
2918 String prmType = getEnumType(paramTypeC);
2919 print("\"" + prmType + "\"");
2920 // Check if this is the last element (don't print a comma)
2921 if (i != methParams.size() - 1) {
2926 checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes);
2927 // Generate array of parameter objects
2928 print("void* paramObj[] = { ");
2929 for (int i = 0; i < methParams.size(); i++) {
2930 print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
2931 // Check if this is the last element (don't print a comma)
2932 if (i != methParams.size() - 1) {
2938 // Check if this is "void"
2939 if (retType.equals("void")) {
2940 println("void* retObj = NULL;");
2941 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2942 } else { // We do have a return value
2943 // Generate array of parameter types
2944 if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
2945 writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType);
2947 // Check if the return value NONPRIMITIVES
2948 if (getParamCategory(retType) == ParamCategory.ENUM) {
2949 checkAndWriteEnumRetTypeCplusStub(retType);
2951 //if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2952 if (isArrayOrList(retType,retType))
2953 println(checkAndGetCplusType(retType) + " retVal;");
2955 println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
2957 println("void* retObj = &retVal;");
2958 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2959 println("return retVal;");
2967 * HELPER: writePropertiesCplusStub() writes the properties of the stub class
2969 private void writePropertiesCplusPermission(String intface) {
2971 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
2972 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
2973 String newIntface = intMeth.getKey();
2974 int newObjectId = mapNewIntfaceObjId.get(newIntface);
2975 println("const static int object" + newObjectId + "Id = " + newObjectId + ";");
2976 println("const static set<int> set" + newObjectId + "Allowed;");
2981 * HELPER: writePropertiesCplusStub() writes the properties of the stub class
2983 private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
2985 println("IoTRMICall *rmiCall;");
2986 //println("IoTRMIObject\t\t\t*rmiObj;");
2987 println("string address;");
2988 println("vector<int> ports;\n");
2989 // Get the object Id
2990 Integer objId = mapIntfaceObjId.get(intface);
2991 println("const static int objectId = " + objId + ";");
2992 mapNewIntfaceObjId.put(newIntface, objId);
2993 mapIntfaceObjId.put(intface, objId++);
2994 if (callbackExist) {
2995 // We assume that each class only has one callback interface for now
2996 Iterator it = callbackClasses.iterator();
2997 String callbackType = (String) it.next();
2998 println("// Callback properties");
2999 println("IoTRMIObject *rmiObj;");
3000 println("vector<" + callbackType + "*> vecCallbackObj;");
3001 println("static int objIdCnt;");
3002 // Generate permission stuff for callback stubs
3003 writePropertiesCplusPermission(callbackType);
3010 * HELPER: writeConstructorCplusStub() writes the constructor of the stub class
3012 private void writeConstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3014 println(newStubClass +
3015 "(int _port, const char* _address, int _rev, bool* _bResult, vector<int> _ports) {");
3016 println("address = _address;");
3017 println("ports = _ports;");
3018 println("rmiCall = new IoTRMICall(_port, _address, _rev, _bResult);");
3019 if (callbackExist) {
3020 println("objIdCnt = 0;");
3021 Iterator it = callbackClasses.iterator();
3022 String callbackType = (String) it.next();
3023 println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
3024 println("th1.detach();");
3025 println("___regCB();");
3032 * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
3034 private void writeDeconstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3036 println("~" + newStubClass + "() {");
3037 println("if (rmiCall != NULL) {");
3038 println("delete rmiCall;");
3039 println("rmiCall = NULL;");
3041 if (callbackExist) {
3042 // We assume that each class only has one callback interface for now
3043 println("if (rmiObj != NULL) {");
3044 println("delete rmiObj;");
3045 println("rmiObj = NULL;");
3047 Iterator it = callbackClasses.iterator();
3048 String callbackType = (String) it.next();
3049 println("for(" + callbackType + "* cb : vecCallbackObj) {");
3050 println("delete cb;");
3051 println("cb = NULL;");
3060 * HELPER: writeCplusMethodCallbackPermission() writes permission checks in stub for callbacks
3062 private void writeCplusMethodCallbackPermission(String intface) {
3064 println("int methodId = IoTRMIObject::getMethodId(method);");
3065 // Get all the different stubs
3066 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3067 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3068 String newIntface = intMeth.getKey();
3069 int newObjectId = mapNewIntfaceObjId.get(newIntface);
3070 println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
3071 println("cerr << \"Callback object for " + intface + " is not allowed to access method: \" << methodId;");
3072 println("exit(-1);");
3079 * HELPER: writeInitCallbackCplusStub() writes the initialization of callback
3081 private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl) {
3083 println("void ___initCallBack() {");
3084 println("bool bResult = false;");
3085 println("rmiObj = new IoTRMIObject(ports[0], &bResult);");
3086 println("while (true) {");
3087 println("char* method = rmiObj->getMethodBytes();");
3088 writeCplusMethodCallbackPermission(intface);
3089 println("int objId = IoTRMIObject::getObjectId(method);");
3090 println("if (objId < vecCallbackObj.size()) { // Check if still within range");
3091 println(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface +
3092 "_CallbackSkeleton*> (vecCallbackObj.at(objId));");
3093 println("skel->invokeMethod(rmiObj);");
3094 println("} else {");
3095 println("cerr << \"Illegal object Id: \" << to_string(objId);");
3096 // TODO: perhaps need to change this into "throw" to make it cleaner (allow stack unfolding)
3097 println("exit(-1);");
3105 * HELPER: writeInitCallbackSendInfoCplusStub() writes the initialization (send info part) of callback
3107 private void writeInitCallbackSendInfoCplusStub(InterfaceDecl intDecl) {
3109 // Generate info sending part
3110 println("void ___regCB() {");
3111 println("int numParam = 3;");
3112 String method = "___initCallBack()";
3113 println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";");
3114 println("string retType = \"void\";");
3115 println("string paramCls[] = { \"int\", \"string\", \"int\" };");
3116 println("int rev = 0;");
3117 println("void* paramObj[] = { &ports[0], &address, &rev };");
3118 println("void* retObj = NULL;");
3119 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
3125 * generateCPlusStubClasses() generate stubs based on the methods list in C++
3127 public void generateCPlusStubClasses() throws IOException {
3129 // Create a new directory
3130 String path = createDirectories(dir, subdir);
3131 for (String intface : mapIntfacePTH.keySet()) {
3133 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3134 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3135 // Open a new file to write into
3136 String newIntface = intMeth.getKey();
3137 String newStubClass = newIntface + "_Stub";
3138 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
3139 pw = new PrintWriter(new BufferedWriter(fw));
3140 // Write file headers
3141 println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
3142 println("#define _" + newStubClass.toUpperCase() + "_HPP__");
3143 println("#include <iostream>");
3144 // Find out if there are callback objects
3145 Set<String> methods = intMeth.getValue();
3146 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
3147 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
3148 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
3149 boolean callbackExist = !callbackClasses.isEmpty();
3150 if (callbackExist) // Need thread library if this has callback
3151 println("#include <thread>");
3152 println("#include \"" + newIntface + ".hpp\""); println("");
3153 println("using namespace std;"); println("");
3154 println("class " + newStubClass + " : public " + newIntface); println("{");
3155 println("private:\n");
3156 writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses);
3157 println("public:\n");
3158 // Add default constructor and destructor
3159 println(newStubClass + "() { }"); println("");
3160 writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3161 writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3163 writeMethodCplusStub(methods, intDecl, callbackClasses);
3164 print("}"); println(";");
3166 writePermissionInitializationCplus(intface, newStubClass, intDecl);
3169 System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
3176 * HELPER: writePropertiesCplusCallbackStub() writes the properties of the stub class
3178 private void writePropertiesCplusCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
3180 println("IoTRMICall *rmiCall;");
3181 // Get the object Id
3182 println("static int objectId;");
3183 if (callbackExist) {
3184 // We assume that each class only has one callback interface for now
3185 Iterator it = callbackClasses.iterator();
3186 String callbackType = (String) it.next();
3187 println("// Callback properties");
3188 println("IoTRMIObject *rmiObj;");
3189 println("vector<" + callbackType + "*> vecCallbackObj;");
3190 println("static int objIdCnt;");
3191 // TODO: Need to initialize address and ports if we want to have callback-in-callback
3192 println("string address;");
3193 println("vector<int> ports;\n");
3194 writePropertiesCplusPermission(callbackType);
3201 * HELPER: writeConstructorCplusCallbackStub() writes the constructor of the stub class
3203 private void writeConstructorCplusCallbackStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3205 println(newStubClass + "(IoTRMICall* _rmiCall, int _objectId) {");
3206 println("objectId = _objectId;");
3207 println("rmiCall = _rmiCall;");
3208 if (callbackExist) {
3209 Iterator it = callbackClasses.iterator();
3210 String callbackType = (String) it.next();
3211 println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
3212 println("th1.detach();");
3213 println("___regCB();");
3220 * generateCPlusCallbackStubClasses() generate callback stubs based on the methods list in C++
3222 public void generateCPlusCallbackStubClasses() throws IOException {
3224 // Create a new directory
3225 String path = createDirectories(dir, subdir);
3226 for (String intface : mapIntfacePTH.keySet()) {
3228 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3229 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3230 // Open a new file to write into
3231 String newIntface = intMeth.getKey();
3232 String newStubClass = newIntface + "_CallbackStub";
3233 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
3234 pw = new PrintWriter(new BufferedWriter(fw));
3235 // Find out if there are callback objects
3236 Set<String> methods = intMeth.getValue();
3237 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
3238 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
3239 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
3240 boolean callbackExist = !callbackClasses.isEmpty();
3241 // Write file headers
3242 println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
3243 println("#define _" + newStubClass.toUpperCase() + "_HPP__");
3244 println("#include <iostream>");
3246 println("#include <thread>");
3247 println("#include \"" + newIntface + ".hpp\""); println("");
3248 println("using namespace std;"); println("");
3249 println("class " + newStubClass + " : public " + newIntface); println("{");
3250 println("private:\n");
3251 writePropertiesCplusCallbackStub(intface, newIntface, callbackExist, callbackClasses);
3252 println("public:\n");
3253 // Add default constructor and destructor
3254 println(newStubClass + "() { }"); println("");
3255 writeConstructorCplusCallbackStub(newStubClass, callbackExist, callbackClasses);
3256 writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3258 writeMethodCplusStub(methods, intDecl, callbackClasses);
3261 writePermissionInitializationCplus(intface, newStubClass, intDecl);
3264 System.out.println("IoTCompiler: Generated callback stub class " + newIntface + ".hpp...");
3271 * HELPER: writePropertiesCplusSkeleton() writes the properties of the skeleton class
3273 private void writePropertiesCplusSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
3275 println(intface + " *mainObj;");
3277 if (callbackExist) {
3278 Iterator it = callbackClasses.iterator();
3279 String callbackType = (String) it.next();
3280 String exchangeType = checkAndGetParamClass(callbackType);
3281 println("// Callback properties");
3282 println("static int objIdCnt;");
3283 println("vector<" + exchangeType + "*> vecCallbackObj;");
3284 println("IoTRMICall *rmiCall;");
3286 println("IoTRMIObject *rmiObj;\n");
3287 // Keep track of object Ids of all stubs registered to this interface
3288 writePropertiesCplusPermission(intface);
3294 * HELPER: writePermissionInitializationCplus() writes the initialization of permission set
3296 private void writePermissionInitializationCplus(String intface, String newSkelClass, InterfaceDecl intDecl) {
3298 // Keep track of object Ids of all stubs registered to this interface
3299 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3300 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3301 String newIntface = intMeth.getKey();
3302 int newObjectId = mapNewIntfaceObjId.get(newIntface);
3303 print("const set<int> " + newSkelClass + "::set" + newObjectId + "Allowed {");
3304 Set<String> methodIds = intMeth.getValue();
3306 for (String methodId : methodIds) {
3307 int methodNumId = intDecl.getMethodNumId(methodId);
3308 print(Integer.toString(methodNumId));
3309 // Check if this is the last element (don't print a comma)
3310 if (i != methodIds.size() - 1) {
3321 * HELPER: writeConstructorCplusSkeleton() writes the constructor of the skeleton class
3323 private void writeConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist) {
3325 println(newSkelClass + "(" + intface + " *_mainObj, int _port) {");
3326 println("bool _bResult = false;");
3327 println("mainObj = _mainObj;");
3328 println("rmiObj = new IoTRMIObject(_port, &_bResult);");
3330 if (callbackExist) {
3331 println("objIdCnt = 0;");
3333 //println("set0Allowed = Arrays.asList(object0Permission);");
3334 println("___waitRequestInvokeMethod();");
3340 * HELPER: writeDeconstructorCplusSkeleton() writes the deconstructor of the skeleton class
3342 private void writeDeconstructorCplusSkeleton(String newSkelClass, boolean callbackExist, Set<String> callbackClasses) {
3344 println("~" + newSkelClass + "() {");
3345 println("if (rmiObj != NULL) {");
3346 println("delete rmiObj;");
3347 println("rmiObj = NULL;");
3349 if (callbackExist) {
3350 // We assume that each class only has one callback interface for now
3351 println("if (rmiCall != NULL) {");
3352 println("delete rmiCall;");
3353 println("rmiCall = NULL;");
3355 Iterator it = callbackClasses.iterator();
3356 String callbackType = (String) it.next();
3357 String exchangeType = checkAndGetParamClass(callbackType);
3358 println("for(" + exchangeType + "* cb : vecCallbackObj) {");
3359 println("delete cb;");
3360 println("cb = NULL;");
3369 * HELPER: writeStdMethodBodyCplusSkeleton() writes the standard method body in the skeleton class
3371 private void writeStdMethodBodyCplusSkeleton(List<String> methParams, String methodId, String methodType) {
3373 if (methodType.equals("void"))
3374 print("mainObj->" + methodId + "(");
3376 print("return mainObj->" + methodId + "(");
3377 for (int i = 0; i < methParams.size(); i++) {
3379 print(getSimpleIdentifier(methParams.get(i)));
3380 // Check if this is the last element (don't print a comma)
3381 if (i != methParams.size() - 1) {
3390 * HELPER: writeInitCallbackCplusSkeleton() writes the init callback method for skeleton class
3392 private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton) {
3394 // This is a callback skeleton generation
3395 if (callbackSkeleton)
3396 println("void ___regCB(IoTRMIObject* rmiObj) {");
3398 println("void ___regCB() {");
3399 println("int numParam = 3;");
3400 println("int param1 = 0;");
3401 println("string param2 = \"\";");
3402 println("int param3 = 0;");
3403 println("void* paramObj[] = { ¶m1, ¶m2, ¶m3 };");
3404 println("bool bResult = false;");
3405 println("rmiCall = new IoTRMICall(param1, param2.c_str(), param3, &bResult);");
3411 * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
3413 private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
3414 Set<String> callbackClasses, boolean callbackSkeleton) {
3416 for (String method : methods) {
3418 List<String> methParams = intDecl.getMethodParams(method);
3419 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3420 String methodId = intDecl.getMethodId(method);
3421 String methodType = checkAndGetCplusType(intDecl.getMethodType(method));
3422 print(methodType + " " + methodId + "(");
3423 boolean isCallbackMethod = false;
3424 String callbackType = null;
3425 for (int i = 0; i < methParams.size(); i++) {
3427 String origParamType = methPrmTypes.get(i);
3428 if (callbackClasses.contains(origParamType)) { // Check if this has callback object
3429 isCallbackMethod = true;
3430 callbackType = origParamType;
3432 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
3433 String methPrmType = checkAndGetCplusType(paramType);
3434 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
3435 print(methParamComplete);
3436 // Check if this is the last element (don't print a comma)
3437 if (i != methParams.size() - 1) {
3442 // Now, write the body of skeleton!
3443 writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method));
3445 if (isCallbackMethod)
3446 writeInitCallbackCplusSkeleton(callbackSkeleton);
3452 * HELPER: writeCallbackCplusNumStubs() writes the numStubs variable
3454 private void writeCallbackCplusNumStubs(List<String> methParams, List<String> methPrmTypes, String callbackType) {
3456 for (int i = 0; i < methParams.size(); i++) {
3457 String paramType = methPrmTypes.get(i);
3458 String param = methParams.get(i);
3459 //if (callbackType.equals(paramType)) {
3460 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
3461 String exchParamType = checkAndGetParamClass(paramType);
3462 // Print array if this is array or list if this is a list of callback objects
3463 println("int numStubs" + i + " = 0;");
3470 * HELPER: writeCallbackCplusStubGeneration() writes the callback stub generation part
3472 private void writeCallbackCplusStubGeneration(List<String> methParams, List<String> methPrmTypes, String callbackType) {
3474 // Iterate over callback objects
3475 for (int i = 0; i < methParams.size(); i++) {
3476 String paramType = methPrmTypes.get(i);
3477 String param = methParams.get(i);
3478 // Generate a loop if needed
3479 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
3480 String exchParamType = checkAndGetParamClass(paramType);
3481 if (isArrayOrList(paramType, param)) {
3482 println("vector<" + exchParamType + "> stub;");
3483 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
3484 println(exchParamType + "* cb" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
3485 println("stub" + i + ".push_back(cb);");
3486 println("vecCallbackObj.push_back(cb);");
3487 println("objIdCnt++;");
3490 println(exchParamType + "* stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
3491 println("vecCallbackObj.push_back(stub" + i + ");");
3492 println("objIdCnt++;");
3500 * HELPER: checkAndWriteEnumTypeCplusSkeleton() writes the enum type (convert from enum to int)
3502 private void checkAndWriteEnumTypeCplusSkeleton(List<String> methParams, List<String> methPrmTypes) {
3504 // Iterate and find enum declarations
3505 for (int i = 0; i < methParams.size(); i++) {
3506 String paramType = methPrmTypes.get(i);
3507 String param = methParams.get(i);
3508 String simpleType = getSimpleType(paramType);
3509 if (isEnumClass(simpleType)) {
3510 // Check if this is enum type
3511 if (isArrayOrList(paramType, param)) { // An array
3512 println("int len" + i + " = paramEnumInt" + i + ".size();");
3513 println("vector<" + simpleType + "> paramEnum" + i + "(len" + i + ");");
3514 println("for (int i=0; i < len" + i + "; i++) {");
3515 println("paramEnum" + i + "[i] = (" + simpleType + ") paramEnumInt" + i + "[i];");
3517 } else { // Just one element
3518 println(simpleType + " paramEnum" + i + ";");
3519 println("paramEnum" + i + " = (" + simpleType + ") paramEnumInt" + i + "[0];");
3527 * HELPER: checkAndWriteEnumRetTypeCplusSkeleton() writes the enum return type (convert from enum to int)
3529 private void checkAndWriteEnumRetTypeCplusSkeleton(String retType) {
3531 // Strips off array "[]" for return type
3532 String pureType = getSimpleArrayType(getSimpleType(retType));
3533 // Take the inner type of generic
3534 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
3535 pureType = getTypeOfGeneric(retType)[0];
3536 if (isEnumClass(pureType)) {
3537 // Check if this is enum type
3539 if (isArrayOrList(retType, retType)) { // An array
3540 println("int retLen = retEnum.size();");
3541 println("vector<int> retEnumInt(retLen);");
3542 println("for (int i=0; i < retLen; i++) {");
3543 println("retEnumInt[i] = (int) retEnum[i];");
3545 } else { // Just one element
3546 println("vector<int> retEnumInt(1);");
3547 println("retEnumInt[0] = (int) retEnum;");
3554 * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton
3556 private void writeMethodInputParameters(List<String> methParams, List<String> methPrmTypes,
3557 Set<String> callbackClasses, String methodId) {
3559 print(methodId + "(");
3560 for (int i = 0; i < methParams.size(); i++) {
3561 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3562 if (callbackClasses.contains(paramType))
3564 else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
3565 print("paramEnum" + i);
3566 else if (isStructClass(getSimpleType(paramType))) // Struct type
3567 print("paramStruct" + i);
3569 print(getSimpleIdentifier(methParams.get(i)));
3570 if (i != methParams.size() - 1) {
3579 * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton
3581 private void writeMethodHelperReturnCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3582 List<String> methPrmTypes, String method, boolean isCallbackMethod, String callbackType,
3583 String methodId, Set<String> callbackClasses) {
3585 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3586 if (isCallbackMethod)
3587 writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType);
3588 checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes);
3589 writeStructMembersInitCplusSkeleton(intDecl, methParams, methPrmTypes, method);
3590 // Check if this is "void"
3591 String retType = intDecl.getMethodType(method);
3592 // Check if this is "void"
3593 if (retType.equals("void")) {
3594 writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
3595 } else { // We do have a return value
3596 if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type
3597 print(checkAndGetCplusType(retType) + " retEnum = ");
3598 else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3599 print(checkAndGetCplusType(retType) + " retStruct = ");
3601 print(checkAndGetCplusType(retType) + " retVal = ");
3602 writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
3603 checkAndWriteEnumRetTypeCplusSkeleton(retType);
3604 if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3605 writeStructReturnCplusSkeleton(getSimpleArrayType(getSimpleType(retType)), retType);
3606 if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type
3607 println("void* retObj = &retEnumInt;");
3609 if (!isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3610 println("void* retObj = &retVal;");
3611 String retTypeC = checkAndGetCplusType(retType);
3612 if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3613 println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);");
3615 println("rmiObj->sendReturnObj(retObj, \"" + checkAndGetCplusRetClsType(getEnumType(retType)) + "\");");
3621 * HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class
3623 private void writeStdMethodHelperBodyCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3624 List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
3626 // Generate array of parameter types
3627 boolean isCallbackMethod = false;
3628 String callbackType = null;
3629 print("string paramCls[] = { ");
3630 for (int i = 0; i < methParams.size(); i++) {
3631 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3632 if (callbackClasses.contains(paramType)) {
3633 isCallbackMethod = true;
3634 callbackType = paramType;
3636 } else { // Generate normal classes if it's not a callback object
3637 //String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
3638 //String prmType = getSimpleType(getEnumType(paramTypeC));
3639 String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
3640 String prmType = getEnumType(paramTypeC);
3641 print("\"" + prmType + "\"");
3643 if (i != methParams.size() - 1) {
3648 println("int numParam = " + methParams.size() + ";");
3649 if (isCallbackMethod)
3650 writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType);
3651 // Generate parameters
3652 for (int i = 0; i < methParams.size(); i++) {
3653 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3654 if (!callbackClasses.contains(paramType)) {
3655 String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
3656 if (isEnumClass(getSimpleType(methPrmType))) { // Check if this is enum type
3657 println("vector<int> paramEnumInt" + i + ";");
3659 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
3660 println(methParamComplete + ";");
3664 // Generate array of parameter objects
3665 print("void* paramObj[] = { ");
3666 for (int i = 0; i < methParams.size(); i++) {
3667 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3668 if (callbackClasses.contains(paramType))
3669 print("&numStubs" + i);
3670 else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
3671 print("¶mEnumInt" + i);
3673 print("&" + getSimpleIdentifier(methParams.get(i)));
3674 if (i != methParams.size() - 1) {
3679 // Write the return value part
3680 writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
3681 callbackType, methodId, callbackClasses);
3686 * HELPER: writeStructMembersCplusSkeleton() writes member parameters of struct
3688 private void writeStructMembersCplusSkeleton(String simpleType, String paramType,
3689 String param, String method, InterfaceDecl intDecl, int iVar) {
3691 // Get the struct declaration for this struct and generate initialization code
3692 StructDecl structDecl = getStructDecl(simpleType);
3693 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3694 List<String> members = structDecl.getMembers(simpleType);
3695 int methodNumId = intDecl.getMethodNumId(method);
3696 String counter = "struct" + methodNumId + "Size" + iVar;
3697 if (isArrayOrList(param, paramType)) { // An array or list
3698 println("for(int i = 0; i < " + counter + "; i++) {");
3701 if (isArrayOrList(param, paramType)) { // An array or list
3702 for (int i = 0; i < members.size(); i++) {
3703 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3704 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3705 println(getSimpleType(getEnumType(prmType)) + " param" + i + "[" + counter + "];");
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(getSimpleType(getEnumType(prmType)) + " param" + i + ";");
3714 println("int pos = 0;");
3715 if (isArrayOrList(param, paramType)) { // An array or list
3716 println("for(int i = 0; i < retLen; i++) {");
3717 for (int i = 0; i < members.size(); i++) {
3718 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3719 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3720 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3721 println("paramObj[pos++] = ¶m" + i + "[i];");
3724 } else { // Just one struct element
3725 for (int i = 0; i < members.size(); i++) {
3726 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3727 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3728 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3729 println("paramObj[pos++] = ¶m" + i + ";");
3736 * HELPER: writeStructMembersInitCplusSkeleton() writes member parameters initialization of struct
3738 private void writeStructMembersInitCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3739 List<String> methPrmTypes, String method) {
3741 for (int i = 0; i < methParams.size(); i++) {
3742 String paramType = methPrmTypes.get(i);
3743 String param = methParams.get(i);
3744 String simpleType = getGenericType(paramType);
3745 if (isStructClass(simpleType)) {
3746 int methodNumId = intDecl.getMethodNumId(method);
3747 String counter = "struct" + methodNumId + "Size" + i;
3749 if (isArrayOrList(param, paramType)) { // An array or list
3750 println("vector<" + simpleType + "> paramStruct" + i + ";");
3752 println(simpleType + " paramStruct" + i + ";");
3753 // Initialize members
3754 StructDecl structDecl = getStructDecl(simpleType);
3755 List<String> members = structDecl.getMembers(simpleType);
3756 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3757 if (isArrayOrList(param, paramType)) { // An array or list
3758 println("for(int i = 0; i < " + counter + "; i++) {");
3759 for (int j = 0; j < members.size(); j++) {
3760 print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j)));
3761 println(" = param" + j + "[i];");
3764 } else { // Just one struct element
3765 for (int j = 0; j < members.size(); j++) {
3766 print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j)));
3767 println(" = param" + j + ";");
3776 * HELPER: writeStructReturnCplusSkeleton() writes parameters of struct for return statement
3778 private void writeStructReturnCplusSkeleton(String simpleType, String retType) {
3780 // Minimum retLen is 1 if this is a single struct object
3781 if (isArrayOrList(retType, retType))
3782 println("int retLen = retStruct.size();");
3783 else // Just single struct object
3784 println("int retLen = 1;");
3785 println("void* retLenObj = &retLen;");
3786 println("rmiObj->sendReturnObj(retLenObj, \"int\");");
3787 int numMem = getNumOfMembers(simpleType);
3788 println("int numRetObj = " + numMem + "*retLen;");
3789 println("string retCls[numRetObj];");
3790 println("void* retObj[numRetObj];");
3791 println("int retPos = 0;");
3792 // Get the struct declaration for this struct and generate initialization code
3793 StructDecl structDecl = getStructDecl(simpleType);
3794 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3795 List<String> members = structDecl.getMembers(simpleType);
3796 if (isArrayOrList(retType, retType)) { // An array or list
3797 println("for(int i = 0; i < retLen; i++) {");
3798 for (int i = 0; i < members.size(); i++) {
3799 String paramTypeC = checkAndGetCplusType(memTypes.get(i));
3800 String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i));
3801 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3802 print("retObj[retPos++] = &retStruct[i].");
3803 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
3807 } else { // Just one struct element
3808 for (int i = 0; i < members.size(); i++) {
3809 String paramTypeC = checkAndGetCplusType(memTypes.get(i));
3810 String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i));
3811 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3812 print("retObj[retPos++] = &retStruct.");
3813 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
3822 * HELPER: writeMethodHelperStructCplusSkeleton() writes the struct in skeleton
3824 private void writeMethodHelperStructCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3825 List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
3827 // Generate array of parameter objects
3828 boolean isCallbackMethod = false;
3829 String callbackType = null;
3830 print("int numParam = ");
3831 writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
3833 println("string paramCls[numParam];");
3834 println("void* paramObj[numParam];");
3835 // Iterate again over the parameters
3836 for (int i = 0; i < methParams.size(); i++) {
3837 String paramType = methPrmTypes.get(i);
3838 String param = methParams.get(i);
3839 String simpleType = getGenericType(paramType);
3840 if (isStructClass(simpleType)) {
3841 writeStructMembersCplusSkeleton(simpleType, paramType, param, method, intDecl, i);
3843 String prmType = returnGenericCallbackType(methPrmTypes.get(i));
3844 if (callbackClasses.contains(prmType)) {
3845 isCallbackMethod = true;
3846 callbackType = paramType;
3847 writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType);
3848 println("paramCls[pos] = \"int\";");
3849 println("paramObj[pos++] = &numStubs" + i + ";");
3850 } else { // Generate normal classes if it's not a callback object
3851 String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
3852 String prmTypeC = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
3853 if (isEnumClass(getSimpleType(paramTypeC))) { // Check if this is enum type
3854 println("vector<int> paramEnumInt" + i + ";");
3856 String methParamComplete = checkAndGetCplusArray(paramTypeC, methParams.get(i));
3857 println(methParamComplete + ";");
3859 println("paramCls[pos] = \"" + getEnumType(prmTypeC) + "\";");
3860 if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
3861 println("paramObj[pos++] = ¶mEnumInt" + i);
3863 println("paramObj[pos++] = &" + getSimpleIdentifier(methParams.get(i)) + ";");
3867 // Write the return value part
3868 writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
3869 callbackType, methodId, callbackClasses);
3874 * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
3876 private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
3878 // Use this set to handle two same methodIds
3879 Set<String> uniqueMethodIds = new HashSet<String>();
3880 for (String method : methods) {
3882 List<String> methParams = intDecl.getMethodParams(method);
3883 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3884 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
3885 String methodId = intDecl.getMethodId(method);
3887 String helperMethod = methodId;
3888 if (uniqueMethodIds.contains(methodId))
3889 helperMethod = helperMethod + intDecl.getMethodNumId(method);
3891 uniqueMethodIds.add(methodId);
3892 String retType = intDecl.getMethodType(method);
3893 print(helperMethod + "(");
3894 boolean begin = true;
3895 for (int i = 0; i < methParams.size(); i++) { // Print size variables
3896 String paramType = methPrmTypes.get(i);
3897 String param = methParams.get(i);
3898 String simpleType = getSimpleType(paramType);
3899 if (isStructClass(simpleType)) {
3900 if (!begin) { // Generate comma for not the beginning variable
3901 print(", "); begin = false;
3903 int methodNumId = intDecl.getMethodNumId(method);
3904 print("int struct" + methodNumId + "Size" + i);
3908 writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
3911 String methodId = intDecl.getMethodId(method);
3913 String helperMethod = methodId;
3914 if (uniqueMethodIds.contains(methodId))
3915 helperMethod = helperMethod + intDecl.getMethodNumId(method);
3917 uniqueMethodIds.add(methodId);
3918 // Check if this is "void"
3919 String retType = intDecl.getMethodType(method);
3920 println(helperMethod + "() {");
3921 // Now, write the helper body of skeleton!
3922 writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
3926 // Write method helper for structs
3927 writeMethodHelperStructSetupCplusSkeleton(methods, intDecl);
3932 * HELPER: writeMethodHelperStructSetupCplusSkeleton() writes the method helper of struct in skeleton class
3934 private void writeMethodHelperStructSetupCplusSkeleton(Collection<String> methods,
3935 InterfaceDecl intDecl) {
3937 // Use this set to handle two same methodIds
3938 for (String method : methods) {
3940 List<String> methParams = intDecl.getMethodParams(method);
3941 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3942 // Check for params with structs
3943 for (int i = 0; i < methParams.size(); i++) {
3944 String paramType = methPrmTypes.get(i);
3945 String param = methParams.get(i);
3946 String simpleType = getSimpleType(paramType);
3947 if (isStructClass(simpleType)) {
3948 int methodNumId = intDecl.getMethodNumId(method);
3950 String helperMethod = methodNumId + "struct" + i;
3951 println(helperMethod + "() {");
3952 // Now, write the helper body of skeleton!
3953 println("string paramCls[] = { \"int\" };");
3954 println("int numParam = 1;");
3955 println("int param0 = 0;");
3956 println("void* paramObj[] = { ¶m0 };");
3957 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3958 println("return param0;");
3967 * HELPER: writeMethodHelperStructSetupCplusCallbackSkeleton() writes the method helper of struct in skeleton class
3969 private void writeMethodHelperStructSetupCplusCallbackSkeleton(Collection<String> methods,
3970 InterfaceDecl intDecl) {
3972 // Use this set to handle two same methodIds
3973 for (String method : methods) {
3975 List<String> methParams = intDecl.getMethodParams(method);
3976 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3977 // Check for params with structs
3978 for (int i = 0; i < methParams.size(); i++) {
3979 String paramType = methPrmTypes.get(i);
3980 String param = methParams.get(i);
3981 String simpleType = getSimpleType(paramType);
3982 if (isStructClass(simpleType)) {
3983 int methodNumId = intDecl.getMethodNumId(method);
3985 String helperMethod = methodNumId + "struct" + i;
3986 println(helperMethod + "(IoTRMIObject* rmiObj) {");
3987 // Now, write the helper body of skeleton!
3988 println("string paramCls[] = { \"int\" };");
3989 println("int numParam = 1;");
3990 println("int param0 = 0;");
3991 println("void* paramObj[] = { ¶m0 };");
3992 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3993 println("return param0;");
4002 * HELPER: writeCplusMethodPermission() writes permission checks in skeleton
4004 private void writeCplusMethodPermission(String intface) {
4006 // Get all the different stubs
4007 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
4008 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
4009 String newIntface = intMeth.getKey();
4010 int newObjectId = mapNewIntfaceObjId.get(newIntface);
4011 println("if (_objectId == object" + newObjectId + "Id) {");
4012 println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
4013 println("cerr << \"Object with object Id: \" << _objectId << \" is not allowed to access method: \" << methodId << endl;");
4014 println("exit(-1);");
4018 println("cerr << \"Object Id: \" << _objectId << \" not recognized!\" << endl;");
4019 println("exit(-1);");
4026 * HELPER: writeCplusWaitRequestInvokeMethod() writes the main loop of the skeleton class
4028 private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
4030 // Use this set to handle two same methodIds
4031 Set<String> uniqueMethodIds = new HashSet<String>();
4032 println("void ___waitRequestInvokeMethod() {");
4033 // Write variables here if we have callbacks or enums or structs
4034 writeCountVarStructSkeleton(methods, intDecl);
4035 println("while (true) {");
4036 println("rmiObj->getMethodBytes();");
4037 println("int _objectId = rmiObj->getObjectId();");
4038 println("int methodId = rmiObj->getMethodId();");
4039 // Generate permission check
4040 writeCplusMethodPermission(intface);
4041 println("switch (methodId) {");
4042 // Print methods and method Ids
4043 for (String method : methods) {
4044 String methodId = intDecl.getMethodId(method);
4045 int methodNumId = intDecl.getMethodNumId(method);
4046 print("case " + methodNumId + ": ___");
4047 String helperMethod = methodId;
4048 if (uniqueMethodIds.contains(methodId))
4049 helperMethod = helperMethod + methodNumId;
4051 uniqueMethodIds.add(methodId);
4052 print(helperMethod + "(");
4053 writeInputCountVarStructSkeleton(method, intDecl);
4054 println("); break;");
4056 String method = "___initCallBack()";
4057 // Print case -9999 (callback handler) if callback exists
4058 if (callbackExist) {
4059 int methodId = intDecl.getHelperMethodNumId(method);
4060 println("case " + methodId + ": ___regCB(); break;");
4062 writeMethodCallStructSkeleton(methods, intDecl);
4063 println("default: ");
4064 println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
4065 println("throw exception();");
4073 * generateCplusSkeletonClass() generate skeletons based on the methods list in C++
4075 public void generateCplusSkeletonClass() throws IOException {
4077 // Create a new directory
4078 String path = createDirectories(dir, subdir);
4079 for (String intface : mapIntfacePTH.keySet()) {
4080 // Open a new file to write into
4081 String newSkelClass = intface + "_Skeleton";
4082 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
4083 pw = new PrintWriter(new BufferedWriter(fw));
4084 // Write file headers
4085 println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
4086 println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
4087 println("#include <iostream>");
4088 println("#include \"" + intface + ".hpp\"\n");
4089 // Pass in set of methods and get import classes
4090 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4091 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
4092 List<String> methods = intDecl.getMethods();
4093 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
4094 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
4095 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
4096 printIncludeStatements(allIncludeClasses); println("");
4097 println("using namespace std;\n");
4098 // Find out if there are callback objects
4099 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
4100 boolean callbackExist = !callbackClasses.isEmpty();
4101 // Write class header
4102 println("class " + newSkelClass + " : public " + intface); println("{");
4103 println("private:\n");
4105 writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses);
4106 println("public:\n");
4107 // Write constructor
4108 writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist);
4109 // Write deconstructor
4110 writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
4112 writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false);
4113 // Write method helper
4114 writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses);
4115 // Write waitRequestInvokeMethod() - main loop
4116 writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
4118 writePermissionInitializationCplus(intface, newSkelClass, intDecl);
4121 System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
4127 * HELPER: writePropertiesCplusCallbackSkeleton() writes the properties of the callback skeleton class
4129 private void writePropertiesCplusCallbackSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
4131 println(intface + " *mainObj;");
4132 // Keep track of object Ids of all stubs registered to this interface
4133 println("static int objectId;");
4135 if (callbackExist) {
4136 Iterator it = callbackClasses.iterator();
4137 String callbackType = (String) it.next();
4138 String exchangeType = checkAndGetParamClass(callbackType);
4139 println("// Callback properties");
4140 println("IoTRMICall* rmiCall;");
4141 println("vector<" + exchangeType + "*> vecCallbackObj;");
4142 println("static int objIdCnt;");
4149 * HELPER: writeConstructorCplusCallbackSkeleton() writes the constructor of the skeleton class
4151 private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface, boolean callbackExist) {
4153 println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {");
4154 println("mainObj = _mainObj;");
4155 println("objectId = _objectId;");
4157 if (callbackExist) {
4158 println("objIdCnt = 0;");
4165 * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
4167 private void writeDeconstructorCplusCallbackSkeleton(String newStubClass, boolean callbackExist,
4168 Set<String> callbackClasses) {
4170 println("~" + newStubClass + "() {");
4171 if (callbackExist) {
4172 // We assume that each class only has one callback interface for now
4173 println("if (rmiCall != NULL) {");
4174 println("delete rmiCall;");
4175 println("rmiCall = NULL;");
4177 Iterator it = callbackClasses.iterator();
4178 String callbackType = (String) it.next();
4179 String exchangeType = checkAndGetParamClass(callbackType);
4180 println("for(" + exchangeType + "* cb : vecCallbackObj) {");
4181 println("delete cb;");
4182 println("cb = NULL;");
4191 * HELPER: writeMethodHelperCplusCallbackSkeleton() writes the method helper of callback skeleton class
4193 private void writeMethodHelperCplusCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl,
4194 Set<String> callbackClasses) {
4196 // Use this set to handle two same methodIds
4197 Set<String> uniqueMethodIds = new HashSet<String>();
4198 for (String method : methods) {
4200 List<String> methParams = intDecl.getMethodParams(method);
4201 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4202 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
4203 String methodId = intDecl.getMethodId(method);
4205 String helperMethod = methodId;
4206 if (uniqueMethodIds.contains(methodId))
4207 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4209 uniqueMethodIds.add(methodId);
4210 String retType = intDecl.getMethodType(method);
4211 print(helperMethod + "(");
4212 boolean begin = true;
4213 for (int i = 0; i < methParams.size(); i++) { // Print size variables
4214 String paramType = methPrmTypes.get(i);
4215 String param = methParams.get(i);
4216 String simpleType = getSimpleType(paramType);
4217 if (isStructClass(simpleType)) {
4218 if (!begin) { // Generate comma for not the beginning variable
4219 print(", "); begin = false;
4221 int methodNumId = intDecl.getMethodNumId(method);
4222 print("int struct" + methodNumId + "Size" + i);
4225 println(", IoTRMIObject* rmiObj) {");
4226 writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4229 String methodId = intDecl.getMethodId(method);
4231 String helperMethod = methodId;
4232 if (uniqueMethodIds.contains(methodId))
4233 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4235 uniqueMethodIds.add(methodId);
4236 // Check if this is "void"
4237 String retType = intDecl.getMethodType(method);
4238 println(helperMethod + "(IoTRMIObject* rmiObj) {");
4239 // Now, write the helper body of skeleton!
4240 writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4244 // Write method helper for structs
4245 writeMethodHelperStructSetupCplusCallbackSkeleton(methods, intDecl);
4250 * HELPER: writeCplusCallbackWaitRequestInvokeMethod() writes the request invoke method of the skeleton callback class
4252 private void writeCplusCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl,
4253 boolean callbackExist) {
4255 // Use this set to handle two same methodIds
4256 Set<String> uniqueMethodIds = new HashSet<String>();
4257 println("void invokeMethod(IoTRMIObject* rmiObj) {");
4258 // Write variables here if we have callbacks or enums or structs
4259 writeCountVarStructSkeleton(methods, intDecl);
4260 // Write variables here if we have callbacks or enums or structs
4261 println("int methodId = rmiObj->getMethodId();");
4262 // TODO: code the permission check here!
4263 println("switch (methodId) {");
4264 // Print methods and method Ids
4265 for (String method : methods) {
4266 String methodId = intDecl.getMethodId(method);
4267 int methodNumId = intDecl.getMethodNumId(method);
4268 print("case " + methodNumId + ": ___");
4269 String helperMethod = methodId;
4270 if (uniqueMethodIds.contains(methodId))
4271 helperMethod = helperMethod + methodNumId;
4273 uniqueMethodIds.add(methodId);
4274 print(helperMethod + "(");
4275 if (writeInputCountVarStructSkeleton(method, intDecl))
4276 println(", rmiObj); break;");
4278 println("rmiObj); break;");
4280 String method = "___initCallBack()";
4281 // Print case -9999 (callback handler) if callback exists
4282 if (callbackExist) {
4283 int methodId = intDecl.getHelperMethodNumId(method);
4284 println("case " + methodId + ": ___regCB(rmiObj); break;");
4286 writeMethodCallStructCallbackSkeleton(methods, intDecl);
4287 println("default: ");
4288 println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
4289 println("throw exception();");
4296 * generateCplusCallbackSkeletonClass() generate callback skeletons based on the methods list in C++
4298 public void generateCplusCallbackSkeletonClass() throws IOException {
4300 // Create a new directory
4301 String path = createDirectories(dir, subdir);
4302 for (String intface : mapIntfacePTH.keySet()) {
4303 // Open a new file to write into
4304 String newSkelClass = intface + "_CallbackSkeleton";
4305 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
4306 pw = new PrintWriter(new BufferedWriter(fw));
4307 // Write file headers
4308 println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
4309 println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
4310 println("#include <iostream>");
4311 println("#include \"" + intface + ".hpp\"\n");
4312 // Pass in set of methods and get import classes
4313 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4314 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
4315 List<String> methods = intDecl.getMethods();
4316 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
4317 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
4318 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
4319 printIncludeStatements(allIncludeClasses); println("");
4320 // Find out if there are callback objects
4321 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
4322 boolean callbackExist = !callbackClasses.isEmpty();
4323 println("using namespace std;\n");
4324 // Write class header
4325 println("class " + newSkelClass + " : public " + intface); println("{");
4326 println("private:\n");
4328 writePropertiesCplusCallbackSkeleton(intface, callbackExist, callbackClasses);
4329 println("public:\n");
4330 // Write constructor
4331 writeConstructorCplusCallbackSkeleton(newSkelClass, intface, callbackExist);
4332 // Write deconstructor
4333 writeDeconstructorCplusCallbackSkeleton(newSkelClass, callbackExist, callbackClasses);
4335 writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true);
4336 // Write method helper
4337 writeMethodHelperCplusCallbackSkeleton(methods, intDecl, callbackClasses);
4338 // Write waitRequestInvokeMethod() - main loop
4339 writeCplusCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
4343 System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".hpp...");
4349 * generateInitializer() generate initializer based on type
4351 public String generateCplusInitializer(String type) {
4353 // Generate dummy returns for now
4354 if (type.equals("short")||
4355 type.equals("int") ||
4356 type.equals("long") ||
4357 type.equals("float")||
4358 type.equals("double")) {
4361 } else if ( type.equals("String") ||
4362 type.equals("string")) {
4365 } else if ( type.equals("char") ||
4366 type.equals("byte")) {
4369 } else if ( type.equals("boolean")) {
4379 * setDirectory() sets a new directory for stub files
4381 public void setDirectory(String _subdir) {
4388 * printUsage() prints the usage of this compiler
4390 public static void printUsage() {
4392 System.out.println();
4393 System.out.println("Sentinel interface and stub compiler version 1.0");
4394 System.out.println("Copyright (c) 2015-2016 University of California, Irvine - Programming Language Group.");
4395 System.out.println("All rights reserved.");
4396 System.out.println("Usage:");
4397 System.out.println("\tjava IoTCompiler -help / --help / -h\n");
4398 System.out.println("\t\tDisplay this help texts\n\n");
4399 System.out.println("\tjava IoTCompiler [<main-policy-file> <req-policy-file>]");
4400 System.out.println("\tjava IoTCompiler [<main-policy-file> <req-policy-file>] [options]\n");
4401 System.out.println("\t\tTake one or more pairs of main-req policy files, and generate Java and/or C++ files\n");
4402 System.out.println("Options:");
4403 System.out.println("\t-java\t<directory>\tGenerate Java stub files");
4404 System.out.println("\t-cplus\t<directory>\tGenerate C++ stub files");
4405 System.out.println();
4410 * parseFile() prepares Lexer and Parser objects, then parses the file
4412 public static ParseNode parseFile(String file) {
4414 ParseNode pn = null;
4416 ComplexSymbolFactory csf = new ComplexSymbolFactory();
4417 ScannerBuffer lexer =
4418 new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(file)),csf));
4419 Parser parse = new Parser(lexer,csf);
4420 pn = (ParseNode) parse.parse().value;
4421 } catch (Exception e) {
4422 e.printStackTrace();
4423 throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file);
4431 * Basic helper functions
4434 boolean newline=true;
4437 private void print(String str) {
4440 if (str.equals("}"))
4442 for(int i=0; i<tab; i++)
4452 * This function converts Java to C++ type for compilation
4454 private String convertType(String jType) {
4456 return mapPrimitives.get(jType);
4461 * A collection of methods with print-to-file functionality
4463 private void println(String str) {
4466 if (str.contains("}") && !str.contains("{"))
4468 for(int i=0; i<tab; i++)
4477 private void updatetabbing(String str) {
4479 tablevel+=count(str,'{')-count(str,'}');
4483 private int count(String str, char key) {
4484 char[] array = str.toCharArray();
4486 for(int i=0; i<array.length; i++) {
4487 if (array[i] == key)
4494 private void createDirectory(String dirName) {
4496 File file = new File(dirName);
4497 if (!file.exists()) {
4499 System.out.println("IoTCompiler: Directory " + dirName + " has been created!");
4501 System.out.println("IoTCompiler: Failed to create directory " + dirName + "!");
4504 System.out.println("IoTCompiler: Directory " + dirName + " exists...");
4509 // Create a directory and possibly a sub directory
4510 private String createDirectories(String dir, String subdir) {
4513 createDirectory(path);
4514 if (subdir != null) {
4515 path = path + "/" + subdir;
4516 createDirectory(path);
4522 // Inserting array members into a Map object
4523 // that maps arrKey to arrVal objects
4524 private void arraysToMap(Map map, Object[] arrKey, Object[] arrVal) {
4526 for(int i = 0; i < arrKey.length; i++) {
4528 map.put(arrKey[i], arrVal[i]);
4533 // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, USERDEFINED, ENUM, or STRUCT
4534 private ParamCategory getParamCategory(String paramType) {
4536 if (mapPrimitives.containsKey(paramType)) {
4537 return ParamCategory.PRIMITIVES;
4538 // We can either use mapNonPrimitivesJava or mapNonPrimitivesCplus here
4539 } else if (mapNonPrimitivesJava.containsKey(getSimpleType(paramType))) {
4540 return ParamCategory.NONPRIMITIVES;
4541 } else if (isEnumClass(paramType)) {
4542 return ParamCategory.ENUM;
4543 } else if (isStructClass(paramType)) {
4544 return ParamCategory.STRUCT;
4546 return ParamCategory.USERDEFINED;
4550 // Return full class name for non-primitives to generate Java import statements
4551 // e.g. java.util.Set for Set
4552 private String getNonPrimitiveJavaClass(String paramNonPrimitives) {
4554 return mapNonPrimitivesJava.get(paramNonPrimitives);
4558 // Return full class name for non-primitives to generate Cplus include statements
4559 // e.g. #include <set> for Set
4560 private String getNonPrimitiveCplusClass(String paramNonPrimitives) {
4562 return mapNonPrimitivesCplus.get(paramNonPrimitives);
4566 // Get simple types, e.g. HashSet for HashSet<...>
4567 // Basically strip off the "<...>"
4568 private String getSimpleType(String paramType) {
4570 // Check if this is generics
4571 if(paramType.contains("<")) {
4572 String[] type = paramType.split("<");
4579 // Generate a set of standard classes for import statements
4580 private List<String> getStandardJavaIntfaceImportClasses() {
4582 List<String> importClasses = new ArrayList<String>();
4583 // Add the standard list first
4584 importClasses.add("java.util.List");
4585 importClasses.add("java.util.ArrayList");
4587 return importClasses;
4591 // Generate a set of standard classes for import statements
4592 private List<String> getStandardJavaImportClasses() {
4594 List<String> importClasses = new ArrayList<String>();
4595 // Add the standard list first
4596 importClasses.add("java.io.IOException");
4597 importClasses.add("java.util.List");
4598 importClasses.add("java.util.ArrayList");
4599 importClasses.add("java.util.Arrays");
4600 importClasses.add("iotrmi.Java.IoTRMICall");
4601 importClasses.add("iotrmi.Java.IoTRMIObject");
4603 return importClasses;
4607 // Generate a set of standard classes for import statements
4608 private List<String> getStandardCplusIncludeClasses() {
4610 List<String> importClasses = new ArrayList<String>();
4611 // Add the standard list first
4612 importClasses.add("<vector>");
4613 importClasses.add("<set>");
4614 importClasses.add("\"IoTRMICall.hpp\"");
4615 importClasses.add("\"IoTRMIObject.hpp\"");
4617 return importClasses;
4621 // Combine all classes for import statements
4622 private List<String> getAllLibClasses(Collection<String> stdLibClasses, Collection<String> libClasses) {
4624 List<String> allLibClasses = new ArrayList<String>(stdLibClasses);
4625 // Iterate over the list of import classes
4626 for (String str : libClasses) {
4627 if (!allLibClasses.contains(str)) {
4628 allLibClasses.add(str);
4631 return allLibClasses;
4636 // Generate a set of classes for import statements
4637 private Set<String> getImportClasses(Collection<String> methods, InterfaceDecl intDecl) {
4639 Set<String> importClasses = new HashSet<String>();
4640 for (String method : methods) {
4641 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4642 for (String paramType : methPrmTypes) {
4644 String simpleType = getSimpleType(paramType);
4645 if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
4646 importClasses.add(getNonPrimitiveJavaClass(simpleType));
4650 return importClasses;
4654 // Handle and return the correct enum declaration
4655 // In Java, if we declare enum in Camera interface, then it becomes "Camera.<enum>"
4656 private String getEnumParamDecl(String type, InterfaceDecl intDecl) {
4658 // Strips off array "[]" for return type
4659 String pureType = getSimpleArrayType(type);
4660 // Take the inner type of generic
4661 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4662 pureType = getTypeOfGeneric(type)[0];
4663 if (isEnumClass(pureType)) {
4664 String enumType = intDecl.getInterface() + "." + type;
4671 // Handle and return the correct type
4672 private String getEnumParam(String type, String param, int i) {
4674 // Strips off array "[]" for return type
4675 String pureType = getSimpleArrayType(type);
4676 // Take the inner type of generic
4677 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4678 pureType = getTypeOfGeneric(type)[0];
4679 if (isEnumClass(pureType)) {
4680 String enumParam = "paramEnum" + i;
4687 // Handle and return the correct enum declaration translate into int[]
4688 private String getEnumType(String type) {
4690 // Strips off array "[]" for return type
4691 String pureType = getSimpleArrayType(type);
4692 // Take the inner type of generic
4693 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4694 pureType = getTypeOfGeneric(type)[0];
4695 if (isEnumClass(pureType)) {
4696 String enumType = "int[]";
4703 // Handle and return the correct struct declaration
4704 private String getStructType(String type) {
4706 // Strips off array "[]" for return type
4707 String pureType = getSimpleArrayType(type);
4708 // Take the inner type of generic
4709 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4710 pureType = getTypeOfGeneric(type)[0];
4711 if (isStructClass(pureType)) {
4712 String structType = "int";
4719 // Check if this an enum declaration
4720 private boolean isEnumClass(String type) {
4722 // Just iterate over the set of interfaces
4723 for (String intface : mapIntfacePTH.keySet()) {
4724 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4725 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
4726 Set<String> setEnumDecl = enumDecl.getEnumDeclarations();
4727 if (setEnumDecl.contains(type))
4734 // Check if this an struct declaration
4735 private boolean isStructClass(String type) {
4737 // Just iterate over the set of interfaces
4738 for (String intface : mapIntfacePTH.keySet()) {
4739 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4740 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4741 List<String> listStructDecl = structDecl.getStructTypes();
4742 if (listStructDecl.contains(type))
4749 // Return a struct declaration
4750 private StructDecl getStructDecl(String type) {
4752 // Just iterate over the set of interfaces
4753 for (String intface : mapIntfacePTH.keySet()) {
4754 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4755 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4756 List<String> listStructDecl = structDecl.getStructTypes();
4757 if (listStructDecl.contains(type))
4764 // Return number of members (-1 if not found)
4765 private int getNumOfMembers(String type) {
4767 // Just iterate over the set of interfaces
4768 for (String intface : mapIntfacePTH.keySet()) {
4769 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4770 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4771 List<String> listStructDecl = structDecl.getStructTypes();
4772 if (listStructDecl.contains(type))
4773 return structDecl.getNumOfMembers(type);
4779 // Generate a set of classes for include statements
4780 private Set<String> getIncludeClasses(Collection<String> methods, InterfaceDecl intDecl, String intface, boolean needExchange) {
4782 Set<String> includeClasses = new HashSet<String>();
4783 for (String method : methods) {
4785 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4786 List<String> methParams = intDecl.getMethodParams(method);
4787 for (int i = 0; i < methPrmTypes.size(); i++) {
4789 String simpleType = getSimpleType(methPrmTypes.get(i));
4790 String param = methParams.get(i);
4791 if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
4792 includeClasses.add("<" + getNonPrimitiveCplusClass(simpleType) + ">");
4793 } else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) {
4794 // For original interface, we need it exchanged... not for stub interfaces
4796 includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
4797 includeClasses.add("\"" + exchangeParamType(simpleType) + "_CallbackStub.hpp\"");
4799 includeClasses.add("\"" + simpleType + ".hpp\"");
4800 includeClasses.add("\"" + simpleType + "_CallbackSkeleton.hpp\"");
4802 } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.ENUM) {
4803 includeClasses.add("\"" + simpleType + ".hpp\"");
4804 } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.STRUCT) {
4805 includeClasses.add("\"" + simpleType + ".hpp\"");
4806 } else if (param.contains("[]")) {
4807 // Check if this is array for C++; translate into vector
4808 includeClasses.add("<vector>");
4812 return includeClasses;
4816 // Generate a set of callback classes
4817 private Set<String> getCallbackClasses(Collection<String> methods, InterfaceDecl intDecl) {
4819 Set<String> callbackClasses = new HashSet<String>();
4820 for (String method : methods) {
4822 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4823 List<String> methParams = intDecl.getMethodParams(method);
4824 for (int i = 0; i < methPrmTypes.size(); i++) {
4826 String type = methPrmTypes.get(i);
4827 if (getParamCategory(type) == ParamCategory.USERDEFINED) {
4828 callbackClasses.add(type);
4829 } else if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) {
4830 // Can be a List<...> of callback objects ...
4831 String genericType = getTypeOfGeneric(type)[0];
4832 if (getParamCategory(type) == ParamCategory.USERDEFINED) {
4833 callbackClasses.add(type);
4838 return callbackClasses;
4842 // Print import statements into file
4843 private void printImportStatements(Collection<String> importClasses) {
4845 for(String cls : importClasses) {
4846 println("import " + cls + ";");
4851 // Print include statements into file
4852 private void printIncludeStatements(Collection<String> includeClasses) {
4854 for(String cls : includeClasses) {
4855 println("#include " + cls);
4860 // Get the C++ version of a non-primitive type
4861 // e.g. set for Set and map for Map
4862 // Input nonPrimitiveType has to be generics in format
4863 private String[] getTypeOfGeneric(String nonPrimitiveType) {
4865 // Handle <, >, and , for 2-type generic/template
4866 String[] substr = nonPrimitiveType.split("<")[1].split(">")[0].split(",");
4871 // Gets generic type inside "<" and ">"
4872 private String getGenericType(String type) {
4874 // Handle <, >, and , for 2-type generic/template
4875 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) {
4876 String[] substr = type.split("<")[1].split(">")[0].split(",");
4883 // This helper function strips off array declaration, e.g. int[] becomes int
4884 private String getSimpleArrayType(String type) {
4886 // Handle [ for array declaration
4887 String substr = type;
4888 if (type.contains("[]")) {
4889 substr = type.split("\\[\\]")[0];
4895 // This helper function strips off array declaration, e.g. D[] becomes D
4896 private String getSimpleIdentifier(String ident) {
4898 // Handle [ for array declaration
4899 String substr = ident;
4900 if (ident.contains("[]")) {
4901 substr = ident.split("\\[\\]")[0];
4907 // Checks and gets type in C++
4908 private String checkAndGetCplusType(String paramType) {
4910 if (getParamCategory(paramType) == ParamCategory.PRIMITIVES) {
4911 return convertType(paramType);
4912 } else if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES) {
4914 // Check for generic/template format
4915 if (paramType.contains("<") && paramType.contains(">")) {
4917 String genericClass = getSimpleType(paramType);
4918 String[] genericType = getTypeOfGeneric(paramType);
4919 String cplusTemplate = null;
4920 if (genericType.length == 1) // Generic/template with one type
4921 cplusTemplate = getNonPrimitiveCplusClass(genericClass) +
4922 "<" + convertType(genericType[0]) + ">";
4923 else // Generic/template with two types
4924 cplusTemplate = getNonPrimitiveCplusClass(genericClass) +
4925 "<" + convertType(genericType[0]) + "," + convertType(genericType[1]) + ">";
4926 return cplusTemplate;
4928 return getNonPrimitiveCplusClass(paramType);
4929 } else if(paramType.contains("[]")) { // Array type (used for return type only)
4930 String cArray = "vector<" + convertType(getSimpleArrayType(paramType)) + ">";
4932 } else if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
4933 return paramType + "*";
4935 // Just return it as is if it's not non-primitives
4937 //return checkAndGetParamClass(paramType, true);
4941 // Detect array declaration, e.g. int A[],
4942 // then generate "int A[]" in C++ as "vector<int> A"
4943 private String checkAndGetCplusArray(String paramType, String param) {
4945 String paramComplete = null;
4946 // Check for array declaration
4947 if (param.contains("[]")) {
4948 paramComplete = "vector<" + paramType + "> " + param.replace("[]","");
4950 // Just return it as is if it's not an array
4951 paramComplete = paramType + " " + param;
4953 return paramComplete;
4957 // Detect array declaration, e.g. int A[],
4958 // then generate "int A[]" in C++ as "vector<int> A"
4959 // This method just returns the type
4960 private String checkAndGetCplusArrayType(String paramType) {
4962 String paramTypeRet = null;
4963 // Check for array declaration
4964 if (paramType.contains("[]")) {
4965 String type = paramType.split("\\[\\]")[0];
4966 paramTypeRet = checkAndGetCplusType(type) + "[]";
4967 } else if (paramType.contains("vector")) {
4968 // Just return it as is if it's not an array
4969 String type = paramType.split("<")[1].split(">")[0];
4970 paramTypeRet = checkAndGetCplusType(type) + "[]";
4972 paramTypeRet = paramType;
4974 return paramTypeRet;
4978 // Detect array declaration, e.g. int A[],
4979 // then generate "int A[]" in C++ as "vector<int> A"
4980 // This method just returns the type
4981 private String checkAndGetCplusArrayType(String paramType, String param) {
4983 String paramTypeRet = null;
4984 // Check for array declaration
4985 if (param.contains("[]")) {
4986 paramTypeRet = checkAndGetCplusType(paramType) + "[]";
4987 } else if (paramType.contains("vector")) {
4988 // Just return it as is if it's not an array
4989 String type = paramType.split("<")[1].split(">")[0];
4990 paramTypeRet = checkAndGetCplusType(type) + "[]";
4992 paramTypeRet = paramType;
4994 return paramTypeRet;
4998 // Return the class type for class resolution (for return value)
4999 // - Check and return C++ array class, e.g. int A[] into int*
5000 // - Check and return C++ vector class, e.g. List<Integer> A into vector<int>
5001 private String checkAndGetCplusRetClsType(String paramType) {
5003 String paramTypeRet = null;
5004 // Check for array declaration
5005 if (paramType.contains("[]")) {
5006 String type = paramType.split("\\[\\]")[0];
5007 paramTypeRet = getSimpleArrayType(type) + "*";
5008 } else if (paramType.contains("<") && paramType.contains(">")) {
5009 // Just return it as is if it's not an array
5010 String type = paramType.split("<")[1].split(">")[0];
5011 paramTypeRet = "vector<" + getGenericType(type) + ">";
5013 paramTypeRet = paramType;
5015 return paramTypeRet;
5019 // Return the class type for class resolution (for method arguments)
5020 // - Check and return C++ array class, e.g. int A[] into int*
5021 // - Check and return C++ vector class, e.g. List<Integer> A into vector<int>
5022 private String checkAndGetCplusArgClsType(String paramType, String param) {
5024 String paramTypeRet = null;
5025 // Check for array declaration
5026 if (param.contains("[]")) {
5027 paramTypeRet = getSimpleArrayType(paramType) + "*";
5028 } else if (paramType.contains("<") && paramType.contains(">")) {
5029 // Just return it as is if it's not an array
5030 String type = paramType.split("<")[1].split(">")[0];
5031 paramTypeRet = "vector<" + getGenericType(type) + ">";
5033 paramTypeRet = paramType;
5035 return paramTypeRet;
5039 // Detect array declaration, e.g. int A[],
5040 // then generate type "int[]"
5041 private String checkAndGetArray(String paramType, String param) {
5043 String paramTypeRet = null;
5044 // Check for array declaration
5045 if (param.contains("[]")) {
5046 paramTypeRet = paramType + "[]";
5048 // Just return it as is if it's not an array
5049 paramTypeRet = paramType;
5051 return paramTypeRet;
5055 // Is array or list?
5056 private boolean isArrayOrList(String paramType, String param) {
5058 // Check for array declaration
5061 else if (isList(paramType))
5069 // For return type we use retType as input parameter
5070 private boolean isArray(String param) {
5072 // Check for array declaration
5073 if (param.contains("[]"))
5081 private boolean isList(String paramType) {
5083 // Check for array declaration
5084 if (paramType.contains("List"))
5091 // Get the right type for a callback object
5092 private String checkAndGetParamClass(String paramType) {
5094 // Check if this is generics
5095 if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
5096 return exchangeParamType(paramType);
5102 // Returns the other interface for type-checking purposes for USERDEFINED
5103 // classes based on the information provided in multiple policy files
5104 // e.g. return CameraWithXXX instead of Camera
5105 private String exchangeParamType(String intface) {
5107 // Param type that's passed is the interface name we need to look for
5108 // in the map of interfaces, based on available policy files.
5109 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
5110 if (decHandler != null) {
5111 // We've found the required interface policy files
5112 RequiresDecl reqDecl = (RequiresDecl) decHandler.getRequiresDecl(intface);
5113 Set<String> setExchInt = reqDecl.getInterfaces();
5114 if (setExchInt.size() == 1) {
5115 Iterator iter = setExchInt.iterator();
5116 return (String) iter.next();
5118 throw new Error("IoTCompiler: Ambiguous stub interfaces: " + setExchInt.toString() +
5119 ". Only one new interface can be declared if the object " + intface +
5120 " needs to be passed in as an input parameter!");
5123 // NULL value - this means policy files missing
5124 throw new Error("IoTCompiler: Parameter type lookup failed for " + intface +
5125 "... Please provide the necessary policy files for user-defined types." +
5126 " If this is an array please type the brackets after the variable name," +
5127 " e.g. \"String str[]\", not \"String[] str\"." +
5128 " If this is a Collections (Java) / STL (C++) type, this compiler only" +
5129 " supports List/ArrayList (Java) or list (C++).");
5134 public static void main(String[] args) throws Exception {
5136 // If there is no argument or just "--help" or "-h", then invoke printUsage()
5137 if ((args[0].equals("-help") ||
5138 args[0].equals("--help")||
5139 args[0].equals("-h")) ||
5140 (args.length == 0)) {
5142 IoTCompiler.printUsage();
5144 } else if (args.length > 1) {
5146 IoTCompiler comp = new IoTCompiler();
5149 // Parse main policy file
5150 ParseNode pnPol = IoTCompiler.parseFile(args[i]);
5151 // Parse "requires" policy file
5152 ParseNode pnReq = IoTCompiler.parseFile(args[i+1]);
5153 // Get interface name
5154 String intface = ParseTreeHandler.getOrigIntface(pnPol);
5155 comp.setDataStructures(intface, pnPol, pnReq);
5156 comp.getMethodsForIntface(intface);
5158 // 1) Check if this is the last option before "-java" or "-cplus"
5159 // 2) Check if this is really the last option (no "-java" or "-cplus")
5160 } while(!args[i].equals("-java") &&
5161 !args[i].equals("-cplus") &&
5164 // Generate everything if we don't see "-java" or "-cplus"
5165 if (i == args.length) {
5166 comp.generateEnumJava();
5167 comp.generateStructJava();
5168 comp.generateJavaLocalInterfaces();
5169 comp.generateJavaInterfaces();
5170 comp.generateJavaStubClasses();
5171 comp.generateJavaCallbackStubClasses();
5172 comp.generateJavaSkeletonClass();
5173 comp.generateJavaCallbackSkeletonClass();
5174 comp.generateEnumCplus();
5175 comp.generateStructCplus();
5176 comp.generateCplusLocalInterfaces();
5177 comp.generateCPlusInterfaces();
5178 comp.generateCPlusStubClasses();
5179 comp.generateCPlusCallbackStubClasses();
5180 comp.generateCplusSkeletonClass();
5181 comp.generateCplusCallbackSkeletonClass();
5183 // Check other options
5184 while(i < args.length) {
5186 if (!args[i].equals("-java") &&
5187 !args[i].equals("-cplus")) {
5188 throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i]);
5190 if (i + 1 < args.length) {
5191 comp.setDirectory(args[i+1]);
5193 throw new Error("IoTCompiler: ERROR - please provide <directory> after option: " + args[i]);
5195 if (args[i].equals("-java")) {
5196 comp.generateEnumJava();
5197 comp.generateStructJava();
5198 comp.generateJavaLocalInterfaces();
5199 comp.generateJavaInterfaces();
5200 comp.generateJavaStubClasses();
5201 comp.generateJavaCallbackStubClasses();
5202 comp.generateJavaSkeletonClass();
5203 comp.generateJavaCallbackSkeletonClass();
5205 comp.generateEnumCplus();
5206 comp.generateStructCplus();
5207 comp.generateCplusLocalInterfaces();
5208 comp.generateCPlusInterfaces();
5209 comp.generateCPlusStubClasses();
5210 comp.generateCPlusCallbackStubClasses();
5211 comp.generateCplusSkeletonClass();
5212 comp.generateCplusCallbackSkeletonClass();
5219 // Need to at least have exactly 2 parameters, i.e. main policy file and requires file
5220 IoTCompiler.printUsage();
5221 throw new Error("IoTCompiler: At least two arguments (main and requires policy files) have to be provided!");