3 import java_cup.runtime.ComplexSymbolFactory;
4 import java_cup.runtime.ScannerBuffer;
6 import java.util.Arrays;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.Iterator;
13 import java.util.List;
17 import iotpolicy.parser.Lexer;
18 import iotpolicy.parser.Parser;
19 import iotpolicy.tree.ParseNode;
20 import iotpolicy.tree.ParseNodeVector;
21 import iotpolicy.tree.ParseTreeHandler;
22 import iotpolicy.tree.Declaration;
23 import iotpolicy.tree.DeclarationHandler;
24 import iotpolicy.tree.CapabilityDecl;
25 import iotpolicy.tree.InterfaceDecl;
26 import iotpolicy.tree.RequiresDecl;
27 import iotpolicy.tree.EnumDecl;
28 import iotpolicy.tree.StructDecl;
30 import iotrmi.Java.IoTRMITypes;
33 /** Class IoTCompiler is the main interface/stub compiler for
34 * files generation. This class calls helper classes
35 * such as Parser, Lexer, InterfaceDecl, CapabilityDecl,
36 * RequiresDecl, ParseTreeHandler, etc.
38 * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
42 public class IoTCompiler {
47 // Maps multiple interfaces to multiple objects of ParseTreeHandler
48 private Map<String,ParseTreeHandler> mapIntfacePTH;
49 private Map<String,DeclarationHandler> mapIntDeclHand;
50 private Map<String,Map<String,Set<String>>> mapInt2NewInts;
51 // Data structure to store our types (primitives and non-primitives) for compilation
52 private Map<String,String> mapPrimitives;
53 private Map<String,String> mapNonPrimitivesJava;
54 private Map<String,String> mapNonPrimitivesCplus;
55 // Other data structures
56 private Map<String,Integer> mapIntfaceObjId; // Maps interface name to object Id
57 private Map<String,Integer> mapNewIntfaceObjId; // Maps new interface name to its object Id (keep track of stubs)
58 private PrintWriter pw;
60 private String subdir;
66 private final static String OUTPUT_DIRECTORY = "output_files";
68 private enum ParamCategory {
70 PRIMITIVES, // All the primitive types, e.g. byte, short, int, long, etc.
71 NONPRIMITIVES, // Non-primitive types, e.g. Set, Map, List, etc.
73 STRUCT, // Struct type
74 USERDEFINED // Assumed as driver classes
81 public IoTCompiler() {
83 mapIntfacePTH = new HashMap<String,ParseTreeHandler>();
84 mapIntDeclHand = new HashMap<String,DeclarationHandler>();
85 mapInt2NewInts = new HashMap<String,Map<String,Set<String>>>();
86 mapIntfaceObjId = new HashMap<String,Integer>();
87 mapNewIntfaceObjId = new HashMap<String,Integer>();
88 mapPrimitives = new HashMap<String,String>();
89 arraysToMap(mapPrimitives, IoTRMITypes.primitivesJava, IoTRMITypes.primitivesCplus);
90 mapNonPrimitivesJava = new HashMap<String,String>();
91 arraysToMap(mapNonPrimitivesJava, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitiveJavaLibs);
92 mapNonPrimitivesCplus = new HashMap<String,String>();
93 arraysToMap(mapNonPrimitivesCplus, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus);
95 dir = OUTPUT_DIRECTORY;
101 * setDataStructures() sets parse tree and other data structures based on policy files.
103 * It also generates parse tree (ParseTreeHandler) and
104 * copies useful information from parse tree into
105 * InterfaceDecl, CapabilityDecl, and RequiresDecl
107 * Additionally, the data structure handles are
108 * returned from tree-parsing for further process.
110 public void setDataStructures(String origInt, ParseNode pnPol, ParseNode pnReq) {
112 ParseTreeHandler ptHandler = new ParseTreeHandler(origInt, pnPol, pnReq);
113 DeclarationHandler decHandler = new DeclarationHandler();
114 // Process ParseNode and generate Declaration objects
116 ptHandler.processInterfaceDecl();
117 InterfaceDecl intDecl = ptHandler.getInterfaceDecl();
118 decHandler.addInterfaceDecl(origInt, intDecl);
120 ptHandler.processCapabilityDecl();
121 CapabilityDecl capDecl = ptHandler.getCapabilityDecl();
122 decHandler.addCapabilityDecl(origInt, capDecl);
124 ptHandler.processRequiresDecl();
125 RequiresDecl reqDecl = ptHandler.getRequiresDecl();
126 decHandler.addRequiresDecl(origInt, reqDecl);
128 ptHandler.processEnumDecl();
129 EnumDecl enumDecl = ptHandler.getEnumDecl();
130 decHandler.addEnumDecl(origInt, enumDecl);
132 ptHandler.processStructDecl();
133 StructDecl structDecl = ptHandler.getStructDecl();
134 decHandler.addStructDecl(origInt, structDecl);
136 mapIntfacePTH.put(origInt, ptHandler);
137 mapIntDeclHand.put(origInt, decHandler);
138 // Set object Id counter to 0 for each interface
139 mapIntfaceObjId.put(origInt, new Integer(0));
144 * getMethodsForIntface() reads for methods in the data structure
146 * It is going to give list of methods for a certain interface
147 * based on the declaration of capabilities.
149 public void getMethodsForIntface(String origInt) {
151 ParseTreeHandler ptHandler = mapIntfacePTH.get(origInt);
152 Map<String,Set<String>> mapNewIntMethods = new HashMap<String,Set<String>>();
153 // Get set of new interfaces, e.g. CameraWithCaptureAndData
154 // Generate this new interface with all the methods it needs
155 // from different capabilities it declares
156 DeclarationHandler decHandler = mapIntDeclHand.get(origInt);
157 RequiresDecl reqDecl = (RequiresDecl) decHandler.getRequiresDecl(origInt);
158 Set<String> setIntfaces = reqDecl.getInterfaces();
159 for (String strInt : setIntfaces) {
161 // Initialize a set of methods
162 Set<String> setMethods = new HashSet<String>();
163 // Get list of capabilities, e.g. ImageCapture, VideoRecording, etc.
164 List<String> listCapab = reqDecl.getCapabList(strInt);
165 for (String strCap : listCapab) {
167 // Get list of methods for each capability
168 CapabilityDecl capDecl = (CapabilityDecl) decHandler.getCapabilityDecl(origInt);
169 List<String> listCapabMeth = capDecl.getMethods(strCap);
170 for (String strMeth : listCapabMeth) {
172 // Add methods into setMethods
173 // This is to also handle redundancies (say two capabilities
174 // share the same methods)
175 setMethods.add(strMeth);
178 // Add interface and methods information into map
179 mapNewIntMethods.put(strInt, setMethods);
181 // Map the map of interface-methods to the original interface
182 mapInt2NewInts.put(origInt, mapNewIntMethods);
187 * HELPER: writeMethodJavaLocalInterface() writes the method of the local interface
189 private void writeMethodJavaLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
191 for (String method : methods) {
193 List<String> methParams = intDecl.getMethodParams(method);
194 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
195 print("public " + intDecl.getMethodType(method) + " " +
196 intDecl.getMethodId(method) + "(");
197 for (int i = 0; i < methParams.size(); i++) {
198 // Check for params with driver class types and exchange it
199 // with its remote interface
200 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
201 print(paramType + " " + methParams.get(i));
202 // Check if this is the last element (don't print a comma)
203 if (i != methParams.size() - 1) {
213 * HELPER: writeMethodJavaInterface() writes the method of the interface
215 private void writeMethodJavaInterface(Collection<String> methods, InterfaceDecl intDecl) {
217 for (String method : methods) {
219 List<String> methParams = intDecl.getMethodParams(method);
220 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
221 print("public " + intDecl.getMethodType(method) + " " +
222 intDecl.getMethodId(method) + "(");
223 for (int i = 0; i < methParams.size(); i++) {
224 // Check for params with driver class types and exchange it
225 // with its remote interface
226 String paramType = methPrmTypes.get(i);
227 print(paramType + " " + methParams.get(i));
228 // Check if this is the last element (don't print a comma)
229 if (i != methParams.size() - 1) {
239 * HELPER: generateEnumJava() writes the enumeration declaration
241 private void generateEnumJava() throws IOException {
243 // Create a new directory
244 createDirectory(dir);
245 for (String intface : mapIntfacePTH.keySet()) {
246 // Get the right EnumDecl
247 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
248 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
249 Set<String> enumTypes = enumDecl.getEnumDeclarations();
250 // Iterate over enum declarations
251 for (String enType : enumTypes) {
252 // Open a new file to write into
253 FileWriter fw = new FileWriter(dir + "/" + enType + ".java");
254 pw = new PrintWriter(new BufferedWriter(fw));
255 println("public enum " + enType + " {");
256 List<String> enumMembers = enumDecl.getMembers(enType);
257 for (int i = 0; i < enumMembers.size(); i++) {
259 String member = enumMembers.get(i);
261 // Check if this is the last element (don't print a comma)
262 if (i != enumMembers.size() - 1)
269 System.out.println("IoTCompiler: Generated enum class " + enType + ".java...");
276 * HELPER: generateStructJava() writes the struct declaration
278 private void generateStructJava() throws IOException {
280 // Create a new directory
281 createDirectory(dir);
282 for (String intface : mapIntfacePTH.keySet()) {
283 // Get the right StructDecl
284 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
285 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
286 List<String> structTypes = structDecl.getStructTypes();
287 // Iterate over enum declarations
288 for (String stType : structTypes) {
289 // Open a new file to write into
290 FileWriter fw = new FileWriter(dir + "/" + stType + ".java");
291 pw = new PrintWriter(new BufferedWriter(fw));
292 println("public class " + stType + " {");
293 List<String> structMemberTypes = structDecl.getMemberTypes(stType);
294 List<String> structMembers = structDecl.getMembers(stType);
295 for (int i = 0; i < structMembers.size(); i++) {
297 String memberType = structMemberTypes.get(i);
298 String member = structMembers.get(i);
299 println("public static " + memberType + " " + member + ";");
303 System.out.println("IoTCompiler: Generated struct class " + stType + ".java...");
310 * generateJavaLocalInterface() writes the local interface and provides type-checking.
312 * It needs to rewrite and exchange USERDEFINED types in input parameters of stub
313 * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording.
314 * The local interface has to be the input parameter for the stub and the stub
315 * interface has to be the input parameter for the local class.
317 public void generateJavaLocalInterfaces() throws IOException {
319 // Create a new directory
320 createDirectory(dir);
321 for (String intface : mapIntfacePTH.keySet()) {
322 // Open a new file to write into
323 FileWriter fw = new FileWriter(dir + "/" + intface + ".java");
324 pw = new PrintWriter(new BufferedWriter(fw));
325 // Pass in set of methods and get import classes
326 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
327 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
328 List<String> methods = intDecl.getMethods();
329 Set<String> importClasses = getImportClasses(methods, intDecl);
330 printImportStatements(importClasses);
331 // Write interface header
333 println("public interface " + intface + " {");
335 writeMethodJavaLocalInterface(methods, intDecl);
338 System.out.println("IoTCompiler: Generated local interface " + intface + ".java...");
344 * generateJavaInterfaces() generate stub interfaces based on the methods list in Java
346 public void generateJavaInterfaces() throws IOException {
348 // Create a new directory
349 String path = createDirectories(dir, subdir);
350 for (String intface : mapIntfacePTH.keySet()) {
352 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
353 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
355 // Open a new file to write into
356 String newIntface = intMeth.getKey();
357 FileWriter fw = new FileWriter(path + "/" + newIntface + ".java");
358 pw = new PrintWriter(new BufferedWriter(fw));
359 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
360 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
361 // Pass in set of methods and get import classes
362 Set<String> importClasses = getImportClasses(intMeth.getValue(), intDecl);
363 printImportStatements(importClasses);
364 // Write interface header
366 println("public interface " + newIntface + " {\n");
368 writeMethodJavaInterface(intMeth.getValue(), intDecl);
371 System.out.println("IoTCompiler: Generated interface " + newIntface + ".java...");
378 * HELPER: writePropertiesJavaPermission() writes the permission in properties
380 private void writePropertiesJavaPermission(String intface, InterfaceDecl intDecl) {
382 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
383 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
384 String newIntface = intMeth.getKey();
385 int newObjectId = mapNewIntfaceObjId.get(newIntface);
386 println("private final static int object" + newObjectId + "Id = " +
387 newObjectId + ";\t//" + newIntface);
388 Set<String> methodIds = intMeth.getValue();
389 print("private static Integer[] object" + newObjectId + "Permission = { ");
391 for (String methodId : methodIds) {
392 int methodNumId = intDecl.getMethodNumId(methodId);
393 print(Integer.toString(methodNumId));
394 // Check if this is the last element (don't print a comma)
395 if (i != methodIds.size() - 1) {
401 println("private List<Integer> set" + newObjectId + "Allowed;");
407 * HELPER: writePropertiesJavaStub() writes the properties of the stub class
409 private void writePropertiesJavaStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
411 println("private IoTRMICall rmiCall;");
412 println("private String address;");
413 println("private int[] ports;\n");
415 Integer objId = mapIntfaceObjId.get(intface);
416 println("private final static int objectId = " + objId + ";");
417 mapNewIntfaceObjId.put(newIntface, objId);
418 mapIntfaceObjId.put(intface, objId++);
420 // We assume that each class only has one callback interface for now
421 Iterator it = callbackClasses.iterator();
422 String callbackType = (String) it.next();
423 println("// Callback properties");
424 println("private IoTRMIObject rmiObj;");
425 println("List<" + callbackType + "> listCallbackObj;");
426 println("private static int objIdCnt = 0;");
427 // Generate permission stuff for callback stubs
428 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
429 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
430 writePropertiesJavaPermission(callbackType, intDecl);
437 * HELPER: writeConstructorJavaPermission() writes the permission in constructor
439 private void writeConstructorJavaPermission(String intface) {
441 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
442 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
443 String newIntface = intMeth.getKey();
444 int newObjectId = mapNewIntfaceObjId.get(newIntface);
445 println("set" + newObjectId + "Allowed = Arrays.asList(object" + newObjectId +"Permission);");
451 * HELPER: writeConstructorJavaStub() writes the constructor of the stub class
453 private void writeConstructorJavaStub(String intface, String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
455 println("public " + newStubClass + "(int _port, String _address, int _rev, int[] _ports) throws Exception {");
456 println("address = _address;");
457 println("ports = _ports;");
458 println("rmiCall = new IoTRMICall(_port, _address, _rev);");
460 Iterator it = callbackClasses.iterator();
461 String callbackType = (String) it.next();
462 writeConstructorJavaPermission(intface);
463 println("listCallbackObj = new ArrayList<" + callbackType + ">();");
464 println("___initCallBack();");
471 * HELPER: writeJavaMethodCallbackPermission() writes permission checks in stub for callbacks
473 private void writeJavaMethodCallbackPermission(String intface) {
475 println("int methodId = IoTRMIObject.getMethodId(method);");
476 // Get all the different stubs
477 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
478 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
479 String newIntface = intMeth.getKey();
480 int newObjectId = mapNewIntfaceObjId.get(newIntface);
481 println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
482 println("throw new Error(\"Callback object for " + intface + " is not allowed to access method: \" + methodId);");
489 * HELPER: writeInitCallbackJavaStub() writes callback initialization in stub
491 private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl) {
493 println("public void ___initCallBack() {");
494 // Generate main thread for callbacks
495 println("Thread thread = new Thread() {");
496 println("public void run() {");
498 println("rmiObj = new IoTRMIObject(ports[0]);");
499 println("while (true) {");
500 println("byte[] method = rmiObj.getMethodBytes();");
501 writeJavaMethodCallbackPermission(intface);
502 println("int objId = IoTRMIObject.getObjectId(method);");
503 println(intface + "_CallbackSkeleton skel = (" + intface + "_CallbackSkeleton) listCallbackObj.get(objId);");
504 println("if (skel != null) {");
505 println("skel.invokeMethod(rmiObj);");
507 println("throw new Error(\"" + intface + ": Object with Id \" + objId + \" not found!\");");
510 println("} catch (Exception ex) {");
511 println("ex.printStackTrace();");
512 println("throw new Error(\"Error instantiating class " + intface + "_CallbackSkeleton!\");");
516 println("thread.start();\n");
517 // Generate info sending part
518 String method = "___initCallBack()";
519 println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";");
520 println("Class<?> retType = void.class;");
521 println("Class<?>[] paramCls = new Class<?>[] { int.class, String.class, int.class };");
522 println("Object[] paramObj = new Object[] { ports[0], address, 0 };");
523 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
529 * HELPER: checkAndWriteEnumTypeJavaStub() writes the enum type (convert from enum to int)
531 private void checkAndWriteEnumTypeJavaStub(List<String> methParams, List<String> methPrmTypes) {
533 // Iterate and find enum declarations
534 for (int i = 0; i < methParams.size(); i++) {
535 String paramType = methPrmTypes.get(i);
536 String param = methParams.get(i);
537 String simpleType = getSimpleType(paramType);
538 if (isEnumClass(simpleType)) {
539 // Check if this is enum type
540 if (isArray(param)) { // An array
541 println("int len" + i + " = " + param + ".length;");
542 println("int paramEnum" + i + "[] = new int[len];");
543 println("for (int i = 0; i < len" + i + "; i++) {");
544 println("paramEnum" + i + "[i] = " + param + "[i].ordinal();");
546 } else if (isList(paramType)) { // A list
547 println("int len" + i + " = " + param + ".size();");
548 println("int paramEnum" + i + "[] = new int[len];");
549 println("for (int i = 0; i < len" + i + "; i++) {");
550 println("paramEnum" + i + "[i] = " + param + ".get(i).ordinal();");
552 } else { // Just one element
553 println("int paramEnum" + i + "[] = new int[1];");
554 println("paramEnum" + i + "[0] = " + param + ".ordinal();");
562 * HELPER: checkAndWriteEnumRetTypeJavaStub() writes the enum return type (convert from enum to int)
564 private void checkAndWriteEnumRetTypeJavaStub(String retType) {
566 // Strips off array "[]" for return type
567 String pureType = getSimpleArrayType(getSimpleType(retType));
568 // Take the inner type of generic
569 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
570 pureType = getTypeOfGeneric(retType)[0];
571 if (isEnumClass(pureType)) {
572 // Check if this is enum type
574 println("int[] retEnum = (int[]) retObj;");
575 println(pureType + "[] enumVals = " + pureType + ".values();");
576 if (isArray(retType)) { // An array
577 println("int retLen = retEnum.length;");
578 println(pureType + "[] enumRetVal = new " + pureType + "[retLen];");
579 println("for (int i = 0; i < retLen; i++) {");
580 println("enumRetVal[i] = enumVals[retEnum[i]];");
582 } else if (isList(retType)) { // A list
583 println("int retLen = retEnum.length;");
584 println("List<" + pureType + "> enumRetVal = new ArrayList<" + pureType + ">();");
585 println("for (int i = 0; i < retLen; i++) {");
586 println("enumRetVal.add(enumVals[retEnum[i]]);");
588 } else { // Just one element
589 println(pureType + " enumRetVal = enumVals[retEnum[0]];");
591 println("return enumRetVal;");
597 * HELPER: checkAndWriteStructSetupJavaStub() writes the struct type setup
599 private void checkAndWriteStructSetupJavaStub(List<String> methParams, List<String> methPrmTypes,
600 InterfaceDecl intDecl, String method) {
602 // Iterate and find struct declarations
603 for (int i = 0; i < methParams.size(); i++) {
604 String paramType = methPrmTypes.get(i);
605 String param = methParams.get(i);
606 String simpleType = getSimpleType(paramType);
607 if (isStructClass(simpleType)) {
608 // Check if this is enum type
609 int methodNumId = intDecl.getMethodNumId(method);
610 String helperMethod = methodNumId + "struct" + i;
611 println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
612 println("Class<?> retTypeStruct" + i + " = void.class;");
613 println("Class<?>[] paramClsStruct" + i + " = new Class<?>[] { int.class };");
614 if (isArray(param)) { // An array
615 println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".length };");
616 } else if (isList(paramType)) { // A list
617 println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".size() };");
618 } else { // Just one element
619 println("Object[] paramObjStruct" + i + " = new Object[] { new Integer(1) };");
621 println("rmiCall.remoteCall(objectId, methodIdStruct" + i +
622 ", retTypeStruct" + i + ", null, paramClsStruct" + i +
623 ", paramObjStruct" + i + ");\n");
630 * HELPER: isStructPresent() checks presence of struct
632 private boolean isStructPresent(List<String> methParams, List<String> methPrmTypes) {
634 // Iterate and find enum declarations
635 for (int i = 0; i < methParams.size(); i++) {
636 String paramType = methPrmTypes.get(i);
637 String param = methParams.get(i);
638 String simpleType = getSimpleType(paramType);
639 if (isStructClass(simpleType))
647 * HELPER: writeLengthStructParamClassJavaStub() writes lengths of parameters
649 private void writeLengthStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
651 // Iterate and find struct declarations - count number of params
652 for (int i = 0; i < methParams.size(); i++) {
653 String paramType = methPrmTypes.get(i);
654 String param = methParams.get(i);
655 String simpleType = getGenericType(paramType);
656 if (isStructClass(simpleType)) {
657 int members = getNumOfMembers(simpleType);
658 if (isArray(param)) { // An array
659 String structLen = param + ".length";
660 print(members + "*" + structLen);
661 } else if (isList(paramType)) { // A list
662 String structLen = param + ".size()";
663 print(members + "*" + structLen);
665 print(Integer.toString(members));
668 if (i != methParams.size() - 1) {
676 * HELPER: writeStructMembersJavaStub() writes parameters of struct
678 private void writeStructMembersJavaStub(String simpleType, String paramType, String param) {
680 // Get the struct declaration for this struct and generate initialization code
681 StructDecl structDecl = getStructDecl(simpleType);
682 List<String> memTypes = structDecl.getMemberTypes(simpleType);
683 List<String> members = structDecl.getMembers(simpleType);
684 if (isArray(param)) { // An array
685 println("for(int i = 0; i < " + param + ".length; i++) {");
686 } else if (isList(paramType)) { // A list
687 println("for(int i = 0; i < " + param + ".size(); i++) {");
689 if (isArrayOrList(param, paramType)) { // An array or list
690 for (int i = 0; i < members.size(); i++) {
691 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
692 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
693 print("paramObj[pos++] = " + param + "[i].");
694 print(getSimpleIdentifier(members.get(i)));
698 } else { // Just one struct element
699 for (int i = 0; i < members.size(); i++) {
700 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
701 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
702 print("paramObj[pos++] = " + param + ".");
703 print(getSimpleIdentifier(members.get(i)));
711 * HELPER: writeStructParamClassJavaStub() writes parameters if struct is present
713 private void writeStructParamClassJavaStub(List<String> methParams, List<String> methPrmTypes) {
715 print("int paramLen = ");
716 writeLengthStructParamClassJavaStub(methParams, methPrmTypes);
718 println("Object[] paramObj = new Object[paramLen];");
719 println("Class<?>[] paramCls = new Class<?>[paramLen];");
720 println("int pos = 0;");
721 // Iterate again over the parameters
722 for (int i = 0; i < methParams.size(); i++) {
723 String paramType = methPrmTypes.get(i);
724 String param = methParams.get(i);
725 String simpleType = getGenericType(paramType);
726 if (isStructClass(simpleType)) {
727 writeStructMembersJavaStub(simpleType, paramType, param);
729 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
730 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
731 print("paramObj[pos++] = ");
732 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
741 * HELPER: writeStructRetMembersJavaStub() writes parameters of struct for return statement
743 private void writeStructRetMembersJavaStub(String simpleType, String retType) {
745 // Get the struct declaration for this struct and generate initialization code
746 StructDecl structDecl = getStructDecl(simpleType);
747 List<String> memTypes = structDecl.getMemberTypes(simpleType);
748 List<String> members = structDecl.getMembers(simpleType);
749 if (isArrayOrList(retType, retType)) { // An array or list
750 println("for(int i = 0; i < retLen; i++) {");
752 if (isArray(retType)) { // An array
753 for (int i = 0; i < members.size(); i++) {
754 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
755 print("structRet[i]." + getSimpleIdentifier(members.get(i)));
756 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
759 } else if (isList(retType)) { // A list
760 println(simpleType + " structRetMem = new " + simpleType + "();");
761 for (int i = 0; i < members.size(); i++) {
762 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
763 print("structRetMem." + getSimpleIdentifier(members.get(i)));
764 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
766 println("structRet.add(structRetMem);");
768 } else { // Just one struct element
769 for (int i = 0; i < members.size(); i++) {
770 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
771 print("structRet." + getSimpleIdentifier(members.get(i)));
772 println(" = (" + getSimpleType(getEnumType(prmType)) + ") retObj[retObjPos++];");
775 println("return structRet;");
780 * HELPER: writeStructReturnJavaStub() writes parameters if struct is present for return statement
782 private void writeStructReturnJavaStub(String simpleType, String retType) {
784 // Handle the returned struct!!!
785 println("Object retLenObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
786 // Minimum retLen is 1 if this is a single struct object
787 println("int retLen = (int) retLenObj;");
788 int numMem = getNumOfMembers(simpleType);
789 println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
790 println("Class<?>[] retClsVal = new Class<?>[" + numMem + "*retLen];");
791 println("int retPos = 0;");
792 // Get the struct declaration for this struct and generate initialization code
793 StructDecl structDecl = getStructDecl(simpleType);
794 List<String> memTypes = structDecl.getMemberTypes(simpleType);
795 List<String> members = structDecl.getMembers(simpleType);
796 if (isArrayOrList(retType, retType)) { // An array or list
797 println("for(int i = 0; i < retLen; i++) {");
798 for (int i = 0; i < members.size(); i++) {
799 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
800 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
801 println("retClsVal[retPos++] = null;");
804 } else { // Just one struct element
805 for (int i = 0; i < members.size(); i++) {
806 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
807 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
808 println("retClsVal[retPos++] = null;");
811 println("Object[] retObj = rmiCall.getStructObjects(retCls, retClsVal);");
812 if (isArray(retType)) { // An array
813 println(simpleType + "[] structRet = new " + simpleType + "[retLen];");
814 println("for(int i = 0; i < retLen; i++) {");
815 println("structRet[i] = new " + simpleType + "();");
817 } else if (isList(retType)) { // A list
818 println("List<" + simpleType + "> structRet = new ArrayList<" + simpleType + ">();");
820 println(simpleType + " structRet = new " + simpleType + "();");
821 println("int retObjPos = 0;");
822 writeStructRetMembersJavaStub(simpleType, retType);
827 * HELPER: writeStdMethodBodyJavaStub() writes the standard method body in the stub class
829 private void writeStdMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
830 List<String> methPrmTypes, String method) {
832 checkAndWriteStructSetupJavaStub(methParams, methPrmTypes, intDecl, method);
833 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
834 String retType = intDecl.getMethodType(method);
835 println("Class<?> retType = " + getSimpleType(getStructType(getEnumType(retType))) + ".class;");
836 checkAndWriteEnumTypeJavaStub(methParams, methPrmTypes);
837 // Generate array of parameter types
838 if (isStructPresent(methParams, methPrmTypes)) {
839 writeStructParamClassJavaStub(methParams, methPrmTypes);
841 print("Class<?>[] paramCls = new Class<?>[] { ");
842 for (int i = 0; i < methParams.size(); i++) {
843 String paramType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
844 print(getSimpleType(getEnumType(paramType)) + ".class");
845 // Check if this is the last element (don't print a comma)
846 if (i != methParams.size() - 1) {
851 // Generate array of parameter objects
852 print("Object[] paramObj = new Object[] { ");
853 for (int i = 0; i < methParams.size(); i++) {
854 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
855 // Check if this is the last element (don't print a comma)
856 if (i != methParams.size() - 1) {
862 // Check if this is "void"
863 if (retType.equals("void")) {
864 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
865 } else { // We do have a return value
866 // Generate array of parameter types
867 if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
868 writeStructReturnJavaStub(getGenericType(getSimpleArrayType(retType)), retType);
870 // Check if the return value NONPRIMITIVES
871 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) {
872 String[] retGenValType = getTypeOfGeneric(retType);
873 println("Class<?> retGenValType = " + retGenValType[0] + ".class;");
874 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);");
875 println("return (" + retType + ")retObj;");
876 } else if (getParamCategory(retType) == ParamCategory.ENUM) {
877 // This is an enum type
878 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
879 checkAndWriteEnumRetTypeJavaStub(retType);
881 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
882 println("return (" + retType + ")retObj;");
890 * HELPER: returnGenericCallbackType() returns the callback type
892 private String returnGenericCallbackType(String paramType) {
894 if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES)
895 return getTypeOfGeneric(paramType)[0];
902 * HELPER: checkCallbackType() checks the callback type
904 private boolean checkCallbackType(String paramType, String callbackType) {
906 String prmType = returnGenericCallbackType(paramType);
907 return callbackType.equals(prmType);
912 * HELPER: writeCallbackMethodBodyJavaStub() writes the callback method of the stub class
914 private void writeCallbackMethodBodyJavaStub(InterfaceDecl intDecl, List<String> methParams,
915 List<String> methPrmTypes, String method, String callbackType) {
918 // Check if this is single object, array, or list of objects
919 for (int i = 0; i < methParams.size(); i++) {
920 String paramType = methPrmTypes.get(i);
921 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
922 String param = methParams.get(i);
923 if (isArrayOrList(paramType, param)) { // Generate loop
924 println("for (" + paramType + " cb : " + getSimpleIdentifier(param) + ") {");
925 println(callbackType + "_CallbackSkeleton skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
927 println(callbackType + "_CallbackSkeleton skel = new " + callbackType + "_CallbackSkeleton(" +
928 getSimpleIdentifier(param) + ", objIdCnt++);");
929 println("listCallbackObj.add(skel);");
930 if (isArrayOrList(paramType, param))
934 println("} catch (Exception ex) {");
935 println("ex.printStackTrace();");
936 println("throw new Error(\"Exception when generating skeleton objects!\");");
938 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
939 String retType = intDecl.getMethodType(method);
940 println("Class<?> retType = " + getSimpleType(getEnumType(retType)) + ".class;");
941 // Generate array of parameter types
942 print("Class<?>[] paramCls = new Class<?>[] { ");
943 for (int i = 0; i < methParams.size(); i++) {
944 String paramType = methPrmTypes.get(i);
945 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
947 } else { // Generate normal classes if it's not a callback object
948 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
949 print(getSimpleType(prmType) + ".class");
951 if (i != methParams.size() - 1) // Check if this is the last element
955 // Generate array of parameter objects
956 print("Object[] paramObj = new Object[] { ");
957 for (int i = 0; i < methParams.size(); i++) {
958 String paramType = methPrmTypes.get(i);
959 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
960 //if (isArray(methPrmTypes.get(i), methParams.get(i)))
961 if (isArray(methParams.get(i)))
962 print(getSimpleIdentifier(methParams.get(i)) + ".length");
963 else if (isList(methPrmTypes.get(i)))
964 print(getSimpleIdentifier(methParams.get(i)) + ".size()");
966 print("new Integer(1)");
968 print(getSimpleIdentifier(methParams.get(i)));
969 if (i != methParams.size() - 1)
973 // Check if this is "void"
974 if (retType.equals("void")) {
975 println("rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
976 } else { // We do have a return value
977 // Check if the return value NONPRIMITIVES
978 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) {
979 String[] retGenValType = getTypeOfGeneric(retType);
980 println("Class<?> retGenValType = " + retGenValType[0] + ".class;");
981 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, retGenValType, paramCls, paramObj);");
982 println("return (" + retType + ")retObj;");
984 println("Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);");
985 println("return (" + retType + ")retObj;");
992 * HELPER: writeMethodJavaStub() writes the methods of the stub class
994 private void writeMethodJavaStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
996 for (String method : methods) {
998 List<String> methParams = intDecl.getMethodParams(method);
999 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1000 print("public " + intDecl.getMethodType(method) + " " +
1001 intDecl.getMethodId(method) + "(");
1002 boolean isCallbackMethod = false;
1003 String callbackType = null;
1004 for (int i = 0; i < methParams.size(); i++) {
1006 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
1007 // Check if this has callback object
1008 if (callbackClasses.contains(paramType)) {
1009 isCallbackMethod = true;
1010 callbackType = paramType;
1011 // Even if there're 2 callback arguments, we expect them to be of the same interface
1013 print(methPrmTypes.get(i) + " " + methParams.get(i));
1014 // Check if this is the last element (don't print a comma)
1015 if (i != methParams.size() - 1) {
1020 // Now, write the body of stub!
1021 if (isCallbackMethod)
1022 writeCallbackMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
1024 writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method);
1026 // Write the init callback helper method
1027 if (isCallbackMethod)
1028 writeInitCallbackJavaStub(callbackType, intDecl);
1034 * generateJavaStubClasses() generate stubs based on the methods list in Java
1036 public void generateJavaStubClasses() throws IOException {
1038 // Create a new directory
1039 String path = createDirectories(dir, subdir);
1040 for (String intface : mapIntfacePTH.keySet()) {
1042 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1043 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1045 // Open a new file to write into
1046 String newIntface = intMeth.getKey();
1047 String newStubClass = newIntface + "_Stub";
1048 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
1049 pw = new PrintWriter(new BufferedWriter(fw));
1050 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
1051 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
1052 // Pass in set of methods and get import classes
1053 Set<String> methods = intMeth.getValue();
1054 Set<String> importClasses = getImportClasses(methods, intDecl);
1055 List<String> stdImportClasses = getStandardJavaImportClasses();
1056 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
1057 printImportStatements(allImportClasses); println("");
1058 // Find out if there are callback objects
1059 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
1060 boolean callbackExist = !callbackClasses.isEmpty();
1061 // Write class header
1062 println("public class " + newStubClass + " implements " + newIntface + " {\n");
1064 writePropertiesJavaStub(intface, newIntface, callbackExist, callbackClasses);
1065 // Write constructor
1066 writeConstructorJavaStub(intface, newStubClass, callbackExist, callbackClasses);
1068 writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses);
1071 System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java...");
1078 * HELPER: writePropertiesJavaCallbackStub() writes the properties of the callback stub class
1080 private void writePropertiesJavaCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
1082 println("private IoTRMICall rmiCall;");
1083 println("private String address;");
1084 println("private int[] ports;\n");
1085 // Get the object Id
1086 println("private static int objectId = 0;");
1087 if (callbackExist) {
1088 // We assume that each class only has one callback interface for now
1089 Iterator it = callbackClasses.iterator();
1090 String callbackType = (String) it.next();
1091 println("// Callback properties");
1092 println("private IoTRMIObject rmiObj;");
1093 println("List<" + callbackType + "> listCallbackObj;");
1094 println("private static int objIdCnt = 0;");
1095 // Generate permission stuff for callback stubs
1096 DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
1097 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
1098 writePropertiesJavaPermission(callbackType, intDecl);
1105 * HELPER: writeConstructorJavaCallbackStub() writes the constructor of the callback stub class
1107 private void writeConstructorJavaCallbackStub(String intface, String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
1109 // TODO: If we want callback in callback, then we need to add address and port initializations
1110 println("public " + newStubClass + "(IoTRMICall _rmiCall, int _objectId) throws Exception {");
1111 println("objectId = _objectId;");
1112 println("rmiCall = _rmiCall;");
1113 if (callbackExist) {
1114 Iterator it = callbackClasses.iterator();
1115 String callbackType = (String) it.next();
1116 writeConstructorJavaPermission(intface);
1117 println("listCallbackObj = new ArrayList<" + callbackType + ">();");
1118 println("___initCallBack();");
1119 println("// TODO: Add address and port initialization here if we want callback in callback!");
1126 * generateJavaCallbackStubClasses() generate callback stubs based on the methods list in Java
1128 * Callback stubs gets the IoTRMICall objects from outside of the class as contructor input
1129 * because all these stubs are populated by the class that takes in this object as a callback
1130 * object. In such a class, we only use one socket, hence one IoTRMICall, for all callback objects.
1132 public void generateJavaCallbackStubClasses() throws IOException {
1134 // Create a new directory
1135 String path = createDirectories(dir, subdir);
1136 for (String intface : mapIntfacePTH.keySet()) {
1138 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1139 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1141 // Open a new file to write into
1142 String newIntface = intMeth.getKey();
1143 String newStubClass = newIntface + "_CallbackStub";
1144 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".java");
1145 pw = new PrintWriter(new BufferedWriter(fw));
1146 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
1147 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
1148 // Pass in set of methods and get import classes
1149 Set<String> methods = intMeth.getValue();
1150 Set<String> importClasses = getImportClasses(methods, intDecl);
1151 List<String> stdImportClasses = getStandardJavaImportClasses();
1152 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
1153 printImportStatements(allImportClasses); println("");
1154 // Find out if there are callback objects
1155 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
1156 boolean callbackExist = !callbackClasses.isEmpty();
1157 // Write class header
1158 println("public class " + newStubClass + " implements " + newIntface + " {\n");
1160 writePropertiesJavaCallbackStub(intface, newIntface, callbackExist, callbackClasses);
1161 // Write constructor
1162 writeConstructorJavaCallbackStub(intface, newStubClass, callbackExist, callbackClasses);
1164 // TODO: perhaps need to generate callback for callback
1165 writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses);
1168 System.out.println("IoTCompiler: Generated callback stub class " + newStubClass + ".java...");
1175 * HELPER: writePropertiesJavaSkeleton() writes the properties of the skeleton class
1177 private void writePropertiesJavaSkeleton(String intface, boolean callbackExist, InterfaceDecl intDecl) {
1179 println("private " + intface + " mainObj;");
1180 //println("private int ports;");
1181 println("private IoTRMIObject rmiObj;\n");
1183 if (callbackExist) {
1184 println("private static int objIdCnt = 0;");
1185 println("private IoTRMICall rmiCall;");
1187 writePropertiesJavaPermission(intface, intDecl);
1193 * HELPER: writeConstructorJavaSkeleton() writes the constructor of the skeleton class
1195 private void writeConstructorJavaSkeleton(String newSkelClass, String intface) {
1197 println("public " + newSkelClass + "(" + intface + " _mainObj, int _port) throws Exception {");
1198 println("mainObj = _mainObj;");
1199 println("rmiObj = new IoTRMIObject(_port);");
1200 // Generate permission control initialization
1201 writeConstructorJavaPermission(intface);
1202 println("___waitRequestInvokeMethod();");
1208 * HELPER: writeStdMethodBodyJavaSkeleton() writes the standard method body in the skeleton class
1210 private void writeStdMethodBodyJavaSkeleton(List<String> methParams, String methodId, String methodType) {
1212 if (methodType.equals("void"))
1213 print("mainObj." + methodId + "(");
1215 print("return mainObj." + methodId + "(");
1216 for (int i = 0; i < methParams.size(); i++) {
1218 print(getSimpleIdentifier(methParams.get(i)));
1219 // Check if this is the last element (don't print a comma)
1220 if (i != methParams.size() - 1) {
1229 * HELPER: writeInitCallbackJavaSkeleton() writes the init callback method for skeleton class
1231 private void writeInitCallbackJavaSkeleton(boolean callbackSkeleton) {
1233 // This is a callback skeleton generation
1234 if (callbackSkeleton)
1235 println("public void ___regCB(IoTRMIObject rmiObj) throws IOException {");
1237 println("public void ___regCB() throws IOException {");
1238 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class, String.class, int.class },");
1239 println("\tnew Class<?>[] { null, null, null });");
1240 println("rmiCall = new IoTRMICall((int) paramObj[0], (String) paramObj[1], (int) paramObj[2]);");
1246 * HELPER: writeMethodJavaSkeleton() writes the method of the skeleton class
1248 private void writeMethodJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses,
1249 boolean callbackSkeleton) {
1251 for (String method : methods) {
1253 List<String> methParams = intDecl.getMethodParams(method);
1254 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1255 String methodId = intDecl.getMethodId(method);
1256 print("public " + intDecl.getMethodType(method) + " " + methodId + "(");
1257 boolean isCallbackMethod = false;
1258 String callbackType = null;
1259 for (int i = 0; i < methParams.size(); i++) {
1261 String origParamType = methPrmTypes.get(i);
1262 String paramType = checkAndGetParamClass(origParamType);
1263 if (callbackClasses.contains(origParamType)) { // Check if this has callback object
1264 isCallbackMethod = true;
1265 callbackType = origParamType;
1267 print(paramType + " " + methParams.get(i));
1268 // Check if this is the last element (don't print a comma)
1269 if (i != methParams.size() - 1) {
1274 // Now, write the body of skeleton!
1275 writeStdMethodBodyJavaSkeleton(methParams, methodId, intDecl.getMethodType(method));
1277 if (isCallbackMethod)
1278 writeInitCallbackJavaSkeleton(callbackSkeleton);
1284 * HELPER: writeCallbackJavaStubGeneration() writes the callback stub generation part
1286 private Map<Integer,String> writeCallbackJavaStubGeneration(List<String> methParams, List<String> methPrmTypes,
1287 String callbackType) {
1289 Map<Integer,String> mapStubParam = new HashMap<Integer,String>();
1290 // Iterate over callback objects
1291 for (int i = 0; i < methParams.size(); i++) {
1292 String paramType = methPrmTypes.get(i);
1293 String param = methParams.get(i);
1294 //if (callbackType.equals(paramType)) {
1295 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
1297 String exchParamType = checkAndGetParamClass(paramType);
1298 // Print array if this is array or list if this is a list of callback objects
1299 if (isArray(param)) {
1300 println("int numStubs" + i + " = (int) paramObj[" + i + "];");
1301 println(exchParamType + "[] stub" + i + " = new " + exchParamType + "[numStubs" + i + "];");
1302 } else if (isList(paramType)) {
1303 println("int numStubs" + i + " = (int) paramObj[" + i + "];");
1304 println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();");
1306 println(exchParamType + " stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
1307 println("objIdCnt++;");
1310 // Generate a loop if needed
1311 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
1312 String exchParamType = checkAndGetParamClass(paramType);
1313 if (isArray(param)) {
1314 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
1315 println("stub" + i + "[objId] = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
1316 println("objIdCnt++;");
1318 } else if (isList(paramType)) {
1319 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
1320 println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt));");
1321 println("objIdCnt++;");
1324 mapStubParam.put(i, "stub" + i); // List of all stub parameters
1327 return mapStubParam;
1332 * HELPER: checkAndWriteEnumTypeJavaSkeleton() writes the enum type (convert from enum to int)
1334 private void checkAndWriteEnumTypeJavaSkeleton(List<String> methParams, List<String> methPrmTypes) {
1336 // Iterate and find enum declarations
1337 for (int i = 0; i < methParams.size(); i++) {
1338 String paramType = methPrmTypes.get(i);
1339 String param = methParams.get(i);
1340 String simpleType = getSimpleType(paramType);
1341 if (isEnumClass(simpleType)) {
1342 // Check if this is enum type
1343 println("int paramInt" + i + "[] = (int[]) paramObj[" + i + "];");
1344 println(simpleType + "[] enumVals = " + simpleType + ".values();");
1345 if (isArray(param)) { // An array
1346 println("int len" + i + " = paramInt" + i + ".length;");
1347 println(simpleType + "[] paramEnum = new " + simpleType + "[len];");
1348 println("for (int i = 0; i < len" + i + "; i++) {");
1349 println("paramEnum[i] = enumVals[paramInt" + i + "[i]];");
1351 } else if (isList(paramType)) { // A list
1352 println("int len" + i + " = paramInt" + i + ".length;");
1353 println("List<" + simpleType + "> paramEnum = new ArrayList<" + simpleType + ">();");
1354 println("for (int i = 0; i < len" + i + "; i++) {");
1355 println("paramEnum.add(enumVals[paramInt" + i + "[i]]);");
1357 } else { // Just one element
1358 println(simpleType + " paramEnum" + i + " = enumVals[paramInt" + i + "[0]];");
1366 * HELPER: checkAndWriteEnumRetTypeJavaSkeleton() writes the enum return type (convert from enum to int)
1368 private void checkAndWriteEnumRetTypeJavaSkeleton(String retType, String methodId) {
1370 // Strips off array "[]" for return type
1371 String pureType = getSimpleArrayType(getSimpleType(retType));
1372 // Take the inner type of generic
1373 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
1374 pureType = getTypeOfGeneric(retType)[0];
1375 if (isEnumClass(pureType)) {
1376 // Check if this is enum type
1378 if (isArray(retType)) { // An array
1379 print(pureType + "[] retEnum = " + methodId + "(");
1380 } else if (isList(retType)) { // A list
1381 print("List<" + pureType + "> retEnum = " + methodId + "(");
1382 } else { // Just one element
1383 print(pureType + " retEnum = " + methodId + "(");
1390 * HELPER: checkAndWriteEnumRetConvJavaSkeleton() writes the enum return type (convert from enum to int)
1392 private void checkAndWriteEnumRetConvJavaSkeleton(String retType) {
1394 // Strips off array "[]" for return type
1395 String pureType = getSimpleArrayType(getSimpleType(retType));
1396 // Take the inner type of generic
1397 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
1398 pureType = getTypeOfGeneric(retType)[0];
1399 if (isEnumClass(pureType)) {
1400 // Check if this is enum type
1401 if (isArray(retType)) { // An array
1402 println("int retLen = retEnum.length;");
1403 println("int[] retEnumVal = new int[retLen];");
1404 println("for (int i = 0; i < retLen; i++) {");
1405 println("retEnumVal[i] = retEnum[i].ordinal();");
1407 } else if (isList(retType)) { // A list
1408 println("int retLen = retEnum.size();");
1409 println("List<" + pureType + "> retEnumVal = new ArrayList<" + pureType + ">();");
1410 println("for (int i = 0; i < retLen; i++) {");
1411 println("retEnumVal.add(retEnum[i].ordinal());");
1413 } else { // Just one element
1414 println("int[] retEnumVal = new int[1];");
1415 println("retEnumVal[0] = retEnum.ordinal();");
1417 println("Object retObj = retEnumVal;");
1423 * HELPER: writeLengthStructParamClassSkeleton() writes lengths of params
1425 private void writeLengthStructParamClassSkeleton(List<String> methParams, List<String> methPrmTypes,
1426 String method, InterfaceDecl intDecl) {
1428 // Iterate and find struct declarations - count number of params
1429 for (int i = 0; i < methParams.size(); i++) {
1430 String paramType = methPrmTypes.get(i);
1431 String param = methParams.get(i);
1432 String simpleType = getGenericType(paramType);
1433 if (isStructClass(simpleType)) {
1434 int members = getNumOfMembers(simpleType);
1435 print(Integer.toString(members) + "*");
1436 int methodNumId = intDecl.getMethodNumId(method);
1437 print("struct" + methodNumId + "Size" + i);
1440 if (i != methParams.size() - 1) {
1448 * HELPER: writeStructMembersJavaSkeleton() writes member parameters of struct
1450 private void writeStructMembersJavaSkeleton(String simpleType, String paramType,
1451 String param, String method, InterfaceDecl intDecl, int iVar) {
1453 // Get the struct declaration for this struct and generate initialization code
1454 StructDecl structDecl = getStructDecl(simpleType);
1455 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1456 List<String> members = structDecl.getMembers(simpleType);
1457 if (isArrayOrList(param, paramType)) { // An array or list
1458 int methodNumId = intDecl.getMethodNumId(method);
1459 String counter = "struct" + methodNumId + "Size" + iVar;
1460 println("for(int i = 0; i < " + counter + "; i++) {");
1462 println("int pos = 0;");
1463 if (isArrayOrList(param, paramType)) { // An array or list
1464 println("for(int i = 0; i < retLen; i++) {");
1465 for (int i = 0; i < members.size(); i++) {
1466 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1467 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1468 println("paramClsGen[pos++] = null;");
1471 } else { // Just one struct element
1472 for (int i = 0; i < members.size(); i++) {
1473 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1474 println("paramCls[pos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1475 println("paramClsGen[pos++] = null;");
1482 * HELPER: writeStructMembersInitJavaSkeleton() writes member parameters initialization of struct
1484 private void writeStructMembersInitJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1485 List<String> methPrmTypes, String method) {
1487 for (int i = 0; i < methParams.size(); i++) {
1488 String paramType = methPrmTypes.get(i);
1489 String param = methParams.get(i);
1490 String simpleType = getGenericType(paramType);
1491 if (isStructClass(simpleType)) {
1492 int methodNumId = intDecl.getMethodNumId(method);
1493 String counter = "struct" + methodNumId + "Size" + i;
1495 if (isArray(param)) { // An array
1496 println(simpleType + "[] paramStruct" + i + " = new " + simpleType + "[" + counter + "];");
1497 println("for(int i = 0; i < " + counter + "; i++) {");
1498 println("paramStruct" + i + "[i] = new " + simpleType + "();");
1500 } else if (isList(paramType)) { // A list
1501 println("List<" + simpleType + "> paramStruct" + i + " = new ArrayList<" + simpleType + ">();");
1503 println(simpleType + " paramStruct" + i + " = new " + simpleType + "();");
1504 println("int objPos = 0;");
1505 // Initialize members
1506 StructDecl structDecl = getStructDecl(simpleType);
1507 List<String> members = structDecl.getMembers(simpleType);
1508 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1509 if (isArrayOrList(param, paramType)) { // An array or list
1510 println("for(int i = 0; i < " + counter + "; i++) {");
1512 if (isArray(param)) { // An array
1513 for (int j = 0; j < members.size(); j++) {
1514 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1515 print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j)));
1516 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1519 } else if (isList(paramType)) { // A list
1520 println(simpleType + " paramStructMem = new " + simpleType + "();");
1521 for (int j = 0; j < members.size(); j++) {
1522 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1523 print("paramStructMem." + getSimpleIdentifier(members.get(j)));
1524 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1526 println("paramStruct" + i + ".add(paramStructMem);");
1528 } else { // Just one struct element
1529 for (int j = 0; j < members.size(); j++) {
1530 String prmType = checkAndGetArray(memTypes.get(j), members.get(j));
1531 print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j)));
1532 println(" = (" + getSimpleType(getEnumType(prmType)) + ") paramObj[objPos++];");
1536 // Take offsets of parameters
1537 println("int offset" + i +" = objPos;");
1544 * HELPER: writeStructReturnJavaSkeleton() writes struct for return statement
1546 private void writeStructReturnJavaSkeleton(String simpleType, String retType) {
1548 // Minimum retLen is 1 if this is a single struct object
1549 if (isArray(retType))
1550 println("int retLen = retStruct.length;");
1551 else if (isList(retType))
1552 println("int retLen = retStruct.size();");
1553 else // Just single struct object
1554 println("int retLen = 1;");
1555 println("Object retLenObj = retLen;");
1556 println("rmiObj.sendReturnObj(retLenObj);");
1557 int numMem = getNumOfMembers(simpleType);
1558 println("Class<?>[] retCls = new Class<?>[" + numMem + "*retLen];");
1559 println("Object[] retObj = new Object[" + numMem + "*retLen];");
1560 println("int retPos = 0;");
1561 // Get the struct declaration for this struct and generate initialization code
1562 StructDecl structDecl = getStructDecl(simpleType);
1563 List<String> memTypes = structDecl.getMemberTypes(simpleType);
1564 List<String> members = structDecl.getMembers(simpleType);
1565 if (isArrayOrList(retType, retType)) { // An array or list
1566 println("for(int i = 0; i < retLen; i++) {");
1567 for (int i = 0; i < members.size(); i++) {
1568 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1569 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1570 print("retObj[retPos++] = retStruct[i].");
1571 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
1575 } else { // Just one struct element
1576 for (int i = 0; i < members.size(); i++) {
1577 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
1578 println("retCls[retPos] = " + getSimpleType(getEnumType(prmType)) + ".class;");
1579 print("retObj[retPos++] = retStruct.");
1580 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
1589 * HELPER: writeMethodHelperReturnJavaSkeleton() writes return statement part in skeleton
1591 private void writeMethodHelperReturnJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1592 List<String> methPrmTypes, String method, boolean isCallbackMethod, String callbackType,
1593 boolean isStructMethod) {
1595 checkAndWriteEnumTypeJavaSkeleton(methParams, methPrmTypes);
1596 Map<Integer,String> mapStubParam = null;
1597 if (isCallbackMethod)
1598 mapStubParam = writeCallbackJavaStubGeneration(methParams, methPrmTypes, callbackType);
1599 // Check if this is "void"
1600 String retType = intDecl.getMethodType(method);
1601 if (retType.equals("void")) {
1602 print(intDecl.getMethodId(method) + "(");
1603 } else if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
1604 checkAndWriteEnumRetTypeJavaSkeleton(retType, intDecl.getMethodId(method));
1605 } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
1606 print(retType + " retStruct = " + intDecl.getMethodId(method) + "(");
1607 } else { // We do have a return value
1608 print("Object retObj = " + intDecl.getMethodId(method) + "(");
1610 for (int i = 0; i < methParams.size(); i++) {
1612 if (isCallbackMethod) {
1613 print(mapStubParam.get(i)); // Get the callback parameter
1614 } else if (isEnumClass(getSimpleType(methPrmTypes.get(i)))) { // Enum class
1615 print(getEnumParam(methPrmTypes.get(i), methParams.get(i), i));
1616 } else if (isStructClass(getSimpleType(methPrmTypes.get(i)))) {
1617 print("paramStruct" + i);
1619 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1621 print("(" + prmType + ") paramObj[offset" + i + "]");
1623 print("(" + prmType + ") paramObj[" + i + "]");
1625 if (i != methParams.size() - 1)
1629 if (!retType.equals("void")) {
1630 if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) { // Enum type
1631 checkAndWriteEnumRetConvJavaSkeleton(retType);
1632 println("rmiObj.sendReturnObj(retObj);");
1633 } else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) { // Struct type
1634 writeStructReturnJavaSkeleton(getSimpleArrayType(getSimpleType(retType)), retType);
1635 println("rmiObj.sendReturnObj(retCls, retObj);");
1637 println("rmiObj.sendReturnObj(retObj);");
1639 if (isCallbackMethod) { // Catch exception if this is callback
1640 println("} catch(Exception ex) {");
1641 println("ex.printStackTrace();");
1642 println("throw new Error(\"Exception from callback object instantiation!\");");
1649 * HELPER: writeMethodHelperStructJavaSkeleton() writes the struct in skeleton
1651 private void writeMethodHelperStructJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1652 List<String> methPrmTypes, String method, Set<String> callbackClasses) {
1654 // Generate array of parameter objects
1655 boolean isCallbackMethod = false;
1656 String callbackType = null;
1657 print("int paramLen = ");
1658 writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
1660 println("Class<?>[] paramCls = new Class<?>[paramLen];");
1661 println("Class<?>[] paramClsGen = new Class<?>[paramLen];");
1662 // Iterate again over the parameters
1663 for (int i = 0; i < methParams.size(); i++) {
1664 String paramType = methPrmTypes.get(i);
1665 String param = methParams.get(i);
1666 String simpleType = getGenericType(paramType);
1667 if (isStructClass(simpleType)) {
1668 writeStructMembersJavaSkeleton(simpleType, paramType, param, method, intDecl, i);
1670 String prmType = returnGenericCallbackType(methPrmTypes.get(i));
1671 if (callbackClasses.contains(prmType)) {
1672 isCallbackMethod = true;
1673 callbackType = prmType;
1674 println("paramCls[pos] = int.class;");
1675 println("paramClsGen[pos++] = null;");
1676 } else { // Generate normal classes if it's not a callback object
1677 String paramTypeOth = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1678 println("paramCls[pos] = " + getSimpleType(getEnumType(paramTypeOth)) + ".class;");
1679 print("paramClsGen[pos++] = ");
1680 String prmTypeOth = methPrmTypes.get(i);
1681 if (getParamCategory(prmTypeOth) == ParamCategory.NONPRIMITIVES)
1682 println(getTypeOfGeneric(prmType)[0] + ".class;");
1688 println("Object[] paramObj = rmiObj.getMethodParams(paramCls, paramClsGen);");
1689 writeStructMembersInitJavaSkeleton(intDecl, methParams, methPrmTypes, method);
1690 // Write the return value part
1691 writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, true);
1696 * HELPER: writeStdMethodHelperBodyJavaSkeleton() writes the standard method body helper in the skeleton class
1698 private void writeStdMethodHelperBodyJavaSkeleton(InterfaceDecl intDecl, List<String> methParams,
1699 List<String> methPrmTypes, String method, Set<String> callbackClasses) {
1701 // Generate array of parameter objects
1702 boolean isCallbackMethod = false;
1703 String callbackType = null;
1704 print("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { ");
1705 for (int i = 0; i < methParams.size(); i++) {
1707 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
1708 if (callbackClasses.contains(paramType)) {
1709 isCallbackMethod = true;
1710 callbackType = paramType;
1712 } else { // Generate normal classes if it's not a callback object
1713 String prmType = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
1714 print(getSimpleType(getEnumType(prmType)) + ".class");
1716 if (i != methParams.size() - 1)
1720 // Generate generic class if it's a generic type.. null otherwise
1721 print("new Class<?>[] { ");
1722 for (int i = 0; i < methParams.size(); i++) {
1723 String prmType = methPrmTypes.get(i);
1724 if (getParamCategory(prmType) == ParamCategory.NONPRIMITIVES)
1725 print(getTypeOfGeneric(prmType)[0] + ".class");
1728 if (i != methParams.size() - 1)
1732 // Write the return value part
1733 writeMethodHelperReturnJavaSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod, callbackType, false);
1738 * HELPER: writeMethodHelperJavaSkeleton() writes the method helper of the skeleton class
1740 private void writeMethodHelperJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
1742 // Use this set to handle two same methodIds
1743 Set<String> uniqueMethodIds = new HashSet<String>();
1744 for (String method : methods) {
1746 List<String> methParams = intDecl.getMethodParams(method);
1747 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1748 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
1749 String methodId = intDecl.getMethodId(method);
1750 print("public void ___");
1751 String helperMethod = methodId;
1752 if (uniqueMethodIds.contains(methodId))
1753 helperMethod = helperMethod + intDecl.getMethodNumId(method);
1755 uniqueMethodIds.add(methodId);
1756 String retType = intDecl.getMethodType(method);
1757 print(helperMethod + "(");
1758 boolean begin = true;
1759 for (int i = 0; i < methParams.size(); i++) { // Print size variables
1760 String paramType = methPrmTypes.get(i);
1761 String param = methParams.get(i);
1762 String simpleType = getSimpleType(paramType);
1763 if (isStructClass(simpleType)) {
1764 if (!begin) { // Generate comma for not the beginning variable
1765 print(", "); begin = false;
1767 int methodNumId = intDecl.getMethodNumId(method);
1768 print("int struct" + methodNumId + "Size" + i);
1771 // Check if this is "void"
1772 if (retType.equals("void"))
1775 println(") throws IOException {");
1776 writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
1779 String methodId = intDecl.getMethodId(method);
1780 print("public void ___");
1781 String helperMethod = methodId;
1782 if (uniqueMethodIds.contains(methodId))
1783 helperMethod = helperMethod + intDecl.getMethodNumId(method);
1785 uniqueMethodIds.add(methodId);
1786 // Check if this is "void"
1787 String retType = intDecl.getMethodType(method);
1788 if (retType.equals("void"))
1789 println(helperMethod + "() {");
1791 println(helperMethod + "() throws IOException {");
1792 // Now, write the helper body of skeleton!
1793 writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
1797 // Write method helper for structs
1798 writeMethodHelperStructSetupJavaSkeleton(methods, intDecl);
1803 * HELPER: writeMethodHelperStructSetupJavaSkeleton() writes the method helper of struct setup in skeleton class
1805 private void writeMethodHelperStructSetupJavaSkeleton(Collection<String> methods,
1806 InterfaceDecl intDecl) {
1808 // Use this set to handle two same methodIds
1809 for (String method : methods) {
1811 List<String> methParams = intDecl.getMethodParams(method);
1812 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1813 // Check for params with structs
1814 for (int i = 0; i < methParams.size(); i++) {
1815 String paramType = methPrmTypes.get(i);
1816 String param = methParams.get(i);
1817 String simpleType = getSimpleType(paramType);
1818 if (isStructClass(simpleType)) {
1819 int methodNumId = intDecl.getMethodNumId(method);
1820 print("public int ___");
1821 String helperMethod = methodNumId + "struct" + i;
1822 println(helperMethod + "() {");
1823 // Now, write the helper body of skeleton!
1824 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
1825 println("return (int) paramObj[0];");
1834 * HELPER: writeMethodHelperStructSetupJavaCallbackSkeleton() writes the method helper of struct setup in callback skeleton class
1836 private void writeMethodHelperStructSetupJavaCallbackSkeleton(Collection<String> methods,
1837 InterfaceDecl intDecl) {
1839 // Use this set to handle two same methodIds
1840 for (String method : methods) {
1842 List<String> methParams = intDecl.getMethodParams(method);
1843 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1844 // Check for params with structs
1845 for (int i = 0; i < methParams.size(); i++) {
1846 String paramType = methPrmTypes.get(i);
1847 String param = methParams.get(i);
1848 String simpleType = getSimpleType(paramType);
1849 if (isStructClass(simpleType)) {
1850 int methodNumId = intDecl.getMethodNumId(method);
1851 print("public int ___");
1852 String helperMethod = methodNumId + "struct" + i;
1853 println(helperMethod + "(IoTRMIObject rmiObj) {");
1854 // Now, write the helper body of skeleton!
1855 println("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, new Class<?>[] { null });");
1856 println("return (int) paramObj[0];");
1865 * HELPER: writeCountVarStructSkeleton() writes counter variable of struct for skeleton
1867 private void writeCountVarStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
1869 // Use this set to handle two same methodIds
1870 for (String method : methods) {
1872 List<String> methParams = intDecl.getMethodParams(method);
1873 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1874 // Check for params with structs
1875 for (int i = 0; i < methParams.size(); i++) {
1876 String paramType = methPrmTypes.get(i);
1877 String param = methParams.get(i);
1878 String simpleType = getSimpleType(paramType);
1879 if (isStructClass(simpleType)) {
1880 int methodNumId = intDecl.getMethodNumId(method);
1881 println("int struct" + methodNumId + "Size" + i + " = 0;");
1889 * HELPER: writeInputCountVarStructSkeleton() writes input counter variable of struct for skeleton
1891 private boolean writeInputCountVarStructSkeleton(String method, InterfaceDecl intDecl) {
1893 List<String> methParams = intDecl.getMethodParams(method);
1894 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1895 boolean structExist = false;
1896 // Check for params with structs
1897 for (int i = 0; i < methParams.size(); i++) {
1898 String paramType = methPrmTypes.get(i);
1899 String param = methParams.get(i);
1900 String simpleType = getSimpleType(paramType);
1901 boolean begin = true;
1902 if (isStructClass(simpleType)) {
1905 print(", "); begin = false;
1907 int methodNumId = intDecl.getMethodNumId(method);
1908 print("struct" + methodNumId + "Size" + i);
1916 * HELPER: writeMethodCallStructSkeleton() writes method call for wait invoke in skeleton
1918 private void writeMethodCallStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
1920 // Use this set to handle two same methodIds
1921 for (String method : methods) {
1923 List<String> methParams = intDecl.getMethodParams(method);
1924 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1925 // Check for params with structs
1926 for (int i = 0; i < methParams.size(); i++) {
1927 String paramType = methPrmTypes.get(i);
1928 String param = methParams.get(i);
1929 String simpleType = getSimpleType(paramType);
1930 if (isStructClass(simpleType)) {
1931 int methodNumId = intDecl.getMethodNumId(method);
1933 String helperMethod = methodNumId + "struct" + i;
1934 String tempVar = "struct" + methodNumId + "Size" + i;
1935 print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
1936 print(tempVar + " = ___");
1937 println(helperMethod + "(); break;");
1945 * HELPER: writeMethodCallStructCallbackSkeleton() writes method call for wait invoke in skeleton
1947 private void writeMethodCallStructCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
1949 // Use this set to handle two same methodIds
1950 for (String method : methods) {
1952 List<String> methParams = intDecl.getMethodParams(method);
1953 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
1954 // Check for params with structs
1955 for (int i = 0; i < methParams.size(); i++) {
1956 String paramType = methPrmTypes.get(i);
1957 String param = methParams.get(i);
1958 String simpleType = getSimpleType(paramType);
1959 if (isStructClass(simpleType)) {
1960 int methodNumId = intDecl.getMethodNumId(method);
1962 String helperMethod = methodNumId + "struct" + i;
1963 String tempVar = "struct" + methodNumId + "Size" + i;
1964 print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
1965 print(tempVar + " = ___");
1966 println(helperMethod + "(rmiObj); break;");
1974 * HELPER: writeJavaMethodPermission() writes permission checks in skeleton
1976 private void writeJavaMethodPermission(String intface) {
1978 // Get all the different stubs
1979 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
1980 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
1981 String newIntface = intMeth.getKey();
1982 int newObjectId = mapNewIntfaceObjId.get(newIntface);
1983 println("if (_objectId == object" + newObjectId + "Id) {");
1984 println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
1985 println("throw new Error(\"Object with object Id: \" + _objectId + \" is not allowed to access method: \" + methodId);");
1989 println("throw new Error(\"Object Id: \" + _objectId + \" not recognized!\");");
1996 * HELPER: writeJavaWaitRequestInvokeMethod() writes the main loop of the skeleton class
1998 private void writeJavaWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
2000 // Use this set to handle two same methodIds
2001 Set<String> uniqueMethodIds = new HashSet<String>();
2002 println("private void ___waitRequestInvokeMethod() throws IOException {");
2003 // Write variables here if we have callbacks or enums or structs
2004 writeCountVarStructSkeleton(methods, intDecl);
2005 println("while (true) {");
2006 println("rmiObj.getMethodBytes();");
2007 println("int _objectId = rmiObj.getObjectId();");
2008 println("int methodId = rmiObj.getMethodId();");
2009 // Generate permission check
2010 writeJavaMethodPermission(intface);
2011 println("switch (methodId) {");
2012 // Print methods and method Ids
2013 for (String method : methods) {
2014 String methodId = intDecl.getMethodId(method);
2015 int methodNumId = intDecl.getMethodNumId(method);
2016 print("case " + methodNumId + ": ___");
2017 String helperMethod = methodId;
2018 if (uniqueMethodIds.contains(methodId))
2019 helperMethod = helperMethod + methodNumId;
2021 uniqueMethodIds.add(methodId);
2022 print(helperMethod + "(");
2023 writeInputCountVarStructSkeleton(method, intDecl);
2024 println("); break;");
2026 String method = "___initCallBack()";
2027 // Print case -9999 (callback handler) if callback exists
2028 if (callbackExist) {
2029 int methodId = intDecl.getHelperMethodNumId(method);
2030 println("case " + methodId + ": ___regCB(); break;");
2032 writeMethodCallStructSkeleton(methods, intDecl);
2033 println("default: ");
2034 println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
2042 * generateJavaSkeletonClass() generate skeletons based on the methods list in Java
2044 public void generateJavaSkeletonClass() throws IOException {
2046 // Create a new directory
2047 String path = createDirectories(dir, subdir);
2048 for (String intface : mapIntfacePTH.keySet()) {
2049 // Open a new file to write into
2050 String newSkelClass = intface + "_Skeleton";
2051 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
2052 pw = new PrintWriter(new BufferedWriter(fw));
2053 // Pass in set of methods and get import classes
2054 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2055 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2056 List<String> methods = intDecl.getMethods();
2057 Set<String> importClasses = getImportClasses(methods, intDecl);
2058 List<String> stdImportClasses = getStandardJavaImportClasses();
2059 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
2060 printImportStatements(allImportClasses);
2061 // Find out if there are callback objects
2062 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
2063 boolean callbackExist = !callbackClasses.isEmpty();
2064 // Write class header
2066 println("public class " + newSkelClass + " implements " + intface + " {\n");
2068 writePropertiesJavaSkeleton(intface, callbackExist, intDecl);
2069 // Write constructor
2070 writeConstructorJavaSkeleton(newSkelClass, intface);
2072 writeMethodJavaSkeleton(methods, intDecl, callbackClasses, false);
2073 // Write method helper
2074 writeMethodHelperJavaSkeleton(methods, intDecl, callbackClasses);
2075 // Write waitRequestInvokeMethod() - main loop
2076 writeJavaWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
2079 System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".java...");
2085 * HELPER: writePropertiesJavaCallbackSkeleton() writes the properties of the callback skeleton class
2087 private void writePropertiesJavaCallbackSkeleton(String intface, boolean callbackExist) {
2089 println("private " + intface + " mainObj;");
2090 // For callback skeletons, this is its own object Id
2091 println("private static int objectId = 0;");
2093 if (callbackExist) {
2094 println("private static int objIdCnt = 0;");
2095 println("private IoTRMICall rmiCall;");
2102 * HELPER: writeConstructorJavaCallbackSkeleton() writes the constructor of the skeleton class
2104 private void writeConstructorJavaCallbackSkeleton(String newSkelClass, String intface) {
2106 println("public " + newSkelClass + "(" + intface + " _mainObj, int _objectId) throws Exception {");
2107 println("mainObj = _mainObj;");
2108 println("objectId = _objectId;");
2114 * HELPER: writeMethodHelperJavaCallbackSkeleton() writes the method helper of the callback skeleton class
2116 private void writeMethodHelperJavaCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
2118 // Use this set to handle two same methodIds
2119 Set<String> uniqueMethodIds = new HashSet<String>();
2120 for (String method : methods) {
2122 List<String> methParams = intDecl.getMethodParams(method);
2123 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2124 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
2125 String methodId = intDecl.getMethodId(method);
2126 print("public void ___");
2127 String helperMethod = methodId;
2128 if (uniqueMethodIds.contains(methodId))
2129 helperMethod = helperMethod + intDecl.getMethodNumId(method);
2131 uniqueMethodIds.add(methodId);
2132 String retType = intDecl.getMethodType(method);
2133 print(helperMethod + "(");
2134 boolean begin = true;
2135 for (int i = 0; i < methParams.size(); i++) { // Print size variables
2136 String paramType = methPrmTypes.get(i);
2137 String param = methParams.get(i);
2138 String simpleType = getSimpleType(paramType);
2139 if (isStructClass(simpleType)) {
2140 if (!begin) { // Generate comma for not the beginning variable
2141 print(", "); begin = false;
2143 int methodNumId = intDecl.getMethodNumId(method);
2144 print("int struct" + methodNumId + "Size" + i);
2147 // Check if this is "void"
2148 if (retType.equals("void"))
2149 println(", IoTRMIObject rmiObj) {");
2151 println(", IoTRMIObject rmiObj) throws IOException {");
2152 writeMethodHelperStructJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
2155 String methodId = intDecl.getMethodId(method);
2156 print("public void ___");
2157 String helperMethod = methodId;
2158 if (uniqueMethodIds.contains(methodId))
2159 helperMethod = helperMethod + intDecl.getMethodNumId(method);
2161 uniqueMethodIds.add(methodId);
2162 // Check if this is "void"
2163 String retType = intDecl.getMethodType(method);
2164 if (retType.equals("void"))
2165 println(helperMethod + "(IoTRMIObject rmiObj) {");
2167 println(helperMethod + "(IoTRMIObject rmiObj) throws IOException {");
2168 // Now, write the helper body of skeleton!
2169 writeStdMethodHelperBodyJavaSkeleton(intDecl, methParams, methPrmTypes, method, callbackClasses);
2173 // Write method helper for structs
2174 writeMethodHelperStructSetupJavaCallbackSkeleton(methods, intDecl);
2179 * HELPER: writeJavaCallbackWaitRequestInvokeMethod() writes the request invoke method of the callback skeleton class
2181 private void writeJavaCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist) {
2183 // Use this set to handle two same methodIds
2184 Set<String> uniqueMethodIds = new HashSet<String>();
2185 println("public void invokeMethod(IoTRMIObject rmiObj) throws IOException {");
2186 // Write variables here if we have callbacks or enums or structs
2187 writeCountVarStructSkeleton(methods, intDecl);
2188 // Write variables here if we have callbacks or enums or structs
2189 println("int methodId = rmiObj.getMethodId();");
2190 // TODO: code the permission check here!
2191 println("switch (methodId) {");
2192 // Print methods and method Ids
2193 for (String method : methods) {
2194 String methodId = intDecl.getMethodId(method);
2195 int methodNumId = intDecl.getMethodNumId(method);
2196 print("case " + methodNumId + ": ___");
2197 String helperMethod = methodId;
2198 if (uniqueMethodIds.contains(methodId))
2199 helperMethod = helperMethod + methodNumId;
2201 uniqueMethodIds.add(methodId);
2202 print(helperMethod + "(");
2203 if (writeInputCountVarStructSkeleton(method, intDecl))
2204 println(", rmiObj); break;");
2206 println("rmiObj); break;");
2208 String method = "___initCallBack()";
2209 // Print case -9999 (callback handler) if callback exists
2210 if (callbackExist) {
2211 int methodId = intDecl.getHelperMethodNumId(method);
2212 println("case " + methodId + ": ___regCB(rmiObj); break;");
2214 writeMethodCallStructCallbackSkeleton(methods, intDecl);
2215 println("default: ");
2216 println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
2223 * generateJavaCallbackSkeletonClass() generate callback skeletons based on the methods list in Java
2225 public void generateJavaCallbackSkeletonClass() throws IOException {
2227 // Create a new directory
2228 String path = createDirectories(dir, subdir);
2229 for (String intface : mapIntfacePTH.keySet()) {
2230 // Open a new file to write into
2231 String newSkelClass = intface + "_CallbackSkeleton";
2232 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".java");
2233 pw = new PrintWriter(new BufferedWriter(fw));
2234 // Pass in set of methods and get import classes
2235 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2236 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2237 List<String> methods = intDecl.getMethods();
2238 Set<String> importClasses = getImportClasses(methods, intDecl);
2239 List<String> stdImportClasses = getStandardJavaImportClasses();
2240 List<String> allImportClasses = getAllLibClasses(stdImportClasses, importClasses);
2241 printImportStatements(allImportClasses);
2242 // Find out if there are callback objects
2243 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
2244 boolean callbackExist = !callbackClasses.isEmpty();
2245 // Write class header
2247 println("public class " + newSkelClass + " implements " + intface + " {\n");
2249 writePropertiesJavaCallbackSkeleton(intface, callbackExist);
2250 // Write constructor
2251 writeConstructorJavaCallbackSkeleton(newSkelClass, intface);
2253 writeMethodJavaSkeleton(methods, intDecl, callbackClasses, true);
2254 // Write method helper
2255 writeMethodHelperJavaCallbackSkeleton(methods, intDecl, callbackClasses);
2256 // Write waitRequestInvokeMethod() - main loop
2257 writeJavaCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
2260 System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".java...");
2266 * HELPER: writeMethodCplusLocalInterface() writes the method of the local interface
2268 private void writeMethodCplusLocalInterface(Collection<String> methods, InterfaceDecl intDecl) {
2270 for (String method : methods) {
2272 List<String> methParams = intDecl.getMethodParams(method);
2273 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2274 print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2275 intDecl.getMethodId(method) + "(");
2276 for (int i = 0; i < methParams.size(); i++) {
2277 // Check for params with driver class types and exchange it
2278 // with its remote interface
2279 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
2280 paramType = checkAndGetCplusType(paramType);
2281 // Check for arrays - translate into vector in C++
2282 String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
2283 print(paramComplete);
2284 // Check if this is the last element (don't print a comma)
2285 if (i != methParams.size() - 1) {
2295 * HELPER: writeMethodCplusInterface() writes the method of the interface
2297 private void writeMethodCplusInterface(Collection<String> methods, InterfaceDecl intDecl) {
2299 for (String method : methods) {
2301 List<String> methParams = intDecl.getMethodParams(method);
2302 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2303 print("virtual " + checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2304 intDecl.getMethodId(method) + "(");
2305 for (int i = 0; i < methParams.size(); i++) {
2306 // Check for params with driver class types and exchange it
2307 // with its remote interface
2308 String paramType = methPrmTypes.get(i);
2309 paramType = checkAndGetCplusType(paramType);
2310 // Check for arrays - translate into vector in C++
2311 String paramComplete = checkAndGetCplusArray(paramType, methParams.get(i));
2312 print(paramComplete);
2313 // Check if this is the last element (don't print a comma)
2314 if (i != methParams.size() - 1) {
2324 * HELPER: generateEnumCplus() writes the enumeration declaration
2326 public void generateEnumCplus() throws IOException {
2328 // Create a new directory
2329 createDirectory(dir);
2330 for (String intface : mapIntfacePTH.keySet()) {
2331 // Get the right StructDecl
2332 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2333 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
2334 Set<String> enumTypes = enumDecl.getEnumDeclarations();
2335 // Iterate over enum declarations
2336 for (String enType : enumTypes) {
2337 // Open a new file to write into
2338 FileWriter fw = new FileWriter(dir + "/" + enType + ".hpp");
2339 pw = new PrintWriter(new BufferedWriter(fw));
2340 // Write file headers
2341 println("#ifndef _" + enType.toUpperCase() + "_HPP__");
2342 println("#define _" + enType.toUpperCase() + "_HPP__");
2343 println("enum " + enType + " {");
2344 List<String> enumMembers = enumDecl.getMembers(enType);
2345 for (int i = 0; i < enumMembers.size(); i++) {
2347 String member = enumMembers.get(i);
2349 // Check if this is the last element (don't print a comma)
2350 if (i != enumMembers.size() - 1)
2358 System.out.println("IoTCompiler: Generated enum " + enType + ".hpp...");
2365 * HELPER: generateStructCplus() writes the struct declaration
2367 public void generateStructCplus() throws IOException {
2369 // Create a new directory
2370 createDirectory(dir);
2371 for (String intface : mapIntfacePTH.keySet()) {
2372 // Get the right StructDecl
2373 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2374 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
2375 List<String> structTypes = structDecl.getStructTypes();
2376 // Iterate over enum declarations
2377 for (String stType : structTypes) {
2378 // Open a new file to write into
2379 FileWriter fw = new FileWriter(dir + "/" + stType + ".hpp");
2380 pw = new PrintWriter(new BufferedWriter(fw));
2381 // Write file headers
2382 println("#ifndef _" + stType.toUpperCase() + "_HPP__");
2383 println("#define _" + stType.toUpperCase() + "_HPP__");
2384 println("struct " + stType + " {");
2385 List<String> structMemberTypes = structDecl.getMemberTypes(stType);
2386 List<String> structMembers = structDecl.getMembers(stType);
2387 for (int i = 0; i < structMembers.size(); i++) {
2389 String memberType = structMemberTypes.get(i);
2390 String member = structMembers.get(i);
2391 String structTypeC = checkAndGetCplusType(memberType);
2392 String structComplete = checkAndGetCplusArray(structTypeC, member);
2393 println(structComplete + ";");
2398 System.out.println("IoTCompiler: Generated struct " + stType + ".hpp...");
2405 * generateCplusLocalInterfaces() writes the local interfaces and provides type-checking.
2407 * It needs to rewrite and exchange USERDEFINED types in input parameters of stub
2408 * and original interfaces, e.g. exchange Camera and CameraWithVideoAndRecording.
2409 * The local interface has to be the input parameter for the stub and the stub
2410 * interface has to be the input parameter for the local class.
2412 public void generateCplusLocalInterfaces() throws IOException {
2414 // Create a new directory
2415 createDirectory(dir);
2416 for (String intface : mapIntfacePTH.keySet()) {
2417 // Open a new file to write into
2418 FileWriter fw = new FileWriter(dir + "/" + intface + ".hpp");
2419 pw = new PrintWriter(new BufferedWriter(fw));
2420 // Write file headers
2421 println("#ifndef _" + intface.toUpperCase() + "_HPP__");
2422 println("#define _" + intface.toUpperCase() + "_HPP__");
2423 println("#include <iostream>");
2424 // Pass in set of methods and get include classes
2425 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2426 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2427 List<String> methods = intDecl.getMethods();
2428 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
2429 printIncludeStatements(includeClasses); println("");
2430 println("using namespace std;\n");
2431 //writeStructCplus(structDecl);
2432 println("class " + intface); println("{");
2435 writeMethodCplusLocalInterface(methods, intDecl);
2439 System.out.println("IoTCompiler: Generated local interface " + intface + ".hpp...");
2445 * generateCPlusInterfaces() generate stub interfaces based on the methods list in C++
2447 * For C++ we use virtual classe as interface
2449 public void generateCPlusInterfaces() throws IOException {
2451 // Create a new directory
2452 String path = createDirectories(dir, subdir);
2453 for (String intface : mapIntfacePTH.keySet()) {
2455 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
2456 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
2458 // Open a new file to write into
2459 String newIntface = intMeth.getKey();
2460 FileWriter fw = new FileWriter(path + "/" + newIntface + ".hpp");
2461 pw = new PrintWriter(new BufferedWriter(fw));
2462 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
2463 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
2464 // Write file headers
2465 println("#ifndef _" + newIntface.toUpperCase() + "_HPP__");
2466 println("#define _" + newIntface.toUpperCase() + "_HPP__");
2467 println("#include <iostream>");
2468 // Pass in set of methods and get import classes
2469 Set<String> includeClasses = getIncludeClasses(intMeth.getValue(), intDecl, intface, false);
2470 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
2471 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
2472 printIncludeStatements(allIncludeClasses); println("");
2473 println("using namespace std;\n");
2474 println("class " + newIntface);
2478 writeMethodCplusInterface(intMeth.getValue(), intDecl);
2482 System.out.println("IoTCompiler: Generated interface " + newIntface + ".hpp...");
2489 * HELPER: writeMethodCplusStub() writes the methods of the stub
2491 private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
2493 for (String method : methods) {
2495 List<String> methParams = intDecl.getMethodParams(method);
2496 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
2497 print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
2498 intDecl.getMethodId(method) + "(");
2499 boolean isCallbackMethod = false;
2500 String callbackType = null;
2501 for (int i = 0; i < methParams.size(); i++) {
2503 String paramType = methPrmTypes.get(i);
2504 // Check if this has callback object
2505 if (callbackClasses.contains(paramType)) {
2506 isCallbackMethod = true;
2507 callbackType = paramType;
2508 // Even if there're 2 callback arguments, we expect them to be of the same interface
2510 String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
2511 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
2512 print(methParamComplete);
2513 // Check if this is the last element (don't print a comma)
2514 if (i != methParams.size() - 1) {
2519 if (isCallbackMethod)
2520 writeCallbackMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType);
2522 writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method);
2524 // Write the init callback helper method
2525 if (isCallbackMethod) {
2526 writeInitCallbackCplusStub(callbackType, intDecl);
2527 writeInitCallbackSendInfoCplusStub(intDecl);
2534 * HELPER: writeCallbackMethodBodyCplusStub() writes the callback method of the stub class
2536 private void writeCallbackMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
2537 List<String> methPrmTypes, String method, String callbackType) {
2539 // Check if this is single object, array, or list of objects
2540 boolean isArrayOrList = false;
2541 String callbackParam = null;
2542 for (int i = 0; i < methParams.size(); i++) {
2544 String paramType = methPrmTypes.get(i);
2545 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2546 String param = methParams.get(i);
2547 if (isArrayOrList(paramType, param)) { // Generate loop
2548 println("for (" + paramType + "* cb : " + getSimpleIdentifier(param) + ") {");
2549 println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(cb, objIdCnt++);");
2550 isArrayOrList = true;
2551 callbackParam = getSimpleIdentifier(param);
2553 println(callbackType + "_CallbackSkeleton* skel = new " + callbackType + "_CallbackSkeleton(" +
2554 getSimpleIdentifier(param) + ", objIdCnt++);");
2555 println("vecCallbackObj.push_back(skel);");
2556 if (isArrayOrList(paramType, param))
2560 println("int numParam = " + methParams.size() + ";");
2561 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
2562 String retType = intDecl.getMethodType(method);
2563 //String retTypeC = checkAndGetCplusType(retType);
2564 //println("string retType = \"" + checkAndGetCplusArrayType(retTypeC) + "\";");
2565 println("string retType = \"" + retType + "\";");
2566 // Generate array of parameter types
2567 print("string paramCls[] = { ");
2568 for (int i = 0; i < methParams.size(); i++) {
2569 String paramType = methPrmTypes.get(i);
2570 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2572 } else { // Generate normal classes if it's not a callback object
2573 //String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
2574 //String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
2575 String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
2576 String prmType = getSimpleType(getEnumType(paramTypeC));
2577 print("\"" + prmType + "\"");
2579 if (i != methParams.size() - 1) // Check if this is the last element
2583 print("int ___paramCB = ");
2585 println(callbackParam + ".size();");
2588 // Generate array of parameter objects
2589 print("void* paramObj[] = { ");
2590 for (int i = 0; i < methParams.size(); i++) {
2591 String paramType = methPrmTypes.get(i);
2592 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
2593 print("&___paramCB");
2595 print(getSimpleIdentifier(methParams.get(i)));
2596 if (i != methParams.size() - 1)
2600 // Check if this is "void"
2601 if (retType.equals("void")) {
2602 println("void* retObj = NULL;");
2603 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2604 } else { // We do have a return value
2605 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2606 println(checkAndGetCplusType(retType) + " retVal;");
2608 println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
2609 println("void* retObj = &retVal;");
2610 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2611 println("return retVal;");
2617 * HELPER: checkAndWriteEnumTypeCplusStub() writes the enum type (convert from enum to int)
2619 private void checkAndWriteEnumTypeCplusStub(List<String> methParams, List<String> methPrmTypes) {
2621 // Iterate and find enum declarations
2622 for (int i = 0; i < methParams.size(); i++) {
2623 String paramType = methPrmTypes.get(i);
2624 String param = methParams.get(i);
2625 String simpleType = getSimpleType(paramType);
2626 if (isEnumClass(simpleType)) {
2627 // Check if this is enum type
2628 if (isArrayOrList(paramType, param)) { // An array or vector
2629 println("int len" + i + " = " + param + ".size();");
2630 println("vector<int> paramEnum" + i + "(len);");
2631 println("for (int i = 0; i < len" + i + "; i++) {");
2632 println("paramEnum" + i + "[i] = (int) " + param + "[i];");
2634 } else { // Just one element
2635 println("vector<int> paramEnum" + i + "(1);");
2636 println("paramEnum" + i + "[0] = (int) " + param + ";");
2644 * HELPER: checkAndWriteEnumRetTypeCplusStub() writes the enum return type (convert from enum to int)
2646 private void checkAndWriteEnumRetTypeCplusStub(String retType) {
2648 // Strips off array "[]" for return type
2649 String pureType = getSimpleArrayType(getSimpleType(retType));
2650 // Take the inner type of generic
2651 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2652 pureType = getTypeOfGeneric(retType)[0];
2653 if (isEnumClass(pureType)) {
2654 // Check if this is enum type
2655 println("vector<int> retEnumInt;");
2656 println("void* retObj = &retEnumInt;");
2657 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2658 if (isArrayOrList(retType, retType)) { // An array or vector
2659 println("int retLen = retEnumInt.size();");
2660 println("vector<" + pureType + "> retVal(retLen);");
2661 println("for (int i = 0; i < retLen; i++) {");
2662 println("retVal[i] = (" + pureType + ") retEnumInt[i];");
2664 } else { // Just one element
2665 println(pureType + " retVal = (" + pureType + ") retEnumInt[0];");
2667 println("return retVal;");
2673 * HELPER: checkAndWriteStructSetupCplusStub() writes the struct type setup
2675 private void checkAndWriteStructSetupCplusStub(List<String> methParams, List<String> methPrmTypes,
2676 InterfaceDecl intDecl, String method) {
2678 // Iterate and find struct declarations
2679 for (int i = 0; i < methParams.size(); i++) {
2680 String paramType = methPrmTypes.get(i);
2681 String param = methParams.get(i);
2682 String simpleType = getSimpleType(paramType);
2683 if (isStructClass(simpleType)) {
2684 // Check if this is enum type
2685 println("int numParam" + i + " = 1;");
2686 int methodNumId = intDecl.getMethodNumId(method);
2687 String helperMethod = methodNumId + "struct" + i;
2688 println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
2689 println("string retTypeStruct" + i + " = \"void\";");
2690 println("string paramClsStruct" + i + "[] = { \"int\" };");
2691 print("int structLen" + i + " = ");
2692 if (isArrayOrList(param, paramType)) { // An array
2693 println(getSimpleArrayType(param) + ".size();");
2694 } else { // Just one element
2697 println("void* paramObjStruct" + i + "[] = { &structLen" + i + " };");
2698 println("void* retStructLen" + i + " = NULL;");
2699 println("rmiCall->remoteCall(objectId, methodIdStruct" + i +
2700 ", retTypeStruct" + i + ", paramClsStruct" + i + ", paramObjStruct" + i +
2701 ", numParam" + i + ", retStructLen" + i + ");\n");
2708 * HELPER: writeLengthStructParamClassCplusStub() writes lengths of params
2710 private void writeLengthStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes) {
2712 // Iterate and find struct declarations - count number of params
2713 for (int i = 0; i < methParams.size(); i++) {
2714 String paramType = methPrmTypes.get(i);
2715 String param = methParams.get(i);
2716 String simpleType = getGenericType(paramType);
2717 if (isStructClass(simpleType)) {
2718 int members = getNumOfMembers(simpleType);
2719 if (isArrayOrList(param, paramType)) { // An array
2720 String structLen = param + ".size()";
2721 print(members + "*" + structLen);
2723 print(Integer.toString(members));
2726 if (i != methParams.size() - 1) {
2734 * HELPER: writeStructMembersCplusStub() writes member parameters of struct
2736 private void writeStructMembersCplusStub(String simpleType, String paramType, String param) {
2738 // Get the struct declaration for this struct and generate initialization code
2739 StructDecl structDecl = getStructDecl(simpleType);
2740 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2741 List<String> members = structDecl.getMembers(simpleType);
2742 if (isArrayOrList(param, paramType)) { // An array or list
2743 println("for(int i = 0; i < " + param + ".size(); i++) {");
2745 if (isArrayOrList(param, paramType)) { // An array or list
2746 for (int i = 0; i < members.size(); i++) {
2747 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2748 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2749 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2750 print("paramObj[pos++] = &" + param + "[i].");
2751 print(getSimpleIdentifier(members.get(i)));
2755 } else { // Just one struct element
2756 for (int i = 0; i < members.size(); i++) {
2757 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2758 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2759 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2760 print("paramObj[pos++] = &" + param + ".");
2761 print(getSimpleIdentifier(members.get(i)));
2769 * HELPER: writeStructParamClassCplusStub() writes member parameters of struct
2771 private void writeStructParamClassCplusStub(List<String> methParams, List<String> methPrmTypes) {
2773 print("int numParam = ");
2774 writeLengthStructParamClassCplusStub(methParams, methPrmTypes);
2776 println("void* paramObj[numParam];");
2777 println("string paramCls[numParam];");
2778 println("int pos = 0;");
2779 // Iterate again over the parameters
2780 for (int i = 0; i < methParams.size(); i++) {
2781 String paramType = methPrmTypes.get(i);
2782 String param = methParams.get(i);
2783 String simpleType = getGenericType(paramType);
2784 if (isStructClass(simpleType)) {
2785 writeStructMembersCplusStub(simpleType, paramType, param);
2787 String prmTypeC = checkAndGetCplusType(methPrmTypes.get(i));
2788 String prmType = checkAndGetCplusArrayType(prmTypeC, methParams.get(i));
2789 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2790 print("paramObj[pos++] = &");
2791 print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
2800 * HELPER: writeStructRetMembersCplusStub() writes member parameters of struct for return statement
2802 private void writeStructRetMembersCplusStub(String simpleType, String retType) {
2804 // Get the struct declaration for this struct and generate initialization code
2805 StructDecl structDecl = getStructDecl(simpleType);
2806 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2807 List<String> members = structDecl.getMembers(simpleType);
2808 if (isArrayOrList(retType, retType)) { // An array or list
2809 println("for(int i = 0; i < retLen; i++) {");
2811 if (isArrayOrList(retType, retType)) { // An array or list
2812 for (int i = 0; i < members.size(); i++) {
2813 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
2814 print("structRet[i]." + getSimpleIdentifier(members.get(i)));
2815 println(" = retParam" + i + "[i];");
2818 } else { // Just one struct element
2819 for (int i = 0; i < members.size(); i++) {
2820 String prmType = checkAndGetArray(memTypes.get(i), members.get(i));
2821 print("structRet." + getSimpleIdentifier(members.get(i)));
2822 println(" = retParam" + i + ";");
2825 println("return structRet;");
2830 * HELPER: writeStructReturnCplusStub() writes member parameters of struct for return statement
2832 private void writeStructReturnCplusStub(String simpleType, String retType) {
2834 // Minimum retLen is 1 if this is a single struct object
2835 println("int retLen = 0;");
2836 println("void* retLenObj = { &retLen };");
2837 // Handle the returned struct!!!
2838 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retLenObj);");
2839 int numMem = getNumOfMembers(simpleType);
2840 println("int numRet = " + numMem + "*retLen;");
2841 println("string retCls[numRet];");
2842 println("void* retObj[numRet];");
2843 StructDecl structDecl = getStructDecl(simpleType);
2844 List<String> memTypes = structDecl.getMemberTypes(simpleType);
2845 List<String> members = structDecl.getMembers(simpleType);
2847 if (isArrayOrList(retType, retType)) { // An array or list
2848 for (int i = 0; i < members.size(); i++) {
2849 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2850 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2851 println(getSimpleType(getEnumType(prmType)) + " retParam" + i + "[retLen];");
2853 } else { // Just one struct element
2854 for (int i = 0; i < members.size(); i++) {
2855 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2856 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2857 println(getSimpleType(getEnumType(prmType)) + " retParam" + i + ";");
2860 println("int retPos = 0;");
2861 // Get the struct declaration for this struct and generate initialization code
2862 if (isArrayOrList(retType, retType)) { // An array or list
2863 println("for(int i = 0; i < retLen; i++) {");
2864 for (int i = 0; i < members.size(); i++) {
2865 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
2866 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
2867 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
2868 println("retObj[retPos++] = &retParam" + i + "[i];");
2871 } else { // Just one struct element
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 + ";");
2879 println("rmiCall->getStructObjects(retCls, numRet, retObj);");
2880 if (isArrayOrList(retType, retType)) { // An array or list
2881 println("vector<" + simpleType + "> structRet(retLen);");
2883 println(simpleType + " structRet;");
2884 writeStructRetMembersCplusStub(simpleType, retType);
2889 * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class
2891 private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List<String> methParams,
2892 List<String> methPrmTypes, String method) {
2894 checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method);
2895 println("int methodId = " + intDecl.getMethodNumId(method) + ";");
2896 String retType = intDecl.getMethodType(method);
2897 //String retTypeC = checkAndGetCplusType(retType);
2898 //println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";");
2899 println("string retType = \"" + retType + "\";");
2900 // Generate array of parameter types
2901 if (isStructPresent(methParams, methPrmTypes)) {
2902 writeStructParamClassCplusStub(methParams, methPrmTypes);
2904 println("int numParam = " + methParams.size() + ";");
2905 print("string paramCls[] = { ");
2906 for (int i = 0; i < methParams.size(); i++) {
2907 //String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
2908 //String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
2909 //print("\"" + getEnumType(paramType) + "\"");
2910 String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
2911 String prmType = getSimpleType(getEnumType(paramTypeC));
2912 print("\"" + prmType + "\"");
2913 // Check if this is the last element (don't print a comma)
2914 if (i != methParams.size() - 1) {
2919 checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes);
2920 // Generate array of parameter objects
2921 print("void* paramObj[] = { ");
2922 for (int i = 0; i < methParams.size(); i++) {
2923 print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i));
2924 // Check if this is the last element (don't print a comma)
2925 if (i != methParams.size() - 1) {
2931 // Check if this is "void"
2932 if (retType.equals("void")) {
2933 println("void* retObj = NULL;");
2934 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2935 } else { // We do have a return value
2936 // Generate array of parameter types
2937 if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
2938 writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType);
2940 // Check if the return value NONPRIMITIVES
2941 if (getParamCategory(retType) == ParamCategory.ENUM) {
2942 checkAndWriteEnumRetTypeCplusStub(retType);
2944 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
2945 println(checkAndGetCplusType(retType) + " retVal;");
2947 println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
2948 println("void* retObj = &retVal;");
2949 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
2950 println("return retVal;");
2958 * HELPER: writePropertiesCplusStub() writes the properties of the stub class
2960 private void writePropertiesCplusPermission(String intface) {
2962 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
2963 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
2964 String newIntface = intMeth.getKey();
2965 int newObjectId = mapNewIntfaceObjId.get(newIntface);
2966 println("const static int object" + newObjectId + "Id = " + newObjectId + ";");
2967 println("const static set<int> set" + newObjectId + "Allowed;");
2972 * HELPER: writePropertiesCplusStub() writes the properties of the stub class
2974 private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
2976 println("IoTRMICall *rmiCall;");
2977 //println("IoTRMIObject\t\t\t*rmiObj;");
2978 println("string address;");
2979 println("vector<int> ports;\n");
2980 // Get the object Id
2981 Integer objId = mapIntfaceObjId.get(intface);
2982 println("const static int objectId = " + objId + ";");
2983 mapNewIntfaceObjId.put(newIntface, objId);
2984 mapIntfaceObjId.put(intface, objId++);
2985 if (callbackExist) {
2986 // We assume that each class only has one callback interface for now
2987 Iterator it = callbackClasses.iterator();
2988 String callbackType = (String) it.next();
2989 println("// Callback properties");
2990 println("IoTRMIObject *rmiObj;");
2991 println("vector<" + callbackType + "*> vecCallbackObj;");
2992 println("static int objIdCnt;");
2993 // Generate permission stuff for callback stubs
2994 writePropertiesCplusPermission(callbackType);
3001 * HELPER: writeConstructorCplusStub() writes the constructor of the stub class
3003 private void writeConstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3005 println(newStubClass +
3006 "(int _port, const char* _address, int _rev, bool* _bResult, vector<int> _ports) {");
3007 println("address = _address;");
3008 println("ports = _ports;");
3009 println("rmiCall = new IoTRMICall(_port, _address, _rev, _bResult);");
3010 if (callbackExist) {
3011 println("objIdCnt = 0;");
3012 Iterator it = callbackClasses.iterator();
3013 String callbackType = (String) it.next();
3014 println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
3015 println("th1.detach();");
3016 println("___regCB();");
3023 * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
3025 private void writeDeconstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3027 println("~" + newStubClass + "() {");
3028 println("if (rmiCall != NULL) {");
3029 println("delete rmiCall;");
3030 println("rmiCall = NULL;");
3032 if (callbackExist) {
3033 // We assume that each class only has one callback interface for now
3034 println("if (rmiObj != NULL) {");
3035 println("delete rmiObj;");
3036 println("rmiObj = NULL;");
3038 Iterator it = callbackClasses.iterator();
3039 String callbackType = (String) it.next();
3040 println("for(" + callbackType + "* cb : vecCallbackObj) {");
3041 println("delete cb;");
3042 println("cb = NULL;");
3051 * HELPER: writeCplusMethodCallbackPermission() writes permission checks in stub for callbacks
3053 private void writeCplusMethodCallbackPermission(String intface) {
3055 println("int methodId = IoTRMIObject::getMethodId(method);");
3056 // Get all the different stubs
3057 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3058 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3059 String newIntface = intMeth.getKey();
3060 int newObjectId = mapNewIntfaceObjId.get(newIntface);
3061 println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
3062 println("cerr << \"Callback object for " + intface + " is not allowed to access method: \" << methodId;");
3063 println("exit(-1);");
3070 * HELPER: writeInitCallbackCplusStub() writes the initialization of callback
3072 private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl) {
3074 println("void ___initCallBack() {");
3075 println("bool bResult = false;");
3076 println("rmiObj = new IoTRMIObject(ports[0], &bResult);");
3077 println("while (true) {");
3078 println("char* method = rmiObj->getMethodBytes();");
3079 writeCplusMethodCallbackPermission(intface);
3080 println("int objId = IoTRMIObject::getObjectId(method);");
3081 println("if (objId < vecCallbackObj.size()) { // Check if still within range");
3082 println(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface +
3083 "_CallbackSkeleton*> (vecCallbackObj.at(objId));");
3084 println("skel->invokeMethod(rmiObj);");
3085 println("} else {");
3086 println("cerr << \"Illegal object Id: \" << to_string(objId);");
3087 // TODO: perhaps need to change this into "throw" to make it cleaner (allow stack unfolding)
3088 println("exit(-1);");
3096 * HELPER: writeInitCallbackSendInfoCplusStub() writes the initialization (send info part) of callback
3098 private void writeInitCallbackSendInfoCplusStub(InterfaceDecl intDecl) {
3100 // Generate info sending part
3101 println("void ___regCB() {");
3102 println("int numParam = 3;");
3103 String method = "___initCallBack()";
3104 println("int methodId = " + intDecl.getHelperMethodNumId(method) + ";");
3105 println("string retType = \"void\";");
3106 println("string paramCls[] = { \"int\", \"string\", \"int\" };");
3107 println("int rev = 0;");
3108 println("void* paramObj[] = { &ports[0], &address, &rev };");
3109 println("void* retObj = NULL;");
3110 println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
3116 * generateCPlusStubClasses() generate stubs based on the methods list in C++
3118 public void generateCPlusStubClasses() throws IOException {
3120 // Create a new directory
3121 String path = createDirectories(dir, subdir);
3122 for (String intface : mapIntfacePTH.keySet()) {
3124 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3125 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3126 // Open a new file to write into
3127 String newIntface = intMeth.getKey();
3128 String newStubClass = newIntface + "_Stub";
3129 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
3130 pw = new PrintWriter(new BufferedWriter(fw));
3131 // Write file headers
3132 println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
3133 println("#define _" + newStubClass.toUpperCase() + "_HPP__");
3134 println("#include <iostream>");
3135 // Find out if there are callback objects
3136 Set<String> methods = intMeth.getValue();
3137 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
3138 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
3139 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
3140 boolean callbackExist = !callbackClasses.isEmpty();
3141 if (callbackExist) // Need thread library if this has callback
3142 println("#include <thread>");
3143 println("#include \"" + newIntface + ".hpp\""); println("");
3144 println("using namespace std;"); println("");
3145 println("class " + newStubClass + " : public " + newIntface); println("{");
3146 println("private:\n");
3147 writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses);
3148 println("public:\n");
3149 // Add default constructor and destructor
3150 println(newStubClass + "() { }"); println("");
3151 writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3152 writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3154 writeMethodCplusStub(methods, intDecl, callbackClasses);
3155 print("}"); println(";");
3157 writePermissionInitializationCplus(intface, newStubClass, intDecl);
3160 System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
3167 * HELPER: writePropertiesCplusCallbackStub() writes the properties of the stub class
3169 private void writePropertiesCplusCallbackStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
3171 println("IoTRMICall *rmiCall;");
3172 // Get the object Id
3173 println("static int objectId;");
3174 if (callbackExist) {
3175 // We assume that each class only has one callback interface for now
3176 Iterator it = callbackClasses.iterator();
3177 String callbackType = (String) it.next();
3178 println("// Callback properties");
3179 println("IoTRMIObject *rmiObj;");
3180 println("vector<" + callbackType + "*> vecCallbackObj;");
3181 println("static int objIdCnt;");
3182 // TODO: Need to initialize address and ports if we want to have callback-in-callback
3183 println("string address;");
3184 println("vector<int> ports;\n");
3185 writePropertiesCplusPermission(callbackType);
3192 * HELPER: writeConstructorCplusCallbackStub() writes the constructor of the stub class
3194 private void writeConstructorCplusCallbackStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
3196 println(newStubClass + "(IoTRMICall* _rmiCall, int _objectId) {");
3197 println("objectId = _objectId;");
3198 println("rmiCall = _rmiCall;");
3199 if (callbackExist) {
3200 Iterator it = callbackClasses.iterator();
3201 String callbackType = (String) it.next();
3202 println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
3203 println("th1.detach();");
3204 println("___regCB();");
3211 * generateCPlusCallbackStubClasses() generate callback stubs based on the methods list in C++
3213 public void generateCPlusCallbackStubClasses() throws IOException {
3215 // Create a new directory
3216 String path = createDirectories(dir, subdir);
3217 for (String intface : mapIntfacePTH.keySet()) {
3219 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3220 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3221 // Open a new file to write into
3222 String newIntface = intMeth.getKey();
3223 String newStubClass = newIntface + "_CallbackStub";
3224 FileWriter fw = new FileWriter(path + "/" + newStubClass + ".hpp");
3225 pw = new PrintWriter(new BufferedWriter(fw));
3226 // Find out if there are callback objects
3227 Set<String> methods = intMeth.getValue();
3228 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
3229 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
3230 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
3231 boolean callbackExist = !callbackClasses.isEmpty();
3232 // Write file headers
3233 println("#ifndef _" + newStubClass.toUpperCase() + "_HPP__");
3234 println("#define _" + newStubClass.toUpperCase() + "_HPP__");
3235 println("#include <iostream>");
3237 println("#include <thread>");
3238 println("#include \"" + newIntface + ".hpp\""); println("");
3239 println("using namespace std;"); println("");
3240 println("class " + newStubClass + " : public " + newIntface); println("{");
3241 println("private:\n");
3242 writePropertiesCplusCallbackStub(intface, newIntface, callbackExist, callbackClasses);
3243 println("public:\n");
3244 // Add default constructor and destructor
3245 println(newStubClass + "() { }"); println("");
3246 writeConstructorCplusCallbackStub(newStubClass, callbackExist, callbackClasses);
3247 writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
3249 writeMethodCplusStub(methods, intDecl, callbackClasses);
3252 writePermissionInitializationCplus(intface, newStubClass, intDecl);
3255 System.out.println("IoTCompiler: Generated callback stub class " + newIntface + ".hpp...");
3262 * HELPER: writePropertiesCplusSkeleton() writes the properties of the skeleton class
3264 private void writePropertiesCplusSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
3266 println(intface + " *mainObj;");
3268 if (callbackExist) {
3269 Iterator it = callbackClasses.iterator();
3270 String callbackType = (String) it.next();
3271 String exchangeType = checkAndGetParamClass(callbackType);
3272 println("// Callback properties");
3273 println("static int objIdCnt;");
3274 println("vector<" + exchangeType + "*> vecCallbackObj;");
3275 println("IoTRMICall *rmiCall;");
3277 println("IoTRMIObject *rmiObj;\n");
3278 // Keep track of object Ids of all stubs registered to this interface
3279 writePropertiesCplusPermission(intface);
3285 * HELPER: writePermissionInitializationCplus() writes the initialization of permission set
3287 private void writePermissionInitializationCplus(String intface, String newSkelClass, InterfaceDecl intDecl) {
3289 // Keep track of object Ids of all stubs registered to this interface
3290 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
3291 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
3292 String newIntface = intMeth.getKey();
3293 int newObjectId = mapNewIntfaceObjId.get(newIntface);
3294 print("const set<int> " + newSkelClass + "::set" + newObjectId + "Allowed {");
3295 Set<String> methodIds = intMeth.getValue();
3297 for (String methodId : methodIds) {
3298 int methodNumId = intDecl.getMethodNumId(methodId);
3299 print(Integer.toString(methodNumId));
3300 // Check if this is the last element (don't print a comma)
3301 if (i != methodIds.size() - 1) {
3312 * HELPER: writeConstructorCplusSkeleton() writes the constructor of the skeleton class
3314 private void writeConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist) {
3316 println(newSkelClass + "(" + intface + " *_mainObj, int _port) {");
3317 println("bool _bResult = false;");
3318 println("mainObj = _mainObj;");
3319 println("rmiObj = new IoTRMIObject(_port, &_bResult);");
3321 if (callbackExist) {
3322 println("objIdCnt = 0;");
3324 //println("set0Allowed = Arrays.asList(object0Permission);");
3325 println("___waitRequestInvokeMethod();");
3331 * HELPER: writeDeconstructorCplusSkeleton() writes the deconstructor of the skeleton class
3333 private void writeDeconstructorCplusSkeleton(String newSkelClass, boolean callbackExist, Set<String> callbackClasses) {
3335 println("~" + newSkelClass + "() {");
3336 println("if (rmiObj != NULL) {");
3337 println("delete rmiObj;");
3338 println("rmiObj = NULL;");
3340 if (callbackExist) {
3341 // We assume that each class only has one callback interface for now
3342 println("if (rmiCall != NULL) {");
3343 println("delete rmiCall;");
3344 println("rmiCall = NULL;");
3346 Iterator it = callbackClasses.iterator();
3347 String callbackType = (String) it.next();
3348 String exchangeType = checkAndGetParamClass(callbackType);
3349 println("for(" + exchangeType + "* cb : vecCallbackObj) {");
3350 println("delete cb;");
3351 println("cb = NULL;");
3360 * HELPER: writeStdMethodBodyCplusSkeleton() writes the standard method body in the skeleton class
3362 private void writeStdMethodBodyCplusSkeleton(List<String> methParams, String methodId, String methodType) {
3364 if (methodType.equals("void"))
3365 print("mainObj->" + methodId + "(");
3367 print("return mainObj->" + methodId + "(");
3368 for (int i = 0; i < methParams.size(); i++) {
3370 print(getSimpleIdentifier(methParams.get(i)));
3371 // Check if this is the last element (don't print a comma)
3372 if (i != methParams.size() - 1) {
3381 * HELPER: writeInitCallbackCplusSkeleton() writes the init callback method for skeleton class
3383 private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton) {
3385 // This is a callback skeleton generation
3386 if (callbackSkeleton)
3387 println("void ___regCB(IoTRMIObject* rmiObj) {");
3389 println("void ___regCB() {");
3390 println("int numParam = 3;");
3391 println("int param1 = 0;");
3392 println("string param2 = \"\";");
3393 println("int param3 = 0;");
3394 println("void* paramObj[] = { ¶m1, ¶m2, ¶m3 };");
3395 println("bool bResult = false;");
3396 println("rmiCall = new IoTRMICall(param1, param2.c_str(), param3, &bResult);");
3402 * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
3404 private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
3405 Set<String> callbackClasses, boolean callbackSkeleton) {
3407 for (String method : methods) {
3409 List<String> methParams = intDecl.getMethodParams(method);
3410 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3411 String methodId = intDecl.getMethodId(method);
3412 String methodType = checkAndGetCplusType(intDecl.getMethodType(method));
3413 print(methodType + " " + methodId + "(");
3414 boolean isCallbackMethod = false;
3415 String callbackType = null;
3416 for (int i = 0; i < methParams.size(); i++) {
3418 String origParamType = methPrmTypes.get(i);
3419 if (callbackClasses.contains(origParamType)) { // Check if this has callback object
3420 isCallbackMethod = true;
3421 callbackType = origParamType;
3423 String paramType = checkAndGetParamClass(methPrmTypes.get(i));
3424 String methPrmType = checkAndGetCplusType(paramType);
3425 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
3426 print(methParamComplete);
3427 // Check if this is the last element (don't print a comma)
3428 if (i != methParams.size() - 1) {
3433 // Now, write the body of skeleton!
3434 writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method));
3436 if (isCallbackMethod)
3437 writeInitCallbackCplusSkeleton(callbackSkeleton);
3443 * HELPER: writeCallbackCplusNumStubs() writes the numStubs variable
3445 private void writeCallbackCplusNumStubs(List<String> methParams, List<String> methPrmTypes, String callbackType) {
3447 for (int i = 0; i < methParams.size(); i++) {
3448 String paramType = methPrmTypes.get(i);
3449 String param = methParams.get(i);
3450 //if (callbackType.equals(paramType)) {
3451 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
3452 String exchParamType = checkAndGetParamClass(paramType);
3453 // Print array if this is array or list if this is a list of callback objects
3454 println("int numStubs" + i + " = 0;");
3461 * HELPER: writeCallbackCplusStubGeneration() writes the callback stub generation part
3463 private void writeCallbackCplusStubGeneration(List<String> methParams, List<String> methPrmTypes, String callbackType) {
3465 // Iterate over callback objects
3466 for (int i = 0; i < methParams.size(); i++) {
3467 String paramType = methPrmTypes.get(i);
3468 String param = methParams.get(i);
3469 // Generate a loop if needed
3470 if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
3471 String exchParamType = checkAndGetParamClass(paramType);
3472 if (isArrayOrList(paramType, param)) {
3473 println("vector<" + exchParamType + "> stub;");
3474 println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
3475 println(exchParamType + "* cb" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
3476 println("stub" + i + ".push_back(cb);");
3477 println("vecCallbackObj.push_back(cb);");
3478 println("objIdCnt++;");
3481 println(exchParamType + "* stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt);");
3482 println("vecCallbackObj.push_back(stub" + i + ");");
3483 println("objIdCnt++;");
3491 * HELPER: checkAndWriteEnumTypeCplusSkeleton() writes the enum type (convert from enum to int)
3493 private void checkAndWriteEnumTypeCplusSkeleton(List<String> methParams, List<String> methPrmTypes) {
3495 // Iterate and find enum declarations
3496 for (int i = 0; i < methParams.size(); i++) {
3497 String paramType = methPrmTypes.get(i);
3498 String param = methParams.get(i);
3499 String simpleType = getSimpleType(paramType);
3500 if (isEnumClass(simpleType)) {
3501 // Check if this is enum type
3502 if (isArrayOrList(paramType, param)) { // An array
3503 println("int len" + i + " = paramEnumInt" + i + ".size();");
3504 println("vector<" + simpleType + "> paramEnum" + i + "(len" + i + ");");
3505 println("for (int i=0; i < len" + i + "; i++) {");
3506 println("paramEnum" + i + "[i] = (" + simpleType + ") paramEnumInt" + i + "[i];");
3508 } else { // Just one element
3509 println(simpleType + " paramEnum" + i + ";");
3510 println("paramEnum" + i + " = (" + simpleType + ") paramEnumInt" + i + "[0];");
3518 * HELPER: checkAndWriteEnumRetTypeCplusSkeleton() writes the enum return type (convert from enum to int)
3520 private void checkAndWriteEnumRetTypeCplusSkeleton(String retType) {
3522 // Strips off array "[]" for return type
3523 String pureType = getSimpleArrayType(getSimpleType(retType));
3524 // Take the inner type of generic
3525 if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
3526 pureType = getTypeOfGeneric(retType)[0];
3527 if (isEnumClass(pureType)) {
3528 // Check if this is enum type
3530 if (isArrayOrList(retType, retType)) { // An array
3531 println("int retLen = retEnum.size();");
3532 println("vector<int> retEnumInt(retLen);");
3533 println("for (int i=0; i < retLen; i++) {");
3534 println("retEnumInt[i] = (int) retEnum[i];");
3536 } else { // Just one element
3537 println("vector<int> retEnumInt(1);");
3538 println("retEnumInt[0] = (int) retEnum;");
3545 * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton
3547 private void writeMethodInputParameters(List<String> methParams, List<String> methPrmTypes,
3548 Set<String> callbackClasses, String methodId) {
3550 print(methodId + "(");
3551 for (int i = 0; i < methParams.size(); i++) {
3552 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3553 if (callbackClasses.contains(paramType))
3555 else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
3556 print("paramEnum" + i);
3557 else if (isStructClass(getSimpleType(paramType))) // Struct type
3558 print("paramStruct" + i);
3560 print(getSimpleIdentifier(methParams.get(i)));
3561 if (i != methParams.size() - 1) {
3570 * HELPER: writeMethodHelperReturnCplusSkeleton() writes the return statement part in skeleton
3572 private void writeMethodHelperReturnCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3573 List<String> methPrmTypes, String method, boolean isCallbackMethod, String callbackType,
3574 String methodId, Set<String> callbackClasses) {
3576 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3577 if (isCallbackMethod)
3578 writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType);
3579 checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes);
3580 writeStructMembersInitCplusSkeleton(intDecl, methParams, methPrmTypes, method);
3581 // Check if this is "void"
3582 String retType = intDecl.getMethodType(method);
3583 // Check if this is "void"
3584 if (retType.equals("void")) {
3585 writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
3586 } else { // We do have a return value
3587 if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type
3588 print(checkAndGetCplusType(retType) + " retEnum = ");
3589 else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3590 print(checkAndGetCplusType(retType) + " retStruct = ");
3592 print(checkAndGetCplusType(retType) + " retVal = ");
3593 writeMethodInputParameters(methParams, methPrmTypes, callbackClasses, methodId);
3594 checkAndWriteEnumRetTypeCplusSkeleton(retType);
3595 if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3596 writeStructReturnCplusSkeleton(getSimpleArrayType(getSimpleType(retType)), retType);
3597 if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type
3598 println("void* retObj = &retEnumInt;");
3600 if (!isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3601 println("void* retObj = &retVal;");
3602 String retTypeC = checkAndGetCplusType(retType);
3603 if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type
3604 println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);");
3606 //println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");");
3607 println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(retType) + "\");");
3613 * HELPER: writeStdMethodHelperBodyCplusSkeleton() writes the standard method body helper in the skeleton class
3615 private void writeStdMethodHelperBodyCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3616 List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
3618 // Generate array of parameter types
3619 boolean isCallbackMethod = false;
3620 String callbackType = null;
3621 print("string paramCls[] = { ");
3622 for (int i = 0; i < methParams.size(); i++) {
3623 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3624 if (callbackClasses.contains(paramType)) {
3625 isCallbackMethod = true;
3626 callbackType = paramType;
3628 } else { // Generate normal classes if it's not a callback object
3629 //String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
3630 //String prmType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
3631 //print("\"" + getEnumType(prmType) + "\"");
3632 String paramTypeC = checkAndGetArray(methPrmTypes.get(i), methParams.get(i));
3633 String prmType = getSimpleType(getEnumType(paramTypeC));
3634 print("\"" + prmType + "\"");
3636 if (i != methParams.size() - 1) {
3641 println("int numParam = " + methParams.size() + ";");
3642 if (isCallbackMethod)
3643 writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType);
3644 // Generate parameters
3645 for (int i = 0; i < methParams.size(); i++) {
3646 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3647 if (!callbackClasses.contains(paramType)) {
3648 String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
3649 if (isEnumClass(getSimpleType(methPrmType))) { // Check if this is enum type
3650 println("vector<int> paramEnumInt" + i + ";");
3652 String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
3653 //println(methParamComplete + " = " + generateCplusInitializer(methPrmType) + ";");
3654 println(methParamComplete + ";");
3658 // Generate array of parameter objects
3659 print("void* paramObj[] = { ");
3660 for (int i = 0; i < methParams.size(); i++) {
3661 String paramType = returnGenericCallbackType(methPrmTypes.get(i));
3662 if (callbackClasses.contains(paramType))
3663 print("&numStubs" + i);
3664 else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
3665 print("¶mEnumInt" + i);
3667 print("&" + getSimpleIdentifier(methParams.get(i)));
3668 if (i != methParams.size() - 1) {
3673 // Write the return value part
3674 writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
3675 callbackType, methodId, callbackClasses);
3680 * HELPER: writeStructMembersCplusSkeleton() writes member parameters of struct
3682 private void writeStructMembersCplusSkeleton(String simpleType, String paramType,
3683 String param, String method, InterfaceDecl intDecl, int iVar) {
3685 // Get the struct declaration for this struct and generate initialization code
3686 StructDecl structDecl = getStructDecl(simpleType);
3687 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3688 List<String> members = structDecl.getMembers(simpleType);
3689 int methodNumId = intDecl.getMethodNumId(method);
3690 String counter = "struct" + methodNumId + "Size" + iVar;
3691 if (isArrayOrList(param, paramType)) { // An array or list
3692 println("for(int i = 0; i < " + counter + "; i++) {");
3695 if (isArrayOrList(param, paramType)) { // An array or list
3696 for (int i = 0; i < members.size(); i++) {
3697 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3698 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3699 println(getSimpleType(getEnumType(prmType)) + " param" + i + "[" + counter + "];");
3701 } else { // Just one struct element
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 + ";");
3708 println("int pos = 0;");
3709 if (isArrayOrList(param, paramType)) { // An array or list
3710 println("for(int i = 0; i < retLen; i++) {");
3711 for (int i = 0; i < members.size(); i++) {
3712 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3713 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3714 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3715 println("paramObj[pos++] = ¶m" + i + "[i];");
3718 } else { // Just one struct element
3719 for (int i = 0; i < members.size(); i++) {
3720 String prmTypeC = checkAndGetCplusType(memTypes.get(i));
3721 String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i));
3722 println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3723 println("paramObj[pos++] = ¶m" + i + ";");
3730 * HELPER: writeStructMembersInitCplusSkeleton() writes member parameters initialization of struct
3732 private void writeStructMembersInitCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3733 List<String> methPrmTypes, String method) {
3735 for (int i = 0; i < methParams.size(); i++) {
3736 String paramType = methPrmTypes.get(i);
3737 String param = methParams.get(i);
3738 String simpleType = getGenericType(paramType);
3739 if (isStructClass(simpleType)) {
3740 int methodNumId = intDecl.getMethodNumId(method);
3741 String counter = "struct" + methodNumId + "Size" + i;
3743 if (isArrayOrList(param, paramType)) { // An array or list
3744 println("vector<" + simpleType + "> paramStruct" + i + ";");
3746 println(simpleType + " paramStruct" + i + ";");
3747 // Initialize members
3748 StructDecl structDecl = getStructDecl(simpleType);
3749 List<String> members = structDecl.getMembers(simpleType);
3750 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3751 if (isArrayOrList(param, paramType)) { // An array or list
3752 println("for(int i = 0; i < " + counter + "; i++) {");
3753 for (int j = 0; j < members.size(); j++) {
3754 print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j)));
3755 println(" = param" + j + "[i];");
3758 } else { // Just one struct element
3759 for (int j = 0; j < members.size(); j++) {
3760 print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j)));
3761 println(" = param" + j + ";");
3770 * HELPER: writeStructReturnCplusSkeleton() writes parameters of struct for return statement
3772 private void writeStructReturnCplusSkeleton(String simpleType, String retType) {
3774 // Minimum retLen is 1 if this is a single struct object
3775 if (isArrayOrList(retType, retType))
3776 println("int retLen = retStruct.size();");
3777 else // Just single struct object
3778 println("int retLen = 1;");
3779 println("void* retLenObj = &retLen;");
3780 println("rmiObj->sendReturnObj(retLenObj, \"int\");");
3781 int numMem = getNumOfMembers(simpleType);
3782 println("int numRetObj = " + numMem + "*retLen;");
3783 println("string retCls[numRetObj];");
3784 println("void* retObj[numRetObj];");
3785 println("int retPos = 0;");
3786 // Get the struct declaration for this struct and generate initialization code
3787 StructDecl structDecl = getStructDecl(simpleType);
3788 List<String> memTypes = structDecl.getMemberTypes(simpleType);
3789 List<String> members = structDecl.getMembers(simpleType);
3790 if (isArrayOrList(retType, retType)) { // An array or list
3791 println("for(int i = 0; i < retLen; i++) {");
3792 for (int i = 0; i < members.size(); i++) {
3793 String paramTypeC = checkAndGetCplusType(memTypes.get(i));
3794 String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i));
3795 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3796 print("retObj[retPos++] = &retStruct[i].");
3797 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
3801 } else { // Just one struct element
3802 for (int i = 0; i < members.size(); i++) {
3803 String paramTypeC = checkAndGetCplusType(memTypes.get(i));
3804 String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i));
3805 println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";");
3806 print("retObj[retPos++] = &retStruct.");
3807 print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i));
3816 * HELPER: writeMethodHelperStructCplusSkeleton() writes the struct in skeleton
3818 private void writeMethodHelperStructCplusSkeleton(InterfaceDecl intDecl, List<String> methParams,
3819 List<String> methPrmTypes, String method, String methodId, Set<String> callbackClasses) {
3821 // Generate array of parameter objects
3822 boolean isCallbackMethod = false;
3823 String callbackType = null;
3824 print("int numParam = ");
3825 writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl);
3827 println("string paramCls[numParam];");
3828 println("void* paramObj[numParam];");
3829 // Iterate again over the parameters
3830 for (int i = 0; i < methParams.size(); i++) {
3831 String paramType = methPrmTypes.get(i);
3832 String param = methParams.get(i);
3833 String simpleType = getGenericType(paramType);
3834 if (isStructClass(simpleType)) {
3835 writeStructMembersCplusSkeleton(simpleType, paramType, param, method, intDecl, i);
3837 String prmType = returnGenericCallbackType(methPrmTypes.get(i));
3838 if (callbackClasses.contains(prmType)) {
3839 isCallbackMethod = true;
3840 callbackType = paramType;
3841 writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType);
3842 println("paramCls[pos] = \"int\";");
3843 println("paramObj[pos++] = &numStubs" + i + ";");
3844 } else { // Generate normal classes if it's not a callback object
3845 String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
3846 String prmTypeC = checkAndGetCplusArrayType(paramTypeC, methParams.get(i));
3847 if (isEnumClass(getSimpleType(paramTypeC))) { // Check if this is enum type
3848 println("vector<int> paramEnumInt" + i + ";");
3850 String methParamComplete = checkAndGetCplusArray(paramTypeC, methParams.get(i));
3851 println(methParamComplete + ";");
3853 println("paramCls[pos] = \"" + getEnumType(prmTypeC) + "\";");
3854 if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type
3855 println("paramObj[pos++] = ¶mEnumInt" + i);
3857 println("paramObj[pos++] = &" + getSimpleIdentifier(methParams.get(i)) + ";");
3861 // Write the return value part
3862 writeMethodHelperReturnCplusSkeleton(intDecl, methParams, methPrmTypes, method, isCallbackMethod,
3863 callbackType, methodId, callbackClasses);
3868 * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
3870 private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
3872 // Use this set to handle two same methodIds
3873 Set<String> uniqueMethodIds = new HashSet<String>();
3874 for (String method : methods) {
3876 List<String> methParams = intDecl.getMethodParams(method);
3877 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3878 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
3879 String methodId = intDecl.getMethodId(method);
3881 String helperMethod = methodId;
3882 if (uniqueMethodIds.contains(methodId))
3883 helperMethod = helperMethod + intDecl.getMethodNumId(method);
3885 uniqueMethodIds.add(methodId);
3886 String retType = intDecl.getMethodType(method);
3887 print(helperMethod + "(");
3888 boolean begin = true;
3889 for (int i = 0; i < methParams.size(); i++) { // Print size variables
3890 String paramType = methPrmTypes.get(i);
3891 String param = methParams.get(i);
3892 String simpleType = getSimpleType(paramType);
3893 if (isStructClass(simpleType)) {
3894 if (!begin) { // Generate comma for not the beginning variable
3895 print(", "); begin = false;
3897 int methodNumId = intDecl.getMethodNumId(method);
3898 print("int struct" + methodNumId + "Size" + i);
3902 writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
3905 String methodId = intDecl.getMethodId(method);
3907 String helperMethod = methodId;
3908 if (uniqueMethodIds.contains(methodId))
3909 helperMethod = helperMethod + intDecl.getMethodNumId(method);
3911 uniqueMethodIds.add(methodId);
3912 // Check if this is "void"
3913 String retType = intDecl.getMethodType(method);
3914 println(helperMethod + "() {");
3915 // Now, write the helper body of skeleton!
3916 writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
3920 // Write method helper for structs
3921 writeMethodHelperStructSetupCplusSkeleton(methods, intDecl);
3926 * HELPER: writeMethodHelperStructSetupCplusSkeleton() writes the method helper of struct in skeleton class
3928 private void writeMethodHelperStructSetupCplusSkeleton(Collection<String> methods,
3929 InterfaceDecl intDecl) {
3931 // Use this set to handle two same methodIds
3932 for (String method : methods) {
3934 List<String> methParams = intDecl.getMethodParams(method);
3935 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3936 // Check for params with structs
3937 for (int i = 0; i < methParams.size(); i++) {
3938 String paramType = methPrmTypes.get(i);
3939 String param = methParams.get(i);
3940 String simpleType = getSimpleType(paramType);
3941 if (isStructClass(simpleType)) {
3942 int methodNumId = intDecl.getMethodNumId(method);
3944 String helperMethod = methodNumId + "struct" + i;
3945 println(helperMethod + "() {");
3946 // Now, write the helper body of skeleton!
3947 println("string paramCls[] = { \"int\" };");
3948 println("int numParam = 1;");
3949 println("int param0 = 0;");
3950 println("void* paramObj[] = { ¶m0 };");
3951 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3952 println("return param0;");
3961 * HELPER: writeMethodHelperStructSetupCplusCallbackSkeleton() writes the method helper of struct in skeleton class
3963 private void writeMethodHelperStructSetupCplusCallbackSkeleton(Collection<String> methods,
3964 InterfaceDecl intDecl) {
3966 // Use this set to handle two same methodIds
3967 for (String method : methods) {
3969 List<String> methParams = intDecl.getMethodParams(method);
3970 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
3971 // Check for params with structs
3972 for (int i = 0; i < methParams.size(); i++) {
3973 String paramType = methPrmTypes.get(i);
3974 String param = methParams.get(i);
3975 String simpleType = getSimpleType(paramType);
3976 if (isStructClass(simpleType)) {
3977 int methodNumId = intDecl.getMethodNumId(method);
3979 String helperMethod = methodNumId + "struct" + i;
3980 println(helperMethod + "(IoTRMIObject* rmiObj) {");
3981 // Now, write the helper body of skeleton!
3982 println("string paramCls[] = { \"int\" };");
3983 println("int numParam = 1;");
3984 println("int param0 = 0;");
3985 println("void* paramObj[] = { ¶m0 };");
3986 println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
3987 println("return param0;");
3996 * HELPER: writeCplusMethodPermission() writes permission checks in skeleton
3998 private void writeCplusMethodPermission(String intface) {
4000 // Get all the different stubs
4001 Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
4002 for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
4003 String newIntface = intMeth.getKey();
4004 int newObjectId = mapNewIntfaceObjId.get(newIntface);
4005 println("if (_objectId == object" + newObjectId + "Id) {");
4006 println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
4007 println("cerr << \"Object with object Id: \" << _objectId << \" is not allowed to access method: \" << methodId << endl;");
4008 println("exit(-1);");
4012 println("cerr << \"Object Id: \" << _objectId << \" not recognized!\" << endl;");
4013 println("exit(-1);");
4020 * HELPER: writeCplusWaitRequestInvokeMethod() writes the main loop of the skeleton class
4022 private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
4024 // Use this set to handle two same methodIds
4025 Set<String> uniqueMethodIds = new HashSet<String>();
4026 println("void ___waitRequestInvokeMethod() {");
4027 // Write variables here if we have callbacks or enums or structs
4028 writeCountVarStructSkeleton(methods, intDecl);
4029 println("while (true) {");
4030 println("rmiObj->getMethodBytes();");
4031 println("int _objectId = rmiObj->getObjectId();");
4032 println("int methodId = rmiObj->getMethodId();");
4033 // Generate permission check
4034 writeCplusMethodPermission(intface);
4035 println("switch (methodId) {");
4036 // Print methods and method Ids
4037 for (String method : methods) {
4038 String methodId = intDecl.getMethodId(method);
4039 int methodNumId = intDecl.getMethodNumId(method);
4040 print("case " + methodNumId + ": ___");
4041 String helperMethod = methodId;
4042 if (uniqueMethodIds.contains(methodId))
4043 helperMethod = helperMethod + methodNumId;
4045 uniqueMethodIds.add(methodId);
4046 print(helperMethod + "(");
4047 writeInputCountVarStructSkeleton(method, intDecl);
4048 println("); break;");
4050 String method = "___initCallBack()";
4051 // Print case -9999 (callback handler) if callback exists
4052 if (callbackExist) {
4053 int methodId = intDecl.getHelperMethodNumId(method);
4054 println("case " + methodId + ": ___regCB(); break;");
4056 writeMethodCallStructSkeleton(methods, intDecl);
4057 println("default: ");
4058 println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
4059 println("throw exception();");
4067 * generateCplusSkeletonClass() generate skeletons based on the methods list in C++
4069 public void generateCplusSkeletonClass() throws IOException {
4071 // Create a new directory
4072 String path = createDirectories(dir, subdir);
4073 for (String intface : mapIntfacePTH.keySet()) {
4074 // Open a new file to write into
4075 String newSkelClass = intface + "_Skeleton";
4076 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
4077 pw = new PrintWriter(new BufferedWriter(fw));
4078 // Write file headers
4079 println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
4080 println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
4081 println("#include <iostream>");
4082 println("#include \"" + intface + ".hpp\"\n");
4083 // Pass in set of methods and get import classes
4084 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4085 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
4086 List<String> methods = intDecl.getMethods();
4087 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
4088 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
4089 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
4090 printIncludeStatements(allIncludeClasses); println("");
4091 println("using namespace std;\n");
4092 // Find out if there are callback objects
4093 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
4094 boolean callbackExist = !callbackClasses.isEmpty();
4095 // Write class header
4096 println("class " + newSkelClass + " : public " + intface); println("{");
4097 println("private:\n");
4099 writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses);
4100 println("public:\n");
4101 // Write constructor
4102 writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist);
4103 // Write deconstructor
4104 writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
4106 writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false);
4107 // Write method helper
4108 writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses);
4109 // Write waitRequestInvokeMethod() - main loop
4110 writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
4112 writePermissionInitializationCplus(intface, newSkelClass, intDecl);
4115 System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
4121 * HELPER: writePropertiesCplusCallbackSkeleton() writes the properties of the callback skeleton class
4123 private void writePropertiesCplusCallbackSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
4125 println(intface + " *mainObj;");
4126 // Keep track of object Ids of all stubs registered to this interface
4127 println("static int objectId;");
4129 if (callbackExist) {
4130 Iterator it = callbackClasses.iterator();
4131 String callbackType = (String) it.next();
4132 String exchangeType = checkAndGetParamClass(callbackType);
4133 println("// Callback properties");
4134 println("IoTRMICall* rmiCall;");
4135 println("vector<" + exchangeType + "*> vecCallbackObj;");
4136 println("static int objIdCnt;");
4143 * HELPER: writeConstructorCplusCallbackSkeleton() writes the constructor of the skeleton class
4145 private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface, boolean callbackExist) {
4147 println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {");
4148 println("mainObj = _mainObj;");
4149 println("objectId = _objectId;");
4151 if (callbackExist) {
4152 println("objIdCnt = 0;");
4159 * HELPER: writeDeconstructorCplusStub() writes the deconstructor of the stub class
4161 private void writeDeconstructorCplusCallbackSkeleton(String newStubClass, boolean callbackExist,
4162 Set<String> callbackClasses) {
4164 println("~" + newStubClass + "() {");
4165 if (callbackExist) {
4166 // We assume that each class only has one callback interface for now
4167 println("if (rmiCall != NULL) {");
4168 println("delete rmiCall;");
4169 println("rmiCall = NULL;");
4171 Iterator it = callbackClasses.iterator();
4172 String callbackType = (String) it.next();
4173 String exchangeType = checkAndGetParamClass(callbackType);
4174 println("for(" + exchangeType + "* cb : vecCallbackObj) {");
4175 println("delete cb;");
4176 println("cb = NULL;");
4185 * HELPER: writeMethodHelperCplusCallbackSkeleton() writes the method helper of callback skeleton class
4187 private void writeMethodHelperCplusCallbackSkeleton(Collection<String> methods, InterfaceDecl intDecl,
4188 Set<String> callbackClasses) {
4190 // Use this set to handle two same methodIds
4191 Set<String> uniqueMethodIds = new HashSet<String>();
4192 for (String method : methods) {
4194 List<String> methParams = intDecl.getMethodParams(method);
4195 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4196 if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
4197 String methodId = intDecl.getMethodId(method);
4199 String helperMethod = methodId;
4200 if (uniqueMethodIds.contains(methodId))
4201 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4203 uniqueMethodIds.add(methodId);
4204 String retType = intDecl.getMethodType(method);
4205 print(helperMethod + "(");
4206 boolean begin = true;
4207 for (int i = 0; i < methParams.size(); i++) { // Print size variables
4208 String paramType = methPrmTypes.get(i);
4209 String param = methParams.get(i);
4210 String simpleType = getSimpleType(paramType);
4211 if (isStructClass(simpleType)) {
4212 if (!begin) { // Generate comma for not the beginning variable
4213 print(", "); begin = false;
4215 int methodNumId = intDecl.getMethodNumId(method);
4216 print("int struct" + methodNumId + "Size" + i);
4219 println(", IoTRMIObject* rmiObj) {");
4220 writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4223 String methodId = intDecl.getMethodId(method);
4225 String helperMethod = methodId;
4226 if (uniqueMethodIds.contains(methodId))
4227 helperMethod = helperMethod + intDecl.getMethodNumId(method);
4229 uniqueMethodIds.add(methodId);
4230 // Check if this is "void"
4231 String retType = intDecl.getMethodType(method);
4232 println(helperMethod + "(IoTRMIObject* rmiObj) {");
4233 // Now, write the helper body of skeleton!
4234 writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
4238 // Write method helper for structs
4239 writeMethodHelperStructSetupCplusCallbackSkeleton(methods, intDecl);
4244 * HELPER: writeCplusCallbackWaitRequestInvokeMethod() writes the request invoke method of the skeleton callback class
4246 private void writeCplusCallbackWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl,
4247 boolean callbackExist) {
4249 // Use this set to handle two same methodIds
4250 Set<String> uniqueMethodIds = new HashSet<String>();
4251 println("void invokeMethod(IoTRMIObject* rmiObj) {");
4252 // Write variables here if we have callbacks or enums or structs
4253 writeCountVarStructSkeleton(methods, intDecl);
4254 // Write variables here if we have callbacks or enums or structs
4255 println("int methodId = rmiObj->getMethodId();");
4256 // TODO: code the permission check here!
4257 println("switch (methodId) {");
4258 // Print methods and method Ids
4259 for (String method : methods) {
4260 String methodId = intDecl.getMethodId(method);
4261 int methodNumId = intDecl.getMethodNumId(method);
4262 print("case " + methodNumId + ": ___");
4263 String helperMethod = methodId;
4264 if (uniqueMethodIds.contains(methodId))
4265 helperMethod = helperMethod + methodNumId;
4267 uniqueMethodIds.add(methodId);
4268 print(helperMethod + "(");
4269 if (writeInputCountVarStructSkeleton(method, intDecl))
4270 println(", rmiObj); break;");
4272 println("rmiObj); break;");
4274 String method = "___initCallBack()";
4275 // Print case -9999 (callback handler) if callback exists
4276 if (callbackExist) {
4277 int methodId = intDecl.getHelperMethodNumId(method);
4278 println("case " + methodId + ": ___regCB(rmiObj); break;");
4280 writeMethodCallStructCallbackSkeleton(methods, intDecl);
4281 println("default: ");
4282 println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
4283 println("throw exception();");
4290 * generateCplusCallbackSkeletonClass() generate callback skeletons based on the methods list in C++
4292 public void generateCplusCallbackSkeletonClass() throws IOException {
4294 // Create a new directory
4295 String path = createDirectories(dir, subdir);
4296 for (String intface : mapIntfacePTH.keySet()) {
4297 // Open a new file to write into
4298 String newSkelClass = intface + "_CallbackSkeleton";
4299 FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".hpp");
4300 pw = new PrintWriter(new BufferedWriter(fw));
4301 // Write file headers
4302 println("#ifndef _" + newSkelClass.toUpperCase() + "_HPP__");
4303 println("#define _" + newSkelClass.toUpperCase() + "_HPP__");
4304 println("#include <iostream>");
4305 println("#include \"" + intface + ".hpp\"\n");
4306 // Pass in set of methods and get import classes
4307 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4308 InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
4309 List<String> methods = intDecl.getMethods();
4310 Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
4311 List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
4312 List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
4313 printIncludeStatements(allIncludeClasses); println("");
4314 // Find out if there are callback objects
4315 Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
4316 boolean callbackExist = !callbackClasses.isEmpty();
4317 println("using namespace std;\n");
4318 // Write class header
4319 println("class " + newSkelClass + " : public " + intface); println("{");
4320 println("private:\n");
4322 writePropertiesCplusCallbackSkeleton(intface, callbackExist, callbackClasses);
4323 println("public:\n");
4324 // Write constructor
4325 writeConstructorCplusCallbackSkeleton(newSkelClass, intface, callbackExist);
4326 // Write deconstructor
4327 writeDeconstructorCplusCallbackSkeleton(newSkelClass, callbackExist, callbackClasses);
4329 writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true);
4330 // Write method helper
4331 writeMethodHelperCplusCallbackSkeleton(methods, intDecl, callbackClasses);
4332 // Write waitRequestInvokeMethod() - main loop
4333 writeCplusCallbackWaitRequestInvokeMethod(methods, intDecl, callbackExist);
4337 System.out.println("IoTCompiler: Generated callback skeleton class " + newSkelClass + ".hpp...");
4343 * generateInitializer() generate initializer based on type
4345 public String generateCplusInitializer(String type) {
4347 // Generate dummy returns for now
4348 if (type.equals("short")||
4349 type.equals("int") ||
4350 type.equals("long") ||
4351 type.equals("float")||
4352 type.equals("double")) {
4355 } else if ( type.equals("String") ||
4356 type.equals("string")) {
4359 } else if ( type.equals("char") ||
4360 type.equals("byte")) {
4363 } else if ( type.equals("boolean")) {
4373 * setDirectory() sets a new directory for stub files
4375 public void setDirectory(String _subdir) {
4382 * printUsage() prints the usage of this compiler
4384 public static void printUsage() {
4386 System.out.println();
4387 System.out.println("Sentinel interface and stub compiler version 1.0");
4388 System.out.println("Copyright (c) 2015-2016 University of California, Irvine - Programming Language Group.");
4389 System.out.println("All rights reserved.");
4390 System.out.println("Usage:");
4391 System.out.println("\tjava IoTCompiler -help / --help / -h\n");
4392 System.out.println("\t\tDisplay this help texts\n\n");
4393 System.out.println("\tjava IoTCompiler [<main-policy-file> <req-policy-file>]");
4394 System.out.println("\tjava IoTCompiler [<main-policy-file> <req-policy-file>] [options]\n");
4395 System.out.println("\t\tTake one or more pairs of main-req policy files, and generate Java and/or C++ files\n");
4396 System.out.println("Options:");
4397 System.out.println("\t-java\t<directory>\tGenerate Java stub files");
4398 System.out.println("\t-cplus\t<directory>\tGenerate C++ stub files");
4399 System.out.println();
4404 * parseFile() prepares Lexer and Parser objects, then parses the file
4406 public static ParseNode parseFile(String file) {
4408 ParseNode pn = null;
4410 ComplexSymbolFactory csf = new ComplexSymbolFactory();
4411 ScannerBuffer lexer =
4412 new ScannerBuffer(new Lexer(new BufferedReader(new FileReader(file)),csf));
4413 Parser parse = new Parser(lexer,csf);
4414 pn = (ParseNode) parse.parse().value;
4415 } catch (Exception e) {
4416 e.printStackTrace();
4417 throw new Error("IoTCompiler: ERROR parsing policy file or wrong command line option: " + file);
4425 * Basic helper functions
4428 boolean newline=true;
4431 private void print(String str) {
4434 if (str.equals("}"))
4436 for(int i=0; i<tab; i++)
4446 * This function converts Java to C++ type for compilation
4448 private String convertType(String jType) {
4450 return mapPrimitives.get(jType);
4455 * A collection of methods with print-to-file functionality
4457 private void println(String str) {
4460 if (str.contains("}") && !str.contains("{"))
4462 for(int i=0; i<tab; i++)
4471 private void updatetabbing(String str) {
4473 tablevel+=count(str,'{')-count(str,'}');
4477 private int count(String str, char key) {
4478 char[] array = str.toCharArray();
4480 for(int i=0; i<array.length; i++) {
4481 if (array[i] == key)
4488 private void createDirectory(String dirName) {
4490 File file = new File(dirName);
4491 if (!file.exists()) {
4493 System.out.println("IoTCompiler: Directory " + dirName + " has been created!");
4495 System.out.println("IoTCompiler: Failed to create directory " + dirName + "!");
4498 System.out.println("IoTCompiler: Directory " + dirName + " exists...");
4503 // Create a directory and possibly a sub directory
4504 private String createDirectories(String dir, String subdir) {
4507 createDirectory(path);
4508 if (subdir != null) {
4509 path = path + "/" + subdir;
4510 createDirectory(path);
4516 // Inserting array members into a Map object
4517 // that maps arrKey to arrVal objects
4518 private void arraysToMap(Map map, Object[] arrKey, Object[] arrVal) {
4520 for(int i = 0; i < arrKey.length; i++) {
4522 map.put(arrKey[i], arrVal[i]);
4527 // Return parameter category, i.e. PRIMITIVES, NONPRIMITIVES, USERDEFINED, ENUM, or STRUCT
4528 private ParamCategory getParamCategory(String paramType) {
4530 if (mapPrimitives.containsKey(paramType)) {
4531 return ParamCategory.PRIMITIVES;
4532 // We can either use mapNonPrimitivesJava or mapNonPrimitivesCplus here
4533 } else if (mapNonPrimitivesJava.containsKey(getSimpleType(paramType))) {
4534 return ParamCategory.NONPRIMITIVES;
4535 } else if (isEnumClass(paramType)) {
4536 return ParamCategory.ENUM;
4537 } else if (isStructClass(paramType)) {
4538 return ParamCategory.STRUCT;
4540 return ParamCategory.USERDEFINED;
4544 // Return full class name for non-primitives to generate Java import statements
4545 // e.g. java.util.Set for Set
4546 private String getNonPrimitiveJavaClass(String paramNonPrimitives) {
4548 return mapNonPrimitivesJava.get(paramNonPrimitives);
4552 // Return full class name for non-primitives to generate Cplus include statements
4553 // e.g. #include <set> for Set
4554 private String getNonPrimitiveCplusClass(String paramNonPrimitives) {
4556 return mapNonPrimitivesCplus.get(paramNonPrimitives);
4560 // Get simple types, e.g. HashSet for HashSet<...>
4561 // Basically strip off the "<...>"
4562 private String getSimpleType(String paramType) {
4564 // Check if this is generics
4565 if(paramType.contains("<")) {
4566 String[] type = paramType.split("<");
4573 // Generate a set of standard classes for import statements
4574 private List<String> getStandardJavaImportClasses() {
4576 List<String> importClasses = new ArrayList<String>();
4577 // Add the standard list first
4578 importClasses.add("java.io.IOException");
4579 importClasses.add("java.util.List");
4580 importClasses.add("java.util.ArrayList");
4581 importClasses.add("java.util.Arrays");
4582 importClasses.add("iotrmi.Java.IoTRMICall");
4583 importClasses.add("iotrmi.Java.IoTRMIObject");
4585 return importClasses;
4589 // Generate a set of standard classes for import statements
4590 private List<String> getStandardCplusIncludeClasses() {
4592 List<String> importClasses = new ArrayList<String>();
4593 // Add the standard list first
4594 importClasses.add("<vector>");
4595 importClasses.add("<set>");
4596 importClasses.add("\"IoTRMICall.hpp\"");
4597 importClasses.add("\"IoTRMIObject.hpp\"");
4599 return importClasses;
4603 // Combine all classes for import statements
4604 private List<String> getAllLibClasses(Collection<String> stdLibClasses, Collection<String> libClasses) {
4606 List<String> allLibClasses = new ArrayList<String>(stdLibClasses);
4607 // Iterate over the list of import classes
4608 for (String str : libClasses) {
4609 if (!allLibClasses.contains(str)) {
4610 allLibClasses.add(str);
4613 return allLibClasses;
4618 // Generate a set of classes for import statements
4619 private Set<String> getImportClasses(Collection<String> methods, InterfaceDecl intDecl) {
4621 Set<String> importClasses = new HashSet<String>();
4622 for (String method : methods) {
4623 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4624 for (String paramType : methPrmTypes) {
4626 String simpleType = getSimpleType(paramType);
4627 if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
4628 importClasses.add(getNonPrimitiveJavaClass(simpleType));
4632 return importClasses;
4636 // Handle and return the correct enum declaration
4637 // In Java, if we declare enum in Camera interface, then it becomes "Camera.<enum>"
4638 private String getEnumParamDecl(String type, InterfaceDecl intDecl) {
4640 // Strips off array "[]" for return type
4641 String pureType = getSimpleArrayType(type);
4642 // Take the inner type of generic
4643 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4644 pureType = getTypeOfGeneric(type)[0];
4645 if (isEnumClass(pureType)) {
4646 String enumType = intDecl.getInterface() + "." + type;
4653 // Handle and return the correct type
4654 private String getEnumParam(String type, String param, int i) {
4656 // Strips off array "[]" for return type
4657 String pureType = getSimpleArrayType(type);
4658 // Take the inner type of generic
4659 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4660 pureType = getTypeOfGeneric(type)[0];
4661 if (isEnumClass(pureType)) {
4662 String enumParam = "paramEnum" + i;
4669 // Handle and return the correct enum declaration translate into int[]
4670 private String getEnumType(String type) {
4672 // Strips off array "[]" for return type
4673 String pureType = getSimpleArrayType(type);
4674 // Take the inner type of generic
4675 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4676 pureType = getTypeOfGeneric(type)[0];
4677 if (isEnumClass(pureType)) {
4678 String enumType = "int[]";
4685 // Handle and return the correct struct declaration
4686 private String getStructType(String type) {
4688 // Strips off array "[]" for return type
4689 String pureType = getSimpleArrayType(type);
4690 // Take the inner type of generic
4691 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES)
4692 pureType = getTypeOfGeneric(type)[0];
4693 if (isStructClass(pureType)) {
4694 String structType = "int";
4701 // Check if this an enum declaration
4702 private boolean isEnumClass(String type) {
4704 // Just iterate over the set of interfaces
4705 for (String intface : mapIntfacePTH.keySet()) {
4706 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4707 EnumDecl enumDecl = (EnumDecl) decHandler.getEnumDecl(intface);
4708 Set<String> setEnumDecl = enumDecl.getEnumDeclarations();
4709 if (setEnumDecl.contains(type))
4716 // Check if this an struct declaration
4717 private boolean isStructClass(String type) {
4719 // Just iterate over the set of interfaces
4720 for (String intface : mapIntfacePTH.keySet()) {
4721 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4722 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4723 List<String> listStructDecl = structDecl.getStructTypes();
4724 if (listStructDecl.contains(type))
4731 // Return a struct declaration
4732 private StructDecl getStructDecl(String type) {
4734 // Just iterate over the set of interfaces
4735 for (String intface : mapIntfacePTH.keySet()) {
4736 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4737 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4738 List<String> listStructDecl = structDecl.getStructTypes();
4739 if (listStructDecl.contains(type))
4746 // Return number of members (-1 if not found)
4747 private int getNumOfMembers(String type) {
4749 // Just iterate over the set of interfaces
4750 for (String intface : mapIntfacePTH.keySet()) {
4751 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
4752 StructDecl structDecl = (StructDecl) decHandler.getStructDecl(intface);
4753 List<String> listStructDecl = structDecl.getStructTypes();
4754 if (listStructDecl.contains(type))
4755 return structDecl.getNumOfMembers(type);
4761 // Generate a set of classes for include statements
4762 private Set<String> getIncludeClasses(Collection<String> methods, InterfaceDecl intDecl, String intface, boolean needExchange) {
4764 Set<String> includeClasses = new HashSet<String>();
4765 for (String method : methods) {
4767 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4768 List<String> methParams = intDecl.getMethodParams(method);
4769 for (int i = 0; i < methPrmTypes.size(); i++) {
4771 String simpleType = getSimpleType(methPrmTypes.get(i));
4772 String param = methParams.get(i);
4773 if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
4774 includeClasses.add("<" + getNonPrimitiveCplusClass(simpleType) + ">");
4775 } else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) {
4776 // For original interface, we need it exchanged... not for stub interfaces
4778 includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
4779 includeClasses.add("\"" + exchangeParamType(simpleType) + "_CallbackStub.hpp\"");
4781 includeClasses.add("\"" + simpleType + ".hpp\"");
4782 includeClasses.add("\"" + simpleType + "_CallbackSkeleton.hpp\"");
4784 } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.ENUM) {
4785 includeClasses.add("\"" + simpleType + ".hpp\"");
4786 } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.STRUCT) {
4787 includeClasses.add("\"" + simpleType + ".hpp\"");
4788 } else if (param.contains("[]")) {
4789 // Check if this is array for C++; translate into vector
4790 includeClasses.add("<vector>");
4794 return includeClasses;
4798 // Generate a set of callback classes
4799 private Set<String> getCallbackClasses(Collection<String> methods, InterfaceDecl intDecl) {
4801 Set<String> callbackClasses = new HashSet<String>();
4802 for (String method : methods) {
4804 List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
4805 List<String> methParams = intDecl.getMethodParams(method);
4806 for (int i = 0; i < methPrmTypes.size(); i++) {
4808 String type = methPrmTypes.get(i);
4809 if (getParamCategory(type) == ParamCategory.USERDEFINED) {
4810 callbackClasses.add(type);
4811 } else if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) {
4812 // Can be a List<...> of callback objects ...
4813 String genericType = getTypeOfGeneric(type)[0];
4814 if (getParamCategory(type) == ParamCategory.USERDEFINED) {
4815 callbackClasses.add(type);
4820 return callbackClasses;
4824 // Print import statements into file
4825 private void printImportStatements(Collection<String> importClasses) {
4827 for(String cls : importClasses) {
4828 println("import " + cls + ";");
4833 // Print include statements into file
4834 private void printIncludeStatements(Collection<String> includeClasses) {
4836 for(String cls : includeClasses) {
4837 println("#include " + cls);
4842 // Get the C++ version of a non-primitive type
4843 // e.g. set for Set and map for Map
4844 // Input nonPrimitiveType has to be generics in format
4845 private String[] getTypeOfGeneric(String nonPrimitiveType) {
4847 // Handle <, >, and , for 2-type generic/template
4848 String[] substr = nonPrimitiveType.split("<")[1].split(">")[0].split(",");
4853 // Gets generic type inside "<" and ">"
4854 private String getGenericType(String type) {
4856 // Handle <, >, and , for 2-type generic/template
4857 if (getParamCategory(type) == ParamCategory.NONPRIMITIVES) {
4858 String[] substr = type.split("<")[1].split(">")[0].split(",");
4865 // This helper function strips off array declaration, e.g. int[] becomes int
4866 private String getSimpleArrayType(String type) {
4868 // Handle [ for array declaration
4869 String substr = type;
4870 if (type.contains("[]")) {
4871 substr = type.split("\\[\\]")[0];
4877 // This helper function strips off array declaration, e.g. D[] becomes D
4878 private String getSimpleIdentifier(String ident) {
4880 // Handle [ for array declaration
4881 String substr = ident;
4882 if (ident.contains("[]")) {
4883 substr = ident.split("\\[\\]")[0];
4889 // Checks and gets type in C++
4890 private String checkAndGetCplusType(String paramType) {
4892 if (getParamCategory(paramType) == ParamCategory.PRIMITIVES) {
4893 return convertType(paramType);
4894 } else if (getParamCategory(paramType) == ParamCategory.NONPRIMITIVES) {
4896 // Check for generic/template format
4897 if (paramType.contains("<") && paramType.contains(">")) {
4899 String genericClass = getSimpleType(paramType);
4900 String[] genericType = getTypeOfGeneric(paramType);
4901 String cplusTemplate = null;
4902 if (genericType.length == 1) // Generic/template with one type
4903 cplusTemplate = getNonPrimitiveCplusClass(genericClass) +
4904 "<" + convertType(genericType[0]) + ">";
4905 else // Generic/template with two types
4906 cplusTemplate = getNonPrimitiveCplusClass(genericClass) +
4907 "<" + convertType(genericType[0]) + "," + convertType(genericType[1]) + ">";
4908 return cplusTemplate;
4910 return getNonPrimitiveCplusClass(paramType);
4911 } else if(paramType.contains("[]")) { // Array type (used for return type only)
4912 String cArray = "vector<" + getSimpleArrayType(paramType) + ">";
4914 } else if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
4915 return paramType + "*";
4917 // Just return it as is if it's not non-primitives
4919 //return checkAndGetParamClass(paramType, true);
4923 // Detect array declaration, e.g. int A[],
4924 // then generate "int A[]" in C++ as "vector<int> A"
4925 private String checkAndGetCplusArray(String paramType, String param) {
4927 String paramComplete = null;
4928 // Check for array declaration
4929 if (param.contains("[]")) {
4930 paramComplete = "vector<" + paramType + "> " + param.replace("[]","");
4932 // Just return it as is if it's not an array
4933 paramComplete = paramType + " " + param;
4935 return paramComplete;
4939 // Detect array declaration, e.g. int A[],
4940 // then generate "int A[]" in C++ as "vector<int> A"
4941 // This method just returns the type
4942 private String checkAndGetCplusArrayType(String paramType) {
4944 String paramTypeRet = null;
4945 // Check for array declaration
4946 if (paramType.contains("[]")) {
4947 String type = paramType.split("\\[\\]")[0];
4948 paramTypeRet = checkAndGetCplusType(type) + "[]";
4949 } else if (paramType.contains("vector")) {
4950 // Just return it as is if it's not an array
4951 String type = paramType.split("<")[1].split(">")[0];
4952 paramTypeRet = checkAndGetCplusType(type) + "[]";
4954 paramTypeRet = paramType;
4956 return paramTypeRet;
4960 // Detect array declaration, e.g. int A[],
4961 // then generate "int A[]" in C++ as "vector<int> A"
4962 // This method just returns the type
4963 private String checkAndGetCplusArrayType(String paramType, String param) {
4965 String paramTypeRet = null;
4966 // Check for array declaration
4967 if (param.contains("[]")) {
4968 paramTypeRet = checkAndGetCplusType(paramType) + "[]";
4969 } else if (paramType.contains("vector")) {
4970 // Just return it as is if it's not an array
4971 String type = paramType.split("<")[1].split(">")[0];
4972 paramTypeRet = checkAndGetCplusType(type) + "[]";
4974 paramTypeRet = paramType;
4976 return paramTypeRet;
4980 // Detect array declaration, e.g. int A[],
4981 // then generate type "int[]"
4982 private String checkAndGetArray(String paramType, String param) {
4984 String paramTypeRet = null;
4985 // Check for array declaration
4986 if (param.contains("[]")) {
4987 paramTypeRet = paramType + "[]";
4989 // Just return it as is if it's not an array
4990 paramTypeRet = paramType;
4992 return paramTypeRet;
4996 // Is array or list?
4997 private boolean isArrayOrList(String paramType, String param) {
4999 // Check for array declaration
5002 else if (isList(paramType))
5010 // For return type we use retType as input parameter
5011 private boolean isArray(String param) {
5013 // Check for array declaration
5014 if (param.contains("[]"))
5022 private boolean isList(String paramType) {
5024 // Check for array declaration
5025 if (paramType.contains("List"))
5032 // Get the right type for a callback object
5033 private String checkAndGetParamClass(String paramType) {
5035 // Check if this is generics
5036 if(getParamCategory(paramType) == ParamCategory.USERDEFINED) {
5037 return exchangeParamType(paramType);
5043 // Returns the other interface for type-checking purposes for USERDEFINED
5044 // classes based on the information provided in multiple policy files
5045 // e.g. return CameraWithXXX instead of Camera
5046 private String exchangeParamType(String intface) {
5048 // Param type that's passed is the interface name we need to look for
5049 // in the map of interfaces, based on available policy files.
5050 DeclarationHandler decHandler = mapIntDeclHand.get(intface);
5051 if (decHandler != null) {
5052 // We've found the required interface policy files
5053 RequiresDecl reqDecl = (RequiresDecl) decHandler.getRequiresDecl(intface);
5054 Set<String> setExchInt = reqDecl.getInterfaces();
5055 if (setExchInt.size() == 1) {
5056 Iterator iter = setExchInt.iterator();
5057 return (String) iter.next();
5059 throw new Error("IoTCompiler: Ambiguous stub interfaces: " + setExchInt.toString() +
5060 ". Only one new interface can be declared if the object " + intface +
5061 " needs to be passed in as an input parameter!");
5064 // NULL value - this means policy files missing
5065 throw new Error("IoTCompiler: Parameter type lookup failed for " + intface +
5066 "... Please provide the necessary policy files for user-defined types." +
5067 " If this is an array please type the brackets after the variable name," +
5068 " e.g. \"String str[]\", not \"String[] str\"." +
5069 " If this is a Collections (Java) / STL (C++) type, this compiler only" +
5070 " supports List/ArrayList (Java) or list (C++).");
5075 public static void main(String[] args) throws Exception {
5077 // If there is no argument or just "--help" or "-h", then invoke printUsage()
5078 if ((args[0].equals("-help") ||
5079 args[0].equals("--help")||
5080 args[0].equals("-h")) ||
5081 (args.length == 0)) {
5083 IoTCompiler.printUsage();
5085 } else if (args.length > 1) {
5087 IoTCompiler comp = new IoTCompiler();
5090 // Parse main policy file
5091 ParseNode pnPol = IoTCompiler.parseFile(args[i]);
5092 // Parse "requires" policy file
5093 ParseNode pnReq = IoTCompiler.parseFile(args[i+1]);
5094 // Get interface name
5095 String intface = ParseTreeHandler.getOrigIntface(pnPol);
5096 comp.setDataStructures(intface, pnPol, pnReq);
5097 comp.getMethodsForIntface(intface);
5099 // 1) Check if this is the last option before "-java" or "-cplus"
5100 // 2) Check if this is really the last option (no "-java" or "-cplus")
5101 } while(!args[i].equals("-java") &&
5102 !args[i].equals("-cplus") &&
5105 // Generate everything if we don't see "-java" or "-cplus"
5106 if (i == args.length) {
5107 comp.generateEnumJava();
5108 comp.generateStructJava();
5109 comp.generateJavaLocalInterfaces();
5110 comp.generateJavaInterfaces();
5111 comp.generateJavaStubClasses();
5112 comp.generateJavaCallbackStubClasses();
5113 comp.generateJavaSkeletonClass();
5114 comp.generateJavaCallbackSkeletonClass();
5115 comp.generateEnumCplus();
5116 comp.generateStructCplus();
5117 comp.generateCplusLocalInterfaces();
5118 comp.generateCPlusInterfaces();
5119 comp.generateCPlusStubClasses();
5120 comp.generateCPlusCallbackStubClasses();
5121 comp.generateCplusSkeletonClass();
5122 comp.generateCplusCallbackSkeletonClass();
5124 // Check other options
5125 while(i < args.length) {
5127 if (!args[i].equals("-java") &&
5128 !args[i].equals("-cplus")) {
5129 throw new Error("IoTCompiler: ERROR - unrecognized command line option: " + args[i]);
5131 if (i + 1 < args.length) {
5132 comp.setDirectory(args[i+1]);
5134 throw new Error("IoTCompiler: ERROR - please provide <directory> after option: " + args[i]);
5136 if (args[i].equals("-java")) {
5137 comp.generateEnumJava();
5138 comp.generateStructJava();
5139 comp.generateJavaLocalInterfaces();
5140 comp.generateJavaInterfaces();
5141 comp.generateJavaStubClasses();
5142 comp.generateJavaCallbackStubClasses();
5143 comp.generateJavaSkeletonClass();
5144 comp.generateJavaCallbackSkeletonClass();
5146 comp.generateEnumCplus();
5147 comp.generateStructCplus();
5148 comp.generateCplusLocalInterfaces();
5149 comp.generateCPlusInterfaces();
5150 comp.generateCPlusStubClasses();
5151 comp.generateCPlusCallbackStubClasses();
5152 comp.generateCplusSkeletonClass();
5153 comp.generateCplusCallbackSkeletonClass();
5160 // Need to at least have exactly 2 parameters, i.e. main policy file and requires file
5161 IoTCompiler.printUsage();
5162 throw new Error("IoTCompiler: At least two arguments (main and requires policy files) have to be provided!");