package uk.ac.imperial.lsds.java2sdg.codegenerator; import java.util.List; import soot.IntType; import uk.ac.imperial.lsds.java2sdg.bricks.TaskElement; import uk.ac.imperial.lsds.java2sdg.bricks.Variable; import uk.ac.imperial.lsds.java2sdg.bricks.SDG.SendType; public class SeepOperatorInternalCodeTemplate { public static String getCodeForMultiOp(List<TaskElement> tes){ StringBuilder sb = new StringBuilder(); sb.append("{"); // open block sb.append(_getCodeForMultiOp(tes)); sb.append("}"); // close block return sb.toString(); } private static String _getCodeForMultiOp(List<TaskElement> tes){ StringBuilder sb = new StringBuilder(); // Build IF block and insert code for first TE TaskElement firstTE = tes.remove(0); String initIFBlock = getInitIFBlock(); sb.append(initIFBlock); sb.append(_getCodeForSingleOp(firstTE)); sb.append("}"); // Once the IF block has started, we just complete it with else clauses int branchId = 1; // 0 is used for firstTE for(TaskElement te : tes){ sb.append("else if(branchId == "+branchId+"){"); branchId++; sb.append(_getCodeForSingleOp(te)); sb.append("}"); } return sb.toString(); } private static String getInitIFBlock(){ StringBuilder sb = new StringBuilder(); String unbox = getUnboxCode("java.lang.Integer", "branchId"); sb.append(unbox); sb.append("if(branchId == 0){"); return sb.toString(); } public static String getCodeForSingleOp(TaskElement te){ StringBuilder sb = new StringBuilder(); sb.append("{"); // open block sb.append(_getCodeForSingleOp(te)); sb.append("}"); // close block return sb.toString(); } private static String _getCodeForSingleOp(TaskElement te){ // Extract and synthesize code for getting the right variables. This is constant List<Variable> localVars = te.getLocalVars(); String header = getCodeToLocalVars(localVars); // Append TE code String code = te.getCode(); // Get code to send downstream. Append branching id always. SendType st = te.getSendType(); List<Variable> varsToStream = te.getVarsToStream(); // Create var for branchId and append at the beginning of varsToStream Variable branchId = Variable.var(IntType.v(), "branchId"); //FIXME: should not be null if there is a configured sink. String footer = ""; if(varsToStream != null){ varsToStream.add(0, branchId); footer = getSendCode(varsToStream, st); } StringBuilder sb = new StringBuilder(); // sb.append("{"); // open block sb.append(header); sb.append(code); sb.append("int branchId = "+te.getSendType().getBranchingIdentifier()+";"); // declare branchid before sending sb.append(footer); // sb.append("}"); // close block return sb.toString(); } private static String getCodeToLocalVars(List<Variable> localVars){ StringBuilder code = new StringBuilder(); for(int i = 0; i<localVars.size(); i++){ Variable v = localVars.get(i); String type = v.getType(); String name = v.getName(); String unbox = getUnboxCode(type, name); // String stmt = "Integer "+localVars.get(i)+" = $1.getInt("+"\""+localVars.get(i)+"\""+");\n"; // String stmt_unbox = "int "+localVars.get(i)+" = "+localVars.get(i)+".intValue();"; // code.append(stmt); code.append(unbox); } return code.toString(); } private static String getUnboxCode(String type, String name){ StringBuilder sb = new StringBuilder(); System.out.println("type: "+type); String varType_stmt1 = null; String unboxVarMethodName_stmt1 = null; String varType_stmt2 = null; String unboxVarMethodName_stmt2 = null; System.out.println("TYPE: "+type); if(type.equals("java.lang.Integer")){ varType_stmt1 = "Integer"; varType_stmt2 = "int"; unboxVarMethodName_stmt1 = " = $1.getInt("; unboxVarMethodName_stmt2 = ".intValue();"; } else if(type.equals("java.lang.String")){ varType_stmt1 = "String"; unboxVarMethodName_stmt1 = " = $1.getString("; } else if(type.equals("java.lang.Long")){ varType_stmt1 = "Long"; varType_stmt2 = "long"; unboxVarMethodName_stmt1 = " = $1.getLong("; unboxVarMethodName_stmt2 = ".longValue();"; } else if(type.equals("java.lang.Double")){ varType_stmt1 = "Double"; varType_stmt2 = "double"; unboxVarMethodName_stmt1 = " = $1.getDouble("; unboxVarMethodName_stmt2 = ".doubleValue();"; } else if(type.equals("java.lang.Character")){ varType_stmt1 = "Character"; varType_stmt2 = "char"; unboxVarMethodName_stmt1 = " = $1.getChar("; unboxVarMethodName_stmt2 = ".charValue();"; } else if(type.equals("java.lang.Boolean")){ varType_stmt1 = "Boolean"; varType_stmt2 = "boolean"; unboxVarMethodName_stmt1 = " = $1.getBoolean("; unboxVarMethodName_stmt2 = ".booleanValue();"; } else{ System.out.println("ERROR. getUnboxCode unknows type"); System.exit(0); } // Build actual lines sb.append(varType_stmt1+" "+name+" "+unboxVarMethodName_stmt1+"\""+name+"\""+");\n"); if(varType_stmt2 != null){ // It there is such statement 2 sb.append(varType_stmt2+" "+name+" = "+name+""+unboxVarMethodName_stmt2); } return sb.toString(); } private static String getSendCode(List<Variable> varsToStream, SendType st){ String code = null; if(st.equals(SendType.SEND)){ code = getCodeToSend(varsToStream); } else if(st.equals(SendType.SEND_ALL)){ } else if(st.equals(SendType.SEND_KEY)){ } else if(st.equals(SendType.SEND_STREAMID)){ } else if(st.equals(SendType.SEND_STREAMID_KEY)){ } return code; } private static String getCodeToSend(List<Variable> varsToStream){ StringBuffer vars = new StringBuffer(); // vars.append("int branchingId = "+); for(int i = 0; i<varsToStream.size(); i++){ Variable v = varsToStream.get(i); String boxCode = getBoxCode(v.getType(), v.getName()); if(i == (varsToStream.size()-1)) vars.append(boxCode); else vars.append(boxCode+", "); } // Note that $1 is the tuple we receive -> data String code = "" + "DataTuple output = $1.setValues(new Object[] {"+vars.toString()+"});\n" + "api.send(output);\n" + ""; return code; } private static String getBoxCode(String type, String name){ String c = null; if(type.equals("java.lang.Integer") || type.equals("int")){ c = "new Integer("+name+")"; } else if(type.equals("java.lang.String")){ c = "new String("+name+")"; } else{ System.out.println("ERROR. getBoxCode unknows type"); System.exit(0); } return c; } private static String getCodeToSend_Source(List<String> varsToStream){ StringBuffer vars = new StringBuffer(); for(int i = 0; i<varsToStream.size(); i++){ //FIXME: assuming always integer for debugging if(i == (varsToStream.size()-1)) vars.append("new Integer("+varsToStream.get(i)+")"); else vars.append("new Integer("+varsToStream.get(i)+"), "); } // Note that $1 is the tuple we receive -> data String code = "" + "DataTuple output = tuple.newTuple(new Object[] {"+vars.toString()+"});\n" + "api.send(output);\n" + ""; return code; } }